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