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