1 /*
2  * Copyright (C) 2010 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 
17 #ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
18 #define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
19 
20 #include <SkDrawFilter.h>
21 #include <SkMatrix.h>
22 #include <SkPaint.h>
23 #include <SkPath.h>
24 #include <SkRegion.h>
25 #include <SkTLazy.h>
26 #include <cutils/compiler.h>
27 
28 #include "Canvas.h"
29 #include "CanvasState.h"
30 #include "DisplayList.h"
31 #include "SkiaCanvasProxy.h"
32 #include "RenderNode.h"
33 #include "ResourceCache.h"
34 
35 namespace android {
36 namespace uirenderer {
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // Defines
40 ///////////////////////////////////////////////////////////////////////////////
41 
42 // Debug
43 #if DEBUG_DISPLAY_LIST
44     #define DISPLAY_LIST_LOGD(...) ALOGD(__VA_ARGS__)
45 #else
46     #define DISPLAY_LIST_LOGD(...)
47 #endif
48 
49 ///////////////////////////////////////////////////////////////////////////////
50 // Display list
51 ///////////////////////////////////////////////////////////////////////////////
52 
53 class DeferredDisplayList;
54 class DeferredLayerUpdater;
55 class DisplayListOp;
56 class DrawOp;
57 class RenderNode;
58 class StateOp;
59 
60 /**
61  * Records drawing commands in a display list for later playback into an OpenGLRenderer.
62  */
63 class ANDROID_API DisplayListCanvas: public Canvas, public CanvasStateClient {
64 public:
65     DisplayListCanvas();
66     virtual ~DisplayListCanvas();
67 
68     void insertReorderBarrier(bool enableReorder);
69 
70     DisplayListData* finishRecording();
71 
72 // ----------------------------------------------------------------------------
73 // HWUI Frame state operations
74 // ----------------------------------------------------------------------------
75 
76     void prepareDirty(float left, float top, float right, float bottom);
prepare()77     void prepare() { prepareDirty(0.0f, 0.0f, width(), height()); }
78     bool finish();
79     void interrupt();
80     void resume();
81 
82 // ----------------------------------------------------------------------------
83 // HWUI Canvas state operations
84 // ----------------------------------------------------------------------------
85 
setViewport(int width,int height)86     void setViewport(int width, int height) { mState.setViewport(width, height); }
87 
getRenderTargetClipBounds()88     const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); }
89 
isCurrentTransformSimple()90     bool isCurrentTransformSimple() {
91         return mState.currentTransform()->isSimple();
92     }
93 
94 // ----------------------------------------------------------------------------
95 // HWUI Canvas draw operations
96 // ----------------------------------------------------------------------------
97 
98     // Bitmap-based
99     void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
100     // TODO: move drawPatch() to Canvas.h
101     void drawPatch(const SkBitmap& bitmap, const Res_png_9patch* patch,
102             float left, float top, float right, float bottom, const SkPaint* paint);
103 
104     // Shapes
105     void drawRects(const float* rects, int count, const SkPaint* paint);
106     void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
107                 CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
108                 CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
109                 CanvasPropertyPaint* paint);
110     void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
111                 CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
112 
113 
114 // ----------------------------------------------------------------------------
115 // HWUI Canvas draw operations - special
116 // ----------------------------------------------------------------------------
117     void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y);
118     void drawRenderNode(RenderNode* renderNode);
119 
120     // TODO: rename for consistency
121     void callDrawGLFunction(Functor* functor);
122 
setHighContrastText(bool highContrastText)123     void setHighContrastText(bool highContrastText) {
124         mHighContrastText = highContrastText;
125     }
126 
127 // ----------------------------------------------------------------------------
128 // CanvasStateClient interface
129 // ----------------------------------------------------------------------------
onViewportInitialized()130     virtual void onViewportInitialized() override { }
onSnapshotRestored(const Snapshot & removed,const Snapshot & restored)131     virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override { }
getTargetFbo()132     virtual GLuint getTargetFbo() const override { return -1; }
133 
134 // ----------------------------------------------------------------------------
135 // android/graphics/Canvas interface
136 // ----------------------------------------------------------------------------
137     virtual SkCanvas* asSkCanvas() override;
138 
setBitmap(const SkBitmap & bitmap)139     virtual void setBitmap(const SkBitmap& bitmap) override {
140         LOG_ALWAYS_FATAL("DisplayListCanvas is not backed by a bitmap.");
141     }
142 
isOpaque()143     virtual bool isOpaque() override { return false; }
width()144     virtual int width() override { return mState.getWidth(); }
height()145     virtual int height() override { return mState.getHeight(); }
146 
147 // ----------------------------------------------------------------------------
148 // android/graphics/Canvas state operations
149 // ----------------------------------------------------------------------------
150     // Save (layer)
getSaveCount()151     virtual int getSaveCount() const override { return mState.getSaveCount(); }
152     virtual int save(SkCanvas::SaveFlags flags) override;
153     virtual void restore() override;
154     virtual void restoreToCount(int saveCount) override;
155 
156     virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
157         SkCanvas::SaveFlags flags) override;
saveLayerAlpha(float left,float top,float right,float bottom,int alpha,SkCanvas::SaveFlags flags)158     virtual int saveLayerAlpha(float left, float top, float right, float bottom,
159             int alpha, SkCanvas::SaveFlags flags) override {
160         SkPaint paint;
161         paint.setAlpha(alpha);
162         return saveLayer(left, top, right, bottom, &paint, flags);
163     }
164 
165     // Matrix
getMatrix(SkMatrix * outMatrix)166     virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); }
167     virtual void setMatrix(const SkMatrix& matrix) override;
168     virtual void setLocalMatrix(const SkMatrix& matrix) override;
169 
170     virtual void concat(const SkMatrix& matrix) override;
171     virtual void rotate(float degrees) override;
172     virtual void scale(float sx, float sy) override;
173     virtual void skew(float sx, float sy) override;
174     virtual void translate(float dx, float dy) override;
175 
176     // Clip
177     virtual bool getClipBounds(SkRect* outRect) const override;
178     virtual bool quickRejectRect(float left, float top, float right, float bottom) const override;
179     virtual bool quickRejectPath(const SkPath& path) const override;
180 
181     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op) override;
182     virtual bool clipPath(const SkPath* path, SkRegion::Op op) override;
183     virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) override;
184 
185     // Misc
getDrawFilter()186     virtual SkDrawFilter* getDrawFilter() override { return mDrawFilter.get(); }
187     virtual void setDrawFilter(SkDrawFilter* filter) override;
188 
189 // ----------------------------------------------------------------------------
190 // android/graphics/Canvas draw operations
191 // ----------------------------------------------------------------------------
192     virtual void drawColor(int color, SkXfermode::Mode mode) override;
193     virtual void drawPaint(const SkPaint& paint) override;
194 
195     // Geometry
drawPoint(float x,float y,const SkPaint & paint)196     virtual void drawPoint(float x, float y, const SkPaint& paint) override {
197         float points[2] = { x, y };
198         drawPoints(points, 2, paint);
199     }
200     virtual void drawPoints(const float* points, int count, const SkPaint& paint) override;
drawLine(float startX,float startY,float stopX,float stopY,const SkPaint & paint)201     virtual void drawLine(float startX, float startY, float stopX, float stopY,
202             const SkPaint& paint) override {
203         float points[4] = { startX, startY, stopX, stopY };
204         drawLines(points, 4, paint);
205     }
206     virtual void drawLines(const float* points, int count, const SkPaint& paint) override;
207     virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override;
208     virtual void drawRoundRect(float left, float top, float right, float bottom,
209             float rx, float ry, const SkPaint& paint) override;
210     virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override;
211     virtual void drawOval(float left, float top, float right, float bottom, const SkPaint& paint) override;
212     virtual void drawArc(float left, float top, float right, float bottom,
213             float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) override;
214     virtual void drawPath(const SkPath& path, const SkPaint& paint) override;
drawVertices(SkCanvas::VertexMode vertexMode,int vertexCount,const float * verts,const float * tex,const int * colors,const uint16_t * indices,int indexCount,const SkPaint & paint)215     virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
216             const float* verts, const float* tex, const int* colors,
217             const uint16_t* indices, int indexCount, const SkPaint& paint) override
218         { /* DisplayListCanvas does not support drawVertices(); ignore */ }
219 
220     // Bitmap-based
221     virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint) override;
222     virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
223                             const SkPaint* paint) override;
224     virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
225             float srcRight, float srcBottom, float dstLeft, float dstTop,
226             float dstRight, float dstBottom, const SkPaint* paint) override;
227     virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
228             const float* vertices, const int* colors, const SkPaint* paint) override;
229 
230     // Text
231     virtual void drawText(const uint16_t* glyphs, const float* positions, int count,
232             const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
233             float boundsRight, float boundsBottom, float totalAdvance) override;
234     virtual void drawPosText(const uint16_t* text, const float* positions, int count,
235             int posCount, const SkPaint& paint) override;
236     virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
237             float hOffset, float vOffset, const SkPaint& paint) override;
drawTextAbsolutePos()238     virtual bool drawTextAbsolutePos() const override { return false; }
239 
240 
241 private:
242 
243     CanvasState mState;
244     std::unique_ptr<SkiaCanvasProxy> mSkiaCanvasProxy;
245 
246     enum DeferredBarrierType {
247         kBarrier_None,
248         kBarrier_InOrder,
249         kBarrier_OutOfOrder,
250     };
251 
252     void flushRestoreToCount();
253     void flushTranslate();
254     void flushReorderBarrier();
255 
alloc()256     LinearAllocator& alloc() { return mDisplayListData->allocator; }
257 
258     // Each method returns final index of op
259     size_t addOpAndUpdateChunk(DisplayListOp* op);
260     // flushes any deferred operations, and appends the op
261     size_t flushAndAddOp(DisplayListOp* op);
262 
263     size_t addStateOp(StateOp* op);
264     size_t addDrawOp(DrawOp* op);
265     size_t addRenderNodeOp(DrawRenderNodeOp* op);
266 
267     void refBitmapsInShader(const SkShader* shader);
268 
269     template<class T>
refBuffer(const T * srcBuffer,int32_t count)270     inline const T* refBuffer(const T* srcBuffer, int32_t count) {
271         if (!srcBuffer) return nullptr;
272 
273         T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T));
274         memcpy(dstBuffer, srcBuffer, count * sizeof(T));
275         return dstBuffer;
276     }
277 
refText(const char * text,size_t byteLength)278     inline char* refText(const char* text, size_t byteLength) {
279         return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
280     }
281 
refPath(const SkPath * path)282     inline const SkPath* refPath(const SkPath* path) {
283         if (!path) return nullptr;
284 
285         // The points/verbs within the path are refcounted so this copy operation
286         // is inexpensive and maintains the generationID of the original path.
287         const SkPath* cachedPath = new SkPath(*path);
288         mDisplayListData->pathResources.add(cachedPath);
289         return cachedPath;
290     }
291 
refPaint(const SkPaint * paint)292     inline const SkPaint* refPaint(const SkPaint* paint) {
293         if (!paint) return nullptr;
294 
295         // If there is a draw filter apply it here and store the modified paint
296         // so that we don't need to modify the paint every time we access it.
297         SkTLazy<SkPaint> filteredPaint;
298         if (mDrawFilter.get()) {
299             filteredPaint.set(*paint);
300             mDrawFilter->filter(filteredPaint.get(), SkDrawFilter::kPaint_Type);
301             paint = filteredPaint.get();
302         }
303 
304         // compute the hash key for the paint and check the cache.
305         const uint32_t key = paint->getHash();
306         const SkPaint* cachedPaint = mPaintMap.valueFor(key);
307         // In the unlikely event that 2 unique paints have the same hash we do a
308         // object equality check to ensure we don't erroneously dedup them.
309         if (cachedPaint == nullptr || *cachedPaint != *paint) {
310             cachedPaint = new SkPaint(*paint);
311             std::unique_ptr<const SkPaint> copy(cachedPaint);
312             mDisplayListData->paints.push_back(std::move(copy));
313 
314             // replaceValueFor() performs an add if the entry doesn't exist
315             mPaintMap.replaceValueFor(key, cachedPaint);
316             refBitmapsInShader(cachedPaint->getShader());
317         }
318 
319         return cachedPaint;
320     }
321 
copyPaint(const SkPaint * paint)322     inline SkPaint* copyPaint(const SkPaint* paint) {
323         if (!paint) return nullptr;
324 
325         SkPaint* returnPaint = new SkPaint(*paint);
326         std::unique_ptr<const SkPaint> copy(returnPaint);
327         mDisplayListData->paints.push_back(std::move(copy));
328 
329         return returnPaint;
330     }
331 
refRegion(const SkRegion * region)332     inline const SkRegion* refRegion(const SkRegion* region) {
333         if (!region) {
334             return region;
335         }
336 
337         const SkRegion* cachedRegion = mRegionMap.valueFor(region);
338         // TODO: Add generation ID to SkRegion
339         if (cachedRegion == nullptr) {
340             std::unique_ptr<const SkRegion> copy(new SkRegion(*region));
341             cachedRegion = copy.get();
342             mDisplayListData->regions.push_back(std::move(copy));
343 
344             // replaceValueFor() performs an add if the entry doesn't exist
345             mRegionMap.replaceValueFor(region, cachedRegion);
346         }
347 
348         return cachedRegion;
349     }
350 
refBitmap(const SkBitmap & bitmap)351     inline const SkBitmap* refBitmap(const SkBitmap& bitmap) {
352         // Note that this assumes the bitmap is immutable. There are cases this won't handle
353         // correctly, such as creating the bitmap from scratch, drawing with it, changing its
354         // contents, and drawing again. The only fix would be to always copy it the first time,
355         // which doesn't seem worth the extra cycles for this unlikely case.
356         SkBitmap* localBitmap = new (alloc()) SkBitmap(bitmap);
357         alloc().autoDestroy(localBitmap);
358         mDisplayListData->bitmapResources.push_back(localBitmap);
359         return localBitmap;
360     }
361 
refPatch(const Res_png_9patch * patch)362     inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
363         mDisplayListData->patchResources.add(patch);
364         mResourceCache.incrementRefcount(patch);
365         return patch;
366     }
367 
368     DefaultKeyedVector<uint32_t, const SkPaint*> mPaintMap;
369     DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
370     DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
371 
372     ResourceCache& mResourceCache;
373     DisplayListData* mDisplayListData;
374 
375     float mTranslateX;
376     float mTranslateY;
377     bool mHasDeferredTranslate;
378     DeferredBarrierType mDeferredBarrierType;
379     bool mHighContrastText;
380 
381     int mRestoreSaveCount;
382 
383     SkAutoTUnref<SkDrawFilter> mDrawFilter;
384 
385     friend class RenderNode;
386 
387 }; // class DisplayListCanvas
388 
389 }; // namespace uirenderer
390 }; // namespace android
391 
392 #endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
393