Home | History | Annotate | Download | only in hwui
      1 /*
      2  * Copyright (C) 2013 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_H
     18 #define ANDROID_HWUI_DISPLAY_LIST_H
     19 
     20 #ifndef LOG_TAG
     21     #define LOG_TAG "OpenGLRenderer"
     22 #endif
     23 
     24 #include <SkCamera.h>
     25 #include <SkMatrix.h>
     26 
     27 #include <private/hwui/DrawGlInfo.h>
     28 
     29 #include <utils/LinearAllocator.h>
     30 #include <utils/RefBase.h>
     31 #include <utils/SortedVector.h>
     32 #include <utils/String8.h>
     33 #include <utils/Vector.h>
     34 
     35 #include <cutils/compiler.h>
     36 
     37 #include <androidfw/ResourceTypes.h>
     38 
     39 #include "Debug.h"
     40 
     41 #define TRANSLATION 0x0001
     42 #define ROTATION    0x0002
     43 #define ROTATION_3D 0x0004
     44 #define SCALE       0x0008
     45 #define PIVOT       0x0010
     46 
     47 class SkBitmap;
     48 class SkPaint;
     49 class SkPath;
     50 class SkRegion;
     51 
     52 namespace android {
     53 namespace uirenderer {
     54 
     55 class DeferredDisplayList;
     56 class DisplayListOp;
     57 class DisplayListRenderer;
     58 class OpenGLRenderer;
     59 class Rect;
     60 class Layer;
     61 class SkiaColorFilter;
     62 class SkiaShader;
     63 
     64 class ClipRectOp;
     65 class SaveLayerOp;
     66 class SaveOp;
     67 class RestoreToCountOp;
     68 
     69 struct DeferStateStruct {
     70     DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags)
     71             : mDeferredList(deferredList), mRenderer(renderer), mReplayFlags(replayFlags) {}
     72     DeferredDisplayList& mDeferredList;
     73     OpenGLRenderer& mRenderer;
     74     const int mReplayFlags;
     75 };
     76 
     77 struct ReplayStateStruct {
     78     ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags)
     79             : mRenderer(renderer), mDirty(dirty), mReplayFlags(replayFlags),
     80             mDrawGlStatus(DrawGlInfo::kStatusDone) {}
     81     OpenGLRenderer& mRenderer;
     82     Rect& mDirty;
     83     const int mReplayFlags;
     84     status_t mDrawGlStatus;
     85 };
     86 
     87 /**
     88  * Refcounted structure that holds data used in display list stream
     89  */
     90 class DisplayListData : public LightRefBase<DisplayListData> {
     91 public:
     92     LinearAllocator allocator;
     93     Vector<DisplayListOp*> displayListOps;
     94 };
     95 
     96 /**
     97  * Replays recorded drawing commands.
     98  */
     99 class DisplayList {
    100 public:
    101     DisplayList(const DisplayListRenderer& recorder);
    102     ANDROID_API ~DisplayList();
    103 
    104     // See flags defined in DisplayList.java
    105     enum ReplayFlag {
    106         kReplayFlag_ClipChildren = 0x1
    107     };
    108 
    109 
    110     ANDROID_API size_t getSize();
    111     ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
    112     ANDROID_API static void outputLogBuffer(int fd);
    113 
    114     void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
    115 
    116     void defer(DeferStateStruct& deferStruct, const int level);
    117     void replay(ReplayStateStruct& replayStruct, const int level);
    118 
    119     void output(uint32_t level = 0);
    120 
    121     ANDROID_API void reset();
    122 
    123     void setRenderable(bool renderable) {
    124         mIsRenderable = renderable;
    125     }
    126 
    127     bool isRenderable() const {
    128         return mIsRenderable;
    129     }
    130 
    131     void setName(const char* name) {
    132         if (name) {
    133             char* lastPeriod = strrchr(name, '.');
    134             if (lastPeriod) {
    135                 mName.setTo(lastPeriod + 1);
    136             } else {
    137                 mName.setTo(name);
    138             }
    139         }
    140     }
    141 
    142     const char* getName() const {
    143         return mName.string();
    144     }
    145 
    146     void setClipToBounds(bool clipToBounds) {
    147         mClipToBounds = clipToBounds;
    148     }
    149 
    150     void setStaticMatrix(SkMatrix* matrix) {
    151         delete mStaticMatrix;
    152         mStaticMatrix = new SkMatrix(*matrix);
    153     }
    154 
    155     // Can return NULL
    156     SkMatrix* getStaticMatrix() {
    157         return mStaticMatrix;
    158     }
    159 
    160     void setAnimationMatrix(SkMatrix* matrix) {
    161         delete mAnimationMatrix;
    162         if (matrix) {
    163             mAnimationMatrix = new SkMatrix(*matrix);
    164         } else {
    165             mAnimationMatrix = NULL;
    166         }
    167     }
    168 
    169     void setAlpha(float alpha) {
    170         alpha = fminf(1.0f, fmaxf(0.0f, alpha));
    171         if (alpha != mAlpha) {
    172             mAlpha = alpha;
    173         }
    174     }
    175 
    176     float getAlpha() const {
    177         return mAlpha;
    178     }
    179 
    180     void setHasOverlappingRendering(bool hasOverlappingRendering) {
    181         mHasOverlappingRendering = hasOverlappingRendering;
    182     }
    183 
    184     bool hasOverlappingRendering() const {
    185         return mHasOverlappingRendering;
    186     }
    187 
    188     void setTranslationX(float translationX) {
    189         if (translationX != mTranslationX) {
    190             mTranslationX = translationX;
    191             mMatrixDirty = true;
    192             if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
    193                 mMatrixFlags &= ~TRANSLATION;
    194             } else {
    195                 mMatrixFlags |= TRANSLATION;
    196             }
    197         }
    198     }
    199 
    200     float getTranslationX() const {
    201         return mTranslationX;
    202     }
    203 
    204     void setTranslationY(float translationY) {
    205         if (translationY != mTranslationY) {
    206             mTranslationY = translationY;
    207             mMatrixDirty = true;
    208             if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
    209                 mMatrixFlags &= ~TRANSLATION;
    210             } else {
    211                 mMatrixFlags |= TRANSLATION;
    212             }
    213         }
    214     }
    215 
    216     float getTranslationY() const {
    217         return mTranslationY;
    218     }
    219 
    220     void setRotation(float rotation) {
    221         if (rotation != mRotation) {
    222             mRotation = rotation;
    223             mMatrixDirty = true;
    224             if (mRotation == 0.0f) {
    225                 mMatrixFlags &= ~ROTATION;
    226             } else {
    227                 mMatrixFlags |= ROTATION;
    228             }
    229         }
    230     }
    231 
    232     float getRotation() const {
    233         return mRotation;
    234     }
    235 
    236     void setRotationX(float rotationX) {
    237         if (rotationX != mRotationX) {
    238             mRotationX = rotationX;
    239             mMatrixDirty = true;
    240             if (mRotationX == 0.0f && mRotationY == 0.0f) {
    241                 mMatrixFlags &= ~ROTATION_3D;
    242             } else {
    243                 mMatrixFlags |= ROTATION_3D;
    244             }
    245         }
    246     }
    247 
    248     float getRotationX() const {
    249         return mRotationX;
    250     }
    251 
    252     void setRotationY(float rotationY) {
    253         if (rotationY != mRotationY) {
    254             mRotationY = rotationY;
    255             mMatrixDirty = true;
    256             if (mRotationX == 0.0f && mRotationY == 0.0f) {
    257                 mMatrixFlags &= ~ROTATION_3D;
    258             } else {
    259                 mMatrixFlags |= ROTATION_3D;
    260             }
    261         }
    262     }
    263 
    264     float getRotationY() const {
    265         return mRotationY;
    266     }
    267 
    268     void setScaleX(float scaleX) {
    269         if (scaleX != mScaleX) {
    270             mScaleX = scaleX;
    271             mMatrixDirty = true;
    272             if (mScaleX == 1.0f && mScaleY == 1.0f) {
    273                 mMatrixFlags &= ~SCALE;
    274             } else {
    275                 mMatrixFlags |= SCALE;
    276             }
    277         }
    278     }
    279 
    280     float getScaleX() const {
    281         return mScaleX;
    282     }
    283 
    284     void setScaleY(float scaleY) {
    285         if (scaleY != mScaleY) {
    286             mScaleY = scaleY;
    287             mMatrixDirty = true;
    288             if (mScaleX == 1.0f && mScaleY == 1.0f) {
    289                 mMatrixFlags &= ~SCALE;
    290             } else {
    291                 mMatrixFlags |= SCALE;
    292             }
    293         }
    294     }
    295 
    296     float getScaleY() const {
    297         return mScaleY;
    298     }
    299 
    300     void setPivotX(float pivotX) {
    301         mPivotX = pivotX;
    302         mMatrixDirty = true;
    303         if (mPivotX == 0.0f && mPivotY == 0.0f) {
    304             mMatrixFlags &= ~PIVOT;
    305         } else {
    306             mMatrixFlags |= PIVOT;
    307         }
    308         mPivotExplicitlySet = true;
    309     }
    310 
    311     ANDROID_API float getPivotX();
    312 
    313     void setPivotY(float pivotY) {
    314         mPivotY = pivotY;
    315         mMatrixDirty = true;
    316         if (mPivotX == 0.0f && mPivotY == 0.0f) {
    317             mMatrixFlags &= ~PIVOT;
    318         } else {
    319             mMatrixFlags |= PIVOT;
    320         }
    321         mPivotExplicitlySet = true;
    322     }
    323 
    324     ANDROID_API float getPivotY();
    325 
    326     void setCameraDistance(float distance) {
    327         if (distance != mCameraDistance) {
    328             mCameraDistance = distance;
    329             mMatrixDirty = true;
    330             if (!mTransformCamera) {
    331                 mTransformCamera = new Sk3DView();
    332                 mTransformMatrix3D = new SkMatrix();
    333             }
    334             mTransformCamera->setCameraLocation(0, 0, distance);
    335         }
    336     }
    337 
    338     float getCameraDistance() const {
    339         return mCameraDistance;
    340     }
    341 
    342     void setLeft(int left) {
    343         if (left != mLeft) {
    344             mLeft = left;
    345             mWidth = mRight - mLeft;
    346             if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
    347                 mMatrixDirty = true;
    348             }
    349         }
    350     }
    351 
    352     float getLeft() const {
    353         return mLeft;
    354     }
    355 
    356     void setTop(int top) {
    357         if (top != mTop) {
    358             mTop = top;
    359             mHeight = mBottom - mTop;
    360             if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
    361                 mMatrixDirty = true;
    362             }
    363         }
    364     }
    365 
    366     float getTop() const {
    367         return mTop;
    368     }
    369 
    370     void setRight(int right) {
    371         if (right != mRight) {
    372             mRight = right;
    373             mWidth = mRight - mLeft;
    374             if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
    375                 mMatrixDirty = true;
    376             }
    377         }
    378     }
    379 
    380     float getRight() const {
    381         return mRight;
    382     }
    383 
    384     void setBottom(int bottom) {
    385         if (bottom != mBottom) {
    386             mBottom = bottom;
    387             mHeight = mBottom - mTop;
    388             if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
    389                 mMatrixDirty = true;
    390             }
    391         }
    392     }
    393 
    394     float getBottom() const {
    395         return mBottom;
    396     }
    397 
    398     void setLeftTop(int left, int top) {
    399         if (left != mLeft || top != mTop) {
    400             mLeft = left;
    401             mTop = top;
    402             mWidth = mRight - mLeft;
    403             mHeight = mBottom - mTop;
    404             if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
    405                 mMatrixDirty = true;
    406             }
    407         }
    408     }
    409 
    410     void setLeftTopRightBottom(int left, int top, int right, int bottom) {
    411         if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
    412             mLeft = left;
    413             mTop = top;
    414             mRight = right;
    415             mBottom = bottom;
    416             mWidth = mRight - mLeft;
    417             mHeight = mBottom - mTop;
    418             if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
    419                 mMatrixDirty = true;
    420             }
    421         }
    422     }
    423 
    424     void offsetLeftRight(float offset) {
    425         if (offset != 0) {
    426             mLeft += offset;
    427             mRight += offset;
    428             if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
    429                 mMatrixDirty = true;
    430             }
    431         }
    432     }
    433 
    434     void offsetTopBottom(float offset) {
    435         if (offset != 0) {
    436             mTop += offset;
    437             mBottom += offset;
    438             if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
    439                 mMatrixDirty = true;
    440             }
    441         }
    442     }
    443 
    444     void setCaching(bool caching) {
    445         mCaching = caching;
    446     }
    447 
    448     int getWidth() {
    449         return mWidth;
    450     }
    451 
    452     int getHeight() {
    453         return mHeight;
    454     }
    455 
    456 private:
    457     void outputViewProperties(const int level);
    458 
    459     template <class T>
    460     inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level);
    461 
    462     template <class T>
    463     inline void iterate(OpenGLRenderer& renderer, T& handler, const int level);
    464 
    465     void init();
    466 
    467     void clearResources();
    468 
    469     void updateMatrix();
    470 
    471     class TextContainer {
    472     public:
    473         size_t length() const {
    474             return mByteLength;
    475         }
    476 
    477         const char* text() const {
    478             return (const char*) mText;
    479         }
    480 
    481         size_t mByteLength;
    482         const char* mText;
    483     };
    484 
    485     Vector<SkBitmap*> mBitmapResources;
    486     Vector<SkBitmap*> mOwnedBitmapResources;
    487     Vector<SkiaColorFilter*> mFilterResources;
    488     Vector<Res_png_9patch*> mPatchResources;
    489 
    490     Vector<SkPaint*> mPaints;
    491     Vector<SkPath*> mPaths;
    492     SortedVector<SkPath*> mSourcePaths;
    493     Vector<SkRegion*> mRegions;
    494     Vector<SkMatrix*> mMatrices;
    495     Vector<SkiaShader*> mShaders;
    496     Vector<Layer*> mLayers;
    497 
    498     sp<DisplayListData> mDisplayListData;
    499 
    500     size_t mSize;
    501 
    502     bool mIsRenderable;
    503     uint32_t mFunctorCount;
    504 
    505     String8 mName;
    506     bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed
    507 
    508     // View properties
    509     bool mClipToBounds;
    510     float mAlpha;
    511     bool mHasOverlappingRendering;
    512     float mTranslationX, mTranslationY;
    513     float mRotation, mRotationX, mRotationY;
    514     float mScaleX, mScaleY;
    515     float mPivotX, mPivotY;
    516     float mCameraDistance;
    517     int mLeft, mTop, mRight, mBottom;
    518     int mWidth, mHeight;
    519     int mPrevWidth, mPrevHeight;
    520     bool mPivotExplicitlySet;
    521     bool mMatrixDirty;
    522     bool mMatrixIsIdentity;
    523     uint32_t mMatrixFlags;
    524     SkMatrix* mTransformMatrix;
    525     Sk3DView* mTransformCamera;
    526     SkMatrix* mTransformMatrix3D;
    527     SkMatrix* mStaticMatrix;
    528     SkMatrix* mAnimationMatrix;
    529     bool mCaching;
    530 
    531     /**
    532      * State operations - needed to defer displayList property operations (for example, when setting
    533      * an alpha causes a SaveLayerAlpha to occur). These operations point into mDisplayListData's
    534      * allocation, or null if uninitialized.
    535      *
    536      * These are initialized (via friend re-constructors) when a displayList is issued in either
    537      * replay or deferred mode. If replaying, the ops are not used until the next frame. If
    538      * deferring, the ops may be stored in the DeferredDisplayList to be played back a second time.
    539      *
    540      * They should be used at most once per frame (one call to 'iterate') to avoid overwriting data
    541      */
    542     ClipRectOp* mClipRectOp;
    543     SaveLayerOp* mSaveLayerOp;
    544     SaveOp* mSaveOp;
    545     RestoreToCountOp* mRestoreToCountOp;
    546 }; // class DisplayList
    547 
    548 }; // namespace uirenderer
    549 }; // namespace android
    550 
    551 #endif // ANDROID_HWUI_OPENGL_RENDERER_H
    552