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