Make SkBitmapCache remove invalid bitmaps from the SkResourceCache.

This adds SkResourceCache::Remove() which will remove a resource from
its cache. The resource is required to be unlocked at the time Remove()
is called.

Then SkBitmapCache::Find() makes use of this to Remove() bitmaps from
the cache whose pixels have been evicted. This allows the bitmap to be
re-added to the cache with pixels again.

After this change, background a tab (and discarding all the bitmaps'
contents) no longer disables image caching for those discarded images
once the tab is visible again.

BUG=skia:2926
NOTRY=true
R=reed@android.com, tomhudson@google.com, reed@google.com

Author: danakj@chromium.org

Review URL: https://codereview.chromium.org/561953002
diff --git a/src/core/SkResourceCache.cpp b/src/core/SkResourceCache.cpp
index 73f788c..6400e8a 100644
--- a/src/core/SkResourceCache.cpp
+++ b/src/core/SkResourceCache.cpp
@@ -286,6 +286,23 @@
     }
 }
 
+void SkResourceCache::remove(Rec* rec) {
+    SkASSERT(0 == rec->fLockCount);
+
+    size_t used = rec->bytesUsed();
+    SkASSERT(used <= fTotalBytesUsed);
+
+    this->detach(rec);
+#ifdef USE_HASH
+    fHash->remove(rec->getKey());
+#endif
+
+    SkDELETE(rec);
+
+    fTotalBytesUsed -= used;
+    fCount -= 1;
+}
+
 void SkResourceCache::purgeAsNeeded() {
     size_t byteLimit;
     int    countLimit;
@@ -298,34 +315,18 @@
         byteLimit = fTotalByteLimit;
     }
 
-    size_t bytesUsed = fTotalBytesUsed;
-    int    countUsed = fCount;
-
     Rec* rec = fTail;
     while (rec) {
-        if (bytesUsed < byteLimit && countUsed < countLimit) {
+        if (fTotalBytesUsed < byteLimit && fCount < countLimit) {
             break;
         }
 
         Rec* prev = rec->fPrev;
         if (0 == rec->fLockCount) {
-            size_t used = rec->bytesUsed();
-            SkASSERT(used <= bytesUsed);
-            this->detach(rec);
-#ifdef USE_HASH
-            fHash->remove(rec->getKey());
-#endif
-
-            SkDELETE(rec);
-
-            bytesUsed -= used;
-            countUsed -= 1;
+            this->remove(rec);
         }
         rec = prev;
     }
-
-    fTotalBytesUsed = bytesUsed;
-    fCount = countUsed;
 }
 
 size_t SkResourceCache::setTotalByteLimit(size_t newLimit) {
@@ -506,6 +507,28 @@
 //    get_cache()->dump();
 }
 
+void SkResourceCache::Remove(SkResourceCache::ID id) {
+    SkAutoMutexAcquire am(gMutex);
+    SkASSERT(id);
+
+#ifdef SK_DEBUG
+    {
+        bool found = false;
+        Rec* rec = get_cache()->fHead;
+        while (rec != NULL) {
+            if (rec == id) {
+                found = true;
+                break;
+            }
+            rec = rec->fNext;
+        }
+        SkASSERT(found);
+    }
+#endif
+    const Rec* rec = id;
+    get_cache()->remove(const_cast<Rec*>(rec));
+}
+
 size_t SkResourceCache::GetTotalBytesUsed() {
     SkAutoMutexAcquire am(gMutex);
     return get_cache()->getTotalBytesUsed();