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