Add SkImageGenerator Interface

-   Add SkDiscardablePixelRef class that uses SkDiscardableMemory and
    a SkImageGenerator.

-   Add SkDecodingImageGenerator class as an example of a
    SkImageGenerator.

-   Add DecodingImageGenerator unit test.

-   Add SkBasicDiscardableMemory implmentation for unit tests only.

R=reed@google.com, scroggo@google.com

Review URL: https://codereview.chromium.org/74793011

git-svn-id: http://skia.googlecode.com/svn/trunk@12341 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/lazy/SkDiscardablePixelRef.cpp b/src/lazy/SkDiscardablePixelRef.cpp
new file mode 100644
index 0000000..b6e1b10
--- /dev/null
+++ b/src/lazy/SkDiscardablePixelRef.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkDiscardablePixelRef.h"
+#include "SkDiscardableMemory.h"
+
+SkDiscardablePixelRef::SkDiscardablePixelRef(SkImageGenerator* generator,
+                                             const SkImageInfo& info,
+                                             size_t size,
+                                             size_t rowBytes)
+    : fGenerator(generator)
+    , fInfo(info)
+    , fSize(size)
+    , fRowBytes(rowBytes)
+    , fDiscardableMemory(NULL) {
+    SkASSERT(fGenerator != NULL);
+    SkASSERT(fSize > 0);
+    SkASSERT(fRowBytes > 0);
+}
+
+SkDiscardablePixelRef::~SkDiscardablePixelRef() {
+    SkDELETE(fGenerator);
+}
+
+void* SkDiscardablePixelRef::onLockPixels(SkColorTable**) {
+    if (fDiscardableMemory != NULL) {
+        if (fDiscardableMemory->lock()) {
+            return fDiscardableMemory->data();
+        }
+        fDiscardableMemory = NULL;
+    }
+    fDiscardableMemory = SkDiscardableMemory::Create(fSize);
+    if (NULL == fDiscardableMemory) {
+        return NULL;  // Memory allocation failed.
+    }
+    void* pixels = fDiscardableMemory->data();
+    if (!fGenerator->getPixels(fInfo, pixels, fRowBytes)) {
+        return NULL;  // TODO(halcanary) Find out correct thing to do.
+    }
+    return pixels;
+}
+void SkDiscardablePixelRef::onUnlockPixels() {
+    if (fDiscardableMemory != NULL) {
+        fDiscardableMemory->unlock();
+    }
+}
+
+bool SkDiscardablePixelRef::Install(SkImageGenerator* generator,
+                                    SkBitmap* dst) {
+    SkImageInfo info;
+    SkASSERT(generator != NULL);
+    if ((NULL == generator)
+        || (!generator->getInfo(&info))
+        || (!dst->setConfig(info, 0))) {
+        SkDELETE(generator);
+        return false;
+    }
+    SkAutoTUnref<SkDiscardablePixelRef> ref(SkNEW_ARGS(SkDiscardablePixelRef,
+                                                   (generator, info,
+                                                    dst->getSize(),
+                                                    dst->rowBytes())));
+    dst->setPixelRef(ref);
+    return true;
+}