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