xref: /aosp_15_r20/frameworks/base/libs/hwui/SkiaCanvas.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker #pragma once
17*d57664e9SAndroid Build Coastguard Worker 
18*d57664e9SAndroid Build Coastguard Worker #include "CanvasProperty.h"
19*d57664e9SAndroid Build Coastguard Worker #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
20*d57664e9SAndroid Build Coastguard Worker #include "DeferredLayerUpdater.h"
21*d57664e9SAndroid Build Coastguard Worker #endif
22*d57664e9SAndroid Build Coastguard Worker #include <SkCanvas.h>
23*d57664e9SAndroid Build Coastguard Worker 
24*d57664e9SAndroid Build Coastguard Worker #include <cassert>
25*d57664e9SAndroid Build Coastguard Worker #include <deque>
26*d57664e9SAndroid Build Coastguard Worker #include <optional>
27*d57664e9SAndroid Build Coastguard Worker 
28*d57664e9SAndroid Build Coastguard Worker #include "RenderNode.h"
29*d57664e9SAndroid Build Coastguard Worker #include "VectorDrawable.h"
30*d57664e9SAndroid Build Coastguard Worker #include "hwui/BlurDrawLooper.h"
31*d57664e9SAndroid Build Coastguard Worker #include "hwui/Canvas.h"
32*d57664e9SAndroid Build Coastguard Worker #include "hwui/Paint.h"
33*d57664e9SAndroid Build Coastguard Worker #include "pipeline/skia/AnimatedDrawables.h"
34*d57664e9SAndroid Build Coastguard Worker 
35*d57664e9SAndroid Build Coastguard Worker enum class SkBlendMode;
36*d57664e9SAndroid Build Coastguard Worker class SkRRect;
37*d57664e9SAndroid Build Coastguard Worker 
38*d57664e9SAndroid Build Coastguard Worker namespace android {
39*d57664e9SAndroid Build Coastguard Worker 
40*d57664e9SAndroid Build Coastguard Worker // Holds an SkCanvas reference plus additional native data.
41*d57664e9SAndroid Build Coastguard Worker class SkiaCanvas : public Canvas {
42*d57664e9SAndroid Build Coastguard Worker public:
43*d57664e9SAndroid Build Coastguard Worker     explicit SkiaCanvas(const SkBitmap& bitmap);
44*d57664e9SAndroid Build Coastguard Worker 
45*d57664e9SAndroid Build Coastguard Worker     /**
46*d57664e9SAndroid Build Coastguard Worker      *  Create a new SkiaCanvas.
47*d57664e9SAndroid Build Coastguard Worker      *
48*d57664e9SAndroid Build Coastguard Worker      *  @param canvas SkCanvas to handle calls made to this SkiaCanvas. Must
49*d57664e9SAndroid Build Coastguard Worker      *      not be NULL. This constructor does not take ownership, so the caller
50*d57664e9SAndroid Build Coastguard Worker      *      must guarantee that it remains valid while the SkiaCanvas is valid.
51*d57664e9SAndroid Build Coastguard Worker      */
52*d57664e9SAndroid Build Coastguard Worker     explicit SkiaCanvas(SkCanvas* canvas);
53*d57664e9SAndroid Build Coastguard Worker 
54*d57664e9SAndroid Build Coastguard Worker     virtual ~SkiaCanvas();
55*d57664e9SAndroid Build Coastguard Worker 
resetRecording(int width,int height,uirenderer::RenderNode * renderNode)56*d57664e9SAndroid Build Coastguard Worker     virtual void resetRecording(int width, int height,
57*d57664e9SAndroid Build Coastguard Worker                                 uirenderer::RenderNode* renderNode) override {
58*d57664e9SAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("SkiaCanvas cannot be reset as a recording canvas");
59*d57664e9SAndroid Build Coastguard Worker     }
60*d57664e9SAndroid Build Coastguard Worker 
finishRecording(uirenderer::RenderNode *)61*d57664e9SAndroid Build Coastguard Worker     virtual void finishRecording(uirenderer::RenderNode*) override {
62*d57664e9SAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("SkiaCanvas does not produce a DisplayList");
63*d57664e9SAndroid Build Coastguard Worker     }
enableZ(bool enableZ)64*d57664e9SAndroid Build Coastguard Worker     virtual void enableZ(bool enableZ) override {
65*d57664e9SAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("SkiaCanvas does not support enableZ");
66*d57664e9SAndroid Build Coastguard Worker     }
67*d57664e9SAndroid Build Coastguard Worker 
68*d57664e9SAndroid Build Coastguard Worker     virtual void punchHole(const SkRRect& rect, float alpha) override;
69*d57664e9SAndroid Build Coastguard Worker 
70*d57664e9SAndroid Build Coastguard Worker     virtual void setBitmap(const SkBitmap& bitmap) override;
71*d57664e9SAndroid Build Coastguard Worker 
72*d57664e9SAndroid Build Coastguard Worker     virtual bool isOpaque() override;
73*d57664e9SAndroid Build Coastguard Worker     virtual int width() override;
74*d57664e9SAndroid Build Coastguard Worker     virtual int height() override;
75*d57664e9SAndroid Build Coastguard Worker 
76*d57664e9SAndroid Build Coastguard Worker     virtual int getSaveCount() const override;
77*d57664e9SAndroid Build Coastguard Worker     virtual int save(SaveFlags::Flags flags) override;
78*d57664e9SAndroid Build Coastguard Worker     virtual void restore() override;
79*d57664e9SAndroid Build Coastguard Worker     virtual void restoreToCount(int saveCount) override;
80*d57664e9SAndroid Build Coastguard Worker     virtual void restoreUnclippedLayer(int saveCount, const Paint& paint) override;
81*d57664e9SAndroid Build Coastguard Worker 
82*d57664e9SAndroid Build Coastguard Worker     virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint) override;
83*d57664e9SAndroid Build Coastguard Worker     virtual int saveLayerAlpha(float left, float top, float right, float bottom, int alpha) override;
84*d57664e9SAndroid Build Coastguard Worker     virtual int saveUnclippedLayer(int left, int top, int right, int bottom) override;
85*d57664e9SAndroid Build Coastguard Worker 
86*d57664e9SAndroid Build Coastguard Worker     virtual void getMatrix(SkMatrix* outMatrix) const override;
87*d57664e9SAndroid Build Coastguard Worker     virtual void setMatrix(const SkMatrix& matrix) override;
88*d57664e9SAndroid Build Coastguard Worker     virtual void concat(const SkMatrix& matrix) override;
89*d57664e9SAndroid Build Coastguard Worker     virtual void concat(const SkM44& matrix) override;
90*d57664e9SAndroid Build Coastguard Worker     virtual void rotate(float degrees) override;
91*d57664e9SAndroid Build Coastguard Worker     virtual void scale(float sx, float sy) override;
92*d57664e9SAndroid Build Coastguard Worker     virtual void skew(float sx, float sy) override;
93*d57664e9SAndroid Build Coastguard Worker     virtual void translate(float dx, float dy) override;
94*d57664e9SAndroid Build Coastguard Worker 
95*d57664e9SAndroid Build Coastguard Worker     virtual bool getClipBounds(SkRect* outRect) const override;
96*d57664e9SAndroid Build Coastguard Worker     virtual bool quickRejectRect(float left, float top, float right, float bottom) const override;
97*d57664e9SAndroid Build Coastguard Worker     virtual bool quickRejectPath(const SkPath& path) const override;
98*d57664e9SAndroid Build Coastguard Worker     virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) override;
99*d57664e9SAndroid Build Coastguard Worker     virtual bool clipPath(const SkPath* path, SkClipOp op) override;
100*d57664e9SAndroid Build Coastguard Worker     virtual void clipShader(sk_sp<SkShader> shader, SkClipOp op) override;
101*d57664e9SAndroid Build Coastguard Worker     virtual bool replaceClipRect_deprecated(float left, float top, float right,
102*d57664e9SAndroid Build Coastguard Worker                                             float bottom) override;
103*d57664e9SAndroid Build Coastguard Worker     virtual bool replaceClipPath_deprecated(const SkPath* path) override;
104*d57664e9SAndroid Build Coastguard Worker 
105*d57664e9SAndroid Build Coastguard Worker     virtual PaintFilter* getPaintFilter() override;
106*d57664e9SAndroid Build Coastguard Worker     virtual void setPaintFilter(sk_sp<PaintFilter> paintFilter) override;
107*d57664e9SAndroid Build Coastguard Worker 
108*d57664e9SAndroid Build Coastguard Worker     virtual SkCanvasState* captureCanvasState() const override;
109*d57664e9SAndroid Build Coastguard Worker 
110*d57664e9SAndroid Build Coastguard Worker     virtual void drawColor(int color, SkBlendMode mode) override;
111*d57664e9SAndroid Build Coastguard Worker     virtual void drawPaint(const Paint& paint) override;
112*d57664e9SAndroid Build Coastguard Worker 
113*d57664e9SAndroid Build Coastguard Worker     virtual void drawPoint(float x, float y, const Paint& paint) override;
114*d57664e9SAndroid Build Coastguard Worker     virtual void drawPoints(const float* points, int count, const Paint& paint) override;
115*d57664e9SAndroid Build Coastguard Worker     virtual void drawLine(float startX, float startY, float stopX, float stopY,
116*d57664e9SAndroid Build Coastguard Worker                           const Paint& paint) override;
117*d57664e9SAndroid Build Coastguard Worker     virtual void drawLines(const float* points, int count, const Paint& paint) override;
118*d57664e9SAndroid Build Coastguard Worker     virtual void drawRect(float left, float top, float right, float bottom,
119*d57664e9SAndroid Build Coastguard Worker                           const Paint& paint) override;
120*d57664e9SAndroid Build Coastguard Worker     virtual void drawRegion(const SkRegion& region, const Paint& paint) override;
121*d57664e9SAndroid Build Coastguard Worker     virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
122*d57664e9SAndroid Build Coastguard Worker                                const Paint& paint) override;
123*d57664e9SAndroid Build Coastguard Worker 
124*d57664e9SAndroid Build Coastguard Worker     virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
125*d57664e9SAndroid Build Coastguard Worker                                      const Paint& paint) override;
126*d57664e9SAndroid Build Coastguard Worker 
127*d57664e9SAndroid Build Coastguard Worker     virtual void drawCircle(float x, float y, float radius, const Paint& paint) override;
128*d57664e9SAndroid Build Coastguard Worker     virtual void drawOval(float left, float top, float right, float bottom,
129*d57664e9SAndroid Build Coastguard Worker                           const Paint& paint) override;
130*d57664e9SAndroid Build Coastguard Worker     virtual void drawArc(float left, float top, float right, float bottom, float startAngle,
131*d57664e9SAndroid Build Coastguard Worker                          float sweepAngle, bool useCenter, const Paint& paint) override;
132*d57664e9SAndroid Build Coastguard Worker     virtual void drawPath(const SkPath& path, const Paint& paint) override;
133*d57664e9SAndroid Build Coastguard Worker     virtual void drawVertices(const SkVertices*, SkBlendMode, const Paint& paint) override;
134*d57664e9SAndroid Build Coastguard Worker     virtual void drawMesh(const Mesh& mesh, sk_sp<SkBlender> blender, const Paint& paint) override;
135*d57664e9SAndroid Build Coastguard Worker 
136*d57664e9SAndroid Build Coastguard Worker     virtual void drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) override;
137*d57664e9SAndroid Build Coastguard Worker     virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const Paint* paint) override;
138*d57664e9SAndroid Build Coastguard Worker     virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
139*d57664e9SAndroid Build Coastguard Worker                             float srcBottom, float dstLeft, float dstTop, float dstRight,
140*d57664e9SAndroid Build Coastguard Worker                             float dstBottom, const Paint* paint) override;
141*d57664e9SAndroid Build Coastguard Worker     virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
142*d57664e9SAndroid Build Coastguard Worker                                 const float* vertices, const int* colors,
143*d57664e9SAndroid Build Coastguard Worker                                 const Paint* paint) override;
144*d57664e9SAndroid Build Coastguard Worker     virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk, float dstLeft,
145*d57664e9SAndroid Build Coastguard Worker                                float dstTop, float dstRight, float dstBottom,
146*d57664e9SAndroid Build Coastguard Worker                                const Paint* paint) override;
147*d57664e9SAndroid Build Coastguard Worker     virtual double drawAnimatedImage(AnimatedImageDrawable* imgDrawable) override;
148*d57664e9SAndroid Build Coastguard Worker 
149*d57664e9SAndroid Build Coastguard Worker     virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
150*d57664e9SAndroid Build Coastguard Worker 
151*d57664e9SAndroid Build Coastguard Worker     virtual void drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
152*d57664e9SAndroid Build Coastguard Worker                                uirenderer::CanvasPropertyPrimitive* top,
153*d57664e9SAndroid Build Coastguard Worker                                uirenderer::CanvasPropertyPrimitive* right,
154*d57664e9SAndroid Build Coastguard Worker                                uirenderer::CanvasPropertyPrimitive* bottom,
155*d57664e9SAndroid Build Coastguard Worker                                uirenderer::CanvasPropertyPrimitive* rx,
156*d57664e9SAndroid Build Coastguard Worker                                uirenderer::CanvasPropertyPrimitive* ry,
157*d57664e9SAndroid Build Coastguard Worker                                uirenderer::CanvasPropertyPaint* paint) override;
158*d57664e9SAndroid Build Coastguard Worker     virtual void drawCircle(uirenderer::CanvasPropertyPrimitive* x,
159*d57664e9SAndroid Build Coastguard Worker                             uirenderer::CanvasPropertyPrimitive* y,
160*d57664e9SAndroid Build Coastguard Worker                             uirenderer::CanvasPropertyPrimitive* radius,
161*d57664e9SAndroid Build Coastguard Worker                             uirenderer::CanvasPropertyPaint* paint) override;
162*d57664e9SAndroid Build Coastguard Worker     virtual void drawRipple(const uirenderer::skiapipeline::RippleDrawableParams& params) override;
163*d57664e9SAndroid Build Coastguard Worker 
164*d57664e9SAndroid Build Coastguard Worker     virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
165*d57664e9SAndroid Build Coastguard Worker     virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
166*d57664e9SAndroid Build Coastguard Worker     virtual void drawPicture(const SkPicture& picture) override;
167*d57664e9SAndroid Build Coastguard Worker 
168*d57664e9SAndroid Build Coastguard Worker protected:
169*d57664e9SAndroid Build Coastguard Worker     SkiaCanvas();
asSkCanvas()170*d57664e9SAndroid Build Coastguard Worker     SkCanvas* asSkCanvas() { return mCanvas; }
171*d57664e9SAndroid Build Coastguard Worker     void reset(SkCanvas* skiaCanvas);
drawDrawable(SkDrawable * drawable)172*d57664e9SAndroid Build Coastguard Worker     void drawDrawable(SkDrawable* drawable) { mCanvas->drawDrawable(drawable); }
173*d57664e9SAndroid Build Coastguard Worker 
174*d57664e9SAndroid Build Coastguard Worker     virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const Paint& paint, float x,
175*d57664e9SAndroid Build Coastguard Worker                             float y, float totalAdvance) override;
176*d57664e9SAndroid Build Coastguard Worker     virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
177*d57664e9SAndroid Build Coastguard Worker                                   const Paint& paint, const SkPath& path, size_t start,
178*d57664e9SAndroid Build Coastguard Worker                                   size_t end) override;
179*d57664e9SAndroid Build Coastguard Worker 
180*d57664e9SAndroid Build Coastguard Worker     virtual void onFilterPaint(Paint& paint);
181*d57664e9SAndroid Build Coastguard Worker 
filterPaint(const Paint & src)182*d57664e9SAndroid Build Coastguard Worker     Paint filterPaint(const Paint& src) {
183*d57664e9SAndroid Build Coastguard Worker         Paint dst(src);
184*d57664e9SAndroid Build Coastguard Worker         this->onFilterPaint(dst);
185*d57664e9SAndroid Build Coastguard Worker         return dst;
186*d57664e9SAndroid Build Coastguard Worker     }
187*d57664e9SAndroid Build Coastguard Worker 
188*d57664e9SAndroid Build Coastguard Worker     // proc(const SkPaint& modifiedPaint)
189*d57664e9SAndroid Build Coastguard Worker     template <typename Proc>
190*d57664e9SAndroid Build Coastguard Worker     void applyLooper(const Paint* paint, Proc proc, void (*preFilter)(SkPaint&) = nullptr) {
191*d57664e9SAndroid Build Coastguard Worker         BlurDrawLooper* looper = paint ? paint->getLooper() : nullptr;
192*d57664e9SAndroid Build Coastguard Worker         Paint pnt = paint ? *paint : Paint();
193*d57664e9SAndroid Build Coastguard Worker         if (preFilter) {
194*d57664e9SAndroid Build Coastguard Worker             preFilter(pnt);
195*d57664e9SAndroid Build Coastguard Worker         }
196*d57664e9SAndroid Build Coastguard Worker         this->onFilterPaint(pnt);
197*d57664e9SAndroid Build Coastguard Worker         if (looper) {
198*d57664e9SAndroid Build Coastguard Worker             looper->apply(pnt, [&](SkPoint offset, const Paint& modifiedPaint) {
199*d57664e9SAndroid Build Coastguard Worker                 mCanvas->save();
200*d57664e9SAndroid Build Coastguard Worker                 mCanvas->translate(offset.fX, offset.fY);
201*d57664e9SAndroid Build Coastguard Worker                 proc(modifiedPaint);
202*d57664e9SAndroid Build Coastguard Worker                 mCanvas->restore();
203*d57664e9SAndroid Build Coastguard Worker             });
204*d57664e9SAndroid Build Coastguard Worker         } else {
205*d57664e9SAndroid Build Coastguard Worker             proc(pnt);
206*d57664e9SAndroid Build Coastguard Worker         }
207*d57664e9SAndroid Build Coastguard Worker     }
208*d57664e9SAndroid Build Coastguard Worker 
209*d57664e9SAndroid Build Coastguard Worker private:
210*d57664e9SAndroid Build Coastguard Worker     struct SaveRec {
211*d57664e9SAndroid Build Coastguard Worker         int saveCount;
212*d57664e9SAndroid Build Coastguard Worker         SaveFlags::Flags saveFlags;
213*d57664e9SAndroid Build Coastguard Worker         size_t clipIndex;
214*d57664e9SAndroid Build Coastguard Worker 
SaveRecSaveRec215*d57664e9SAndroid Build Coastguard Worker         SaveRec(int saveCount, SaveFlags::Flags saveFlags, size_t clipIndex)
216*d57664e9SAndroid Build Coastguard Worker                 : saveCount(saveCount), saveFlags(saveFlags), clipIndex(clipIndex) {}
217*d57664e9SAndroid Build Coastguard Worker     };
218*d57664e9SAndroid Build Coastguard Worker 
219*d57664e9SAndroid Build Coastguard Worker     const SaveRec* currentSaveRec() const;
220*d57664e9SAndroid Build Coastguard Worker     void recordPartialSave(SaveFlags::Flags flags);
221*d57664e9SAndroid Build Coastguard Worker 
222*d57664e9SAndroid Build Coastguard Worker     template <typename T>
223*d57664e9SAndroid Build Coastguard Worker     void recordClip(const T&, SkClipOp);
224*d57664e9SAndroid Build Coastguard Worker     void applyPersistentClips(size_t clipStartIndex);
225*d57664e9SAndroid Build Coastguard Worker 
226*d57664e9SAndroid Build Coastguard Worker     void drawPoints(const float* points, int count, const Paint& paint, SkCanvas::PointMode mode);
227*d57664e9SAndroid Build Coastguard Worker 
228*d57664e9SAndroid Build Coastguard Worker     bool useGainmapShader(Bitmap& bitmap);
229*d57664e9SAndroid Build Coastguard Worker 
230*d57664e9SAndroid Build Coastguard Worker     class Clip;
231*d57664e9SAndroid Build Coastguard Worker 
232*d57664e9SAndroid Build Coastguard Worker     std::unique_ptr<SkCanvas> mCanvasOwned;  // Might own a canvas we allocated.
233*d57664e9SAndroid Build Coastguard Worker     SkCanvas* mCanvas;                       // We do NOT own this canvas, it must survive us
234*d57664e9SAndroid Build Coastguard Worker                                              // unless it is the same as mCanvasOwned.get().
235*d57664e9SAndroid Build Coastguard Worker     std::unique_ptr<std::deque<SaveRec>> mSaveStack;  // Lazily allocated, tracks partial saves.
236*d57664e9SAndroid Build Coastguard Worker     std::vector<Clip> mClipStack;                     // Tracks persistent clips.
237*d57664e9SAndroid Build Coastguard Worker     sk_sp<PaintFilter> mPaintFilter;
238*d57664e9SAndroid Build Coastguard Worker };
239*d57664e9SAndroid Build Coastguard Worker 
240*d57664e9SAndroid Build Coastguard Worker }  // namespace android
241