DisplayListRenderer.h revision a1cff5043d0fbd78fcf9c48e7658e56a5b0c2de3
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 <SkCamera.h>
24#include <SkPaint.h>
25#include <SkPath.h>
26#include <SkRefCnt.h>
27#include <SkTDArray.h>
28#include <SkTSearch.h>
29
30#include <cutils/compiler.h>
31
32#include "DisplayListLogBuffer.h"
33#include "OpenGLRenderer.h"
34
35namespace android {
36namespace uirenderer {
37
38///////////////////////////////////////////////////////////////////////////////
39// Defines
40///////////////////////////////////////////////////////////////////////////////
41
42#define MIN_WRITER_SIZE 4096
43#define OP_MAY_BE_SKIPPED_MASK 0xff000000
44
45// Debug
46#if DEBUG_DISPLAY_LIST
47    #define DISPLAY_LIST_LOGD(...) ALOGD(__VA_ARGS__)
48#else
49    #define DISPLAY_LIST_LOGD(...)
50#endif
51
52// Set to 1 to enable native processing of View properties. 0 by default. Eventually this
53// will go away and we will always use this approach for accelerated apps.
54#define USE_DISPLAY_LIST_PROPERTIES 0
55
56#define TRANSLATION 0x0001
57#define ROTATION    0x0002
58#define ROTATION_3D 0x0004
59#define SCALE       0x0008
60#define PIVOT       0x0010
61
62///////////////////////////////////////////////////////////////////////////////
63// Display list
64///////////////////////////////////////////////////////////////////////////////
65
66class DisplayListRenderer;
67
68/**
69 * Replays recorded drawing commands.
70 */
71class DisplayList {
72public:
73    DisplayList(const DisplayListRenderer& recorder);
74    ANDROID_API ~DisplayList();
75
76    // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file
77    //            when modifying this file
78    enum Op {
79        // Non-drawing operations
80        Save = 0,
81        Restore,
82        RestoreToCount,
83        SaveLayer,
84        SaveLayerAlpha,
85        Translate,
86        Rotate,
87        Scale,
88        Skew,
89        SetMatrix,
90        ConcatMatrix,
91        ClipRect,
92        // Drawing operations
93        DrawDisplayList,
94        DrawLayer,
95        DrawBitmap,
96        DrawBitmapMatrix,
97        DrawBitmapRect,
98        DrawBitmapMesh,
99        DrawPatch,
100        DrawColor,
101        DrawRect,
102        DrawRoundRect,
103        DrawCircle,
104        DrawOval,
105        DrawArc,
106        DrawPath,
107        DrawLines,
108        DrawPoints,
109        DrawText,
110        DrawTextOnPath,
111        DrawPosText,
112        ResetShader,
113        SetupShader,
114        ResetColorFilter,
115        SetupColorFilter,
116        ResetShadow,
117        SetupShadow,
118        ResetPaintFilter,
119        SetupPaintFilter,
120        DrawGLFunction,
121    };
122
123    // See flags defined in DisplayList.java
124    enum ReplayFlag {
125        kReplayFlag_ClipChildren = 0x1
126    };
127
128    static const char* OP_NAMES[];
129
130    void setViewProperties(OpenGLRenderer& renderer, uint32_t width, uint32_t height,
131            uint32_t level);
132    void outputViewProperties(OpenGLRenderer& renderer, char* indent);
133
134    ANDROID_API size_t getSize();
135    ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
136    ANDROID_API static void outputLogBuffer(int fd);
137
138    void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
139
140    bool replay(OpenGLRenderer& renderer, uint32_t width, uint32_t height,
141            Rect& dirty, int32_t flags, uint32_t level = 0);
142
143    void output(OpenGLRenderer& renderer, uint32_t level = 0);
144
145    void setRenderable(bool renderable) {
146        mIsRenderable = renderable;
147    }
148
149    bool isRenderable() const {
150        return mIsRenderable;
151    }
152
153    void setName(const char* name) {
154        if (name) {
155            mName.setTo(name);
156        }
157    }
158
159    void setApplicationScale(float scale) {
160        mApplicationScale = scale;
161    }
162
163    void setClipChildren(bool clipChildren) {
164        mClipChildren = clipChildren;
165    }
166
167    void setAlpha(float alpha) {
168        if (alpha != mAlpha) {
169            mAlpha = alpha;
170            mMultipliedAlpha = (int)(255 * alpha);
171        }
172    }
173
174    void setTranslationX(float translationX) {
175        if (translationX != mTranslationX) {
176            mTranslationX = translationX;
177            mMatrixDirty = true;
178            if (ALMOST_EQUAL(mTranslationX, 0) && ALMOST_EQUAL(mTranslationY, 0)) {
179                mMatrixFlags &= ~TRANSLATION;
180            } else {
181                mMatrixFlags |= TRANSLATION;
182            }
183        }
184    }
185
186    void setTranslationY(float translationY) {
187        if (translationY != mTranslationY) {
188            mTranslationY = translationY;
189            mMatrixDirty = true;
190            if (ALMOST_EQUAL(mTranslationX, 0) && ALMOST_EQUAL(mTranslationY, 0)) {
191                mMatrixFlags &= ~TRANSLATION;
192            } else {
193                mMatrixFlags |= TRANSLATION;
194            }
195        }
196    }
197
198    void setRotation(float rotation) {
199        if (rotation != mRotation) {
200            mRotation = rotation;
201            mMatrixDirty = true;
202            if (ALMOST_EQUAL(mRotation, 0)) {
203                mMatrixFlags &= ~ROTATION;
204            } else {
205                mMatrixFlags |= ROTATION;
206            }
207        }
208    }
209
210    void setRotationX(float rotationX) {
211        if (rotationX != mRotationX) {
212            mRotationX = rotationX;
213            mMatrixDirty = true;
214            if (ALMOST_EQUAL(mRotationX, 0) && ALMOST_EQUAL(mRotationY, 0)) {
215                mMatrixFlags &= ~ROTATION_3D;
216            } else {
217                mMatrixFlags |= ROTATION_3D;
218            }
219        }
220    }
221
222    void setRotationY(float rotationY) {
223        if (rotationY != mRotationY) {
224            mRotationY = rotationY;
225            mMatrixDirty = true;
226            if (ALMOST_EQUAL(mRotationX, 0) && ALMOST_EQUAL(mRotationY, 0)) {
227                mMatrixFlags &= ~ROTATION_3D;
228            } else {
229                mMatrixFlags |= ROTATION_3D;
230            }
231        }
232    }
233
234    void setScaleX(float scaleX) {
235        if (scaleX != mScaleX) {
236            mScaleX = scaleX;
237            mMatrixDirty = true;
238            if (ALMOST_EQUAL(mScaleX, 1) && ALMOST_EQUAL(mScaleY, 1)) {
239                mMatrixFlags &= ~SCALE;
240            } else {
241                mMatrixFlags |= SCALE;
242            }
243        }
244    }
245
246    void setScaleY(float scaleY) {
247        if (scaleY != mScaleY) {
248            mScaleY = scaleY;
249            mMatrixDirty = true;
250            if (ALMOST_EQUAL(mScaleX, 1) && ALMOST_EQUAL(mScaleY, 1)) {
251                mMatrixFlags &= ~SCALE;
252            } else {
253                mMatrixFlags |= SCALE;
254            }
255        }
256    }
257
258    void setPivotX(float pivotX) {
259        mPivotX = pivotX;
260        mMatrixDirty = true;
261        if (ALMOST_EQUAL(mPivotX, 0) && ALMOST_EQUAL(mPivotY, 0)) {
262            mMatrixFlags &= ~PIVOT;
263        } else {
264            mMatrixFlags |= PIVOT;
265        }
266        mPivotExplicitlySet = true;
267    }
268
269    void setPivotY(float pivotY) {
270        mPivotY = pivotY;
271        mMatrixDirty = true;
272        if (ALMOST_EQUAL(mPivotX, 0) && ALMOST_EQUAL(mPivotY, 0)) {
273            mMatrixFlags &= ~PIVOT;
274        } else {
275            mMatrixFlags |= PIVOT;
276        }
277        mPivotExplicitlySet = true;
278    }
279
280    void setCameraDistance(float distance) {
281        if (distance != mCameraDistance) {
282            mCameraDistance = distance;
283            mMatrixDirty = true;
284            if (!mTransformCamera) {
285                mTransformCamera = new Sk3DView();
286                mTransformMatrix3D = new SkMatrix();
287            }
288            mTransformCamera->setCameraLocation(0, 0, distance);
289        }
290    }
291
292    void setLeft(int left) {
293        if (left != mLeft) {
294            mLeft = left;
295            mWidth = mRight - mLeft;
296            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
297                mMatrixDirty = true;
298            }
299        }
300    }
301
302    void setTop(int top) {
303        if (top != mTop) {
304            mTop = top;
305            mHeight = mBottom - mTop;
306            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
307                mMatrixDirty = true;
308            }
309        }
310    }
311
312    void setRight(int right) {
313        if (right != mRight) {
314            mRight = right;
315            mWidth = mRight - mLeft;
316            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
317                mMatrixDirty = true;
318            }
319        }
320    }
321
322    void setBottom(int bottom) {
323        if (bottom != mBottom) {
324            mBottom = bottom;
325            mHeight = mBottom - mTop;
326            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
327                mMatrixDirty = true;
328            }
329        }
330    }
331
332    void setLeftTop(int left, int top) {
333        if (left != mLeft || top != mTop) {
334            mLeft = left;
335            mTop = top;
336            mWidth = mRight - mLeft;
337            mHeight = mBottom - mTop;
338            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
339                mMatrixDirty = true;
340            }
341        }
342    }
343
344    void setLeftTopRightBottom(int left, int top, int right, int bottom) {
345        if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
346            mLeft = left;
347            mTop = top;
348            mRight = right;
349            mBottom = bottom;
350            mWidth = mRight - mLeft;
351            mHeight = mBottom - mTop;
352            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
353                mMatrixDirty = true;
354            }
355        }
356    }
357
358    void offsetLeftRight(int offset) {
359        if (offset != 0) {
360            mLeft += offset;
361            mRight += offset;
362            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
363                mMatrixDirty = true;
364            }
365        }
366    }
367
368    void offsetTopBottom(int offset) {
369        if (offset != 0) {
370            mTop += offset;
371            mBottom += offset;
372            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
373                mMatrixDirty = true;
374            }
375        }
376    }
377
378    void setCaching(bool caching) {
379        mCaching = caching;
380    }
381
382    void transformRect(float left, float top, float right, float bottom, Rect& result);
383
384private:
385    void init();
386
387    void initProperties();
388
389    void clearResources();
390
391    void updateMatrix();
392
393    class TextContainer {
394    public:
395        size_t length() const {
396            return mByteLength;
397        }
398
399        const char* text() const {
400            return (const char*) mText;
401        }
402
403        size_t mByteLength;
404        const char* mText;
405    };
406
407    SkBitmap* getBitmap() {
408        return (SkBitmap*) getInt();
409    }
410
411    SkiaShader* getShader() {
412        return (SkiaShader*) getInt();
413    }
414
415    SkiaColorFilter* getColorFilter() {
416        return (SkiaColorFilter*) getInt();
417    }
418
419    inline int32_t getIndex() {
420        return mReader.readInt();
421    }
422
423    inline int32_t getInt() {
424        return mReader.readInt();
425    }
426
427    inline uint32_t getUInt() {
428        return mReader.readU32();
429    }
430
431    SkMatrix* getMatrix() {
432        return (SkMatrix*) getInt();
433    }
434
435    SkPath* getPath() {
436        return (SkPath*) getInt();
437    }
438
439    SkPaint* getPaint(OpenGLRenderer& renderer) {
440        return renderer.filterPaint((SkPaint*) getInt());
441    }
442
443    DisplayList* getDisplayList() {
444        return (DisplayList*) getInt();
445    }
446
447    inline float getFloat() {
448        return mReader.readScalar();
449    }
450
451    int32_t* getInts(uint32_t& count) {
452        count = getInt();
453        return (int32_t*) mReader.skip(count * sizeof(int32_t));
454    }
455
456    uint32_t* getUInts(int8_t& count) {
457        count = getInt();
458        return (uint32_t*) mReader.skip(count * sizeof(uint32_t));
459    }
460
461    float* getFloats(int32_t& count) {
462        count = getInt();
463        return (float*) mReader.skip(count * sizeof(float));
464    }
465
466    void getText(TextContainer* text) {
467        size_t length = text->mByteLength = getInt();
468        text->mText = (const char*) mReader.skip(length);
469    }
470
471    Vector<SkBitmap*> mBitmapResources;
472    Vector<SkiaColorFilter*> mFilterResources;
473
474    Vector<SkPaint*> mPaints;
475    Vector<SkPath*> mPaths;
476    Vector<SkMatrix*> mMatrices;
477    Vector<SkiaShader*> mShaders;
478
479    mutable SkFlattenableReadBuffer mReader;
480
481    size_t mSize;
482
483    bool mIsRenderable;
484
485    String8 mName;
486
487    // View properties
488    float mApplicationScale;
489    bool mClipChildren;
490    float mAlpha;
491    int mMultipliedAlpha;
492    float mTranslationX, mTranslationY;
493    float mRotation, mRotationX, mRotationY;
494    float mScaleX, mScaleY;
495    float mPivotX, mPivotY;
496    float mCameraDistance;
497    int mLeft, mTop, mRight, mBottom;
498    int mWidth, mHeight;
499    int mPrevWidth, mPrevHeight;
500    bool mPivotExplicitlySet;
501    bool mMatrixDirty;
502    bool mMatrixIsIdentity;
503    uint32_t mMatrixFlags;
504    SkMatrix* mTransformMatrix;
505    Sk3DView* mTransformCamera;
506    SkMatrix* mTransformMatrix3D;
507    bool mCaching;
508};
509
510///////////////////////////////////////////////////////////////////////////////
511// Renderer
512///////////////////////////////////////////////////////////////////////////////
513
514/**
515 * Records drawing commands in a display list for latter playback.
516 */
517class DisplayListRenderer: public OpenGLRenderer {
518public:
519    ANDROID_API DisplayListRenderer();
520    virtual ~DisplayListRenderer();
521
522    ANDROID_API DisplayList* getDisplayList(DisplayList* displayList);
523
524    virtual void setViewport(int width, int height);
525    virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
526    virtual void finish();
527
528    virtual bool callDrawGLFunction(Functor *functor, Rect& dirty);
529
530    virtual void interrupt();
531    virtual void resume();
532
533    virtual int save(int flags);
534    virtual void restore();
535    virtual void restoreToCount(int saveCount);
536
537    virtual int saveLayer(float left, float top, float right, float bottom,
538            SkPaint* p, int flags);
539    virtual int saveLayerAlpha(float left, float top, float right, float bottom,
540                int alpha, int flags);
541
542    virtual void translate(float dx, float dy);
543    virtual void rotate(float degrees);
544    virtual void scale(float sx, float sy);
545    virtual void skew(float sx, float sy);
546
547    virtual void setMatrix(SkMatrix* matrix);
548    virtual void concatMatrix(SkMatrix* matrix);
549
550    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
551
552    virtual bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
553            Rect& dirty, int32_t flags, uint32_t level = 0);
554    virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
555    virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
556    virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
557    virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
558            float srcRight, float srcBottom, float dstLeft, float dstTop,
559            float dstRight, float dstBottom, SkPaint* paint);
560    virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
561            float* vertices, int* colors, SkPaint* paint);
562    virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
563            const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
564            float left, float top, float right, float bottom, SkPaint* paint);
565    virtual void drawColor(int color, SkXfermode::Mode mode);
566    virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
567    virtual void drawRoundRect(float left, float top, float right, float bottom,
568            float rx, float ry, SkPaint* paint);
569    virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
570    virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
571    virtual void drawArc(float left, float top, float right, float bottom,
572            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
573    virtual void drawPath(SkPath* path, SkPaint* paint);
574    virtual void drawLines(float* points, int count, SkPaint* paint);
575    virtual void drawPoints(float* points, int count, SkPaint* paint);
576    virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
577            SkPaint* paint, float length = 1.0f);
578    virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
579            float hOffset, float vOffset, SkPaint* paint);
580    virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
581            SkPaint* paint);
582
583    virtual void resetShader();
584    virtual void setupShader(SkiaShader* shader);
585
586    virtual void resetColorFilter();
587    virtual void setupColorFilter(SkiaColorFilter* filter);
588
589    virtual void resetShadow();
590    virtual void setupShadow(float radius, float dx, float dy, int color);
591
592    virtual void resetPaintFilter();
593    virtual void setupPaintFilter(int clearBits, int setBits);
594
595    ANDROID_API void reset();
596
597    const SkWriter32& writeStream() const {
598        return mWriter;
599    }
600
601    const Vector<SkBitmap*>& getBitmapResources() const {
602        return mBitmapResources;
603    }
604
605    const Vector<SkiaColorFilter*>& getFilterResources() const {
606        return mFilterResources;
607    }
608
609    const Vector<SkiaShader*>& getShaders() const {
610        return mShaders;
611    }
612
613    const Vector<SkPaint*>& getPaints() const {
614        return mPaints;
615    }
616
617    const Vector<SkPath*>& getPaths() const {
618        return mPaths;
619    }
620
621    const Vector<SkMatrix*>& getMatrices() const {
622        return mMatrices;
623    }
624
625private:
626    void insertRestoreToCount() {
627        if (mRestoreSaveCount >= 0) {
628            mWriter.writeInt(DisplayList::RestoreToCount);
629            addInt(mRestoreSaveCount);
630            mRestoreSaveCount = -1;
631        }
632    }
633
634    void insertTranlate() {
635        if (mHasTranslate) {
636            if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
637                mWriter.writeInt(DisplayList::Translate);
638                addPoint(mTranslateX, mTranslateY);
639                mTranslateX = mTranslateY = 0.0f;
640            }
641            mHasTranslate = false;
642        }
643    }
644
645    inline void addOp(const DisplayList::Op drawOp) {
646        insertRestoreToCount();
647        insertTranlate();
648        mWriter.writeInt(drawOp);
649        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
650    }
651
652    uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) {
653        insertRestoreToCount();
654        insertTranlate();
655        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
656        if (reject) {
657            mWriter.writeInt(OP_MAY_BE_SKIPPED_MASK | drawOp);
658            mWriter.writeInt(0xdeaddead);
659            uint32_t* location = reject ?
660                    mWriter.peek32(mWriter.size() - sizeof(int32_t)) : NULL;
661            return location;
662        }
663        mWriter.writeInt(drawOp);
664        return NULL;
665    }
666
667    inline void addSkip(uint32_t* location) {
668        if (location) {
669            *location = (int32_t) (mWriter.peek32(
670                    mWriter.size() - sizeof(int32_t)) - location);
671        }
672    }
673
674    inline void addInt(int32_t value) {
675        mWriter.writeInt(value);
676    }
677
678    inline void addSize(uint32_t w, uint32_t h) {
679        mWriter.writeInt(w);
680        mWriter.writeInt(h);
681    }
682
683    void addInts(const int32_t* values, uint32_t count) {
684        mWriter.writeInt(count);
685        for (uint32_t i = 0; i < count; i++) {
686            mWriter.writeInt(values[i]);
687        }
688    }
689
690    void addUInts(const uint32_t* values, int8_t count) {
691        mWriter.writeInt(count);
692        for (int8_t i = 0; i < count; i++) {
693            mWriter.writeInt(values[i]);
694        }
695    }
696
697    inline void addFloat(float value) {
698        mWriter.writeScalar(value);
699    }
700
701    void addFloats(const float* values, int32_t count) {
702        mWriter.writeInt(count);
703        for (int32_t i = 0; i < count; i++) {
704            mWriter.writeScalar(values[i]);
705        }
706    }
707
708    inline void addPoint(float x, float y) {
709        mWriter.writeScalar(x);
710        mWriter.writeScalar(y);
711    }
712
713    inline void addBounds(float left, float top, float right, float bottom) {
714        mWriter.writeScalar(left);
715        mWriter.writeScalar(top);
716        mWriter.writeScalar(right);
717        mWriter.writeScalar(bottom);
718    }
719
720    inline void addText(const void* text, size_t byteLength) {
721        mWriter.writeInt(byteLength);
722        mWriter.writePad(text, byteLength);
723    }
724
725    inline void addPath(SkPath* path) {
726        if (!path) {
727            addInt((int) NULL);
728            return;
729        }
730
731        SkPath* pathCopy = mPathMap.valueFor(path);
732        if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
733            pathCopy = new SkPath(*path);
734            pathCopy->setSourcePath(path);
735            // replaceValueFor() performs an add if the entry doesn't exist
736            mPathMap.replaceValueFor(path, pathCopy);
737            mPaths.add(pathCopy);
738        }
739
740        addInt((int) pathCopy);
741    }
742
743    inline void addPaint(SkPaint* paint) {
744        if (!paint) {
745            addInt((int) NULL);
746            return;
747        }
748
749        SkPaint* paintCopy = mPaintMap.valueFor(paint);
750        if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
751            paintCopy = new SkPaint(*paint);
752            // replaceValueFor() performs an add if the entry doesn't exist
753            mPaintMap.replaceValueFor(paint, paintCopy);
754            mPaints.add(paintCopy);
755        }
756
757        addInt((int) paintCopy);
758    }
759
760    inline void addDisplayList(DisplayList* displayList) {
761        // TODO: To be safe, the display list should be ref-counted in the
762        //       resources cache, but we rely on the caller (UI toolkit) to
763        //       do the right thing for now
764        addInt((int) displayList);
765    }
766
767    inline void addMatrix(SkMatrix* matrix) {
768        // Copying the matrix is cheap and prevents against the user changing the original
769        // matrix before the operation that uses it
770        SkMatrix* copy = new SkMatrix(*matrix);
771        addInt((int) copy);
772        mMatrices.add(copy);
773    }
774
775    inline void addBitmap(SkBitmap* bitmap) {
776        // Note that this assumes the bitmap is immutable. There are cases this won't handle
777        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
778        // contents, and drawing again. The only fix would be to always copy it the first time,
779        // which doesn't seem worth the extra cycles for this unlikely case.
780        addInt((int) bitmap);
781        mBitmapResources.add(bitmap);
782        Caches::getInstance().resourceCache.incrementRefcount(bitmap);
783    }
784
785    inline void addShader(SkiaShader* shader) {
786        if (!shader) {
787            addInt((int) NULL);
788            return;
789        }
790
791        SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
792        // TODO: We also need to handle generation ID changes in compose shaders
793        if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
794            shaderCopy = shader->copy();
795            // replaceValueFor() performs an add if the entry doesn't exist
796            mShaderMap.replaceValueFor(shader, shaderCopy);
797            mShaders.add(shaderCopy);
798            Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
799        }
800
801        addInt((int) shaderCopy);
802    }
803
804    inline void addColorFilter(SkiaColorFilter* colorFilter) {
805        addInt((int) colorFilter);
806        mFilterResources.add(colorFilter);
807        Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
808    }
809
810    Vector<SkBitmap*> mBitmapResources;
811    Vector<SkiaColorFilter*> mFilterResources;
812
813    Vector<SkPaint*> mPaints;
814    DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
815
816    Vector<SkPath*> mPaths;
817    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
818
819    Vector<SkiaShader*> mShaders;
820    DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
821
822    Vector<SkMatrix*> mMatrices;
823
824    SkWriter32 mWriter;
825
826    int mRestoreSaveCount;
827
828    float mTranslateX;
829    float mTranslateY;
830    bool mHasTranslate;
831
832    bool mHasDrawOps;
833
834    friend class DisplayList;
835
836}; // class DisplayListRenderer
837
838}; // namespace uirenderer
839}; // namespace android
840
841#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
842