From 9a814875c4e3a98fea99dae623f22268a9afa38a Mon Sep 17 00:00:00 2001 From: John Reck Date: Mon, 22 May 2017 15:04:21 -0700 Subject: [PATCH] Improve time to texture destruction Eliminate textureCache.mGarbage which is only cleared in a trimMemory. Instead when we hit ~Bitmap post a message to RenderThread to release the texture immediately Bug: 38258699 Test: manual Change-Id: I962ba275e89afb628ba02f74769287edbab9fed4 --- libs/hwui/Caches.cpp | 1 - libs/hwui/TextureCache.cpp | 25 +++++++------------------ libs/hwui/TextureCache.h | 12 +++--------- libs/hwui/hwui/Bitmap.cpp | 4 +--- libs/hwui/renderstate/RenderState.cpp | 7 +++++++ libs/hwui/renderstate/RenderState.h | 1 + libs/hwui/renderthread/RenderProxy.cpp | 15 +++++++++++++++ libs/hwui/renderthread/RenderProxy.h | 2 ++ 8 files changed, 36 insertions(+), 31 deletions(-) diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index a0366dee3218c..2fdfcd42a1e19 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -223,7 +223,6 @@ void Caches::dumpMemoryUsage(String8 &log) { /////////////////////////////////////////////////////////////////////////////// void Caches::clearGarbage() { - textureCache.clearGarbage(); pathCache.clearGarbage(); patchCache.clearGarbage(); } diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 63a6a2c8c89cb..710cdd9286e8b 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -191,25 +191,14 @@ Texture* TextureCache::get(Bitmap* bitmap) { return texture; } -void TextureCache::releaseTexture(uint32_t pixelRefStableID) { - Mutex::Autolock _l(mLock); - mGarbage.push_back(pixelRefStableID); -} - -void TextureCache::clearGarbage() { - Mutex::Autolock _l(mLock); - size_t count = mGarbage.size(); - for (size_t i = 0; i < count; i++) { - uint32_t pixelRefId = mGarbage[i]; - auto hardwareIter = mHardwareTextures.find(pixelRefId); - if (hardwareIter == mHardwareTextures.end()) { - mCache.remove(pixelRefId); - } else { - hardwareIter->second->deleteTexture(); - mHardwareTextures.erase(hardwareIter); - } +bool TextureCache::destroyTexture(uint32_t pixelRefStableID) { + auto hardwareIter = mHardwareTextures.find(pixelRefStableID); + if (hardwareIter != mHardwareTextures.end()) { + hardwareIter->second->deleteTexture(); + mHardwareTextures.erase(hardwareIter); + return true; } - mGarbage.clear(); + return mCache.remove(pixelRefStableID); } void TextureCache::clear() { diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index db4ff39aed83e..776ff8a03fd1c 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -94,14 +94,10 @@ public: Texture* get(Bitmap* bitmap); /** - * Removes the texture associated with the specified pixelRef. This is meant - * to be called from threads that are not the EGL context thread. + * Removes the texture associated with the specified pixelRef. Must be called from RenderThread + * Returns true if a texture was destroyed, false if no texture with that id was found */ - ANDROID_API void releaseTexture(uint32_t pixelRefStableID); - /** - * Process deferred removals. - */ - void clearGarbage(); + bool destroyTexture(uint32_t pixelRefStableID); /** * Clears the cache. This causes all textures to be deleted. @@ -139,9 +135,7 @@ private: bool mDebugEnabled; - std::vector mGarbage; std::unordered_map> mHardwareTextures; - mutable Mutex mLock; }; // class TextureCache }; // namespace uirenderer diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index d765584a7530c..72be564105b66 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -416,9 +416,7 @@ Bitmap::~Bitmap() { } - if (android::uirenderer::Caches::hasInstance()) { - android::uirenderer::Caches::getInstance().textureCache.releaseTexture(getStableID()); - } + android::uirenderer::renderthread::RenderProxy::onBitmapDestroyed(getStableID()); } bool Bitmap::hasHardwareMipMap() const { diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp index c8833d2a74892..b89272ebd486f 100644 --- a/libs/hwui/renderstate/RenderState.cpp +++ b/libs/hwui/renderstate/RenderState.cpp @@ -122,6 +122,13 @@ void RenderState::flush(Caches::FlushMode mode) { mCaches->flush(mode); } +void RenderState::onBitmapDestroyed(uint32_t pixelRefId) { + if (mCaches->textureCache.destroyTexture(pixelRefId)) { + glFlush(); + GL_CHECKPOINT(MODERATE); + } +} + void RenderState::setViewport(GLsizei width, GLsizei height) { mViewportWidth = width; mViewportHeight = height; diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h index f78bf7a4e088c..787946f79f6be 100644 --- a/libs/hwui/renderstate/RenderState.h +++ b/libs/hwui/renderstate/RenderState.h @@ -63,6 +63,7 @@ public: void onVkContextDestroyed(); void flush(Caches::FlushMode flushMode); + void onBitmapDestroyed(uint32_t pixelRefId); void setViewport(GLsizei width, GLsizei height); void getViewport(GLsizei* outWidth, GLsizei* outHeight); diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index a1f1717e6b962..eed5238104038 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -24,6 +24,7 @@ #include "renderthread/EglManager.h" #include "renderthread/RenderTask.h" #include "renderthread/RenderThread.h" +#include "renderstate/RenderState.h" #include "utils/Macros.h" #include "utils/TimeUtils.h" @@ -693,6 +694,20 @@ int RenderProxy::copyGraphicBufferInto(GraphicBuffer* buffer, SkBitmap* bitmap) } } +CREATE_BRIDGE2(onBitmapDestroyed, RenderThread* thread, uint32_t pixelRefId) { + args->thread->renderState().onBitmapDestroyed(args->pixelRefId); + return nullptr; +} + +void RenderProxy::onBitmapDestroyed(uint32_t pixelRefId) { + if (!RenderThread::hasInstance()) return; + SETUP_TASK(onBitmapDestroyed); + RenderThread& thread = RenderThread::getInstance(); + args->thread = &thread; + args->pixelRefId = pixelRefId; + thread.queue(task); +} + void RenderProxy::post(RenderTask* task) { mRenderThread.queue(task); } diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index a60ed55c70d25..b21772cd88de5 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -135,6 +135,8 @@ public: static sk_sp allocateHardwareBitmap(SkBitmap& bitmap); static int copyGraphicBufferInto(GraphicBuffer* buffer, SkBitmap* bitmap); + + static void onBitmapDestroyed(uint32_t pixelRefId); private: RenderThread& mRenderThread; CanvasContext* mContext;