DisplayListRenderer.h revision 76240dafe8654cc3b858241e76618e5b2db5451c
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
382private:
383    void init();
384
385    void initProperties();
386
387    void clearResources();
388
389    void updateMatrix();
390
391    class TextContainer {
392    public:
393        size_t length() const {
394            return mByteLength;
395        }
396
397        const char* text() const {
398            return (const char*) mText;
399        }
400
401        size_t mByteLength;
402        const char* mText;
403    };
404
405    SkBitmap* getBitmap() {
406        return (SkBitmap*) getInt();
407    }
408
409    SkiaShader* getShader() {
410        return (SkiaShader*) getInt();
411    }
412
413    SkiaColorFilter* getColorFilter() {
414        return (SkiaColorFilter*) getInt();
415    }
416
417    inline int32_t getIndex() {
418        return mReader.readInt();
419    }
420
421    inline int32_t getInt() {
422        return mReader.readInt();
423    }
424
425    inline uint32_t getUInt() {
426        return mReader.readU32();
427    }
428
429    SkMatrix* getMatrix() {
430        return (SkMatrix*) getInt();
431    }
432
433    SkPath* getPath() {
434        return (SkPath*) getInt();
435    }
436
437    SkPaint* getPaint(OpenGLRenderer& renderer) {
438        return renderer.filterPaint((SkPaint*) getInt());
439    }
440
441    DisplayList* getDisplayList() {
442        return (DisplayList*) getInt();
443    }
444
445    inline float getFloat() {
446        return mReader.readScalar();
447    }
448
449    int32_t* getInts(uint32_t& count) {
450        count = getInt();
451        return (int32_t*) mReader.skip(count * sizeof(int32_t));
452    }
453
454    uint32_t* getUInts(int8_t& count) {
455        count = getInt();
456        return (uint32_t*) mReader.skip(count * sizeof(uint32_t));
457    }
458
459    float* getFloats(int32_t& count) {
460        count = getInt();
461        return (float*) mReader.skip(count * sizeof(float));
462    }
463
464    void getText(TextContainer* text) {
465        size_t length = text->mByteLength = getInt();
466        text->mText = (const char*) mReader.skip(length);
467    }
468
469    Vector<SkBitmap*> mBitmapResources;
470    Vector<SkiaColorFilter*> mFilterResources;
471
472    Vector<SkPaint*> mPaints;
473    Vector<SkPath*> mPaths;
474    Vector<SkMatrix*> mMatrices;
475    Vector<SkiaShader*> mShaders;
476
477    mutable SkFlattenableReadBuffer mReader;
478
479    size_t mSize;
480
481    bool mIsRenderable;
482
483    String8 mName;
484
485    // View properties
486    float mApplicationScale;
487    bool mClipChildren;
488    float mAlpha;
489    int mMultipliedAlpha;
490    float mTranslationX, mTranslationY;
491    float mRotation, mRotationX, mRotationY;
492    float mScaleX, mScaleY;
493    float mPivotX, mPivotY;
494    float mCameraDistance;
495    int mLeft, mTop, mRight, mBottom;
496    int mWidth, mHeight;
497    int mPrevWidth, mPrevHeight;
498    bool mPivotExplicitlySet;
499    bool mMatrixDirty;
500    bool mMatrixIsIdentity;
501    uint32_t mMatrixFlags;
502    SkMatrix* mTransformMatrix;
503    Sk3DView* mTransformCamera;
504    SkMatrix* mTransformMatrix3D;
505    bool mCaching;
506};
507
508///////////////////////////////////////////////////////////////////////////////
509// Renderer
510///////////////////////////////////////////////////////////////////////////////
511
512/**
513 * Records drawing commands in a display list for latter playback.
514 */
515class DisplayListRenderer: public OpenGLRenderer {
516public:
517    ANDROID_API DisplayListRenderer();
518    virtual ~DisplayListRenderer();
519
520    ANDROID_API DisplayList* getDisplayList(DisplayList* displayList);
521
522    virtual void setViewport(int width, int height);
523    virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
524    virtual void finish();
525
526    virtual status_t callDrawGLFunction(Functor *functor, Rect& dirty);
527
528    virtual void interrupt();
529    virtual void resume();
530
531    virtual int save(int flags);
532    virtual void restore();
533    virtual void restoreToCount(int saveCount);
534
535    virtual int saveLayer(float left, float top, float right, float bottom,
536            SkPaint* p, int flags);
537    virtual int saveLayerAlpha(float left, float top, float right, float bottom,
538                int alpha, int flags);
539
540    virtual void translate(float dx, float dy);
541    virtual void rotate(float degrees);
542    virtual void scale(float sx, float sy);
543    virtual void skew(float sx, float sy);
544
545    virtual void setMatrix(SkMatrix* matrix);
546    virtual void concatMatrix(SkMatrix* matrix);
547
548    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
549
550    virtual status_t drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
551            Rect& dirty, int32_t flags, uint32_t level = 0);
552    virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
553    virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
554    virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
555    virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
556            float srcRight, float srcBottom, float dstLeft, float dstTop,
557            float dstRight, float dstBottom, SkPaint* paint);
558    virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
559            float* vertices, int* colors, SkPaint* paint);
560    virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
561            const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
562            float left, float top, float right, float bottom, SkPaint* paint);
563    virtual void drawColor(int color, SkXfermode::Mode mode);
564    virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
565    virtual void drawRoundRect(float left, float top, float right, float bottom,
566            float rx, float ry, SkPaint* paint);
567    virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
568    virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
569    virtual void drawArc(float left, float top, float right, float bottom,
570            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
571    virtual void drawPath(SkPath* path, SkPaint* paint);
572    virtual void drawLines(float* points, int count, SkPaint* paint);
573    virtual void drawPoints(float* points, int count, SkPaint* paint);
574    virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
575            SkPaint* paint, float length = -1.0f);
576    virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
577            float hOffset, float vOffset, SkPaint* paint);
578    virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
579            SkPaint* paint);
580
581    virtual void resetShader();
582    virtual void setupShader(SkiaShader* shader);
583
584    virtual void resetColorFilter();
585    virtual void setupColorFilter(SkiaColorFilter* filter);
586
587    virtual void resetShadow();
588    virtual void setupShadow(float radius, float dx, float dy, int color);
589
590    virtual void resetPaintFilter();
591    virtual void setupPaintFilter(int clearBits, int setBits);
592
593    ANDROID_API void reset();
594
595    const SkWriter32& writeStream() const {
596        return mWriter;
597    }
598
599    const Vector<SkBitmap*>& getBitmapResources() const {
600        return mBitmapResources;
601    }
602
603    const Vector<SkiaColorFilter*>& getFilterResources() const {
604        return mFilterResources;
605    }
606
607    const Vector<SkiaShader*>& getShaders() const {
608        return mShaders;
609    }
610
611    const Vector<SkPaint*>& getPaints() const {
612        return mPaints;
613    }
614
615    const Vector<SkPath*>& getPaths() const {
616        return mPaths;
617    }
618
619    const Vector<SkMatrix*>& getMatrices() const {
620        return mMatrices;
621    }
622
623private:
624    void insertRestoreToCount() {
625        if (mRestoreSaveCount >= 0) {
626            mWriter.writeInt(DisplayList::RestoreToCount);
627            addInt(mRestoreSaveCount);
628            mRestoreSaveCount = -1;
629        }
630    }
631
632    void insertTranlate() {
633        if (mHasTranslate) {
634            if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
635                mWriter.writeInt(DisplayList::Translate);
636                addPoint(mTranslateX, mTranslateY);
637                mTranslateX = mTranslateY = 0.0f;
638            }
639            mHasTranslate = false;
640        }
641    }
642
643    inline void addOp(const DisplayList::Op drawOp) {
644        insertRestoreToCount();
645        insertTranlate();
646        mWriter.writeInt(drawOp);
647        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
648    }
649
650    uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) {
651        insertRestoreToCount();
652        insertTranlate();
653        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
654        if (reject) {
655            mWriter.writeInt(OP_MAY_BE_SKIPPED_MASK | drawOp);
656            mWriter.writeInt(0xdeaddead);
657            mBufferSize = mWriter.size();
658            return mWriter.peek32(mBufferSize - sizeof(int32_t));
659        }
660        mWriter.writeInt(drawOp);
661        return NULL;
662    }
663
664    inline void addSkip(uint32_t* location) {
665        if (location) {
666            *location = (int32_t) (mWriter.size() - mBufferSize);
667        }
668    }
669
670    inline void addInt(int32_t value) {
671        mWriter.writeInt(value);
672    }
673
674    inline void addSize(uint32_t w, uint32_t h) {
675        mWriter.writeInt(w);
676        mWriter.writeInt(h);
677    }
678
679    void addInts(const int32_t* values, uint32_t count) {
680        mWriter.writeInt(count);
681        for (uint32_t i = 0; i < count; i++) {
682            mWriter.writeInt(values[i]);
683        }
684    }
685
686    void addUInts(const uint32_t* values, int8_t count) {
687        mWriter.writeInt(count);
688        for (int8_t i = 0; i < count; i++) {
689            mWriter.writeInt(values[i]);
690        }
691    }
692
693    inline void addFloat(float value) {
694        mWriter.writeScalar(value);
695    }
696
697    void addFloats(const float* values, int32_t count) {
698        mWriter.writeInt(count);
699        for (int32_t i = 0; i < count; i++) {
700            mWriter.writeScalar(values[i]);
701        }
702    }
703
704    inline void addPoint(float x, float y) {
705        mWriter.writeScalar(x);
706        mWriter.writeScalar(y);
707    }
708
709    inline void addBounds(float left, float top, float right, float bottom) {
710        mWriter.writeScalar(left);
711        mWriter.writeScalar(top);
712        mWriter.writeScalar(right);
713        mWriter.writeScalar(bottom);
714    }
715
716    inline void addText(const void* text, size_t byteLength) {
717        mWriter.writeInt(byteLength);
718        mWriter.writePad(text, byteLength);
719    }
720
721    inline void addPath(SkPath* path) {
722        if (!path) {
723            addInt((int) NULL);
724            return;
725        }
726
727        SkPath* pathCopy = mPathMap.valueFor(path);
728        if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
729            pathCopy = new SkPath(*path);
730            pathCopy->setSourcePath(path);
731            // replaceValueFor() performs an add if the entry doesn't exist
732            mPathMap.replaceValueFor(path, pathCopy);
733            mPaths.add(pathCopy);
734        }
735
736        addInt((int) pathCopy);
737    }
738
739    inline void addPaint(SkPaint* paint) {
740        if (!paint) {
741            addInt((int) NULL);
742            return;
743        }
744
745        SkPaint* paintCopy = mPaintMap.valueFor(paint);
746        if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
747            paintCopy = new SkPaint(*paint);
748            // replaceValueFor() performs an add if the entry doesn't exist
749            mPaintMap.replaceValueFor(paint, paintCopy);
750            mPaints.add(paintCopy);
751        }
752
753        addInt((int) paintCopy);
754    }
755
756    inline void addDisplayList(DisplayList* displayList) {
757        // TODO: To be safe, the display list should be ref-counted in the
758        //       resources cache, but we rely on the caller (UI toolkit) to
759        //       do the right thing for now
760        addInt((int) displayList);
761    }
762
763    inline void addMatrix(SkMatrix* matrix) {
764        // Copying the matrix is cheap and prevents against the user changing the original
765        // matrix before the operation that uses it
766        SkMatrix* copy = new SkMatrix(*matrix);
767        addInt((int) copy);
768        mMatrices.add(copy);
769    }
770
771    inline void addBitmap(SkBitmap* bitmap) {
772        // Note that this assumes the bitmap is immutable. There are cases this won't handle
773        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
774        // contents, and drawing again. The only fix would be to always copy it the first time,
775        // which doesn't seem worth the extra cycles for this unlikely case.
776        addInt((int) bitmap);
777        mBitmapResources.add(bitmap);
778        Caches::getInstance().resourceCache.incrementRefcount(bitmap);
779    }
780
781    inline void addShader(SkiaShader* shader) {
782        if (!shader) {
783            addInt((int) NULL);
784            return;
785        }
786
787        SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
788        // TODO: We also need to handle generation ID changes in compose shaders
789        if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
790            shaderCopy = shader->copy();
791            // replaceValueFor() performs an add if the entry doesn't exist
792            mShaderMap.replaceValueFor(shader, shaderCopy);
793            mShaders.add(shaderCopy);
794            Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
795        }
796
797        addInt((int) shaderCopy);
798    }
799
800    inline void addColorFilter(SkiaColorFilter* colorFilter) {
801        addInt((int) colorFilter);
802        mFilterResources.add(colorFilter);
803        Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
804    }
805
806    Vector<SkBitmap*> mBitmapResources;
807    Vector<SkiaColorFilter*> mFilterResources;
808
809    Vector<SkPaint*> mPaints;
810    DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
811
812    Vector<SkPath*> mPaths;
813    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
814
815    Vector<SkiaShader*> mShaders;
816    DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
817
818    Vector<SkMatrix*> mMatrices;
819
820    SkWriter32 mWriter;
821    uint32_t mBufferSize;
822
823    int mRestoreSaveCount;
824
825    float mTranslateX;
826    float mTranslateY;
827    bool mHasTranslate;
828
829    bool mHasDrawOps;
830
831    friend class DisplayList;
832
833}; // class DisplayListRenderer
834
835}; // namespace uirenderer
836}; // namespace android
837
838#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
839