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