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