• 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 <SkChunkAlloc.h>
21 #include <SkFlattenable.h>
22 #include <SkMatrix.h>
23 #include <SkPaint.h>
24 #include <SkPath.h>
25 #include <SkRefCnt.h>
26 #include <SkTDArray.h>
27 #include <SkTSearch.h>
28 
29 #include "DisplayListLogBuffer.h"
30 #include "OpenGLRenderer.h"
31 #include "utils/Functor.h"
32 
33 namespace android {
34 namespace uirenderer {
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 // Defines
38 ///////////////////////////////////////////////////////////////////////////////
39 
40 #define MIN_WRITER_SIZE 4096
41 
42 // Debug
43 #if DEBUG_DISPLAY_LIST
44     #define DISPLAY_LIST_LOGD(...) LOGD(__VA_ARGS__)
45 #else
46     #define DISPLAY_LIST_LOGD(...)
47 #endif
48 
49 ///////////////////////////////////////////////////////////////////////////////
50 // Display list
51 ///////////////////////////////////////////////////////////////////////////////
52 
53 class DisplayListRenderer;
54 
55 /**
56  * Replays recorded drawing commands.
57  */
58 class DisplayList {
59 public:
60     DisplayList(const DisplayListRenderer& recorder);
61     ~DisplayList();
62 
63     // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file
64     //            when modifying this file
65     enum Op {
66         // Non-drawing operations
67         Save = 0,
68         Restore,
69         RestoreToCount,
70         SaveLayer,
71         SaveLayerAlpha,
72         Translate,
73         Rotate,
74         Scale,
75         Skew,
76         SetMatrix,
77         ConcatMatrix,
78         ClipRect,
79         // Drawing operations
80         DrawDisplayList,
81         DrawLayer,
82         DrawBitmap,
83         DrawBitmapMatrix,
84         DrawBitmapRect,
85         DrawBitmapMesh,
86         DrawPatch,
87         DrawColor,
88         DrawRect,
89         DrawRoundRect,
90         DrawCircle,
91         DrawOval,
92         DrawArc,
93         DrawPath,
94         DrawLines,
95         DrawPoints,
96         DrawText,
97         ResetShader,
98         SetupShader,
99         ResetColorFilter,
100         SetupColorFilter,
101         ResetShadow,
102         SetupShadow,
103         DrawGLFunction,
104     };
105 
106     static const char* OP_NAMES[];
107 
108     void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
109 
110     size_t getSize();
111 
112     bool replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level = 0);
113 
114     void output(OpenGLRenderer& renderer, uint32_t level = 0);
115 
116     static void outputLogBuffer(int fd);
117 
setRenderable(bool renderable)118     void setRenderable(bool renderable) {
119         mIsRenderable = renderable;
120     }
121 
isRenderable()122     bool isRenderable() const {
123         return mIsRenderable;
124     }
125 
126 private:
127     void init();
128 
129     void clearResources();
130 
131     class TextContainer {
132     public:
length()133         size_t length() const {
134             return mByteLength;
135         }
136 
text()137         const char* text() const {
138             return (const char*) mText;
139         }
140 
141         size_t mByteLength;
142         const char* mText;
143     };
144 
getBitmap()145     SkBitmap* getBitmap() {
146         return (SkBitmap*) getInt();
147     }
148 
getShader()149     SkiaShader* getShader() {
150         return (SkiaShader*) getInt();
151     }
152 
getColorFilter()153     SkiaColorFilter* getColorFilter() {
154         return (SkiaColorFilter*) getInt();
155     }
156 
getIndex()157     inline int getIndex() {
158         return mReader.readInt();
159     }
160 
getInt()161     inline int getInt() {
162         return mReader.readInt();
163     }
164 
getUInt()165     inline uint32_t getUInt() {
166         return mReader.readU32();
167     }
168 
getMatrix()169     SkMatrix* getMatrix() {
170         return (SkMatrix*) getInt();
171     }
172 
getPath()173     SkPath* getPath() {
174         return (SkPath*) getInt();
175     }
176 
getPaint()177     SkPaint* getPaint() {
178         return (SkPaint*) getInt();
179     }
180 
getDisplayList()181     DisplayList* getDisplayList() {
182         return (DisplayList*) getInt();
183     }
184 
getFloat()185     inline float getFloat() {
186         return mReader.readScalar();
187     }
188 
getInts(uint32_t & count)189     int32_t* getInts(uint32_t& count) {
190         count = getInt();
191         return (int32_t*) mReader.skip(count * sizeof(int32_t));
192     }
193 
getUInts(int8_t & count)194     uint32_t* getUInts(int8_t& count) {
195         count = getInt();
196         return (uint32_t*) mReader.skip(count * sizeof(uint32_t));
197     }
198 
getFloats(int & count)199     float* getFloats(int& count) {
200         count = getInt();
201         return (float*) mReader.skip(count * sizeof(float));
202     }
203 
getText(TextContainer * text)204     void getText(TextContainer* text) {
205         size_t length = text->mByteLength = getInt();
206         text->mText = (const char*) mReader.skip(length);
207     }
208 
209     Vector<SkBitmap*> mBitmapResources;
210     Vector<SkiaColorFilter*> mFilterResources;
211 
212     Vector<SkPaint*> mPaints;
213     Vector<SkPath*> mPaths;
214     Vector<SkMatrix*> mMatrices;
215     Vector<SkiaShader*> mShaders;
216 
217     mutable SkFlattenableReadBuffer mReader;
218 
219     size_t mSize;
220 
221     bool mIsRenderable;
222 };
223 
224 ///////////////////////////////////////////////////////////////////////////////
225 // Renderer
226 ///////////////////////////////////////////////////////////////////////////////
227 
228 /**
229  * Records drawing commands in a display list for latter playback.
230  */
231 class DisplayListRenderer: public OpenGLRenderer {
232 public:
233     DisplayListRenderer();
234     ~DisplayListRenderer();
235 
236     DisplayList* getDisplayList(DisplayList* displayList);
237 
238     void setViewport(int width, int height);
239     void prepareDirty(float left, float top, float right, float bottom, bool opaque);
240     void finish();
241 
242     bool callDrawGLFunction(Functor *functor, Rect& dirty);
243 
244     void interrupt();
245     void resume();
246 
247     int save(int flags);
248     void restore();
249     void restoreToCount(int saveCount);
250 
251     int saveLayer(float left, float top, float right, float bottom,
252             SkPaint* p, int flags);
253     int saveLayerAlpha(float left, float top, float right, float bottom,
254                 int alpha, int flags);
255 
256     void translate(float dx, float dy);
257     void rotate(float degrees);
258     void scale(float sx, float sy);
259     void skew(float sx, float sy);
260 
261     void setMatrix(SkMatrix* matrix);
262     void concatMatrix(SkMatrix* matrix);
263 
264     bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
265 
266     bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
267             Rect& dirty, uint32_t level = 0);
268     void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
269     void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
270     void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
271     void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
272             float srcRight, float srcBottom, float dstLeft, float dstTop,
273             float dstRight, float dstBottom, SkPaint* paint);
274     void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
275             float* vertices, int* colors, SkPaint* paint);
276     void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
277             const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
278             float left, float top, float right, float bottom, SkPaint* paint);
279     void drawColor(int color, SkXfermode::Mode mode);
280     void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
281     void drawRoundRect(float left, float top, float right, float bottom,
282             float rx, float ry, SkPaint* paint);
283     void drawCircle(float x, float y, float radius, SkPaint* paint);
284     void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
285     void drawArc(float left, float top, float right, float bottom,
286             float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
287     void drawPath(SkPath* path, SkPaint* paint);
288     void drawLines(float* points, int count, SkPaint* paint);
289     void drawPoints(float* points, int count, SkPaint* paint);
290     void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
291 
292     void resetShader();
293     void setupShader(SkiaShader* shader);
294 
295     void resetColorFilter();
296     void setupColorFilter(SkiaColorFilter* filter);
297 
298     void resetShadow();
299     void setupShadow(float radius, float dx, float dy, int color);
300 
301     void reset();
302 
writeStream()303     const SkWriter32& writeStream() const {
304         return mWriter;
305     }
306 
getBitmapResources()307     const Vector<SkBitmap*>& getBitmapResources() const {
308         return mBitmapResources;
309     }
310 
getFilterResources()311     const Vector<SkiaColorFilter*>& getFilterResources() const {
312         return mFilterResources;
313     }
314 
getShaders()315     const Vector<SkiaShader*>& getShaders() const {
316         return mShaders;
317     }
318 
getPaints()319     const Vector<SkPaint*>& getPaints() const {
320         return mPaints;
321     }
322 
getPaths()323     const Vector<SkPath*>& getPaths() const {
324         return mPaths;
325     }
326 
getMatrices()327     const Vector<SkMatrix*>& getMatrices() const {
328         return mMatrices;
329     }
330 
331 private:
insertRestoreToCount()332     void insertRestoreToCount() {
333         if (mRestoreSaveCount >= 0) {
334             mWriter.writeInt(DisplayList::RestoreToCount);
335             addInt(mRestoreSaveCount);
336             mRestoreSaveCount = -1;
337         }
338     }
339 
addOp(DisplayList::Op drawOp)340     inline void addOp(DisplayList::Op drawOp) {
341         insertRestoreToCount();
342         mWriter.writeInt(drawOp);
343         mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
344     }
345 
addInt(int value)346     inline void addInt(int value) {
347         mWriter.writeInt(value);
348     }
349 
addSize(uint32_t w,uint32_t h)350     inline void addSize(uint32_t w, uint32_t h) {
351         mWriter.writeInt(w);
352         mWriter.writeInt(h);
353     }
354 
addInts(const int32_t * values,uint32_t count)355     void addInts(const int32_t* values, uint32_t count) {
356         mWriter.writeInt(count);
357         for (uint32_t i = 0; i < count; i++) {
358             mWriter.writeInt(values[i]);
359         }
360     }
361 
addUInts(const uint32_t * values,int8_t count)362     void addUInts(const uint32_t* values, int8_t count) {
363         mWriter.writeInt(count);
364         for (int8_t i = 0; i < count; i++) {
365             mWriter.writeInt(values[i]);
366         }
367     }
368 
addFloat(float value)369     inline void addFloat(float value) {
370         mWriter.writeScalar(value);
371     }
372 
addFloats(const float * values,int count)373     void addFloats(const float* values, int count) {
374         mWriter.writeInt(count);
375         for (int i = 0; i < count; i++) {
376             mWriter.writeScalar(values[i]);
377         }
378     }
379 
addPoint(float x,float y)380     inline void addPoint(float x, float y) {
381         mWriter.writeScalar(x);
382         mWriter.writeScalar(y);
383     }
384 
addBounds(float left,float top,float right,float bottom)385     inline void addBounds(float left, float top, float right, float bottom) {
386         mWriter.writeScalar(left);
387         mWriter.writeScalar(top);
388         mWriter.writeScalar(right);
389         mWriter.writeScalar(bottom);
390     }
391 
addText(const void * text,size_t byteLength)392     inline void addText(const void* text, size_t byteLength) {
393         mWriter.writeInt(byteLength);
394         mWriter.writePad(text, byteLength);
395     }
396 
addPath(SkPath * path)397     inline void addPath(SkPath* path) {
398         if (!path) {
399             addInt((int) NULL);
400             return;
401         }
402 
403         SkPath* pathCopy = mPathMap.valueFor(path);
404         if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
405             pathCopy = new SkPath(*path);
406             mPathMap.add(path, pathCopy);
407             mPaths.add(pathCopy);
408         }
409 
410         addInt((int) pathCopy);
411     }
412 
addPaint(SkPaint * paint)413     inline void addPaint(SkPaint* paint) {
414         if (!paint) {
415             addInt((int) NULL);
416             return;
417         }
418 
419         SkPaint* paintCopy =  mPaintMap.valueFor(paint);
420         if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
421             paintCopy = new SkPaint(*paint);
422             mPaintMap.add(paint, paintCopy);
423             mPaints.add(paintCopy);
424         }
425 
426         addInt((int) paintCopy);
427     }
428 
addDisplayList(DisplayList * displayList)429     inline void addDisplayList(DisplayList* displayList) {
430         // TODO: To be safe, the display list should be ref-counted in the
431         //       resources cache, but we rely on the caller (UI toolkit) to
432         //       do the right thing for now
433         addInt((int) displayList);
434     }
435 
addMatrix(SkMatrix * matrix)436     inline void addMatrix(SkMatrix* matrix) {
437         // Copying the matrix is cheap and prevents against the user changing the original
438         // matrix before the operation that uses it
439         SkMatrix* copy = new SkMatrix(*matrix);
440         addInt((int) copy);
441         mMatrices.add(copy);
442     }
443 
addBitmap(SkBitmap * bitmap)444     inline void addBitmap(SkBitmap* bitmap) {
445         // Note that this assumes the bitmap is immutable. There are cases this won't handle
446         // correctly, such as creating the bitmap from scratch, drawing with it, changing its
447         // contents, and drawing again. The only fix would be to always copy it the first time,
448         // which doesn't seem worth the extra cycles for this unlikely case.
449         addInt((int) bitmap);
450         mBitmapResources.add(bitmap);
451         Caches::getInstance().resourceCache.incrementRefcount(bitmap);
452     }
453 
addShader(SkiaShader * shader)454     inline void addShader(SkiaShader* shader) {
455         if (!shader) {
456             addInt((int) NULL);
457             return;
458         }
459 
460         SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
461         // TODO: We also need to handle generation ID changes in compose shaders
462         if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
463             shaderCopy = shader->copy();
464             mShaderMap.add(shader, shaderCopy);
465             mShaders.add(shaderCopy);
466             Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
467         }
468 
469         addInt((int) shaderCopy);
470     }
471 
addColorFilter(SkiaColorFilter * colorFilter)472     inline void addColorFilter(SkiaColorFilter* colorFilter) {
473         addInt((int) colorFilter);
474         mFilterResources.add(colorFilter);
475         Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
476     }
477 
478     Vector<SkBitmap*> mBitmapResources;
479     Vector<SkiaColorFilter*> mFilterResources;
480 
481     Vector<SkPaint*> mPaints;
482     DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
483 
484     Vector<SkPath*> mPaths;
485     DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
486 
487     Vector<SkiaShader*> mShaders;
488     DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
489 
490     Vector<SkMatrix*> mMatrices;
491 
492     SkWriter32 mWriter;
493 
494     int mRestoreSaveCount;
495     bool mHasDrawOps;
496 
497     friend class DisplayList;
498 
499 }; // class DisplayListRenderer
500 
501 }; // namespace uirenderer
502 }; // namespace android
503 
504 #endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
505