DisplayListRenderer.h revision ad1daaa87b793af30f3dd67a0f3cd5c0fd6ac0c1
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(0xdeaddead);
395            uint32_t* location = reject ?
396                    mWriter.peek32(mWriter.size() - sizeof(int32_t)) : NULL;
397            return location;
398        }
399        mWriter.writeInt(drawOp);
400        return NULL;
401    }
402
403    inline void addSkip(uint32_t* location) {
404        if (location) {
405            *location = (int32_t) (mWriter.peek32(
406                    mWriter.size() - sizeof(int32_t)) - location);
407        }
408    }
409
410    inline void addInt(int32_t value) {
411        mWriter.writeInt(value);
412    }
413
414    inline void addSize(uint32_t w, uint32_t h) {
415        mWriter.writeInt(w);
416        mWriter.writeInt(h);
417    }
418
419    void addInts(const int32_t* values, uint32_t count) {
420        mWriter.writeInt(count);
421        for (uint32_t i = 0; i < count; i++) {
422            mWriter.writeInt(values[i]);
423        }
424    }
425
426    void addUInts(const uint32_t* values, int8_t count) {
427        mWriter.writeInt(count);
428        for (int8_t i = 0; i < count; i++) {
429            mWriter.writeInt(values[i]);
430        }
431    }
432
433    inline void addFloat(float value) {
434        mWriter.writeScalar(value);
435    }
436
437    void addFloats(const float* values, int32_t count) {
438        mWriter.writeInt(count);
439        for (int32_t i = 0; i < count; i++) {
440            mWriter.writeScalar(values[i]);
441        }
442    }
443
444    inline void addPoint(float x, float y) {
445        mWriter.writeScalar(x);
446        mWriter.writeScalar(y);
447    }
448
449    inline void addBounds(float left, float top, float right, float bottom) {
450        mWriter.writeScalar(left);
451        mWriter.writeScalar(top);
452        mWriter.writeScalar(right);
453        mWriter.writeScalar(bottom);
454    }
455
456    inline void addText(const void* text, size_t byteLength) {
457        mWriter.writeInt(byteLength);
458        mWriter.writePad(text, byteLength);
459    }
460
461    inline void addPath(SkPath* path) {
462        if (!path) {
463            addInt((int) NULL);
464            return;
465        }
466
467        SkPath* pathCopy = mPathMap.valueFor(path);
468        if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
469            pathCopy = new SkPath(*path);
470            pathCopy->setSourcePath(path);
471            // replaceValueFor() performs an add if the entry doesn't exist
472            mPathMap.replaceValueFor(path, pathCopy);
473            mPaths.add(pathCopy);
474        }
475
476        addInt((int) pathCopy);
477    }
478
479    inline void addPaint(SkPaint* paint) {
480        if (!paint) {
481            addInt((int) NULL);
482            return;
483        }
484
485        SkPaint* paintCopy = mPaintMap.valueFor(paint);
486        if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
487            paintCopy = new SkPaint(*paint);
488            // replaceValueFor() performs an add if the entry doesn't exist
489            mPaintMap.replaceValueFor(paint, paintCopy);
490            mPaints.add(paintCopy);
491        }
492
493        addInt((int) paintCopy);
494    }
495
496    inline void addDisplayList(DisplayList* displayList) {
497        // TODO: To be safe, the display list should be ref-counted in the
498        //       resources cache, but we rely on the caller (UI toolkit) to
499        //       do the right thing for now
500        addInt((int) displayList);
501    }
502
503    inline void addMatrix(SkMatrix* matrix) {
504        // Copying the matrix is cheap and prevents against the user changing the original
505        // matrix before the operation that uses it
506        SkMatrix* copy = new SkMatrix(*matrix);
507        addInt((int) copy);
508        mMatrices.add(copy);
509    }
510
511    inline void addBitmap(SkBitmap* bitmap) {
512        // Note that this assumes the bitmap is immutable. There are cases this won't handle
513        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
514        // contents, and drawing again. The only fix would be to always copy it the first time,
515        // which doesn't seem worth the extra cycles for this unlikely case.
516        addInt((int) bitmap);
517        mBitmapResources.add(bitmap);
518        Caches::getInstance().resourceCache.incrementRefcount(bitmap);
519    }
520
521    inline void addShader(SkiaShader* shader) {
522        if (!shader) {
523            addInt((int) NULL);
524            return;
525        }
526
527        SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
528        // TODO: We also need to handle generation ID changes in compose shaders
529        if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
530            shaderCopy = shader->copy();
531            // replaceValueFor() performs an add if the entry doesn't exist
532            mShaderMap.replaceValueFor(shader, shaderCopy);
533            mShaders.add(shaderCopy);
534            Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
535        }
536
537        addInt((int) shaderCopy);
538    }
539
540    inline void addColorFilter(SkiaColorFilter* colorFilter) {
541        addInt((int) colorFilter);
542        mFilterResources.add(colorFilter);
543        Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
544    }
545
546    Vector<SkBitmap*> mBitmapResources;
547    Vector<SkiaColorFilter*> mFilterResources;
548
549    Vector<SkPaint*> mPaints;
550    DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
551
552    Vector<SkPath*> mPaths;
553    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
554
555    Vector<SkiaShader*> mShaders;
556    DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
557
558    Vector<SkMatrix*> mMatrices;
559
560    SkWriter32 mWriter;
561
562    int mRestoreSaveCount;
563
564    float mTranslateX;
565    float mTranslateY;
566    bool mHasTranslate;
567
568    bool mHasDrawOps;
569
570    friend class DisplayList;
571
572}; // class DisplayListRenderer
573
574}; // namespace uirenderer
575}; // namespace android
576
577#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
578