DisplayListRenderer.h revision 6554943a1dd6854c0f4976900956e556767b49e1
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    status_t 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 status_t 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 status_t 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            mBufferSize = mWriter.size();
660            return mWriter.peek32(mBufferSize - sizeof(int32_t));
661        }
662        mWriter.writeInt(drawOp);
663        return NULL;
664    }
665
666    inline void addSkip(uint32_t* location) {
667        if (location) {
668            *location = (int32_t) (mWriter.size() - mBufferSize);
669        }
670    }
671
672    inline void addInt(int32_t value) {
673        mWriter.writeInt(value);
674    }
675
676    inline void addSize(uint32_t w, uint32_t h) {
677        mWriter.writeInt(w);
678        mWriter.writeInt(h);
679    }
680
681    void addInts(const int32_t* values, uint32_t count) {
682        mWriter.writeInt(count);
683        for (uint32_t i = 0; i < count; i++) {
684            mWriter.writeInt(values[i]);
685        }
686    }
687
688    void addUInts(const uint32_t* values, int8_t count) {
689        mWriter.writeInt(count);
690        for (int8_t i = 0; i < count; i++) {
691            mWriter.writeInt(values[i]);
692        }
693    }
694
695    inline void addFloat(float value) {
696        mWriter.writeScalar(value);
697    }
698
699    void addFloats(const float* values, int32_t count) {
700        mWriter.writeInt(count);
701        for (int32_t i = 0; i < count; i++) {
702            mWriter.writeScalar(values[i]);
703        }
704    }
705
706    inline void addPoint(float x, float y) {
707        mWriter.writeScalar(x);
708        mWriter.writeScalar(y);
709    }
710
711    inline void addBounds(float left, float top, float right, float bottom) {
712        mWriter.writeScalar(left);
713        mWriter.writeScalar(top);
714        mWriter.writeScalar(right);
715        mWriter.writeScalar(bottom);
716    }
717
718    inline void addText(const void* text, size_t byteLength) {
719        mWriter.writeInt(byteLength);
720        mWriter.writePad(text, byteLength);
721    }
722
723    inline void addPath(SkPath* path) {
724        if (!path) {
725            addInt((int) NULL);
726            return;
727        }
728
729        SkPath* pathCopy = mPathMap.valueFor(path);
730        if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
731            pathCopy = new SkPath(*path);
732            pathCopy->setSourcePath(path);
733            // replaceValueFor() performs an add if the entry doesn't exist
734            mPathMap.replaceValueFor(path, pathCopy);
735            mPaths.add(pathCopy);
736        }
737
738        addInt((int) pathCopy);
739    }
740
741    inline void addPaint(SkPaint* paint) {
742        if (!paint) {
743            addInt((int) NULL);
744            return;
745        }
746
747        SkPaint* paintCopy = mPaintMap.valueFor(paint);
748        if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
749            paintCopy = new SkPaint(*paint);
750            // replaceValueFor() performs an add if the entry doesn't exist
751            mPaintMap.replaceValueFor(paint, paintCopy);
752            mPaints.add(paintCopy);
753        }
754
755        addInt((int) paintCopy);
756    }
757
758    inline void addDisplayList(DisplayList* displayList) {
759        // TODO: To be safe, the display list should be ref-counted in the
760        //       resources cache, but we rely on the caller (UI toolkit) to
761        //       do the right thing for now
762        addInt((int) displayList);
763    }
764
765    inline void addMatrix(SkMatrix* matrix) {
766        // Copying the matrix is cheap and prevents against the user changing the original
767        // matrix before the operation that uses it
768        SkMatrix* copy = new SkMatrix(*matrix);
769        addInt((int) copy);
770        mMatrices.add(copy);
771    }
772
773    inline void addBitmap(SkBitmap* bitmap) {
774        // Note that this assumes the bitmap is immutable. There are cases this won't handle
775        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
776        // contents, and drawing again. The only fix would be to always copy it the first time,
777        // which doesn't seem worth the extra cycles for this unlikely case.
778        addInt((int) bitmap);
779        mBitmapResources.add(bitmap);
780        Caches::getInstance().resourceCache.incrementRefcount(bitmap);
781    }
782
783    inline void addShader(SkiaShader* shader) {
784        if (!shader) {
785            addInt((int) NULL);
786            return;
787        }
788
789        SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
790        // TODO: We also need to handle generation ID changes in compose shaders
791        if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
792            shaderCopy = shader->copy();
793            // replaceValueFor() performs an add if the entry doesn't exist
794            mShaderMap.replaceValueFor(shader, shaderCopy);
795            mShaders.add(shaderCopy);
796            Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
797        }
798
799        addInt((int) shaderCopy);
800    }
801
802    inline void addColorFilter(SkiaColorFilter* colorFilter) {
803        addInt((int) colorFilter);
804        mFilterResources.add(colorFilter);
805        Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
806    }
807
808    Vector<SkBitmap*> mBitmapResources;
809    Vector<SkiaColorFilter*> mFilterResources;
810
811    Vector<SkPaint*> mPaints;
812    DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
813
814    Vector<SkPath*> mPaths;
815    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
816
817    Vector<SkiaShader*> mShaders;
818    DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
819
820    Vector<SkMatrix*> mMatrices;
821
822    SkWriter32 mWriter;
823    uint32_t mBufferSize;
824
825    int mRestoreSaveCount;
826
827    float mTranslateX;
828    float mTranslateY;
829    bool mHasTranslate;
830
831    bool mHasDrawOps;
832
833    friend class DisplayList;
834
835}; // class DisplayListRenderer
836
837}; // namespace uirenderer
838}; // namespace android
839
840#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
841