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