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/tests/SkResourceCacheTest.cpp b/tests/SkResourceCacheTest.cpp
index b660890..20c3f7f 100644
--- a/tests/SkResourceCacheTest.cpp
+++ b/tests/SkResourceCacheTest.cpp
@@ -8,6 +8,7 @@
 #include "SkCanvas.h"
 #include "SkGraphics.h"
 #include "SkBitmapCache.h"
+#include "SkDiscardableMemoryPool.h"
 
 static const int kCanvasSize = 1;
 static const int kBitmapSize = 16;
@@ -109,4 +110,36 @@
     // Should be in the cache, we just added it
     REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm));
 }
+
+DEF_TEST(BitmapCache_discarded_bitmap, reporter) {
+    SkBitmap bm;
+    SkIRect rect = SkIRect::MakeWH(5, 5);
+    SkBitmap cachedBitmap = createAllocatedBitmap(SkImageInfo::MakeN32Premul(5, 5));
+    cachedBitmap.setImmutable();
+    cachedBitmap.unlockPixels();
+
+    // Add a bitmap to the cache.
+    REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.getGenerationID(), rect, cachedBitmap));
+    REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm));
+
+    // Finding more than once works fine.
+    REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm));
+    bm.unlockPixels();
+
+    // Drop the pixels in the bitmap.
+    REPORTER_ASSERT(reporter, SkGetGlobalDiscardableMemoryPool()->getRAMUsed() > 0);
+    SkGetGlobalDiscardableMemoryPool()->dumpPool();
+    REPORTER_ASSERT(reporter, SkGetGlobalDiscardableMemoryPool()->getRAMUsed() == 0);
+
+    // The bitmap is not in the cache since it has been dropped.
+    REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm));
+
+    cachedBitmap = createAllocatedBitmap(SkImageInfo::MakeN32Premul(5, 5));
+    cachedBitmap.setImmutable();
+    cachedBitmap.unlockPixels();
+
+    // We can add the bitmap back to the cache and find it again.
+    REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.getGenerationID(), rect, cachedBitmap));
+    REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm));
+}
 #endif