Yank ResourceCache out of Caches

Bug: 17947547

Pull the ResourceCache (aka, ref-counting side channel) out of
Caches so that DisplayListRenderer doesn't use Caches, avoiding
the risk of instantiating Caches on the wrong thread or
without a GL context

Change-Id: I7d63b70b3b0a0163308c5dedd6ef255eadebe8fd
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 70cf9a8..d7eef6e 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -17,7 +17,7 @@
 
 #include <jni.h>
 
-#include <Caches.h>
+#include <ResourceCache.h>
 
 #if 0
     #define TRACE_BITMAP(code)  code
@@ -365,8 +365,8 @@
 static void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) {
     SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
 #ifdef USE_OPENGL_RENDERER
-    if (android::uirenderer::Caches::hasInstance()) {
-        android::uirenderer::Caches::getInstance().resourceCache.destructor(bitmap);
+    if (android::uirenderer::ResourceCache::hasInstance()) {
+        android::uirenderer::ResourceCache::getInstance().destructor(bitmap);
         return;
     }
 #endif // USE_OPENGL_RENDERER
@@ -376,9 +376,9 @@
 static jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) {
     SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
 #ifdef USE_OPENGL_RENDERER
-    if (android::uirenderer::Caches::hasInstance()) {
+    if (android::uirenderer::ResourceCache::hasInstance()) {
         bool result;
-        result = android::uirenderer::Caches::getInstance().resourceCache.recycle(bitmap);
+        result = android::uirenderer::ResourceCache::getInstance().recycle(bitmap);
         return result ? JNI_TRUE : JNI_FALSE;
     }
 #endif // USE_OPENGL_RENDERER
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index cf23771..be62fdd 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -21,7 +21,7 @@
 #include <androidfw/ResourceTypes.h>
 #include <utils/Log.h>
 
-#include <Caches.h>
+#include <ResourceCache.h>
 
 #include "Paint.h"
 #include "Canvas.h"
@@ -80,9 +80,9 @@
     static void finalize(JNIEnv* env, jobject, jlong patchHandle) {
         int8_t* patch = reinterpret_cast<int8_t*>(patchHandle);
 #ifdef USE_OPENGL_RENDERER
-        if (android::uirenderer::Caches::hasInstance()) {
+        if (android::uirenderer::ResourceCache::hasInstance()) {
             Res_png_9patch* p = (Res_png_9patch*) patch;
-            android::uirenderer::Caches::getInstance().resourceCache.destructor(p);
+            android::uirenderer::ResourceCache::getInstance().destructor(p);
             return;
         }
 #endif // USE_OPENGL_RENDERER
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index 9d3e74b..30ce58d 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -27,7 +27,7 @@
 #include "SkPath.h"
 #include "SkPathOps.h"
 
-#include <Caches.h>
+#include <ResourceCache.h>
 #include <vector>
 #include <map>
 
@@ -39,8 +39,8 @@
     static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
         SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
 #ifdef USE_OPENGL_RENDERER
-        if (android::uirenderer::Caches::hasInstance()) {
-            android::uirenderer::Caches::getInstance().resourceCache.destructor(obj);
+        if (android::uirenderer::ResourceCache::hasInstance()) {
+            android::uirenderer::ResourceCache::getInstance().destructor(obj);
             return;
         }
 #endif
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 7aa628c..e338686 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -340,7 +340,6 @@
     TessellationCache tessellationCache;
     TextDropShadowCache dropShadowCache;
     FboCache fboCache;
-    ResourceCache resourceCache;
 
     GammaFontRenderer* fontRenderer;
 
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 4a927cf..8953166 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -39,29 +39,28 @@
 }
 
 void DisplayListData::cleanupResources() {
-    Caches& caches = Caches::getInstance();
-    caches.unregisterFunctors(functors.size());
-    caches.resourceCache.lock();
+    ResourceCache& resourceCache = ResourceCache::getInstance();
+    resourceCache.lock();
 
     for (size_t i = 0; i < bitmapResources.size(); i++) {
-        caches.resourceCache.decrementRefcountLocked(bitmapResources.itemAt(i));
+        resourceCache.decrementRefcountLocked(bitmapResources.itemAt(i));
     }
 
     for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
         const SkBitmap* bitmap = ownedBitmapResources.itemAt(i);
-        caches.resourceCache.decrementRefcountLocked(bitmap);
-        caches.resourceCache.destructorLocked(bitmap);
+        resourceCache.decrementRefcountLocked(bitmap);
+        resourceCache.destructorLocked(bitmap);
     }
 
     for (size_t i = 0; i < patchResources.size(); i++) {
-        caches.resourceCache.decrementRefcountLocked(patchResources.itemAt(i));
+        resourceCache.decrementRefcountLocked(patchResources.itemAt(i));
     }
 
     for (size_t i = 0; i < sourcePaths.size(); i++) {
-        caches.resourceCache.decrementRefcountLocked(sourcePaths.itemAt(i));
+        resourceCache.decrementRefcountLocked(sourcePaths.itemAt(i));
     }
 
-    caches.resourceCache.unlock();
+    resourceCache.unlock();
 
     for (size_t i = 0; i < paints.size(); i++) {
         delete paints.itemAt(i);
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index c17dd09..1b1f6cc 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -21,7 +21,7 @@
 
 #include <private/hwui/DrawGlInfo.h>
 
-#include "Caches.h"
+#include "ResourceCache.h"
 #include "DeferredDisplayList.h"
 #include "DisplayListLogBuffer.h"
 #include "DisplayListOp.h"
@@ -32,7 +32,7 @@
 namespace uirenderer {
 
 DisplayListRenderer::DisplayListRenderer()
-    : mCaches(Caches::getInstance())
+    : mResourceCache(ResourceCache::getInstance())
     , mDisplayListData(NULL)
     , mTranslateX(0.0f)
     , mTranslateY(0.0f)
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 901e8f0..8068663 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -24,6 +24,7 @@
 
 #include "DisplayListLogBuffer.h"
 #include "RenderNode.h"
+#include "ResourceCache.h"
 
 namespace android {
 namespace uirenderer {
@@ -209,7 +210,7 @@
             mDisplayListData->paths.add(pathCopy);
         }
         if (mDisplayListData->sourcePaths.indexOf(path) < 0) {
-            mCaches.resourceCache.incrementRefcount(path);
+            mResourceCache.incrementRefcount(path);
             mDisplayListData->sourcePaths.add(path);
         }
         return pathCopy;
@@ -273,19 +274,19 @@
         // contents, and drawing again. The only fix would be to always copy it the first time,
         // which doesn't seem worth the extra cycles for this unlikely case.
         mDisplayListData->bitmapResources.add(bitmap);
-        mCaches.resourceCache.incrementRefcount(bitmap);
+        mResourceCache.incrementRefcount(bitmap);
         return bitmap;
     }
 
     inline const SkBitmap* refBitmapData(const SkBitmap* bitmap) {
         mDisplayListData->ownedBitmapResources.add(bitmap);
-        mCaches.resourceCache.incrementRefcount(bitmap);
+        mResourceCache.incrementRefcount(bitmap);
         return bitmap;
     }
 
     inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
         mDisplayListData->patchResources.add(patch);
-        mCaches.resourceCache.incrementRefcount(patch);
+        mResourceCache.incrementRefcount(patch);
         return patch;
     }
 
@@ -293,7 +294,7 @@
     DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
     DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
 
-    Caches& mCaches;
+    ResourceCache& mResourceCache;
     DisplayListData* mDisplayListData;
 
     float mTranslateX;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index c9ed9a7..13c5499 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -98,9 +98,6 @@
     mNeedsDisplayListDataSync = true;
     delete mStagingDisplayListData;
     mStagingDisplayListData = data;
-    if (mStagingDisplayListData) {
-        Caches::getInstance().registerFunctors(mStagingDisplayListData->functors.size());
-    }
 }
 
 /**
@@ -305,6 +302,10 @@
         // changes in isRenderable or, in the future, bounds
         damageSelf(info);
         deleteDisplayListData();
+        // TODO: Remove this caches stuff
+        if (mStagingDisplayListData && mStagingDisplayListData->functors.size()) {
+            Caches::getInstance().registerFunctors(mStagingDisplayListData->functors.size());
+        }
         mDisplayListData = mStagingDisplayListData;
         mStagingDisplayListData = NULL;
         if (mDisplayListData) {
@@ -321,6 +322,9 @@
         for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
             mDisplayListData->children()[i]->mRenderNode->decParentRefCount();
         }
+        if (mDisplayListData->functors.size()) {
+            Caches::getInstance().unregisterFunctors(mDisplayListData->functors.size());
+        }
     }
     delete mDisplayListData;
     mDisplayListData = NULL;
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 329d92f..12d4928 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -21,6 +21,12 @@
 #include "Caches.h"
 
 namespace android {
+
+#ifdef USE_OPENGL_RENDERER
+using namespace uirenderer;
+ANDROID_SINGLETON_STATIC_INSTANCE(ResourceCache);
+#endif
+
 namespace uirenderer {
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index 8539d12..a922d53 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -22,6 +22,7 @@
 #include <SkBitmap.h>
 
 #include <utils/KeyedVector.h>
+#include <utils/Singleton.h>
 
 #include <androidfw/ResourceTypes.h>
 
@@ -53,11 +54,14 @@
     ResourceType resourceType;
 };
 
-class ANDROID_API ResourceCache {
-public:
+class ANDROID_API ResourceCache: public Singleton<ResourceCache> {
     ResourceCache();
     ~ResourceCache();
 
+    friend class Singleton<ResourceCache>;
+
+public:
+
     /**
      * When using these two methods, make sure to only invoke the *Locked()
      * variants of increment/decrementRefcount(), recyle() and destructor()