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