Create SkLazyPixelRef which performs lazy decoding.

The new pixel ref behaves similarly to SkImageRef, with some key differences:
It does not depend on the images project.
It requires an SkImageCache, which handles allocation and caching of the pixel
memory.
It takes a function signature for decoding which decodes into already allocated
pixel memory rather than into an SkBitmap.

Add two implementations of SkImageCache: SkLruImageCache and SkAshmemImageCache.

Replace SkSerializationHelpers::DecodeBitmap with SkPicture::InstallPixelRefProc,
and update sites that referenced it.

SkBitmapFactory now sets the pixel ref to a new object of the new
class SkLazyPixelRef, provided it has an SkImageCache for caching.

Provide an option to do lazy decodes in render_pictures and bench_pictures.

SkPicture:
Eliminate the default parameters in the constructor.
If a proc for decoding bitmaps is installed, use it to decode any encoded
data in subpictures.
When parsing deserializing subpictures, check for success.
When serializing subpictures, pass the picture's bitmap encoder to the
subpicture's call to serialize.

Update BitmapFactoryTest to test its new behavior.

BUG=https://code.google.com/p/skia/issues/detail?id=1008
BUG=https://code.google.com/p/skia/issues/detail?id=1009

Review URL: https://codereview.appspot.com/7060052

git-svn-id: http://skia.googlecode.com/svn/trunk@7835 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tests/BitmapFactoryTest.cpp b/tests/BitmapFactoryTest.cpp
index b24fd25..8bfbaf1 100644
--- a/tests/BitmapFactoryTest.cpp
+++ b/tests/BitmapFactoryTest.cpp
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2012 Google Inc.
  *
@@ -6,17 +5,26 @@
  * found in the LICENSE file.
  */
 
+#ifdef SK_DEBUG
+
 #include "SkBitmap.h"
 #include "SkBitmapFactory.h"
 #include "SkCanvas.h"
 #include "SkColor.h"
 #include "SkData.h"
+#include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
+#include "SkLazyPixelRef.h"
+#include "SkLruImageCache.h"
 #include "SkPaint.h"
 #include "SkStream.h"
 #include "SkTemplates.h"
 #include "Test.h"
 
+#ifdef SK_BUILD_FOR_ANDROID
+#include "SkAshmemImageCache.h"
+#endif
+
 static SkBitmap* create_bitmap() {
     SkBitmap* bm = SkNEW(SkBitmap);
     const int W = 100, H = 100;
@@ -44,6 +52,45 @@
     REPORTER_ASSERT(reporter, bm1.height() == bm2.height());
 }
 
+static void test_cache(skiatest::Reporter* reporter, SkImageCache* cache, SkData* encodedData,
+                       const SkBitmap& origBitmap) {
+    SkBitmapFactory factory(&SkImageDecoder::DecodeMemoryToTarget);
+    factory.setImageCache(cache);
+    SkAutoTDelete<SkBitmap> bitmapFromFactory(SkNEW(SkBitmap));
+    bool success = factory.installPixelRef(encodedData, bitmapFromFactory.get());
+    // This assumes that if the encoder worked, the decoder should also work, so the above call
+    // should not fail.
+    REPORTER_ASSERT(reporter, success);
+    assert_bounds_equal(reporter, origBitmap, *bitmapFromFactory.get());
+
+    SkPixelRef* pixelRef = bitmapFromFactory->pixelRef();
+    REPORTER_ASSERT(reporter, pixelRef != NULL);
+    if (NULL == cache) {
+        // This assumes that installPixelRef called lockPixels.
+        REPORTER_ASSERT(reporter, bitmapFromFactory->readyToDraw());
+    } else {
+        // Lazy decoding
+        REPORTER_ASSERT(reporter, !bitmapFromFactory->readyToDraw());
+        SkLazyPixelRef* lazyRef = static_cast<SkLazyPixelRef*>(pixelRef);
+        int32_t cacheID = lazyRef->getCacheId();
+        REPORTER_ASSERT(reporter, cache->getCacheStatus(cacheID)
+                                  != SkImageCache::kPinned_CacheStatus);
+        {
+            SkAutoLockPixels alp(*bitmapFromFactory.get());
+            REPORTER_ASSERT(reporter, bitmapFromFactory->readyToDraw());
+            cacheID = lazyRef->getCacheId();
+            REPORTER_ASSERT(reporter, cache->getCacheStatus(cacheID)
+                                      == SkImageCache::kPinned_CacheStatus);
+        }
+        REPORTER_ASSERT(reporter, !bitmapFromFactory->readyToDraw());
+        REPORTER_ASSERT(reporter, cache->getCacheStatus(cacheID)
+                                  != SkImageCache::kPinned_CacheStatus);
+        bitmapFromFactory.free();
+        REPORTER_ASSERT(reporter, cache->getCacheStatus(cacheID)
+                                  == SkImageCache::kThrownAway_CacheStatus);
+    }
+}
+
 static void TestBitmapFactory(skiatest::Reporter* reporter) {
     SkAutoTDelete<SkBitmap> bitmap(create_bitmap());
     SkASSERT(bitmap.get() != NULL);
@@ -54,23 +101,15 @@
         return;
     }
 
-    SkBitmap bitmapFromFactory;
-    bool success = SkBitmapFactory::DecodeBitmap(&bitmapFromFactory, encodedBitmap);
-    // This assumes that if the encoder worked, the decoder should also work, so the above call
-    // should not fail.
-    REPORTER_ASSERT(reporter, success);
-    assert_bounds_equal(reporter, *bitmap.get(), bitmapFromFactory);
-    REPORTER_ASSERT(reporter, bitmapFromFactory.pixelRef() != NULL);
-
-    // When only requesting that the bounds be decoded, the bounds should be set properly while
-    // the pixels should be empty.
-    SkBitmap boundedBitmap;
-    success = SkBitmapFactory::DecodeBitmap(&boundedBitmap, encodedBitmap,
-                                            SkBitmapFactory::kDecodeBoundsOnly_Constraint);
-    REPORTER_ASSERT(reporter, success);
-    assert_bounds_equal(reporter, *bitmap.get(), boundedBitmap);
-    REPORTER_ASSERT(reporter, boundedBitmap.pixelRef() == NULL);
+    SkAutoTUnref<SkLruImageCache> lruCache(SkNEW_ARGS(SkLruImageCache, (1024 * 1024)));
+    test_cache(reporter, lruCache, encodedBitmap, *bitmap.get());
+    test_cache(reporter, NULL, encodedBitmap, *bitmap.get());
+#ifdef SK_BUILD_FOR_ANDROID
+    test_cache(reporter, SkAshmemImageCache::GetAshmemImageCache(), encodedBitmap, *bitmap.get());
+#endif
 }
 
 #include "TestClassDef.h"
 DEFINE_TESTCLASS("BitmapFactory", TestBitmapFactoryClass, TestBitmapFactory)
+
+#endif // SK_DEBUG