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