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