DisplayListRenderer.h revision 54c1a64d5441a964890b44280e4457e11f4f924a
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    uint32_t mFunctorCount;
507
508    String8 mName;
509
510    // View properties
511    bool mClipChildren;
512    float mAlpha;
513    int mMultipliedAlpha;
514    bool mHasOverlappingRendering;
515    float mTranslationX, mTranslationY;
516    float mRotation, mRotationX, mRotationY;
517    float mScaleX, mScaleY;
518    float mPivotX, mPivotY;
519    float mCameraDistance;
520    int mLeft, mTop, mRight, mBottom;
521    int mWidth, mHeight;
522    int mPrevWidth, mPrevHeight;
523    bool mPivotExplicitlySet;
524    bool mMatrixDirty;
525    bool mMatrixIsIdentity;
526    uint32_t mMatrixFlags;
527    SkMatrix* mTransformMatrix;
528    Sk3DView* mTransformCamera;
529    SkMatrix* mTransformMatrix3D;
530    SkMatrix* mStaticMatrix;
531    SkMatrix* mAnimationMatrix;
532    bool mCaching;
533};
534
535///////////////////////////////////////////////////////////////////////////////
536// Renderer
537///////////////////////////////////////////////////////////////////////////////
538
539/**
540 * Records drawing commands in a display list for latter playback.
541 */
542class DisplayListRenderer: public OpenGLRenderer {
543public:
544    ANDROID_API DisplayListRenderer();
545    virtual ~DisplayListRenderer();
546
547    ANDROID_API DisplayList* getDisplayList(DisplayList* displayList);
548
549    virtual bool isDeferred();
550
551    virtual void setViewport(int width, int height);
552    virtual int prepareDirty(float left, float top, float right, float bottom, bool opaque);
553    virtual void finish();
554
555    virtual status_t callDrawGLFunction(Functor *functor, Rect& dirty);
556
557    virtual void interrupt();
558    virtual void resume();
559
560    virtual int save(int flags);
561    virtual void restore();
562    virtual void restoreToCount(int saveCount);
563
564    virtual int saveLayer(float left, float top, float right, float bottom,
565            SkPaint* p, int flags);
566    virtual int saveLayerAlpha(float left, float top, float right, float bottom,
567                int alpha, int flags);
568
569    virtual void translate(float dx, float dy);
570    virtual void rotate(float degrees);
571    virtual void scale(float sx, float sy);
572    virtual void skew(float sx, float sy);
573
574    virtual void setMatrix(SkMatrix* matrix);
575    virtual void concatMatrix(SkMatrix* matrix);
576
577    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
578
579    virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags,
580            uint32_t level = 0);
581    virtual status_t drawLayer(Layer* layer, float x, float y, SkPaint* paint);
582    virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
583    virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
584    virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
585            float srcRight, float srcBottom, float dstLeft, float dstTop,
586            float dstRight, float dstBottom, SkPaint* paint);
587    virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
588    virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
589            float* vertices, int* colors, SkPaint* paint);
590    virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
591            const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
592            float left, float top, float right, float bottom, SkPaint* paint);
593    virtual status_t drawColor(int color, SkXfermode::Mode mode);
594    virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint);
595    virtual status_t drawRoundRect(float left, float top, float right, float bottom,
596            float rx, float ry, SkPaint* paint);
597    virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint);
598    virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint);
599    virtual status_t drawArc(float left, float top, float right, float bottom,
600            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
601    virtual status_t drawPath(SkPath* path, SkPaint* paint);
602    virtual status_t drawLines(float* points, int count, SkPaint* paint);
603    virtual status_t drawPoints(float* points, int count, SkPaint* paint);
604    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
605            float hOffset, float vOffset, SkPaint* paint);
606    virtual status_t drawPosText(const char* text, int bytesCount, int count,
607            const float* positions, SkPaint* paint);
608    virtual status_t drawText(const char* text, int bytesCount, int count,
609            float x, float y, const float* positions, SkPaint* paint, float length);
610
611    virtual void resetShader();
612    virtual void setupShader(SkiaShader* shader);
613
614    virtual void resetColorFilter();
615    virtual void setupColorFilter(SkiaColorFilter* filter);
616
617    virtual void resetShadow();
618    virtual void setupShadow(float radius, float dx, float dy, int color);
619
620    virtual void resetPaintFilter();
621    virtual void setupPaintFilter(int clearBits, int setBits);
622
623    ANDROID_API void reset();
624
625    const SkWriter32& writeStream() const {
626        return mWriter;
627    }
628
629    const Vector<SkBitmap*>& getBitmapResources() const {
630        return mBitmapResources;
631    }
632
633    const Vector<SkBitmap*>& getOwnedBitmapResources() const {
634        return mOwnedBitmapResources;
635    }
636
637    const Vector<SkiaColorFilter*>& getFilterResources() const {
638        return mFilterResources;
639    }
640
641    const Vector<SkiaShader*>& getShaders() const {
642        return mShaders;
643    }
644
645    const Vector<SkPaint*>& getPaints() const {
646        return mPaints;
647    }
648
649    const Vector<SkPath*>& getPaths() const {
650        return mPaths;
651    }
652
653    const SortedVector<SkPath*>& getSourcePaths() const {
654        return mSourcePaths;
655    }
656
657    const Vector<Layer*>& getLayers() const {
658        return mLayers;
659    }
660
661    const Vector<SkMatrix*>& getMatrices() const {
662        return mMatrices;
663    }
664
665    uint32_t getFunctorCount() const {
666        return mFunctorCount;
667    }
668
669private:
670    void insertRestoreToCount() {
671        if (mRestoreSaveCount >= 0) {
672            mWriter.writeInt(DisplayList::RestoreToCount);
673            addInt(mRestoreSaveCount);
674            mRestoreSaveCount = -1;
675        }
676    }
677
678    void insertTranlate() {
679        if (mHasTranslate) {
680            if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
681                mWriter.writeInt(DisplayList::Translate);
682                addPoint(mTranslateX, mTranslateY);
683                mTranslateX = mTranslateY = 0.0f;
684            }
685            mHasTranslate = false;
686        }
687    }
688
689    inline void addOp(const DisplayList::Op drawOp) {
690        insertRestoreToCount();
691        insertTranlate();
692        mWriter.writeInt(drawOp);
693        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
694    }
695
696    uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) {
697        insertRestoreToCount();
698        insertTranlate();
699        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
700        if (reject) {
701            mWriter.writeInt(OP_MAY_BE_SKIPPED_MASK | drawOp);
702            mWriter.writeInt(0xdeaddead);
703            mBufferSize = mWriter.size();
704            return mWriter.peek32(mBufferSize - sizeof(int32_t));
705        }
706        mWriter.writeInt(drawOp);
707        return NULL;
708    }
709
710    inline void addSkip(uint32_t* location) {
711        if (location) {
712            *location = (int32_t) (mWriter.size() - mBufferSize);
713        }
714    }
715
716    inline void addInt(int32_t value) {
717        mWriter.writeInt(value);
718    }
719
720    inline void addSize(uint32_t w, uint32_t h) {
721        mWriter.writeInt(w);
722        mWriter.writeInt(h);
723    }
724
725    void addInts(const int32_t* values, uint32_t count) {
726        mWriter.writeInt(count);
727        mWriter.write(values, count * sizeof(int32_t));
728    }
729
730    void addUInts(const uint32_t* values, int8_t count) {
731        mWriter.writeInt(count);
732        mWriter.write(values, count * sizeof(uint32_t));
733    }
734
735    inline void addFloat(float value) {
736        mWriter.writeScalar(value);
737    }
738
739    void addFloats(const float* values, int32_t count) {
740        mWriter.writeInt(count);
741        mWriter.write(values, count * sizeof(float));
742    }
743
744    inline void addPoint(float x, float y) {
745        mWriter.writeScalar(x);
746        mWriter.writeScalar(y);
747    }
748
749    inline void addBounds(float left, float top, float right, float bottom) {
750        mWriter.writeScalar(left);
751        mWriter.writeScalar(top);
752        mWriter.writeScalar(right);
753        mWriter.writeScalar(bottom);
754    }
755
756    inline void addText(const void* text, size_t byteLength) {
757        mWriter.writeInt(byteLength);
758        mWriter.writePad(text, byteLength);
759    }
760
761    inline void addPath(SkPath* path) {
762        if (!path) {
763            addInt((int) NULL);
764            return;
765        }
766
767        SkPath* pathCopy = mPathMap.valueFor(path);
768        if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
769            pathCopy = new SkPath(*path);
770            pathCopy->setSourcePath(path);
771            // replaceValueFor() performs an add if the entry doesn't exist
772            mPathMap.replaceValueFor(path, pathCopy);
773            mPaths.add(pathCopy);
774        }
775        if (mSourcePaths.indexOf(path) < 0) {
776            mCaches.resourceCache.incrementRefcount(path);
777            mSourcePaths.add(path);
778        }
779
780        addInt((int) pathCopy);
781    }
782
783    inline SkPaint* addPaint(SkPaint* paint) {
784        if (!paint) {
785            addInt((int) NULL);
786            return paint;
787        }
788
789        SkPaint* paintCopy = mPaintMap.valueFor(paint);
790        if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
791            paintCopy = new SkPaint(*paint);
792            // replaceValueFor() performs an add if the entry doesn't exist
793            mPaintMap.replaceValueFor(paint, paintCopy);
794            mPaints.add(paintCopy);
795        }
796
797        addInt((int) paintCopy);
798
799        return paintCopy;
800    }
801
802    inline void addDisplayList(DisplayList* displayList) {
803        // TODO: To be safe, the display list should be ref-counted in the
804        //       resources cache, but we rely on the caller (UI toolkit) to
805        //       do the right thing for now
806        addInt((int) displayList);
807    }
808
809    inline void addMatrix(SkMatrix* matrix) {
810        // Copying the matrix is cheap and prevents against the user changing the original
811        // matrix before the operation that uses it
812        SkMatrix* copy = new SkMatrix(*matrix);
813        addInt((int) copy);
814        mMatrices.add(copy);
815    }
816
817    inline void addLayer(Layer* layer) {
818        addInt((int) layer);
819        mLayers.add(layer);
820        mCaches.resourceCache.incrementRefcount(layer);
821    }
822
823    inline void addBitmap(SkBitmap* bitmap) {
824        // Note that this assumes the bitmap is immutable. There are cases this won't handle
825        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
826        // contents, and drawing again. The only fix would be to always copy it the first time,
827        // which doesn't seem worth the extra cycles for this unlikely case.
828        addInt((int) bitmap);
829        mBitmapResources.add(bitmap);
830        mCaches.resourceCache.incrementRefcount(bitmap);
831    }
832
833    void addBitmapData(SkBitmap* bitmap) {
834        addInt((int) bitmap);
835        mOwnedBitmapResources.add(bitmap);
836        mCaches.resourceCache.incrementRefcount(bitmap);
837    }
838
839    inline void addShader(SkiaShader* shader) {
840        if (!shader) {
841            addInt((int) NULL);
842            return;
843        }
844
845        SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
846        // TODO: We also need to handle generation ID changes in compose shaders
847        if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
848            shaderCopy = shader->copy();
849            // replaceValueFor() performs an add if the entry doesn't exist
850            mShaderMap.replaceValueFor(shader, shaderCopy);
851            mShaders.add(shaderCopy);
852            mCaches.resourceCache.incrementRefcount(shaderCopy);
853        }
854
855        addInt((int) shaderCopy);
856    }
857
858    inline void addColorFilter(SkiaColorFilter* colorFilter) {
859        addInt((int) colorFilter);
860        mFilterResources.add(colorFilter);
861        mCaches.resourceCache.incrementRefcount(colorFilter);
862    }
863
864    Vector<SkBitmap*> mBitmapResources;
865    Vector<SkBitmap*> mOwnedBitmapResources;
866    Vector<SkiaColorFilter*> mFilterResources;
867
868    Vector<SkPaint*> mPaints;
869    DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
870
871    Vector<SkPath*> mPaths;
872    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
873
874    SortedVector<SkPath*> mSourcePaths;
875
876    Vector<SkiaShader*> mShaders;
877    DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
878
879    Vector<SkMatrix*> mMatrices;
880
881    Vector<Layer*> mLayers;
882
883    uint32_t mBufferSize;
884
885    int mRestoreSaveCount;
886
887    Caches& mCaches;
888    SkWriter32 mWriter;
889
890    float mTranslateX;
891    float mTranslateY;
892    bool mHasTranslate;
893    bool mHasDrawOps;
894
895    uint32_t mFunctorCount;
896
897    friend class DisplayList;
898
899}; // class DisplayListRenderer
900
901}; // namespace uirenderer
902}; // namespace android
903
904#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
905