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