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