diff options
Diffstat (limited to 'libs/hwui/DisplayList.h')
| -rw-r--r-- | libs/hwui/DisplayList.h | 527 |
1 files changed, 69 insertions, 458 deletions
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index 1cd5f1c..b2ead5b 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -26,6 +26,7 @@ #include <private/hwui/DrawGlInfo.h> +#include <utils/KeyedVector.h> #include <utils/LinearAllocator.h> #include <utils/RefBase.h> #include <utils/SortedVector.h> @@ -37,12 +38,9 @@ #include <androidfw/ResourceTypes.h> #include "Debug.h" - -#define TRANSLATION 0x0001 -#define ROTATION 0x0002 -#define ROTATION_3D 0x0004 -#define SCALE 0x0008 -#define PIVOT 0x0010 +#include "Matrix.h" +#include "DeferredDisplayList.h" +#include "RenderProperties.h" class SkBitmap; class SkPaint; @@ -58,492 +56,105 @@ class DisplayListRenderer; class OpenGLRenderer; class Rect; class Layer; -class SkiaColorFilter; class SkiaShader; class ClipRectOp; class SaveLayerOp; class SaveOp; class RestoreToCountOp; +class DrawDisplayListOp; -struct DeferStateStruct { - DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags) - : mDeferredList(deferredList), mRenderer(renderer), mReplayFlags(replayFlags) {} - DeferredDisplayList& mDeferredList; +/** + * Holds data used in the playback a tree of DisplayLists. + */ +class PlaybackStateStruct { +protected: + PlaybackStateStruct(OpenGLRenderer& renderer, int replayFlags, LinearAllocator* allocator) + : mRenderer(renderer), mReplayFlags(replayFlags), mAllocator(allocator){} + +public: OpenGLRenderer& mRenderer; const int mReplayFlags; + + // Allocator with the lifetime of a single frame. + // replay uses an Allocator owned by the struct, while defer shares the DeferredDisplayList's Allocator + LinearAllocator * const mAllocator; }; -struct ReplayStateStruct { - ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags) - : mRenderer(renderer), mDirty(dirty), mReplayFlags(replayFlags), - mDrawGlStatus(DrawGlInfo::kStatusDone) {} - OpenGLRenderer& mRenderer; - Rect& mDirty; - const int mReplayFlags; - status_t mDrawGlStatus; +class DeferStateStruct : public PlaybackStateStruct { +public: + DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags) + : PlaybackStateStruct(renderer, replayFlags, &(deferredList.mAllocator)), + mDeferredList(deferredList) {} + + DeferredDisplayList& mDeferredList; }; -/** - * Refcounted structure that holds data used in display list stream - */ -class DisplayListData : public LightRefBase<DisplayListData> { +class ReplayStateStruct : public PlaybackStateStruct { public: - LinearAllocator allocator; - Vector<DisplayListOp*> displayListOps; + ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags) + : PlaybackStateStruct(renderer, replayFlags, &mReplayAllocator), + mDirty(dirty), mDrawGlStatus(DrawGlInfo::kStatusDone) {} + + Rect& mDirty; + status_t mDrawGlStatus; + LinearAllocator mReplayAllocator; }; /** - * Replays recorded drawing commands. + * Data structure that holds the list of commands used in display list stream */ -class DisplayList { +class DisplayListData { public: - DisplayList(const DisplayListRenderer& recorder); - ANDROID_API ~DisplayList(); - - // See flags defined in DisplayList.java - enum ReplayFlag { - kReplayFlag_ClipChildren = 0x1 - }; - - - ANDROID_API size_t getSize(); - ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList); - ANDROID_API static void outputLogBuffer(int fd); - - void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); + DisplayListData(); + ~DisplayListData(); - void defer(DeferStateStruct& deferStruct, const int level); - void replay(ReplayStateStruct& replayStruct, const int level); - - void output(uint32_t level = 0); - - ANDROID_API void reset(); - - void setRenderable(bool renderable) { - mIsRenderable = renderable; - } - - bool isRenderable() const { - return mIsRenderable; - } - - void setName(const char* name) { - if (name) { - char* lastPeriod = strrchr(name, '.'); - if (lastPeriod) { - mName.setTo(lastPeriod + 1); - } else { - mName.setTo(name); - } - } - } - - const char* getName() const { - return mName.string(); - } - - void setClipToBounds(bool clipToBounds) { - mClipToBounds = clipToBounds; - } - - void setStaticMatrix(SkMatrix* matrix) { - delete mStaticMatrix; - mStaticMatrix = new SkMatrix(*matrix); - } - - // Can return NULL - SkMatrix* getStaticMatrix() { - return mStaticMatrix; - } - - void setAnimationMatrix(SkMatrix* matrix) { - delete mAnimationMatrix; - if (matrix) { - mAnimationMatrix = new SkMatrix(*matrix); - } else { - mAnimationMatrix = NULL; - } - } - - void setAlpha(float alpha) { - alpha = fminf(1.0f, fmaxf(0.0f, alpha)); - if (alpha != mAlpha) { - mAlpha = alpha; - } - } - - float getAlpha() const { - return mAlpha; - } - - void setHasOverlappingRendering(bool hasOverlappingRendering) { - mHasOverlappingRendering = hasOverlappingRendering; - } - - bool hasOverlappingRendering() const { - return mHasOverlappingRendering; - } - - void setTranslationX(float translationX) { - if (translationX != mTranslationX) { - mTranslationX = translationX; - mMatrixDirty = true; - if (mTranslationX == 0.0f && mTranslationY == 0.0f) { - mMatrixFlags &= ~TRANSLATION; - } else { - mMatrixFlags |= TRANSLATION; - } - } - } - - float getTranslationX() const { - return mTranslationX; - } - - void setTranslationY(float translationY) { - if (translationY != mTranslationY) { - mTranslationY = translationY; - mMatrixDirty = true; - if (mTranslationX == 0.0f && mTranslationY == 0.0f) { - mMatrixFlags &= ~TRANSLATION; - } else { - mMatrixFlags |= TRANSLATION; - } - } - } - - float getTranslationY() const { - return mTranslationY; - } - - void setRotation(float rotation) { - if (rotation != mRotation) { - mRotation = rotation; - mMatrixDirty = true; - if (mRotation == 0.0f) { - mMatrixFlags &= ~ROTATION; - } else { - mMatrixFlags |= ROTATION; - } - } - } - - float getRotation() const { - return mRotation; - } - - void setRotationX(float rotationX) { - if (rotationX != mRotationX) { - mRotationX = rotationX; - mMatrixDirty = true; - if (mRotationX == 0.0f && mRotationY == 0.0f) { - mMatrixFlags &= ~ROTATION_3D; - } else { - mMatrixFlags |= ROTATION_3D; - } - } - } - - float getRotationX() const { - return mRotationX; - } - - void setRotationY(float rotationY) { - if (rotationY != mRotationY) { - mRotationY = rotationY; - mMatrixDirty = true; - if (mRotationX == 0.0f && mRotationY == 0.0f) { - mMatrixFlags &= ~ROTATION_3D; - } else { - mMatrixFlags |= ROTATION_3D; - } - } - } - - float getRotationY() const { - return mRotationY; - } - - void setScaleX(float scaleX) { - if (scaleX != mScaleX) { - mScaleX = scaleX; - mMatrixDirty = true; - if (mScaleX == 1.0f && mScaleY == 1.0f) { - mMatrixFlags &= ~SCALE; - } else { - mMatrixFlags |= SCALE; - } - } - } - - float getScaleX() const { - return mScaleX; - } - - void setScaleY(float scaleY) { - if (scaleY != mScaleY) { - mScaleY = scaleY; - mMatrixDirty = true; - if (mScaleX == 1.0f && mScaleY == 1.0f) { - mMatrixFlags &= ~SCALE; - } else { - mMatrixFlags |= SCALE; - } - } - } - - float getScaleY() const { - return mScaleY; - } - - void setPivotX(float pivotX) { - mPivotX = pivotX; - mMatrixDirty = true; - if (mPivotX == 0.0f && mPivotY == 0.0f) { - mMatrixFlags &= ~PIVOT; - } else { - mMatrixFlags |= PIVOT; - } - mPivotExplicitlySet = true; - } - - ANDROID_API float getPivotX(); - - void setPivotY(float pivotY) { - mPivotY = pivotY; - mMatrixDirty = true; - if (mPivotX == 0.0f && mPivotY == 0.0f) { - mMatrixFlags &= ~PIVOT; - } else { - mMatrixFlags |= PIVOT; - } - mPivotExplicitlySet = true; - } - - ANDROID_API float getPivotY(); - - void setCameraDistance(float distance) { - if (distance != mCameraDistance) { - mCameraDistance = distance; - mMatrixDirty = true; - if (!mTransformCamera) { - mTransformCamera = new Sk3DView(); - mTransformMatrix3D = new SkMatrix(); - } - mTransformCamera->setCameraLocation(0, 0, distance); - } - } - - float getCameraDistance() const { - return mCameraDistance; - } - - void setLeft(int left) { - if (left != mLeft) { - mLeft = left; - mWidth = mRight - mLeft; - if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { - mMatrixDirty = true; - } - } - } - - float getLeft() const { - return mLeft; - } - - void setTop(int top) { - if (top != mTop) { - mTop = top; - mHeight = mBottom - mTop; - if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { - mMatrixDirty = true; - } - } - } - - float getTop() const { - return mTop; - } - - void setRight(int right) { - if (right != mRight) { - mRight = right; - mWidth = mRight - mLeft; - if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { - mMatrixDirty = true; - } - } - } + // allocator into which all ops were allocated + LinearAllocator allocator; - float getRight() const { - return mRight; - } + // pointers to all ops within display list, pointing into allocator data + Vector<DisplayListOp*> displayListOps; - void setBottom(int bottom) { - if (bottom != mBottom) { - mBottom = bottom; - mHeight = mBottom - mTop; - if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { - mMatrixDirty = true; - } - } - } + // index of DisplayListOp restore, after which projected descendents should be drawn + int projectionReceiveIndex; - float getBottom() const { - return mBottom; - } + Vector<const SkBitmap*> bitmapResources; + Vector<const SkBitmap*> ownedBitmapResources; + Vector<const Res_png_9patch*> patchResources; - void setLeftTop(int left, int top) { - if (left != mLeft || top != mTop) { - mLeft = left; - mTop = top; - mWidth = mRight - mLeft; - mHeight = mBottom - mTop; - if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { - mMatrixDirty = true; - } - } - } + Vector<const SkPaint*> paints; + Vector<const SkPath*> paths; + SortedVector<const SkPath*> sourcePaths; + Vector<const SkRegion*> regions; + Vector<const SkMatrix*> matrices; + Vector<SkiaShader*> shaders; + Vector<Layer*> layers; + uint32_t functorCount; + bool hasDrawOps; - void setLeftTopRightBottom(int left, int top, int right, int bottom) { - if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) { - mLeft = left; - mTop = top; - mRight = right; - mBottom = bottom; - mWidth = mRight - mLeft; - mHeight = mBottom - mTop; - if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { - mMatrixDirty = true; - } - } + bool isEmpty() { + return !displayListOps.size(); } - void offsetLeftRight(float offset) { - if (offset != 0) { - mLeft += offset; - mRight += offset; - if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { - mMatrixDirty = true; - } - } - } + void addChild(DrawDisplayListOp* childOp); + const Vector<DrawDisplayListOp*>& children() { return mChildren; } - void offsetTopBottom(float offset) { - if (offset != 0) { - mTop += offset; - mBottom += offset; - if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { - mMatrixDirty = true; - } - } + void refProperty(CanvasPropertyPrimitive* prop) { + mReferenceHolders.push(prop); } - void setCaching(bool caching) { - mCaching = caching; + void refProperty(CanvasPropertyPaint* prop) { + mReferenceHolders.push(prop); } - int getWidth() { - return mWidth; - } +private: + Vector< sp<VirtualLightRefBase> > mReferenceHolders; - int getHeight() { - return mHeight; - } + // list of children display lists for quick, non-drawing traversal + Vector<DrawDisplayListOp*> mChildren; -private: - void outputViewProperties(const int level); - - template <class T> - inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level); - - template <class T> - inline void iterate(OpenGLRenderer& renderer, T& handler, const int level); - - void init(); - - void clearResources(); - - void updateMatrix(); - - class TextContainer { - public: - size_t length() const { - return mByteLength; - } - - const char* text() const { - return (const char*) mText; - } - - size_t mByteLength; - const char* mText; - }; - - Vector<SkBitmap*> mBitmapResources; - Vector<SkBitmap*> mOwnedBitmapResources; - Vector<SkiaColorFilter*> mFilterResources; - Vector<Res_png_9patch*> mPatchResources; - - Vector<SkPaint*> mPaints; - Vector<SkPath*> mPaths; - SortedVector<SkPath*> mSourcePaths; - Vector<SkRegion*> mRegions; - Vector<SkMatrix*> mMatrices; - Vector<SkiaShader*> mShaders; - Vector<Layer*> mLayers; - - sp<DisplayListData> mDisplayListData; - - size_t mSize; - - bool mIsRenderable; - uint32_t mFunctorCount; - - String8 mName; - bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed - - // View properties - bool mClipToBounds; - float mAlpha; - bool mHasOverlappingRendering; - float mTranslationX, mTranslationY; - float mRotation, mRotationX, mRotationY; - float mScaleX, mScaleY; - float mPivotX, mPivotY; - float mCameraDistance; - int mLeft, mTop, mRight, mBottom; - int mWidth, mHeight; - int mPrevWidth, mPrevHeight; - bool mPivotExplicitlySet; - bool mMatrixDirty; - bool mMatrixIsIdentity; - uint32_t mMatrixFlags; - SkMatrix* mTransformMatrix; - Sk3DView* mTransformCamera; - SkMatrix* mTransformMatrix3D; - SkMatrix* mStaticMatrix; - SkMatrix* mAnimationMatrix; - bool mCaching; - - /** - * State operations - needed to defer displayList property operations (for example, when setting - * an alpha causes a SaveLayerAlpha to occur). These operations point into mDisplayListData's - * allocation, or null if uninitialized. - * - * These are initialized (via friend re-constructors) when a displayList is issued in either - * replay or deferred mode. If replaying, the ops are not used until the next frame. If - * deferring, the ops may be stored in the DeferredDisplayList to be played back a second time. - * - * They should be used at most once per frame (one call to 'iterate') to avoid overwriting data - */ - ClipRectOp* mClipRectOp; - SaveLayerOp* mSaveLayerOp; - SaveOp* mSaveOp; - RestoreToCountOp* mRestoreToCountOp; -}; // class DisplayList + void cleanupResources(); +}; }; // namespace uirenderer }; // namespace android |
