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