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