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