From 8aa195d7081b889f3a7b1f426cbd8556377aae5e Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Tue, 4 Jun 2013 18:00:09 -0700 Subject: Introduce Caches::bindTexture() to reduce glBindTexture calls Change-Id: Ic345422567c020c0a9035ff51dcf2ae2a1fc59f4 --- libs/hwui/PathCache.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libs/hwui/PathCache.cpp') diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index fdb10e2..3f6485c 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -139,7 +139,7 @@ static void drawPath(const SkPath *path, const SkPaint* paint, SkBitmap& bitmap, static PathTexture* createTexture(float left, float top, float offset, uint32_t width, uint32_t height, uint32_t id) { - PathTexture* texture = new PathTexture(); + PathTexture* texture = new PathTexture(Caches::getInstance()); texture->left = left; texture->top = top; texture->offset = offset; @@ -300,7 +300,7 @@ void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) { glGenTextures(1, &texture->id); - glBindTexture(GL_TEXTURE_2D, texture->id); + Caches::getInstance().bindTexture(texture->id); // Textures are Alpha8 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); -- cgit v1.1 From be1b127c7bec252e0c6ab0e06ed6babed07d496f Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Thu, 6 Jun 2013 14:02:54 -0700 Subject: Assume a texture is unbound after deleting it Bug #9316260 The GL specification indicates that deleting a bound texture has the side effect of binding the default texture (name=0). This change replaces all calls to glDeleteTextures() by Caches::deleteTexture() to properly keep track of texture bindings. Change-Id: Ifbc60ef433e0f9776a668dd5bd5f0adbc65a77a0 --- libs/hwui/PathCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libs/hwui/PathCache.cpp') diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 3f6485c..3ab40da 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -223,7 +223,7 @@ void PathCache::removeTexture(PathTexture* texture) { } if (texture->id) { - glDeleteTextures(1, &texture->id); + Caches::getInstance().deleteTexture(texture->id); } delete texture; } -- cgit v1.1 From e3b0a0117a2ab4118f868a731b238fe8f2430276 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Wed, 26 Jun 2013 15:45:41 -0700 Subject: Refcount 9-patches and properly handle GC events This change adds refcounting of Res_png_9patch instances, the native data structure used to represent 9-patches. The Dalvik NinePatch class now holds a native pointer instead of a Dalvik byte[]. This pointer is used whenever we need to draw the 9-patch (software or hardware.) Since we are now tracking garbage collection of NinePatch objects libhwui's PatchCache must keep a list of free blocks in the VBO used to store the meshes. This change also removes unnecessary instances tracking from GLES20DisplayList. Bitmaps and 9-patches are refcounted at the native level and do not need to be tracked by the Dalvik layer. Change-Id: Ib8682d573a538aaf1945f8ec5a9bd5da5d16f74b --- libs/hwui/PathCache.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'libs/hwui/PathCache.cpp') diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 3ab40da..70ab6e7 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -350,8 +350,7 @@ void PathCache::PathProcessor::onProcess(const sp >& task) { // Paths /////////////////////////////////////////////////////////////////////////////// -void PathCache::remove(const path_pair_t& pair) { - Vector pathsToRemove; +void PathCache::remove(Vector& pathsToRemove, const path_pair_t& pair) { LruCache::Iterator i(mCache); while (i.next()) { @@ -362,10 +361,6 @@ void PathCache::remove(const path_pair_t& pair) { pathsToRemove.push(key); } } - - for (size_t i = 0; i < pathsToRemove.size(); i++) { - mCache.remove(pathsToRemove.itemAt(i)); - } } void PathCache::removeDeferred(SkPath* path) { @@ -374,12 +369,20 @@ void PathCache::removeDeferred(SkPath* path) { } void PathCache::clearGarbage() { - Mutex::Autolock l(mLock); - size_t count = mGarbage.size(); - for (size_t i = 0; i < count; i++) { - remove(mGarbage.itemAt(i)); + Vector pathsToRemove; + + { // scope for the mutex + Mutex::Autolock l(mLock); + size_t count = mGarbage.size(); + for (size_t i = 0; i < count; i++) { + remove(pathsToRemove, mGarbage.itemAt(i)); + } + mGarbage.clear(); + } + + for (size_t i = 0; i < pathsToRemove.size(); i++) { + mCache.remove(pathsToRemove.itemAt(i)); } - mGarbage.clear(); } /** -- cgit v1.1 From 0a8c51b1d0d66d6060afcec1eab33091d49332ae Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Wed, 21 Aug 2013 17:35:38 -0700 Subject: Properly account for created paths in the cache Change-Id: I47b89b3085cefab6daac9194e7bfd3c140b37fa2 --- libs/hwui/PathCache.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'libs/hwui/PathCache.cpp') diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 70ab6e7..25afe63 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -283,6 +283,11 @@ void PathCache::generateTexture(const PathDescription& entry, SkBitmap* bitmap, mCache.put(entry, texture); } } else { + // It's okay to add a texture that's bigger than the cache since + // we'll trim the cache later when addToCache is set to false + if (!addToCache) { + mSize += size; + } texture->cleanup = true; } } -- cgit v1.1 From 5d923200846ed59e813373bde789d97d4ccc40b5 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Wed, 21 Aug 2013 18:40:24 -0700 Subject: Second attempt at avoiding infinite loop in PathCache::trim() Bug #10347089 Change-Id: I70f5a3933e848632473acc6636c88be5dc6ac430 --- libs/hwui/PathCache.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'libs/hwui/PathCache.cpp') diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 25afe63..5df6408 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -214,7 +214,22 @@ void PathCache::operator()(PathDescription& entry, PathTexture*& texture) { void PathCache::removeTexture(PathTexture* texture) { if (texture) { const uint32_t size = texture->width * texture->height; - mSize -= size; + + // If there is a pending task we must wait for it to return + // before attempting our cleanup + const sp >& task = texture->task(); + if (task != NULL) { + SkBitmap* bitmap = task->getResult(); + texture->clearTask(); + } else { + // If there is a pending task, the path was not added + // to the cache and the size wasn't increased + if (size > mSize) { + ALOGE("Removing path texture of size %d will leave " + "the cache in an inconsistent state", size); + } + mSize -= size; + } PATH_LOGD("PathCache::delete name, size, mSize = %d, %d, %d", texture->id, size, mSize); -- cgit v1.1