diff options
author | John Reck <jreck@google.com> | 2014-05-29 18:56:11 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2014-05-30 12:19:33 -0700 |
commit | d72e0a339b54af0c4e731513bbad120dff694723 (patch) | |
tree | ca8ac198de9a0cfeeae1e9e8039e35523e7810c3 /libs | |
parent | aee470c0232afdac4256d13020fa0cf04f30395c (diff) | |
download | frameworks_base-d72e0a339b54af0c4e731513bbad120dff694723.zip frameworks_base-d72e0a339b54af0c4e731513bbad120dff694723.tar.gz frameworks_base-d72e0a339b54af0c4e731513bbad120dff694723.tar.bz2 |
Re-jigger layers
Bug: 15185239
Bug: 15238382
Make DeferredLayerUpdater ref counted so that
HardwareLayer:finalizer() works non-crashily on
leaked layers
Give DeferredLayerUpdater the ability to have a layer destroyer
set so that leaked layers can still be recycled on the
RenderThread
Order layer updates based off of pushLayerUpdate() calls to fix
issue with nested layers
Change-Id: I4449cee607f7e5126e02fed7464cf48038e3dfdf
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DeferredLayerUpdater.cpp | 17 | ||||
-rw-r--r-- | libs/hwui/DeferredLayerUpdater.h | 14 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 26 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 6 | ||||
-rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.cpp | 31 | ||||
-rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.h | 13 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 33 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 3 |
8 files changed, 74 insertions, 69 deletions
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index 285c8c3..97e9bf6 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -22,14 +22,19 @@ namespace android { namespace uirenderer { -DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, OpenGLRenderer* renderer) +static void defaultLayerDestroyer(Layer* layer) { + Caches::getInstance().resourceCache.decrementRefcount(layer); +} + +DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, LayerDestroyer destroyer) : mDisplayList(0) , mSurfaceTexture(0) , mTransform(0) , mNeedsGLContextAttach(false) , mUpdateTexImage(false) , mLayer(layer) - , mCaches(Caches::getInstance()) { + , mCaches(Caches::getInstance()) + , mDestroyer(destroyer) { mWidth = mLayer->layer.getWidth(); mHeight = mLayer->layer.getHeight(); mBlend = mLayer->isBlend(); @@ -37,14 +42,16 @@ DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, OpenGLRenderer* rendere mAlpha = mLayer->getAlpha(); mMode = mLayer->getMode(); mDirtyRect.setEmpty(); + + if (!mDestroyer) { + mDestroyer = defaultLayerDestroyer; + } } DeferredLayerUpdater::~DeferredLayerUpdater() { SkSafeUnref(mColorFilter); setTransform(0); - if (mLayer) { - mCaches.resourceCache.decrementRefcount(mLayer); - } + mDestroyer(mLayer); } void DeferredLayerUpdater::setPaint(const SkPaint* paint) { diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index cc62caa..b7cfe80 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -30,13 +30,15 @@ namespace android { namespace uirenderer { +typedef void (*LayerDestroyer)(Layer* layer); + // Container to hold the properties a layer should be set to at the start // of a render pass -class DeferredLayerUpdater { +class DeferredLayerUpdater : public VirtualLightRefBase { public: // Note that DeferredLayerUpdater assumes it is taking ownership of the layer // and will not call incrementRef on it as a result. - ANDROID_API DeferredLayerUpdater(Layer* layer, OpenGLRenderer* renderer = 0); + ANDROID_API DeferredLayerUpdater(Layer* layer, LayerDestroyer = 0); ANDROID_API ~DeferredLayerUpdater(); ANDROID_API bool setSize(uint32_t width, uint32_t height) { @@ -83,12 +85,6 @@ public: return mLayer; } - ANDROID_API Layer* detachBackingLayer() { - Layer* layer = mLayer; - mLayer = 0; - return layer; - } - private: // Generic properties uint32_t mWidth; @@ -111,6 +107,8 @@ private: Layer* mLayer; Caches& mCaches; + LayerDestroyer mDestroyer; + void doUpdateTexImage(); }; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index f91e90e..9ebee1d 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -427,27 +427,11 @@ void CanvasContext::makeCurrent() { mHaveNewSurface |= mGlobalContext->makeCurrent(mEglSurface); } -void CanvasContext::prepareDraw(const Vector<DeferredLayerUpdater*>* layerUpdaters, - TreeInfo& info) { - LOG_ALWAYS_FATAL_IF(!mCanvas, "Cannot prepareDraw without a canvas!"); - makeCurrent(); - - processLayerUpdates(layerUpdaters, info); - if (info.out.hasAnimations) { - // TODO: Uh... crap? - } - prepareTree(info); -} - -void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, - TreeInfo& info) { - for (size_t i = 0; i < layerUpdaters->size(); i++) { - DeferredLayerUpdater* update = layerUpdaters->itemAt(i); - bool success = update->apply(info); - LOG_ALWAYS_FATAL_IF(!success, "Failed to update layer!"); - if (update->backingLayer()->deferredUpdateScheduled) { - mCanvas->pushLayerUpdate(update->backingLayer()); - } +void CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater, TreeInfo& info) { + bool success = layerUpdater->apply(info); + LOG_ALWAYS_FATAL_IF(!success, "Failed to update layer!"); + if (layerUpdater->backingLayer()->deferredUpdateScheduled) { + mCanvas->pushLayerUpdate(layerUpdater->backingLayer()); } } diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index a04269b..00c5bf0 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -55,7 +55,8 @@ public: void setup(int width, int height, const Vector3& lightCenter, float lightRadius); void setOpaque(bool opaque); void makeCurrent(); - void prepareDraw(const Vector<DeferredLayerUpdater*>* layerUpdaters, TreeInfo& info); + void processLayerUpdate(DeferredLayerUpdater* layerUpdater, TreeInfo& info); + void prepareTree(TreeInfo& info); void draw(Rect* dirty); void destroyCanvasAndSurface(); @@ -83,9 +84,6 @@ public: private: friend class RegisterFrameCallbackTask; - void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, TreeInfo& info); - void prepareTree(TreeInfo& info); - void setSurface(ANativeWindow* window); void swapBuffers(); void requireSurface(); diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 7ea358f..61d67ca 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -21,6 +21,7 @@ #include <utils/Log.h> #include <utils/Trace.h> +#include "../DeferredLayerUpdater.h" #include "../DisplayList.h" #include "../RenderNode.h" #include "CanvasContext.h" @@ -47,17 +48,22 @@ void DrawFrameTask::setContext(RenderThread* thread, CanvasContext* context) { mContext = context; } -void DrawFrameTask::addLayer(DeferredLayerUpdater* layer) { - LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to addLayer with!"); +void DrawFrameTask::pushLayerUpdate(DeferredLayerUpdater* layer) { + LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to pushLayerUpdate with!"); - mLayers.push(layer); + for (size_t i = 0; i < mLayers.size(); i++) { + if (mLayers[i].get() == layer) { + return; + } + } + mLayers.push_back(layer); } -void DrawFrameTask::removeLayer(DeferredLayerUpdater* layer) { +void DrawFrameTask::removeLayerUpdate(DeferredLayerUpdater* layer) { for (size_t i = 0; i < mLayers.size(); i++) { - if (mLayers[i] == layer) { - mLayers.removeAt(i); - break; + if (mLayers[i].get() == layer) { + mLayers.erase(mLayers.begin() + i); + return; } } } @@ -132,7 +138,16 @@ bool DrawFrameTask::syncFrameState(TreeInfo& info) { mContext->makeCurrent(); Caches::getInstance().textureCache.resetMarkInUse(); initTreeInfo(info); - mContext->prepareDraw(&mLayers, info); + + for (size_t i = 0; i < mLayers.size(); i++) { + mContext->processLayerUpdate(mLayers[i].get(), info); + } + mLayers.clear(); + if (info.out.hasAnimations) { + // TODO: Uh... crap? + } + mContext->prepareTree(info); + if (info.out.hasAnimations) { // TODO: dirty calculations, for now just do a full-screen inval mDirty.setEmpty(); diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h index 30c8880..d4129b6 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -16,10 +16,11 @@ #ifndef DRAWFRAMETASK_H #define DRAWFRAMETASK_H +#include <vector> + #include <utils/Condition.h> #include <utils/Mutex.h> #include <utils/StrongPointer.h> -#include <utils/Vector.h> #include "RenderTask.h" @@ -56,8 +57,8 @@ public: void setContext(RenderThread* thread, CanvasContext* context); - void addLayer(DeferredLayerUpdater* layer); - void removeLayer(DeferredLayerUpdater* layer); + void pushLayerUpdate(DeferredLayerUpdater* layer); + void removeLayerUpdate(DeferredLayerUpdater* layer); void setDirty(int left, int top, int right, int bottom); void setDensity(float density) { mDensity = density; } @@ -83,13 +84,9 @@ private: nsecs_t mFrameTimeNanos; nsecs_t mRecordDurationNanos; float mDensity; + std::vector< sp<DeferredLayerUpdater> > mLayers; int mSyncResult; - - /********************************************* - * Multi frame data - *********************************************/ - Vector<DeferredLayerUpdater*> mLayers; }; } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 77c0aa7..0901963 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -229,10 +229,21 @@ void RenderProxy::runWithGlContext(RenderTask* gltask) { postAndWait(task); } +CREATE_BRIDGE1(destroyLayer, Layer* layer) { + LayerRenderer::destroyLayer(args->layer); + return NULL; +} + +static void enqueueDestroyLayer(Layer* layer) { + SETUP_TASK(destroyLayer); + args->layer = layer; + RenderThread::getInstance().queue(task); +} + CREATE_BRIDGE3(createDisplayListLayer, CanvasContext* context, int width, int height) { Layer* layer = args->context->createRenderLayer(args->width, args->height); if (!layer) return 0; - return new DeferredLayerUpdater(layer); + return new DeferredLayerUpdater(layer, enqueueDestroyLayer); } DeferredLayerUpdater* RenderProxy::createDisplayListLayer(int width, int height) { @@ -242,14 +253,13 @@ DeferredLayerUpdater* RenderProxy::createDisplayListLayer(int width, int height) args->context = mContext; void* retval = postAndWait(task); DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval); - mDrawFrameTask.addLayer(layer); return layer; } CREATE_BRIDGE1(createTextureLayer, CanvasContext* context) { Layer* layer = args->context->createTextureLayer(); if (!layer) return 0; - return new DeferredLayerUpdater(layer); + return new DeferredLayerUpdater(layer, enqueueDestroyLayer); } DeferredLayerUpdater* RenderProxy::createTextureLayer() { @@ -257,15 +267,9 @@ DeferredLayerUpdater* RenderProxy::createTextureLayer() { args->context = mContext; void* retval = postAndWait(task); DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval); - mDrawFrameTask.addLayer(layer); return layer; } -CREATE_BRIDGE1(destroyLayer, Layer* layer) { - LayerRenderer::destroyLayer(args->layer); - return NULL; -} - CREATE_BRIDGE3(copyLayerInto, CanvasContext* context, DeferredLayerUpdater* layer, SkBitmap* bitmap) { bool success = args->context->copyLayerInto(args->layer, args->bitmap); @@ -280,11 +284,12 @@ bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) { return (bool) postAndWait(task); } -void RenderProxy::destroyLayer(DeferredLayerUpdater* layer) { - mDrawFrameTask.removeLayer(layer); - SETUP_TASK(destroyLayer); - args->layer = layer->detachBackingLayer(); - post(task); +void RenderProxy::pushLayerUpdate(DeferredLayerUpdater* layer) { + mDrawFrameTask.pushLayerUpdate(layer); +} + +void RenderProxy::cancelLayerUpdate(DeferredLayerUpdater* layer) { + mDrawFrameTask.removeLayerUpdate(layer); } CREATE_BRIDGE2(flushCaches, CanvasContext* context, Caches::FlushMode flushMode) { diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index c8d42ec..944ff9c 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -80,7 +80,8 @@ public: ANDROID_API DeferredLayerUpdater* createDisplayListLayer(int width, int height); ANDROID_API DeferredLayerUpdater* createTextureLayer(); ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap); - ANDROID_API void destroyLayer(DeferredLayerUpdater* layer); + ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer); + ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer); ANDROID_API void flushCaches(Caches::FlushMode flushMode); |