Home | History | Annotate | Download | only in hwui
      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 
     35 namespace android {
     36 namespace 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 
     62 class DisplayListRenderer;
     63 
     64 /**
     65  * Replays recorded drawing commands.
     66  */
     67 class DisplayList {
     68 public:
     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         DrawText,
    107         DrawTextOnPath,
    108         DrawPosText,
    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 
    400 private:
    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  */
    540 class DisplayListRenderer: public OpenGLRenderer {
    541 public:
    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 drawText(const char* text, int bytesCount, int count, float x, float y,
    603             SkPaint* paint, float length = -1.0f);
    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 
    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 
    659 private:
    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 void addPaint(SkPaint* paint) {
    774         if (!paint) {
    775             addInt((int) NULL);
    776             return;
    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 
    790     inline void addDisplayList(DisplayList* displayList) {
    791         // TODO: To be safe, the display list should be ref-counted in the
    792         //       resources cache, but we rely on the caller (UI toolkit) to
    793         //       do the right thing for now
    794         addInt((int) displayList);
    795     }
    796 
    797     inline void addMatrix(SkMatrix* matrix) {
    798         // Copying the matrix is cheap and prevents against the user changing the original
    799         // matrix before the operation that uses it
    800         SkMatrix* copy = new SkMatrix(*matrix);
    801         addInt((int) copy);
    802         mMatrices.add(copy);
    803     }
    804 
    805     inline void addBitmap(SkBitmap* bitmap) {
    806         // Note that this assumes the bitmap is immutable. There are cases this won't handle
    807         // correctly, such as creating the bitmap from scratch, drawing with it, changing its
    808         // contents, and drawing again. The only fix would be to always copy it the first time,
    809         // which doesn't seem worth the extra cycles for this unlikely case.
    810         addInt((int) bitmap);
    811         mBitmapResources.add(bitmap);
    812         Caches::getInstance().resourceCache.incrementRefcount(bitmap);
    813     }
    814 
    815     void addBitmapData(SkBitmap* bitmap) {
    816         addInt((int) bitmap);
    817         mOwnedBitmapResources.add(bitmap);
    818         Caches::getInstance().resourceCache.incrementRefcount(bitmap);
    819     }
    820 
    821     inline void addShader(SkiaShader* shader) {
    822         if (!shader) {
    823             addInt((int) NULL);
    824             return;
    825         }
    826 
    827         SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
    828         // TODO: We also need to handle generation ID changes in compose shaders
    829         if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
    830             shaderCopy = shader->copy();
    831             // replaceValueFor() performs an add if the entry doesn't exist
    832             mShaderMap.replaceValueFor(shader, shaderCopy);
    833             mShaders.add(shaderCopy);
    834             Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
    835         }
    836 
    837         addInt((int) shaderCopy);
    838     }
    839 
    840     inline void addColorFilter(SkiaColorFilter* colorFilter) {
    841         addInt((int) colorFilter);
    842         mFilterResources.add(colorFilter);
    843         Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
    844     }
    845 
    846     Vector<SkBitmap*> mBitmapResources;
    847     Vector<SkBitmap*> mOwnedBitmapResources;
    848     Vector<SkiaColorFilter*> mFilterResources;
    849 
    850     Vector<SkPaint*> mPaints;
    851     DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
    852 
    853     Vector<SkPath*> mPaths;
    854     DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
    855 
    856     SortedVector<SkPath*> mSourcePaths;
    857 
    858     Vector<SkiaShader*> mShaders;
    859     DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
    860 
    861     Vector<SkMatrix*> mMatrices;
    862 
    863     SkWriter32 mWriter;
    864     uint32_t mBufferSize;
    865 
    866     int mRestoreSaveCount;
    867 
    868     float mTranslateX;
    869     float mTranslateY;
    870     bool mHasTranslate;
    871 
    872     bool mHasDrawOps;
    873 
    874     friend class DisplayList;
    875 
    876 }; // class DisplayListRenderer
    877 
    878 }; // namespace uirenderer
    879 }; // namespace android
    880 
    881 #endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
    882