DisplayListRenderer.h revision 5b3b35296e8b2c8d3f07d32bb645d5414db41a1d
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 <SkPictureFlat.h>
26#include <SkRefCnt.h>
27#include <SkTDArray.h>
28#include <SkTSearch.h>
29
30#include "OpenGLRenderer.h"
31
32namespace android {
33namespace uirenderer {
34
35///////////////////////////////////////////////////////////////////////////////
36// Defines
37///////////////////////////////////////////////////////////////////////////////
38
39#define MIN_WRITER_SIZE 16384
40#define HEAP_BLOCK_SIZE 4096
41
42///////////////////////////////////////////////////////////////////////////////
43// Helpers
44///////////////////////////////////////////////////////////////////////////////
45
46class PathHeap: public SkRefCnt {
47public:
48    PathHeap();
49    PathHeap(SkFlattenableReadBuffer& buffer);
50    ~PathHeap();
51
52    int append(const SkPath& path);
53
54    int count() const { return mPaths.count(); }
55
56    SkPath& operator[](int index) const {
57        return *mPaths[index];
58    }
59
60    void flatten(SkFlattenableWriteBuffer& buffer) const;
61
62private:
63    SkChunkAlloc mHeap;
64    SkTDArray<SkPath*> mPaths;
65};
66
67///////////////////////////////////////////////////////////////////////////////
68// Display list
69///////////////////////////////////////////////////////////////////////////////
70
71class DisplayListRenderer;
72
73/**
74 * Replays recorded drawing commands.
75 */
76class DisplayList {
77public:
78    DisplayList(const DisplayListRenderer& recorder);
79    ~DisplayList();
80
81    enum Op {
82        AcquireContext,
83        ReleaseContext,
84        Save,
85        Restore,
86        RestoreToCount,
87        SaveLayer,
88        SaveLayerAlpha,
89        Translate,
90        Rotate,
91        Scale,
92        SetMatrix,
93        ConcatMatrix,
94        ClipRect,
95        DrawBitmap,
96        DrawBitmapMatrix,
97        DrawBitmapRect,
98        DrawPatch,
99        DrawColor,
100        DrawRect,
101        DrawPath,
102        DrawLines,
103        DrawText,
104        ResetShader,
105        SetupShader,
106        ResetColorFilter,
107        SetupColorFilter,
108        ResetShadow,
109        SetupShadow
110    };
111
112    void replay(OpenGLRenderer& renderer);
113
114private:
115    void init();
116
117    class TextContainer {
118    public:
119        size_t length() const {
120            return mByteLength;
121        }
122
123        const char* text() const {
124            return (const char*) mText;
125        }
126
127        size_t mByteLength;
128        const char* mText;
129    };
130
131    SkBitmap* getBitmap() {
132        return (SkBitmap*) getInt();
133    }
134
135    SkiaShader* getShader() {
136        return (SkiaShader*) getInt();
137    }
138
139    SkiaColorFilter* getColorFilter() {
140        return (SkiaColorFilter*) getInt();
141    }
142
143    inline int getIndex() {
144        return mReader.readInt();
145    }
146
147    inline int getInt() {
148        return mReader.readInt();
149    }
150
151    SkMatrix* getMatrix() {
152        return (SkMatrix*) getInt();
153    }
154
155    SkPath* getPath() {
156        return &(*mPathHeap)[getInt() - 1];
157    }
158
159    SkPaint* getPaint() {
160        return (SkPaint*) 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    PathHeap* mPathHeap;
188
189    Vector<SkBitmap*> mBitmapResources;
190    Vector<SkiaShader*> mShaderResources;
191    Vector<SkiaColorFilter*> mFilterResources;
192
193    Vector<SkPaint*> mPaints;
194    Vector<SkMatrix*> mMatrices;
195
196    mutable SkFlattenableReadBuffer mReader;
197
198    SkRefCntPlayback mRCPlayback;
199    SkTypefacePlayback mTFPlayback;
200};
201
202///////////////////////////////////////////////////////////////////////////////
203// Renderer
204///////////////////////////////////////////////////////////////////////////////
205
206/**
207 * Records drawing commands in a display list for latter playback.
208 */
209class DisplayListRenderer: public OpenGLRenderer {
210public:
211    DisplayListRenderer();
212    ~DisplayListRenderer();
213
214    void setViewport(int width, int height);
215    void prepare(bool opaque);
216
217    void acquireContext();
218    void releaseContext();
219
220    int save(int flags);
221    void restore();
222    void restoreToCount(int saveCount);
223
224    int saveLayer(float left, float top, float right, float bottom,
225            SkPaint* p, int flags);
226    int saveLayerAlpha(float left, float top, float right, float bottom,
227                int alpha, int flags);
228
229    void translate(float dx, float dy);
230    void rotate(float degrees);
231    void scale(float sx, float sy);
232
233    void setMatrix(SkMatrix* matrix);
234    void concatMatrix(SkMatrix* matrix);
235
236    bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
237
238    void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
239    void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
240    void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
241            float srcRight, float srcBottom, float dstLeft, float dstTop,
242            float dstRight, float dstBottom, SkPaint* paint);
243    void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
244            const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
245            float left, float top, float right, float bottom, SkPaint* paint);
246    void drawColor(int color, SkXfermode::Mode mode);
247    void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
248    void drawPath(SkPath* path, SkPaint* paint);
249    void drawLines(float* points, int count, SkPaint* paint);
250    void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
251
252    void resetShader();
253    void setupShader(SkiaShader* shader);
254
255    void resetColorFilter();
256    void setupColorFilter(SkiaColorFilter* filter);
257
258    void resetShadow();
259    void setupShadow(float radius, float dx, float dy, int color);
260
261    void reset();
262
263    DisplayList* getDisplayList() const {
264        return new DisplayList(*this);
265    }
266
267    const SkWriter32& writeStream() const {
268        return mWriter;
269    }
270
271    const Vector<SkBitmap*>& getBitmapResources() const {
272        return mBitmapResources;
273    }
274
275    const Vector<SkiaShader*>& getShaderResources() const {
276        return mShaderResources;
277    }
278
279    const Vector<SkPaint*>& getPaints() const {
280        return mPaints;
281    }
282
283    const Vector<SkMatrix*>& getMatrices() const {
284        return mMatrices;
285    }
286
287    const Vector<SkiaColorFilter*>& getFilterResources() const {
288        return mFilterResources;
289    }
290
291private:
292    inline void addOp(DisplayList::Op drawOp) {
293        mWriter.writeInt(drawOp);
294    }
295
296    inline void addInt(int value) {
297        mWriter.writeInt(value);
298    }
299
300    void addInts(const int32_t* values, uint32_t count) {
301        mWriter.writeInt(count);
302        for (uint32_t i = 0; i < count; i++) {
303            mWriter.writeInt(values[i]);
304        }
305    }
306
307    void addUInts(const uint32_t* values, int8_t count) {
308        mWriter.writeInt(count);
309        for (int8_t i = 0; i < count; i++) {
310            mWriter.writeInt(values[i]);
311        }
312    }
313
314    inline void addFloat(float value) {
315        mWriter.writeScalar(value);
316    }
317
318    void addFloats(const float* values, int count) {
319        mWriter.writeInt(count);
320        for (int i = 0; i < count; i++) {
321            mWriter.writeScalar(values[i]);
322        }
323    }
324
325    inline void addPoint(float x, float y) {
326        mWriter.writeScalar(x);
327        mWriter.writeScalar(y);
328    }
329
330    inline void addBounds(float left, float top, float right, float bottom) {
331        mWriter.writeScalar(left);
332        mWriter.writeScalar(top);
333        mWriter.writeScalar(right);
334        mWriter.writeScalar(bottom);
335    }
336
337    inline void addText(const void* text, size_t byteLength) {
338        mWriter.writeInt(byteLength);
339        mWriter.writePad(text, byteLength);
340    }
341
342    inline void addPath(const SkPath* path) {
343        if (mPathHeap == NULL) {
344            mPathHeap = new PathHeap();
345        }
346        addInt(mPathHeap->append(*path));
347    }
348
349    inline void addPaint(SkPaint* paint) {
350        if (paint == NULL) {
351            addInt((int)NULL);
352            return;
353        }
354        SkPaint *paintCopy =  mPaintMap.valueFor(paint);
355        if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
356            paintCopy = new SkPaint(*paint);
357            mPaintMap.add(paint, paintCopy);
358            mPaints.add(paintCopy);
359        }
360        addInt((int)paintCopy);
361    }
362
363    inline void addMatrix(SkMatrix* matrix) {
364        // Copying the matrix is cheap and prevents against the user changing the original
365        // matrix before the operation that uses it
366        addInt((int) new SkMatrix(*matrix));
367    }
368
369    inline void addBitmap(SkBitmap* bitmap) {
370        // Note that this assumes the bitmap is immutable. There are cases this won't handle
371        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
372        // contents, and drawing again. The only fix would be to always copy it the first time,
373        // which doesn't seem worth the extra cycles for this unlikely case.
374        addInt((int)bitmap);
375        mBitmapResources.add(bitmap);
376        Caches& caches = Caches::getInstance();
377        caches.resourceCache.incrementRefcount(bitmap);
378    }
379
380    inline void addShader(SkiaShader* shader) {
381        addInt((int)shader);
382        mShaderResources.add(shader);
383        Caches& caches = Caches::getInstance();
384        caches.resourceCache.incrementRefcount(shader);
385    }
386
387    inline void addColorFilter(SkiaColorFilter* colorFilter) {
388        addInt((int)colorFilter);
389        mFilterResources.add(colorFilter);
390        Caches& caches = Caches::getInstance();
391        caches.resourceCache.incrementRefcount(colorFilter);
392    }
393
394    SkChunkAlloc mHeap;
395
396    Vector<SkBitmap*> mBitmapResources;
397    Vector<SkiaShader*> mShaderResources;
398    Vector<SkiaColorFilter*> mFilterResources;
399
400    Vector<SkPaint*> mPaints;
401    DefaultKeyedVector<SkPaint *, SkPaint *> mPaintMap;
402    Vector<SkMatrix*> mMatrices;
403
404    PathHeap* mPathHeap;
405    SkWriter32 mWriter;
406
407    SkRefCntRecorder mRCRecorder;
408    SkRefCntRecorder mTFRecorder;
409
410    friend class DisplayList;
411
412}; // class DisplayListRenderer
413
414}; // namespace uirenderer
415}; // namespace android
416
417#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
418