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