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