DisplayListRenderer.h revision 7b5b6abf852c039983eded25ebe43a70fef5a4ab
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    inline uint32_t getUInt() {
148        return mReader.readU32();
149    }
150
151    SkMatrix* getMatrix() {
152        return (SkMatrix*) getInt();
153    }
154
155    SkPath* getPath() {
156        return (SkPath*) getInt();
157    }
158
159    SkPaint* getPaint() {
160        return (SkPaint*) getInt();
161    }
162
163    DisplayList* getDisplayList() {
164        return (DisplayList*) getInt();
165    }
166
167    inline float getFloat() {
168        return mReader.readScalar();
169    }
170
171    int32_t* getInts(uint32_t& count) {
172        count = getInt();
173        return (int32_t*) mReader.skip(count * sizeof(int32_t));
174    }
175
176    uint32_t* getUInts(int8_t& count) {
177        count = getInt();
178        return (uint32_t*) mReader.skip(count * sizeof(uint32_t));
179    }
180
181    float* getFloats(int& count) {
182        count = getInt();
183        return (float*) mReader.skip(count * sizeof(float));
184    }
185
186    void getText(TextContainer* text) {
187        size_t length = text->mByteLength = getInt();
188        text->mText = (const char*) mReader.skip(length);
189    }
190
191    Vector<SkBitmap*> mBitmapResources;
192    Vector<SkiaColorFilter*> mFilterResources;
193
194    Vector<SkPaint*> mPaints;
195    Vector<SkPath*> mPaths;
196    Vector<SkPath*> mOriginalPaths;
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 drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
269
270    void resetShader();
271    void setupShader(SkiaShader* shader);
272
273    void resetColorFilter();
274    void setupColorFilter(SkiaColorFilter* filter);
275
276    void resetShadow();
277    void setupShadow(float radius, float dx, float dy, int color);
278
279    void reset();
280
281    const SkWriter32& writeStream() const {
282        return mWriter;
283    }
284
285    const Vector<SkBitmap*>& getBitmapResources() const {
286        return mBitmapResources;
287    }
288
289    const Vector<SkiaShader*>& getShaders() const {
290        return mShaders;
291    }
292
293    const Vector<SkPaint*>& getPaints() const {
294        return mPaints;
295    }
296
297    const Vector<SkPath*>& getPaths() const {
298        return mPaths;
299    }
300
301    const Vector<SkPath*>& getOriginalPaths() const {
302        return mOriginalPaths;
303    }
304
305    const Vector<SkMatrix*>& getMatrices() const {
306        return mMatrices;
307    }
308
309    const Vector<SkiaColorFilter*>& getFilterResources() const {
310        return mFilterResources;
311    }
312
313private:
314    void insertRestoreToCount() {
315        if (mRestoreSaveCount >= 0) {
316            mWriter.writeInt(DisplayList::RestoreToCount);
317            addInt(mRestoreSaveCount);
318            mRestoreSaveCount = -1;
319        }
320    }
321
322    inline void addOp(DisplayList::Op drawOp) {
323        insertRestoreToCount();
324        mWriter.writeInt(drawOp);
325    }
326
327    inline void addInt(int value) {
328        mWriter.writeInt(value);
329    }
330
331    inline void addSize(uint32_t w, uint32_t h) {
332        mWriter.writeInt(w);
333        mWriter.writeInt(h);
334    }
335
336    void addInts(const int32_t* values, uint32_t count) {
337        mWriter.writeInt(count);
338        for (uint32_t i = 0; i < count; i++) {
339            mWriter.writeInt(values[i]);
340        }
341    }
342
343    void addUInts(const uint32_t* values, int8_t count) {
344        mWriter.writeInt(count);
345        for (int8_t i = 0; i < count; i++) {
346            mWriter.writeInt(values[i]);
347        }
348    }
349
350    inline void addFloat(float value) {
351        mWriter.writeScalar(value);
352    }
353
354    void addFloats(const float* values, int count) {
355        mWriter.writeInt(count);
356        for (int i = 0; i < count; i++) {
357            mWriter.writeScalar(values[i]);
358        }
359    }
360
361    inline void addPoint(float x, float y) {
362        mWriter.writeScalar(x);
363        mWriter.writeScalar(y);
364    }
365
366    inline void addBounds(float left, float top, float right, float bottom) {
367        mWriter.writeScalar(left);
368        mWriter.writeScalar(top);
369        mWriter.writeScalar(right);
370        mWriter.writeScalar(bottom);
371    }
372
373    inline void addText(const void* text, size_t byteLength) {
374        mWriter.writeInt(byteLength);
375        mWriter.writePad(text, byteLength);
376    }
377
378    inline void addPath(SkPath* path) {
379        if (!path) {
380            addInt((int) NULL);
381            return;
382        }
383
384        SkPath* pathCopy = mPathMap.valueFor(path);
385        if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
386            if (pathCopy == NULL) {
387                pathCopy = path;
388                mOriginalPaths.add(path);
389                Caches& caches = Caches::getInstance();
390                caches.resourceCache.incrementRefcount(path);
391            } else {
392                pathCopy = new SkPath(*path);
393                mPaths.add(pathCopy);
394            }
395            mPathMap.add(path, pathCopy);
396        }
397
398        addInt((int) pathCopy);
399    }
400
401    inline void addPaint(SkPaint* paint) {
402        if (!paint) {
403            addInt((int) NULL);
404            return;
405        }
406
407        SkPaint* paintCopy =  mPaintMap.valueFor(paint);
408        if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
409            paintCopy = new SkPaint(*paint);
410            mPaintMap.add(paint, paintCopy);
411            mPaints.add(paintCopy);
412        }
413
414        addInt((int) paintCopy);
415    }
416
417    inline void addDisplayList(DisplayList* displayList) {
418        // TODO: To be safe, the display list should be ref-counted in the
419        //       resources cache, but we rely on the caller (UI toolkit) to
420        //       do the right thing for now
421        addInt((int) displayList);
422    }
423
424    inline void addMatrix(SkMatrix* matrix) {
425        // Copying the matrix is cheap and prevents against the user changing the original
426        // matrix before the operation that uses it
427        addInt((int) new SkMatrix(*matrix));
428    }
429
430    inline void addBitmap(SkBitmap* bitmap) {
431        // Note that this assumes the bitmap is immutable. There are cases this won't handle
432        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
433        // contents, and drawing again. The only fix would be to always copy it the first time,
434        // which doesn't seem worth the extra cycles for this unlikely case.
435        addInt((int) bitmap);
436        mBitmapResources.add(bitmap);
437        Caches& caches = Caches::getInstance();
438        caches.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& caches = Caches::getInstance();
463        caches.resourceCache.incrementRefcount(colorFilter);
464    }
465
466    Vector<SkBitmap*> mBitmapResources;
467    Vector<SkiaColorFilter*> mFilterResources;
468
469    Vector<SkPaint*> mPaints;
470    DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
471
472    Vector<SkPath*> mOriginalPaths;
473    Vector<SkPath*> mPaths;
474    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
475
476    Vector<SkiaShader*> mShaders;
477    DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
478
479    Vector<SkMatrix*> mMatrices;
480
481    SkWriter32 mWriter;
482
483    DisplayList *mDisplayList;
484
485    int mRestoreSaveCount;
486
487    friend class DisplayList;
488
489}; // class DisplayListRenderer
490
491}; // namespace uirenderer
492}; // namespace android
493
494#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
495