• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <SkMatrix.h>
21 #include <SkPaint.h>
22 #include <SkPath.h>
23 #include <cutils/compiler.h>
24 
25 #include "DisplayListLogBuffer.h"
26 #include "RenderNode.h"
27 #include "ResourceCache.h"
28 
29 namespace android {
30 namespace uirenderer {
31 
32 ///////////////////////////////////////////////////////////////////////////////
33 // Defines
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 // Debug
37 #if DEBUG_DISPLAY_LIST
38     #define DISPLAY_LIST_LOGD(...) ALOGD(__VA_ARGS__)
39 #else
40     #define DISPLAY_LIST_LOGD(...)
41 #endif
42 
43 ///////////////////////////////////////////////////////////////////////////////
44 // Display list
45 ///////////////////////////////////////////////////////////////////////////////
46 
47 class DeferredDisplayList;
48 class DeferredLayerUpdater;
49 class DisplayListRenderer;
50 class DisplayListOp;
51 class DrawOp;
52 class StateOp;
53 
54 /**
55  * Records drawing commands in a display list for later playback into an OpenGLRenderer.
56  */
57 class ANDROID_API DisplayListRenderer: public StatefulBaseRenderer {
58 public:
59     DisplayListRenderer();
60     virtual ~DisplayListRenderer();
61 
62     void insertReorderBarrier(bool enableReorder);
63 
64     DisplayListData* finishRecording();
65 
66 // ----------------------------------------------------------------------------
67 // Frame state operations
68 // ----------------------------------------------------------------------------
69     virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
70     virtual void finish();
71     virtual void interrupt();
72     virtual void resume();
73 
74 // ----------------------------------------------------------------------------
75 // Canvas state operations
76 // ----------------------------------------------------------------------------
77     // Save (layer)
78     virtual int save(int flags);
79     virtual void restore();
80     virtual void restoreToCount(int saveCount);
81     virtual int saveLayer(float left, float top, float right, float bottom,
82             const SkPaint* paint, int flags);
83 
84     // Matrix
85     virtual void translate(float dx, float dy, float dz = 0.0f);
86     virtual void rotate(float degrees);
87     virtual void scale(float sx, float sy);
88     virtual void skew(float sx, float sy);
89 
90     virtual void setMatrix(const SkMatrix& matrix);
91     virtual void concatMatrix(const SkMatrix& matrix);
92 
93     // Clip
94     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
95     virtual bool clipPath(const SkPath* path, SkRegion::Op op);
96     virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
97 
98     // Misc - should be implemented with SkPaint inspection
99     virtual void resetPaintFilter();
100     virtual void setupPaintFilter(int clearBits, int setBits);
101 
isCurrentTransformSimple()102     bool isCurrentTransformSimple() {
103         return currentTransform()->isSimple();
104     }
105 
106 // ----------------------------------------------------------------------------
107 // Canvas draw operations
108 // ----------------------------------------------------------------------------
109     virtual status_t drawColor(int color, SkXfermode::Mode mode);
110 
111     // Bitmap-based
112     virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
113     virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
114             float srcRight, float srcBottom, float dstLeft, float dstTop,
115             float dstRight, float dstBottom, const SkPaint* paint);
116     virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
117     virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
118             const float* vertices, const int* colors, const SkPaint* paint);
119     virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
120             float left, float top, float right, float bottom, const SkPaint* paint);
121 
122     // Shapes
123     virtual status_t drawRect(float left, float top, float right, float bottom,
124             const SkPaint* paint);
125     virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
126     virtual status_t drawRoundRect(float left, float top, float right, float bottom,
127             float rx, float ry, const SkPaint* paint);
128     virtual status_t drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
129                 CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
130                 CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
131                 CanvasPropertyPaint* paint);
132     virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
133     virtual status_t drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
134                 CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
135     virtual status_t drawOval(float left, float top, float right, float bottom,
136             const SkPaint* paint);
137     virtual status_t drawArc(float left, float top, float right, float bottom,
138             float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
139     virtual status_t drawPath(const SkPath* path, const SkPaint* paint);
140     virtual status_t drawLines(const float* points, int count, const SkPaint* paint);
141     virtual status_t drawPoints(const float* points, int count, const SkPaint* paint);
142 
143     // Text
144     virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
145             const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
146             DrawOpMode drawOpMode = kDrawOpMode_Immediate);
147     virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
148             float hOffset, float vOffset, const SkPaint* paint);
149     virtual status_t drawPosText(const char* text, int bytesCount, int count,
150             const float* positions, const SkPaint* paint);
151 
152 // ----------------------------------------------------------------------------
153 // Canvas draw operations - special
154 // ----------------------------------------------------------------------------
155     virtual status_t drawLayer(DeferredLayerUpdater* layerHandle, float x, float y);
156     virtual status_t drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags);
157 
158     // TODO: rename for consistency
159     virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty);
160 
setHighContrastText(bool highContrastText)161     void setHighContrastText(bool highContrastText) {
162         mHighContrastText = highContrastText;
163     }
164 private:
165     enum DeferredBarrierType {
166         kBarrier_None,
167         kBarrier_InOrder,
168         kBarrier_OutOfOrder,
169     };
170 
171     void flushRestoreToCount();
172     void flushTranslate();
173     void flushReorderBarrier();
174 
alloc()175     LinearAllocator& alloc() { return mDisplayListData->allocator; }
176 
177     // Each method returns final index of op
178     size_t addOpAndUpdateChunk(DisplayListOp* op);
179     // flushes any deferred operations, and appends the op
180     size_t flushAndAddOp(DisplayListOp* op);
181 
182     size_t addStateOp(StateOp* op);
183     size_t addDrawOp(DrawOp* op);
184     size_t addRenderNodeOp(DrawRenderNodeOp* op);
185 
186 
187     template<class T>
refBuffer(const T * srcBuffer,int32_t count)188     inline const T* refBuffer(const T* srcBuffer, int32_t count) {
189         if (!srcBuffer) return NULL;
190 
191         T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T));
192         memcpy(dstBuffer, srcBuffer, count * sizeof(T));
193         return dstBuffer;
194     }
195 
refText(const char * text,size_t byteLength)196     inline char* refText(const char* text, size_t byteLength) {
197         return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
198     }
199 
refPath(const SkPath * path)200     inline const SkPath* refPath(const SkPath* path) {
201         if (!path) return NULL;
202 
203         const SkPath* pathCopy = mPathMap.valueFor(path);
204         if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
205             SkPath* newPathCopy = new SkPath(*path);
206             newPathCopy->setSourcePath(path);
207 
208             pathCopy = newPathCopy;
209             // replaceValueFor() performs an add if the entry doesn't exist
210             mPathMap.replaceValueFor(path, pathCopy);
211             mDisplayListData->paths.add(pathCopy);
212         }
213         if (mDisplayListData->sourcePaths.indexOf(path) < 0) {
214             mResourceCache.incrementRefcount(path);
215             mDisplayListData->sourcePaths.add(path);
216         }
217         return pathCopy;
218     }
219 
refPaint(const SkPaint * paint)220     inline const SkPaint* refPaint(const SkPaint* paint) {
221         if (!paint) return NULL;
222 
223         const SkPaint* paintCopy = mPaintMap.valueFor(paint);
224         if (paintCopy == NULL
225                 || paintCopy->getGenerationID() != paint->getGenerationID()
226                 // We can't compare shader pointers because that will always
227                 // change as we do partial copying via wrapping. However, if the
228                 // shader changes the paint generationID will have changed and
229                 // so we don't hit this comparison anyway
230                 || !(paint->getShader() && paintCopy->getShader()
231                         && paint->getShader()->getGenerationID() == paintCopy->getShader()->getGenerationID())) {
232             paintCopy = copyPaint(paint);
233             // replaceValueFor() performs an add if the entry doesn't exist
234             mPaintMap.replaceValueFor(paint, paintCopy);
235         }
236 
237         return paintCopy;
238     }
239 
copyPaint(const SkPaint * paint)240     inline SkPaint* copyPaint(const SkPaint* paint) {
241         if (!paint) return NULL;
242         SkPaint* paintCopy = new SkPaint(*paint);
243         if (paint->getShader()) {
244             SkShader* shaderCopy = SkShader::CreateLocalMatrixShader(
245                     paint->getShader(), paint->getShader()->getLocalMatrix());
246             paintCopy->setShader(shaderCopy);
247             paintCopy->setGenerationID(paint->getGenerationID());
248             shaderCopy->setGenerationID(paint->getShader()->getGenerationID());
249             shaderCopy->unref();
250         }
251         mDisplayListData->paints.add(paintCopy);
252         return paintCopy;
253     }
254 
refRegion(const SkRegion * region)255     inline const SkRegion* refRegion(const SkRegion* region) {
256         if (!region) {
257             return region;
258         }
259 
260         const SkRegion* regionCopy = mRegionMap.valueFor(region);
261         // TODO: Add generation ID to SkRegion
262         if (regionCopy == NULL) {
263             regionCopy = new SkRegion(*region);
264             // replaceValueFor() performs an add if the entry doesn't exist
265             mRegionMap.replaceValueFor(region, regionCopy);
266             mDisplayListData->regions.add(regionCopy);
267         }
268 
269         return regionCopy;
270     }
271 
refBitmap(const SkBitmap * bitmap)272     inline const SkBitmap* refBitmap(const SkBitmap* bitmap) {
273         // Note that this assumes the bitmap is immutable. There are cases this won't handle
274         // correctly, such as creating the bitmap from scratch, drawing with it, changing its
275         // contents, and drawing again. The only fix would be to always copy it the first time,
276         // which doesn't seem worth the extra cycles for this unlikely case.
277         mDisplayListData->bitmapResources.add(bitmap);
278         mResourceCache.incrementRefcount(bitmap);
279         return bitmap;
280     }
281 
refBitmapData(const SkBitmap * bitmap)282     inline const SkBitmap* refBitmapData(const SkBitmap* bitmap) {
283         mDisplayListData->ownedBitmapResources.add(bitmap);
284         mResourceCache.incrementRefcount(bitmap);
285         return bitmap;
286     }
287 
refPatch(const Res_png_9patch * patch)288     inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
289         mDisplayListData->patchResources.add(patch);
290         mResourceCache.incrementRefcount(patch);
291         return patch;
292     }
293 
294     DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap;
295     DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
296     DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
297 
298     ResourceCache& mResourceCache;
299     DisplayListData* mDisplayListData;
300 
301     float mTranslateX;
302     float mTranslateY;
303     bool mHasDeferredTranslate;
304     DeferredBarrierType mDeferredBarrierType;
305     bool mHighContrastText;
306 
307     int mRestoreSaveCount;
308 
309     friend class RenderNode;
310 
311 }; // class DisplayListRenderer
312 
313 }; // namespace uirenderer
314 }; // namespace android
315 
316 #endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
317