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