DisplayListRenderer.h revision 4bb942083a0d4db746adf95349108dd8ef842e32
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_UI_DISPLAY_LIST_RENDERER_H
18#define ANDROID_UI_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        Translate,
89        Rotate,
90        Scale,
91        SetMatrix,
92        ConcatMatrix,
93        ClipRect,
94        DrawBitmap,
95        DrawBitmapMatrix,
96        DrawBitmapRect,
97        DrawPatch,
98        DrawColor,
99        DrawRect,
100        DrawPath,
101        DrawLines,
102        DrawText,
103        ResetShader,
104        SetupShader,
105        ResetColorFilter,
106        SetupColorFilter,
107        ResetShadow,
108        SetupShadow
109    };
110
111    void replay(OpenGLRenderer& renderer);
112
113private:
114    void init();
115
116    class TextContainer {
117    public:
118        size_t length() const {
119            return mByteLength;
120        }
121
122        const char* text() const {
123            return (const char*) mText;
124        }
125
126        size_t mByteLength;
127        const char* mText;
128    };
129
130    SkBitmap* getBitmap() {
131        int index = getInt();
132        return &mBitmaps[index - 1];
133    }
134
135    inline int getIndex() {
136        return mReader.readInt();
137    }
138
139    inline int getInt() {
140        return mReader.readInt();
141    }
142
143    SkMatrix* getMatrix() {
144        int index = getInt();
145        if (index == 0) {
146            return NULL;
147        }
148        return &mMatrices[index - 1];
149    }
150
151    SkPath* getPath() {
152        return &(*mPathHeap)[getInt() - 1];
153    }
154
155    SkPaint* getPaint() {
156        int index = getInt();
157        if (index == 0) {
158            return NULL;
159        }
160        return &mPaints[index - 1];
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    SkBitmap* mBitmaps;
190    int mBitmapCount;
191
192    SkMatrix* mMatrices;
193    int mMatrixCount;
194
195    SkPaint* mPaints;
196    int mPaintCount;
197
198    mutable SkFlattenableReadBuffer mReader;
199
200    SkRefCntPlayback mRCPlayback;
201    SkTypefacePlayback mTFPlayback;
202};
203
204///////////////////////////////////////////////////////////////////////////////
205// Renderer
206///////////////////////////////////////////////////////////////////////////////
207
208/**
209 * Records drawing commands in a display list for latter playback.
210 */
211class DisplayListRenderer: public OpenGLRenderer {
212public:
213    DisplayListRenderer();
214    ~DisplayListRenderer();
215
216    void setViewport(int width, int height);
217    void prepare(bool opaque);
218
219    void acquireContext();
220    void releaseContext();
221
222    int save(int flags);
223    void restore();
224    void restoreToCount(int saveCount);
225
226    int saveLayer(float left, float top, float right, float bottom,
227            const SkPaint* p, 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, const SkPaint* paint);
239    void drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const 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, const 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, const SkPaint* paint);
246    void drawColor(int color, SkXfermode::Mode mode);
247    void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
248    void drawPath(SkPath* path, SkPaint* paint);
249    void drawLines(float* points, int count, const 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 SkTDArray<const SkFlatBitmap*>& getBitmaps() const {
272        return mBitmaps;
273    }
274
275    const SkTDArray<const SkFlatMatrix*>& getMatrices() const {
276        return mMatrices;
277    }
278
279    const SkTDArray<const SkFlatPaint*>& getPaints() const {
280        return mPaints;
281    }
282
283private:
284    inline void addOp(DisplayList::Op drawOp) {
285        mWriter.writeInt(drawOp);
286    }
287
288    inline void addInt(int value) {
289        mWriter.writeInt(value);
290    }
291
292    void addInts(const int32_t* values, uint32_t count) {
293        mWriter.writeInt(count);
294        for (uint32_t i = 0; i < count; i++) {
295            mWriter.writeInt(values[i]);
296        }
297    }
298
299    void addUInts(const uint32_t* values, int8_t count) {
300        mWriter.writeInt(count);
301        for (int8_t i = 0; i < count; i++) {
302            mWriter.writeInt(values[i]);
303        }
304    }
305
306    inline void addFloat(float value) {
307        mWriter.writeScalar(value);
308    }
309
310    void addFloats(const float* values, int count) {
311        mWriter.writeInt(count);
312        for (int i = 0; i < count; i++) {
313            mWriter.writeScalar(values[i]);
314        }
315    }
316
317    inline void addPoint(float x, float y) {
318        mWriter.writeScalar(x);
319        mWriter.writeScalar(y);
320    }
321
322    inline void addBounds(float left, float top, float right, float bottom) {
323        mWriter.writeScalar(left);
324        mWriter.writeScalar(top);
325        mWriter.writeScalar(right);
326        mWriter.writeScalar(bottom);
327    }
328
329    inline void addText(const void* text, size_t byteLength) {
330        mWriter.writeInt(byteLength);
331        mWriter.writePad(text, byteLength);
332    }
333
334    inline void addPath(const SkPath* path) {
335        if (mPathHeap == NULL) {
336            mPathHeap = new PathHeap();
337        }
338        addInt(mPathHeap->append(*path));
339    }
340
341    int find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint);
342
343    inline void addPaint(const SkPaint* paint) {
344        addInt(find(mPaints, paint));
345    }
346
347    int find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix);
348
349    inline void addMatrix(const SkMatrix* matrix) {
350        addInt(find(mMatrices, matrix));
351    }
352
353    int find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap);
354
355    inline void addBitmap(const SkBitmap* bitmap) {
356        addInt(find(mBitmaps, *bitmap));
357    }
358
359    SkChunkAlloc mHeap;
360
361    int mBitmapIndex;
362    SkTDArray<const SkFlatBitmap*> mBitmaps;
363
364    int mMatrixIndex;
365    SkTDArray<const SkFlatMatrix*> mMatrices;
366
367    int mPaintIndex;
368    SkTDArray<const SkFlatPaint*> mPaints;
369
370    PathHeap* mPathHeap;
371    SkWriter32 mWriter;
372
373    SkRefCntRecorder mRCRecorder;
374    SkRefCntRecorder mTFRecorder;
375
376    friend class DisplayList;
377
378}; // class DisplayListRenderer
379
380}; // namespace uirenderer
381}; // namespace android
382
383#endif // ANDROID_UI_DISPLAY_LIST_RENDERER_H
384