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