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