DisplayListRenderer.h revision eb9a5367e8f0e970db8509ffb2584f5376bc62ed
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        DrawGLFunction,
107    };
108
109    static const char* OP_NAMES[];
110
111    void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
112
113    ANDROID_API size_t getSize();
114
115    bool replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level = 0);
116
117    void output(OpenGLRenderer& renderer, uint32_t level = 0);
118
119    ANDROID_API static void outputLogBuffer(int fd);
120
121    void setRenderable(bool renderable) {
122        mIsRenderable = renderable;
123    }
124
125    bool isRenderable() const {
126        return mIsRenderable;
127    }
128
129private:
130    void init();
131
132    void clearResources();
133
134    class TextContainer {
135    public:
136        size_t length() const {
137            return mByteLength;
138        }
139
140        const char* text() const {
141            return (const char*) mText;
142        }
143
144        size_t mByteLength;
145        const char* mText;
146    };
147
148    SkBitmap* getBitmap() {
149        return (SkBitmap*) getInt();
150    }
151
152    SkiaShader* getShader() {
153        return (SkiaShader*) getInt();
154    }
155
156    SkiaColorFilter* getColorFilter() {
157        return (SkiaColorFilter*) getInt();
158    }
159
160    inline int getIndex() {
161        return mReader.readInt();
162    }
163
164    inline int getInt() {
165        return mReader.readInt();
166    }
167
168    inline uint32_t getUInt() {
169        return mReader.readU32();
170    }
171
172    SkMatrix* getMatrix() {
173        return (SkMatrix*) getInt();
174    }
175
176    SkPath* getPath() {
177        return (SkPath*) getInt();
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    Vector<SkBitmap*> mBitmapResources;
213    Vector<SkiaColorFilter*> mFilterResources;
214
215    Vector<SkPaint*> mPaints;
216    Vector<SkPath*> mPaths;
217    Vector<SkMatrix*> mMatrices;
218    Vector<SkiaShader*> mShaders;
219
220    mutable SkFlattenableReadBuffer mReader;
221
222    size_t mSize;
223
224    bool mIsRenderable;
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    ANDROID_API DisplayListRenderer();
237    virtual ~DisplayListRenderer();
238
239    ANDROID_API DisplayList* getDisplayList(DisplayList* displayList);
240
241    virtual void setViewport(int width, int height);
242    virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
243    virtual void finish();
244
245    virtual bool callDrawGLFunction(Functor *functor, Rect& dirty);
246
247    virtual void interrupt();
248    virtual void resume();
249
250    virtual int save(int flags);
251    virtual void restore();
252    virtual void restoreToCount(int saveCount);
253
254    virtual int saveLayer(float left, float top, float right, float bottom,
255            SkPaint* p, int flags);
256    virtual int saveLayerAlpha(float left, float top, float right, float bottom,
257                int alpha, int flags);
258
259    virtual void translate(float dx, float dy);
260    virtual void rotate(float degrees);
261    virtual void scale(float sx, float sy);
262    virtual void skew(float sx, float sy);
263
264    virtual void setMatrix(SkMatrix* matrix);
265    virtual void concatMatrix(SkMatrix* matrix);
266
267    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
268
269    virtual bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
270            Rect& dirty, uint32_t level = 0);
271    virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
272    virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
273    virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
274    virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
275            float srcRight, float srcBottom, float dstLeft, float dstTop,
276            float dstRight, float dstBottom, SkPaint* paint);
277    virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
278            float* vertices, int* colors, SkPaint* paint);
279    virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
280            const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
281            float left, float top, float right, float bottom, SkPaint* paint);
282    virtual void drawColor(int color, SkXfermode::Mode mode);
283    virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
284    virtual void drawRoundRect(float left, float top, float right, float bottom,
285            float rx, float ry, SkPaint* paint);
286    virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
287    virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
288    virtual void drawArc(float left, float top, float right, float bottom,
289            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
290    virtual void drawPath(SkPath* path, SkPaint* paint);
291    virtual void drawLines(float* points, int count, SkPaint* paint);
292    virtual void drawPoints(float* points, int count, SkPaint* paint);
293    virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
294            SkPaint* paint, float length = 1.0f);
295    virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
296            SkPaint* paint);
297
298    virtual void resetShader();
299    virtual void setupShader(SkiaShader* shader);
300
301    virtual void resetColorFilter();
302    virtual void setupColorFilter(SkiaColorFilter* filter);
303
304    virtual void resetShadow();
305    virtual void setupShadow(float radius, float dx, float dy, int color);
306
307    ANDROID_API void reset();
308
309    const SkWriter32& writeStream() const {
310        return mWriter;
311    }
312
313    const Vector<SkBitmap*>& getBitmapResources() const {
314        return mBitmapResources;
315    }
316
317    const Vector<SkiaColorFilter*>& getFilterResources() const {
318        return mFilterResources;
319    }
320
321    const Vector<SkiaShader*>& getShaders() const {
322        return mShaders;
323    }
324
325    const Vector<SkPaint*>& getPaints() const {
326        return mPaints;
327    }
328
329    const Vector<SkPath*>& getPaths() const {
330        return mPaths;
331    }
332
333    const Vector<SkMatrix*>& getMatrices() const {
334        return mMatrices;
335    }
336
337private:
338    void insertRestoreToCount() {
339        if (mRestoreSaveCount >= 0) {
340            mWriter.writeInt(DisplayList::RestoreToCount);
341            addInt(mRestoreSaveCount);
342            mRestoreSaveCount = -1;
343        }
344    }
345
346    inline void addOp(DisplayList::Op drawOp) {
347        insertRestoreToCount();
348        mWriter.writeInt(drawOp);
349        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
350    }
351
352    inline void addInt(int value) {
353        mWriter.writeInt(value);
354    }
355
356    inline void addSize(uint32_t w, uint32_t h) {
357        mWriter.writeInt(w);
358        mWriter.writeInt(h);
359    }
360
361    void addInts(const int32_t* values, uint32_t count) {
362        mWriter.writeInt(count);
363        for (uint32_t i = 0; i < count; i++) {
364            mWriter.writeInt(values[i]);
365        }
366    }
367
368    void addUInts(const uint32_t* values, int8_t count) {
369        mWriter.writeInt(count);
370        for (int8_t i = 0; i < count; i++) {
371            mWriter.writeInt(values[i]);
372        }
373    }
374
375    inline void addFloat(float value) {
376        mWriter.writeScalar(value);
377    }
378
379    void addFloats(const float* values, int count) {
380        mWriter.writeInt(count);
381        for (int i = 0; i < count; i++) {
382            mWriter.writeScalar(values[i]);
383        }
384    }
385
386    inline void addPoint(float x, float y) {
387        mWriter.writeScalar(x);
388        mWriter.writeScalar(y);
389    }
390
391    inline void addBounds(float left, float top, float right, float bottom) {
392        mWriter.writeScalar(left);
393        mWriter.writeScalar(top);
394        mWriter.writeScalar(right);
395        mWriter.writeScalar(bottom);
396    }
397
398    inline void addText(const void* text, size_t byteLength) {
399        mWriter.writeInt(byteLength);
400        mWriter.writePad(text, byteLength);
401    }
402
403    inline void addPath(SkPath* path) {
404        if (!path) {
405            addInt((int) NULL);
406            return;
407        }
408
409        SkPath* pathCopy = mPathMap.valueFor(path);
410        if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
411            pathCopy = new SkPath(*path);
412            mPathMap.add(path, pathCopy);
413            mPaths.add(pathCopy);
414        }
415
416        addInt((int) pathCopy);
417    }
418
419    inline void addPaint(SkPaint* paint) {
420        if (!paint) {
421            addInt((int) NULL);
422            return;
423        }
424
425        SkPaint* paintCopy =  mPaintMap.valueFor(paint);
426        if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
427            paintCopy = new SkPaint(*paint);
428            mPaintMap.add(paint, paintCopy);
429            mPaints.add(paintCopy);
430        }
431
432        addInt((int) paintCopy);
433    }
434
435    inline void addDisplayList(DisplayList* displayList) {
436        // TODO: To be safe, the display list should be ref-counted in the
437        //       resources cache, but we rely on the caller (UI toolkit) to
438        //       do the right thing for now
439        addInt((int) displayList);
440    }
441
442    inline void addMatrix(SkMatrix* matrix) {
443        // Copying the matrix is cheap and prevents against the user changing the original
444        // matrix before the operation that uses it
445        SkMatrix* copy = new SkMatrix(*matrix);
446        addInt((int) copy);
447        mMatrices.add(copy);
448    }
449
450    inline void addBitmap(SkBitmap* bitmap) {
451        // Note that this assumes the bitmap is immutable. There are cases this won't handle
452        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
453        // contents, and drawing again. The only fix would be to always copy it the first time,
454        // which doesn't seem worth the extra cycles for this unlikely case.
455        addInt((int) bitmap);
456        mBitmapResources.add(bitmap);
457        Caches::getInstance().resourceCache.incrementRefcount(bitmap);
458    }
459
460    inline void addShader(SkiaShader* shader) {
461        if (!shader) {
462            addInt((int) NULL);
463            return;
464        }
465
466        SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
467        // TODO: We also need to handle generation ID changes in compose shaders
468        if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
469            shaderCopy = shader->copy();
470            mShaderMap.add(shader, shaderCopy);
471            mShaders.add(shaderCopy);
472            Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
473        }
474
475        addInt((int) shaderCopy);
476    }
477
478    inline void addColorFilter(SkiaColorFilter* colorFilter) {
479        addInt((int) colorFilter);
480        mFilterResources.add(colorFilter);
481        Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
482    }
483
484    Vector<SkBitmap*> mBitmapResources;
485    Vector<SkiaColorFilter*> mFilterResources;
486
487    Vector<SkPaint*> mPaints;
488    DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
489
490    Vector<SkPath*> mPaths;
491    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
492
493    Vector<SkiaShader*> mShaders;
494    DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
495
496    Vector<SkMatrix*> mMatrices;
497
498    SkWriter32 mWriter;
499
500    int mRestoreSaveCount;
501    bool mHasDrawOps;
502
503    friend class DisplayList;
504
505}; // class DisplayListRenderer
506
507}; // namespace uirenderer
508}; // namespace android
509
510#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
511