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