DisplayListRenderer.h revision 52244fff29042926e21fa897ef5ab11148e35299
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 <SkMatrix.h>
21#include <SkPaint.h>
22#include <SkPath.h>
23#include <cutils/compiler.h>
24
25#include "DisplayListLogBuffer.h"
26#include "OpenGLRenderer.h"
27#include "RenderNode.h"
28
29namespace android {
30namespace uirenderer {
31
32///////////////////////////////////////////////////////////////////////////////
33// Defines
34///////////////////////////////////////////////////////////////////////////////
35
36#define MIN_WRITER_SIZE 4096
37#define OP_MAY_BE_SKIPPED_MASK 0xff000000
38
39// Debug
40#if DEBUG_DISPLAY_LIST
41    #define DISPLAY_LIST_LOGD(...) ALOGD(__VA_ARGS__)
42#else
43    #define DISPLAY_LIST_LOGD(...)
44#endif
45
46///////////////////////////////////////////////////////////////////////////////
47// Display list
48///////////////////////////////////////////////////////////////////////////////
49
50class DeferredDisplayList;
51class DisplayListRenderer;
52class DisplayListOp;
53class DrawOp;
54class StateOp;
55
56/**
57 * Records drawing commands in a display list for later playback into an OpenGLRenderer.
58 */
59class DisplayListRenderer: public OpenGLRenderer {
60public:
61    ANDROID_API DisplayListRenderer();
62    virtual ~DisplayListRenderer();
63
64    ANDROID_API DisplayListData* finishRecording();
65
66    virtual bool isRecording() const { return true; }
67
68// ----------------------------------------------------------------------------
69// Frame state operations
70// ----------------------------------------------------------------------------
71    virtual void setViewport(int width, int height);
72    virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
73    virtual void finish();
74    virtual void interrupt();
75    virtual void resume();
76
77// ----------------------------------------------------------------------------
78// Canvas state operations
79// ----------------------------------------------------------------------------
80    // Save (layer)
81    virtual int save(int flags);
82    virtual void restore();
83    virtual void restoreToCount(int saveCount);
84    virtual int saveLayer(float left, float top, float right, float bottom,
85            const SkPaint* paint, int flags);
86
87    // Matrix
88    virtual void translate(float dx, float dy, float dz);
89    virtual void rotate(float degrees);
90    virtual void scale(float sx, float sy);
91    virtual void skew(float sx, float sy);
92
93    virtual void setMatrix(const SkMatrix* matrix);
94    virtual void concatMatrix(const SkMatrix* matrix);
95
96    // Clip
97    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
98    virtual bool clipPath(const SkPath* path, SkRegion::Op op);
99    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
100
101    // Misc - should be implemented with SkPaint inspection
102    virtual void resetShader();
103    virtual void setupShader(SkiaShader* shader);
104
105    virtual void resetShadow();
106    virtual void setupShadow(float radius, float dx, float dy, int color);
107
108    virtual void resetPaintFilter();
109    virtual void setupPaintFilter(int clearBits, int setBits);
110
111// ----------------------------------------------------------------------------
112// Canvas draw operations
113// ----------------------------------------------------------------------------
114    virtual status_t drawColor(int color, SkXfermode::Mode mode);
115
116    // Bitmap-based
117    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
118            const SkPaint* paint);
119    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
120            const SkPaint* paint);
121    virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
122            float srcRight, float srcBottom, float dstLeft, float dstTop,
123            float dstRight, float dstBottom, const SkPaint* paint);
124    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
125            const SkPaint* paint);
126    virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
127            const float* vertices, const int* colors, const SkPaint* paint);
128    virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
129            float left, float top, float right, float bottom, const SkPaint* paint);
130
131    // Shapes
132    virtual status_t drawRect(float left, float top, float right, float bottom,
133            const SkPaint* paint);
134    virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
135    virtual status_t drawRoundRect(float left, float top, float right, float bottom,
136            float rx, float ry, const SkPaint* paint);
137    virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
138    virtual status_t drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
139                CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
140    virtual status_t drawOval(float left, float top, float right, float bottom,
141            const SkPaint* paint);
142    virtual status_t drawArc(float left, float top, float right, float bottom,
143            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
144    virtual status_t drawPath(const SkPath* path, const SkPaint* paint);
145    virtual status_t drawLines(const float* points, int count, const SkPaint* paint);
146    virtual status_t drawPoints(const float* points, int count, const SkPaint* paint);
147
148    // Text
149    virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
150            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
151            DrawOpMode drawOpMode = kDrawOpMode_Immediate);
152    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
153            float hOffset, float vOffset, const SkPaint* paint);
154    virtual status_t drawPosText(const char* text, int bytesCount, int count,
155            const float* positions, const SkPaint* paint);
156
157// ----------------------------------------------------------------------------
158// Canvas draw operations - special
159// ----------------------------------------------------------------------------
160    virtual status_t drawLayer(Layer* layer, float x, float y);
161    virtual status_t drawDisplayList(RenderNode* displayList, Rect& dirty,
162            int32_t replayFlags);
163
164    // TODO: rename for consistency
165    virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty);
166
167private:
168    void insertRestoreToCount();
169    void insertTranslate();
170
171    LinearAllocator& alloc() { return mDisplayListData->allocator; }
172    void addStateOp(StateOp* op);
173    void addDrawOp(DrawOp* op);
174    void addOpInternal(DisplayListOp* op) {
175        insertRestoreToCount();
176        insertTranslate();
177        mDisplayListData->displayListOps.add(op);
178    }
179
180    template<class T>
181    inline const T* refBuffer(const T* srcBuffer, int32_t count) {
182        if (!srcBuffer) return NULL;
183
184        T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T));
185        memcpy(dstBuffer, srcBuffer, count * sizeof(T));
186        return dstBuffer;
187    }
188
189    inline char* refText(const char* text, size_t byteLength) {
190        return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
191    }
192
193    inline const SkPath* refPath(const SkPath* path) {
194        if (!path) return NULL;
195
196        const SkPath* pathCopy = mPathMap.valueFor(path);
197        if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
198            SkPath* newPathCopy = new SkPath(*path);
199            newPathCopy->setSourcePath(path);
200
201            pathCopy = newPathCopy;
202            // replaceValueFor() performs an add if the entry doesn't exist
203            mPathMap.replaceValueFor(path, pathCopy);
204            mDisplayListData->paths.add(pathCopy);
205        }
206        if (mDisplayListData->sourcePaths.indexOf(path) < 0) {
207            mCaches.resourceCache.incrementRefcount(path);
208            mDisplayListData->sourcePaths.add(path);
209        }
210        return pathCopy;
211    }
212
213    inline const SkPaint* refPaint(const SkPaint* paint) {
214        if (!paint) {
215            return paint;
216        }
217
218        const SkPaint* paintCopy = mPaintMap.valueFor(paint);
219        if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
220            paintCopy = new SkPaint(*paint);
221            // replaceValueFor() performs an add if the entry doesn't exist
222            mPaintMap.replaceValueFor(paint, paintCopy);
223            mDisplayListData->paints.add(paintCopy);
224        }
225
226        return paintCopy;
227    }
228
229    inline const SkRegion* refRegion(const SkRegion* region) {
230        if (!region) {
231            return region;
232        }
233
234        const SkRegion* regionCopy = mRegionMap.valueFor(region);
235        // TODO: Add generation ID to SkRegion
236        if (regionCopy == NULL) {
237            regionCopy = new SkRegion(*region);
238            // replaceValueFor() performs an add if the entry doesn't exist
239            mRegionMap.replaceValueFor(region, regionCopy);
240            mDisplayListData->regions.add(regionCopy);
241        }
242
243        return regionCopy;
244    }
245
246    inline const SkMatrix* refMatrix(const SkMatrix* matrix) {
247        if (matrix) {
248            // Copying the matrix is cheap and prevents against the user changing
249            // the original matrix before the operation that uses it
250            const SkMatrix* copy = new SkMatrix(*matrix);
251            mDisplayListData->matrices.add(copy);
252            return copy;
253        }
254        return matrix;
255    }
256
257    inline Layer* refLayer(Layer* layer) {
258        mDisplayListData->layers.add(layer);
259        mCaches.resourceCache.incrementRefcount(layer);
260        return layer;
261    }
262
263    inline const SkBitmap* refBitmap(const SkBitmap* bitmap) {
264        // Note that this assumes the bitmap is immutable. There are cases this won't handle
265        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
266        // contents, and drawing again. The only fix would be to always copy it the first time,
267        // which doesn't seem worth the extra cycles for this unlikely case.
268        mDisplayListData->bitmapResources.add(bitmap);
269        mCaches.resourceCache.incrementRefcount(bitmap);
270        return bitmap;
271    }
272
273    inline const SkBitmap* refBitmapData(const SkBitmap* bitmap) {
274        mDisplayListData->ownedBitmapResources.add(bitmap);
275        mCaches.resourceCache.incrementRefcount(bitmap);
276        return bitmap;
277    }
278
279    inline SkiaShader* refShader(SkiaShader* shader) {
280        if (!shader) return NULL;
281
282        SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
283        // TODO: We also need to handle generation ID changes in compose shaders
284        if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
285            shaderCopy = shader->copy();
286            // replaceValueFor() performs an add if the entry doesn't exist
287            mShaderMap.replaceValueFor(shader, shaderCopy);
288            mDisplayListData->shaders.add(shaderCopy);
289            mCaches.resourceCache.incrementRefcount(shaderCopy);
290        }
291        return shaderCopy;
292    }
293
294    inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
295        mDisplayListData->patchResources.add(patch);
296        mCaches.resourceCache.incrementRefcount(patch);
297        return patch;
298    }
299
300    DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap;
301    DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
302    DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
303    DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
304
305    Caches& mCaches;
306    DisplayListData* mDisplayListData;
307
308    float mTranslateX;
309    float mTranslateY;
310    bool mHasTranslate;
311
312    int mRestoreSaveCount;
313
314    friend class RenderNode;
315
316}; // class DisplayListRenderer
317
318}; // namespace uirenderer
319}; // namespace android
320
321#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
322