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 "RenderNode.h"
23 #include "VectorDrawable.h"
24 #include "hwui/Canvas.h"
25 #include "hwui/Paint.h"
26 
27 #include <SkCanvas.h>
28 #include "src/core/SkArenaAlloc.h"
29 
30 #include <cassert>
31 #include <optional>
32 
33 namespace android {
34 
35 // Holds an SkCanvas reference plus additional native data.
36 class SkiaCanvas : public Canvas {
37 public:
38     explicit SkiaCanvas(const SkBitmap& bitmap);
39 
40     /**
41      *  Create a new SkiaCanvas.
42      *
43      *  @param canvas SkCanvas to handle calls made to this SkiaCanvas. Must
44      *      not be NULL. This constructor does not take ownership, so the caller
45      *      must guarantee that it remains valid while the SkiaCanvas is valid.
46      */
47     explicit SkiaCanvas(SkCanvas* canvas);
48 
49     virtual ~SkiaCanvas();
50 
resetRecording(int width,int height,uirenderer::RenderNode * renderNode)51     virtual void resetRecording(int width, int height,
52                                 uirenderer::RenderNode* renderNode) override {
53         LOG_ALWAYS_FATAL("SkiaCanvas cannot be reset as a recording canvas");
54     }
55 
finishRecording()56     virtual uirenderer::DisplayList* finishRecording() override {
57         LOG_ALWAYS_FATAL("SkiaCanvas does not produce a DisplayList");
58         return nullptr;
59     }
insertReorderBarrier(bool enableReorder)60     virtual void insertReorderBarrier(bool enableReorder) override {
61         LOG_ALWAYS_FATAL("SkiaCanvas does not support reordering barriers");
62     }
63 
64     virtual void setBitmap(const SkBitmap& bitmap) override;
65 
66     virtual bool isOpaque() override;
67     virtual int width() override;
68     virtual int height() override;
69 
70     virtual int getSaveCount() const override;
71     virtual int save(SaveFlags::Flags flags) override;
72     virtual void restore() override;
73     virtual void restoreToCount(int saveCount) override;
74     virtual void restoreUnclippedLayer(int saveCount, const SkPaint& paint) override;
75 
76     virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
77                           SaveFlags::Flags flags) override;
78     virtual int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
79                                SaveFlags::Flags flags) override;
80     virtual int saveUnclippedLayer(int left, int top, int right, int bottom) override;
81 
82     virtual void getMatrix(SkMatrix* outMatrix) const override;
83     virtual void setMatrix(const SkMatrix& matrix) override;
84     virtual void concat(const SkMatrix& matrix) override;
85     virtual void rotate(float degrees) override;
86     virtual void scale(float sx, float sy) override;
87     virtual void skew(float sx, float sy) override;
88     virtual void translate(float dx, float dy) override;
89 
90     virtual bool getClipBounds(SkRect* outRect) const override;
91     virtual bool quickRejectRect(float left, float top, float right, float bottom) const override;
92     virtual bool quickRejectPath(const SkPath& path) const override;
93     virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) override;
94     virtual bool clipPath(const SkPath* path, SkClipOp op) override;
95 
96     virtual PaintFilter* getPaintFilter() override;
97     virtual void setPaintFilter(sk_sp<PaintFilter> paintFilter) override;
98 
99     virtual SkCanvasState* captureCanvasState() const override;
100 
101     virtual void drawColor(int color, SkBlendMode mode) override;
102     virtual void drawPaint(const SkPaint& paint) override;
103 
104     virtual void drawPoint(float x, float y, const Paint& paint) override;
105     virtual void drawPoints(const float* points, int count, const Paint& paint) override;
106     virtual void drawLine(float startX, float startY, float stopX, float stopY,
107                           const Paint& paint) override;
108     virtual void drawLines(const float* points, int count, const Paint& paint) override;
109     virtual void drawRect(float left, float top, float right, float bottom,
110                           const Paint& paint) override;
111     virtual void drawRegion(const SkRegion& region, const Paint& paint) override;
112     virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
113                                const Paint& paint) override;
114 
115    virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
116                                const Paint& paint) override;
117 
118     virtual void drawCircle(float x, float y, float radius, const Paint& paint) override;
119     virtual void drawOval(float left, float top, float right, float bottom,
120                           const Paint& paint) override;
121     virtual void drawArc(float left, float top, float right, float bottom, float startAngle,
122                          float sweepAngle, bool useCenter, const Paint& paint) override;
123     virtual void drawPath(const SkPath& path, const Paint& paint) override;
124     virtual void drawVertices(const SkVertices*, SkBlendMode, const Paint& paint) override;
125 
126     virtual void drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) override;
127     virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const Paint* paint) override;
128     virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
129                             float srcBottom, float dstLeft, float dstTop, float dstRight,
130                             float dstBottom, const Paint* paint) override;
131     virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
132                                 const float* vertices, const int* colors,
133                                 const Paint* paint) override;
134     virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk, float dstLeft,
135                                float dstTop, float dstRight, float dstBottom,
136                                const Paint* paint) override;
137     virtual double drawAnimatedImage(AnimatedImageDrawable* imgDrawable) override;
138 
139     virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
140 
141     virtual void drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
142                                uirenderer::CanvasPropertyPrimitive* top,
143                                uirenderer::CanvasPropertyPrimitive* right,
144                                uirenderer::CanvasPropertyPrimitive* bottom,
145                                uirenderer::CanvasPropertyPrimitive* rx,
146                                uirenderer::CanvasPropertyPrimitive* ry,
147                                uirenderer::CanvasPropertyPaint* paint) override;
148     virtual void drawCircle(uirenderer::CanvasPropertyPrimitive* x,
149                             uirenderer::CanvasPropertyPrimitive* y,
150                             uirenderer::CanvasPropertyPrimitive* radius,
151                             uirenderer::CanvasPropertyPaint* paint) override;
152 
153     virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
154     virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
155     virtual void callDrawGLFunction(Functor* functor,
156                                     uirenderer::GlFunctorLifecycleListener* listener) override;
157     virtual void drawPicture(const SkPicture& picture) override;
158 
159 protected:
160     SkiaCanvas();
asSkCanvas()161     SkCanvas* asSkCanvas() { return mCanvas; }
162     void reset(SkCanvas* skiaCanvas);
drawDrawable(SkDrawable * drawable)163     void drawDrawable(SkDrawable* drawable) { mCanvas->drawDrawable(drawable); }
164 
165     virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const Paint& paint, float x,
166                             float y, float boundsLeft, float boundsTop, float boundsRight,
167                             float boundsBottom, float totalAdvance) override;
168     virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
169                                   const Paint& paint, const SkPath& path, size_t start,
170                                   size_t end) override;
171 
172     /** This class acts as a copy on write SkPaint.
173      *
174      *  Initially this will be the SkPaint passed to the contructor.
175      *  The first time writable() is called this will become a copy of the
176      *  initial SkPaint (or a default SkPaint if nullptr).
177      */
178     struct PaintCoW {
PaintCoWPaintCoW179         PaintCoW(const SkPaint& that) : mPtr(&that) {}
PaintCoWPaintCoW180         PaintCoW(const SkPaint* ptr) : mPtr(ptr) {}
181         PaintCoW(const PaintCoW&) = delete;
182         PaintCoW(PaintCoW&&) = delete;
183         PaintCoW& operator=(const PaintCoW&) = delete;
184         PaintCoW& operator=(PaintCoW&&) = delete;
writeablePaintCoW185         SkPaint& writeable() {
186             if (!mStorage) {
187                 if (!mPtr) {
188                     mStorage.emplace();
189                 } else {
190                     mStorage.emplace(*mPtr);
191                 }
192                 mPtr = &*mStorage;
193             }
194             return *mStorage;
195         }
196         operator const SkPaint*() const { return mPtr; }
197         const SkPaint* operator->() const { assert(mPtr); return mPtr; }
198         const SkPaint& operator*() const { assert(mPtr); return *mPtr; }
199         explicit operator bool() { return mPtr != nullptr; }
200     private:
201         const SkPaint* mPtr;
202         std::optional<SkPaint> mStorage;
203     };
204 
205     /** Filters the paint using the current paint filter.
206      *
207      *  @param paint the paint to filter. Will be initialized with the default
208      *      SkPaint before filtering if filtering is required.
209      */
210     PaintCoW&& filterPaint(PaintCoW&& paint) const;
211 
apply_looper(const Paint * paint,Proc proc)212     template <typename Proc> void apply_looper(const Paint* paint, Proc proc) {
213         SkPaint skp;
214         SkDrawLooper* looper = nullptr;
215         if (paint) {
216             skp = *filterPaint(paint);
217             looper = paint->getLooper();
218         }
219         if (looper) {
220             SkSTArenaAlloc<256> alloc;
221             SkDrawLooper::Context* ctx = looper->makeContext(&alloc);
222             if (ctx) {
223                 SkDrawLooper::Context::Info info;
224                 for (;;) {
225                     SkPaint p = skp;
226                     if (!ctx->next(&info, &p)) {
227                         break;
228                     }
229                     mCanvas->save();
230                     mCanvas->translate(info.fTranslate.fX, info.fTranslate.fY);
231                     proc(p);
232                     mCanvas->restore();
233                 }
234             }
235         } else {
236             proc(skp);
237         }
238     }
239 
240 
241 private:
242     struct SaveRec {
243         int saveCount;
244         SaveFlags::Flags saveFlags;
245         size_t clipIndex;
246     };
247 
248     const SaveRec* currentSaveRec() const;
249     void recordPartialSave(SaveFlags::Flags flags);
250 
251     template <typename T>
252     void recordClip(const T&, SkClipOp);
253     void applyPersistentClips(size_t clipStartIndex);
254 
255     void drawPoints(const float* points, int count, const Paint& paint, SkCanvas::PointMode mode);
256 
257     class Clip;
258 
259     std::unique_ptr<SkCanvas> mCanvasOwned;    // might own a canvas we allocated
260     SkCanvas* mCanvas;                         // we do NOT own this canvas, it must survive us
261                                                // unless it is the same as mCanvasOwned.get()
262     std::unique_ptr<SkDeque> mSaveStack;       // lazily allocated, tracks partial saves.
263     std::vector<Clip> mClipStack;              // tracks persistent clips.
264     sk_sp<PaintFilter> mPaintFilter;
265 };
266 
267 }  // namespace android
268