DisplayListRenderer.h revision cabfcc1364eb7e4de0b15b3574fba45027b45cfc
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        DrawText,
93        ResetShader,
94        SetupShader,
95        ResetColorFilter,
96        SetupColorFilter,
97        ResetShadow,
98        SetupShadow,
99        DrawGLFunction,
100    };
101
102    static const char* OP_NAMES[];
103
104    void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
105
106    bool replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level = 0);
107
108private:
109    void init();
110
111    void clearResources();
112
113    class TextContainer {
114    public:
115        size_t length() const {
116            return mByteLength;
117        }
118
119        const char* text() const {
120            return (const char*) mText;
121        }
122
123        size_t mByteLength;
124        const char* mText;
125    };
126
127    SkBitmap* getBitmap() {
128        return (SkBitmap*) getInt();
129    }
130
131    SkiaShader* getShader() {
132        return (SkiaShader*) getInt();
133    }
134
135    SkiaColorFilter* getColorFilter() {
136        return (SkiaColorFilter*) getInt();
137    }
138
139    inline int getIndex() {
140        return mReader.readInt();
141    }
142
143    inline int getInt() {
144        return mReader.readInt();
145    }
146
147    SkMatrix* getMatrix() {
148        return (SkMatrix*) getInt();
149    }
150
151    SkPath* getPath() {
152        return (SkPath*) getInt();
153    }
154
155    SkPaint* getPaint() {
156        return (SkPaint*) getInt();
157    }
158
159    DisplayList* getDisplayList() {
160        return (DisplayList*) getInt();
161    }
162
163    inline float getFloat() {
164        return mReader.readScalar();
165    }
166
167    int32_t* getInts(uint32_t& count) {
168        count = getInt();
169        return (int32_t*) mReader.skip(count * sizeof(int32_t));
170    }
171
172    uint32_t* getUInts(int8_t& count) {
173        count = getInt();
174        return (uint32_t*) mReader.skip(count * sizeof(uint32_t));
175    }
176
177    float* getFloats(int& count) {
178        count = getInt();
179        return (float*) mReader.skip(count * sizeof(float));
180    }
181
182    void getText(TextContainer* text) {
183        size_t length = text->mByteLength = getInt();
184        text->mText = (const char*) mReader.skip(length);
185    }
186
187    Vector<SkBitmap*> mBitmapResources;
188    Vector<SkiaColorFilter*> mFilterResources;
189
190    Vector<SkPaint*> mPaints;
191    Vector<SkPath*> mPaths;
192    Vector<SkPath*> mOriginalPaths;
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, Rect& dirty);
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, Rect& dirty, 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<SkPath*>& getOriginalPaths() const {
297        return mOriginalPaths;
298    }
299
300    const Vector<SkMatrix*>& getMatrices() const {
301        return mMatrices;
302    }
303
304    const Vector<SkiaColorFilter*>& getFilterResources() const {
305        return mFilterResources;
306    }
307
308private:
309    void insertRestoreToCount() {
310        if (mRestoreSaveCount >= 0) {
311            mWriter.writeInt(DisplayList::RestoreToCount);
312            addInt(mRestoreSaveCount);
313            mRestoreSaveCount = -1;
314        }
315    }
316
317    inline void addOp(DisplayList::Op drawOp) {
318        insertRestoreToCount();
319        mWriter.writeInt(drawOp);
320    }
321
322    inline void addInt(int value) {
323        mWriter.writeInt(value);
324    }
325
326    void addInts(const int32_t* values, uint32_t count) {
327        mWriter.writeInt(count);
328        for (uint32_t i = 0; i < count; i++) {
329            mWriter.writeInt(values[i]);
330        }
331    }
332
333    void addUInts(const uint32_t* values, int8_t count) {
334        mWriter.writeInt(count);
335        for (int8_t i = 0; i < count; i++) {
336            mWriter.writeInt(values[i]);
337        }
338    }
339
340    inline void addFloat(float value) {
341        mWriter.writeScalar(value);
342    }
343
344    void addFloats(const float* values, int count) {
345        mWriter.writeInt(count);
346        for (int i = 0; i < count; i++) {
347            mWriter.writeScalar(values[i]);
348        }
349    }
350
351    inline void addPoint(float x, float y) {
352        mWriter.writeScalar(x);
353        mWriter.writeScalar(y);
354    }
355
356    inline void addBounds(float left, float top, float right, float bottom) {
357        mWriter.writeScalar(left);
358        mWriter.writeScalar(top);
359        mWriter.writeScalar(right);
360        mWriter.writeScalar(bottom);
361    }
362
363    inline void addText(const void* text, size_t byteLength) {
364        mWriter.writeInt(byteLength);
365        mWriter.writePad(text, byteLength);
366    }
367
368    inline void addPath(SkPath* path) {
369        if (!path) {
370            addInt((int) NULL);
371            return;
372        }
373
374        SkPath* pathCopy = mPathMap.valueFor(path);
375        if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
376            if (pathCopy == NULL) {
377                pathCopy = path;
378                mOriginalPaths.add(path);
379                Caches& caches = Caches::getInstance();
380                caches.resourceCache.incrementRefcount(path);
381            } else {
382                pathCopy = new SkPath(*path);
383                mPaths.add(pathCopy);
384            }
385            mPathMap.add(path, 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*> mOriginalPaths;
463    Vector<SkPath*> mPaths;
464    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
465
466    Vector<SkiaShader*> mShaders;
467    DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
468
469    Vector<SkMatrix*> mMatrices;
470
471    SkWriter32 mWriter;
472
473    DisplayList *mDisplayList;
474
475    int mRestoreSaveCount;
476
477    friend class DisplayList;
478
479}; // class DisplayListRenderer
480
481}; // namespace uirenderer
482}; // namespace android
483
484#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
485