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