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