Revert "PixelRef now returns (nearly) everything that is currently in SkBitmap. The goal is to refactor bitmap later to remove redundancy, and more interestingly, remove the chance for a disconnect between the actual (pixelref) rowbytes and config, and the one claimed by the bitmap."""""

This reverts commit d08eca87a0bef10112a211de540f89656a80b86a.

BUG=

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

git-svn-id: http://skia.googlecode.com/svn/trunk/src@12623 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkBitmap.cpp b/core/SkBitmap.cpp
index b529617..25a6b1d 100644
--- a/core/SkBitmap.cpp
+++ b/core/SkBitmap.cpp
@@ -453,20 +453,10 @@
         return;
     }
 
-    SkImageInfo info;
-    if (!this->asImageInfo(&info)) {
-        this->setPixelRef(NULL, 0);
-        return;
-    }
+    Sk64 size = this->getSize64();
+    SkASSERT(!size.isNeg() && size.is32());
 
-    SkPixelRef* pr = SkMallocPixelRef::NewDirect(info, p, fRowBytes, ctable);
-    if (NULL == pr) {
-        this->setPixelRef(NULL, 0);
-        return;
-    }
-
-    this->setPixelRef(pr)->unref();
-
+    this->setPixelRef(new SkMallocPixelRef(p, size.get32(), ctable, false))->unref();
     // since we're already allocated, we lockPixels right away
     this->lockPixels();
     SkDEBUGCODE(this->validate();)
@@ -531,19 +521,17 @@
  */
 bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst,
                                             SkColorTable* ctable) {
-    SkImageInfo info;
-    if (!dst->asImageInfo(&info)) {
-//        SkDebugf("unsupported config for info %d\n", dst->config());
-        return false;
-    }
-    
-    SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, dst->rowBytes(),
-                                                   ctable);
-    if (NULL == pr) {
+    Sk64 size = dst->getSize64();
+    if (size.isNeg() || !size.is32()) {
         return false;
     }
 
-    dst->setPixelRef(pr, 0)->unref();
+    void* addr = sk_malloc_flags(size.get32(), 0);  // returns NULL on failure
+    if (NULL == addr) {
+        return false;
+    }
+
+    dst->setPixelRef(new SkMallocPixelRef(addr, size.get32(), ctable))->unref();
     // since we're already allocated, we lockPixels right away
     dst->lockPixels();
     return true;
@@ -1653,28 +1641,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkImageInfo::unflatten(SkFlattenableReadBuffer& buffer) {
-    fWidth = buffer.read32();
-    fHeight = buffer.read32();
-
-    uint32_t packed = buffer.read32();
-    SkASSERT(0 == (packed >> 16));
-    fAlphaType = (SkAlphaType)((packed >> 8) & 0xFF);
-    fColorType = (SkColorType)((packed >> 0) & 0xFF);
-}
-
-void SkImageInfo::flatten(SkFlattenableWriteBuffer& buffer) const {
-    buffer.write32(fWidth);
-    buffer.write32(fHeight);
-
-    SkASSERT(0 == (fAlphaType & ~0xFF));
-    SkASSERT(0 == (fColorType & ~0xFF));
-    uint32_t packed = (fAlphaType << 8) | fColorType;
-    buffer.write32(packed);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
 #ifdef SK_DEBUG
 void SkBitmap::validate() const {
     SkASSERT(fConfig < kConfigCount);
diff --git a/core/SkBitmapDevice.cpp b/core/SkBitmapDevice.cpp
index 368c807..1668618 100644
--- a/core/SkBitmapDevice.cpp
+++ b/core/SkBitmapDevice.cpp
@@ -24,30 +24,31 @@
     , fBitmap(bitmap) {
 }
 
-void SkBitmapDevice::init(SkBitmap::Config config, int width, int height, bool isOpaque) {
+SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque) {
     fBitmap.setConfig(config, width, height, 0, isOpaque ?
                       kOpaque_SkAlphaType : kPremul_SkAlphaType);
-    
-    if (SkBitmap::kNo_Config != config) {
-        if (!fBitmap.allocPixels()) {
-            // indicate failure by zeroing our bitmap
-            fBitmap.setConfig(config, 0, 0, 0, isOpaque ?
-                              kOpaque_SkAlphaType : kPremul_SkAlphaType);
-        } else if (!isOpaque) {
-            fBitmap.eraseColor(SK_ColorTRANSPARENT);
-        }
+    if (!fBitmap.allocPixels()) {
+        fBitmap.setConfig(config, 0, 0, 0, isOpaque ?
+                          kOpaque_SkAlphaType : kPremul_SkAlphaType);
     }
-}
-
-SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque) {
-    this->init(config, width, height, isOpaque);
+    if (!isOpaque) {
+        fBitmap.eraseColor(SK_ColorTRANSPARENT);
+    }
 }
 
 SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque,
                                const SkDeviceProperties& deviceProperties)
-    : SkBaseDevice(deviceProperties)
-{
-    this->init(config, width, height, isOpaque);
+    : SkBaseDevice(deviceProperties) {
+
+    fBitmap.setConfig(config, width, height, 0, isOpaque ?
+                      kOpaque_SkAlphaType : kPremul_SkAlphaType);
+    if (!fBitmap.allocPixels()) {
+        fBitmap.setConfig(config, 0, 0, 0, isOpaque ?
+                          kOpaque_SkAlphaType : kPremul_SkAlphaType);
+    }
+    if (!isOpaque) {
+        fBitmap.eraseColor(SK_ColorTRANSPARENT);
+    }
 }
 
 SkBitmapDevice::~SkBitmapDevice() {
diff --git a/core/SkImageFilterUtils.cpp b/core/SkImageFilterUtils.cpp
index e535d93..8385fb4 100644
--- a/core/SkImageFilterUtils.cpp
+++ b/core/SkImageFilterUtils.cpp
@@ -15,14 +15,8 @@
 #include "SkGr.h"
 
 bool SkImageFilterUtils::WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result) {
-    SkImageInfo info;
-    info.fWidth = width;
-    info.fHeight = height;
-    info.fColorType = kPMColor_SkColorType;
-    info.fAlphaType = kPremul_SkAlphaType;
-
-    result->setConfig(info);
-    result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
+    result->setConfig(SkBitmap::kARGB_8888_Config, width, height);
+    result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (texture)))->unref();
     return true;
 }
 
@@ -42,12 +36,8 @@
     } else {
         if (filter->filterImage(proxy, src, ctm, result, offset)) {
             if (!result->getTexture()) {
-                SkImageInfo info;
-                if (!result->asImageInfo(&info)) {
-                    return false;
-                }
                 GrTexture* resultTex = GrLockAndRefCachedBitmapTexture(context, *result, NULL);
-                result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref();
+                result->setPixelRef(new SkGrPixelRef(resultTex))->unref();
                 GrUnlockAndUnrefCachedBitmapTexture(resultTex);
             }
             return true;
diff --git a/core/SkMallocPixelRef.cpp b/core/SkMallocPixelRef.cpp
index 613491a..f229e9d 100644
--- a/core/SkMallocPixelRef.cpp
+++ b/core/SkMallocPixelRef.cpp
@@ -1,105 +1,27 @@
+
 /*
  * Copyright 2011 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-
 #include "SkMallocPixelRef.h"
 #include "SkBitmap.h"
 #include "SkFlattenableBuffers.h"
 
-static bool check_info(const SkImageInfo& info, SkColorTable* ctable) {
-    if (info.fWidth < 0 ||
-        info.fHeight < 0 ||
-        (unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType ||
-        (unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType)
-    {
-        return false;
+SkMallocPixelRef::SkMallocPixelRef(void* storage, size_t size,
+                                   SkColorTable* ctable, bool ownPixels) {
+    if (NULL == storage) {
+        SkASSERT(ownPixels);
+        storage = sk_malloc_throw(size);
     }
-    
-    // these seem like good checks, but currently we have (at least) tests
-    // that expect the pixelref to succeed even when there is a mismatch
-    // with colortables. fix?
-#if 0
-    if (kIndex8_SkColorType == info.fColorType && NULL == ctable) {
-        return false;
-    }
-    if (kIndex8_SkColorType != info.fColorType && NULL != ctable) {
-        return false;
-    }
-#endif
-    return true;
-}
-
-SkMallocPixelRef* SkMallocPixelRef::NewDirect(const SkImageInfo& info,
-                                              void* addr,
-                                              size_t rowBytes,
-                                              SkColorTable* ctable) {
-    if (!check_info(info, ctable)) {
-        return NULL;
-    }
-    return SkNEW_ARGS(SkMallocPixelRef, (info, addr, rowBytes, ctable, false));
-}
-
-SkMallocPixelRef* SkMallocPixelRef::NewAllocate(const SkImageInfo& info,
-                                                size_t requestedRowBytes,
-                                                SkColorTable* ctable) {
-    if (!check_info(info, ctable)) {
-        return NULL;
-    }
-
-    int32_t minRB = info.minRowBytes();
-    if (minRB < 0) {
-        return NULL;    // allocation will be too large
-    }
-    if (requestedRowBytes > 0 && (int32_t)requestedRowBytes < minRB) {
-        return NULL;    // cannot meet requested rowbytes
-    }
-
-    int32_t rowBytes;
-    if (requestedRowBytes) {
-        rowBytes = requestedRowBytes;
-    } else {
-        rowBytes = minRB;
-    }
-
-    Sk64 bigSize;
-    bigSize.setMul(info.fHeight, rowBytes);
-    if (!bigSize.is32()) {
-        return NULL;
-    }
-
-    size_t size = bigSize.get32();
-    void* addr = sk_malloc_flags(size, 0);
-    if (NULL == addr) {
-        return NULL;
-    }
-
-    return SkNEW_ARGS(SkMallocPixelRef, (info, addr, rowBytes, ctable, true));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage,
-                                   size_t rowBytes, SkColorTable* ctable,
-                                   bool ownsPixels)
-    : SkPixelRef(info)
-    , fOwnPixels(ownsPixels)
-{
-    SkASSERT(check_info(info, ctable));
-    SkASSERT(rowBytes >= info.minRowBytes());
-
-    if (kIndex_8_SkColorType != info.fColorType) {
-        ctable = NULL;
-    }
-
     fStorage = storage;
+    fSize = size;
     fCTable = ctable;
-    fRB = rowBytes;
     SkSafeRef(ctable);
-    
-    this->setPreLocked(fStorage, fRB, fCTable);
+    fOwnPixels = ownPixels;
+
+    this->setPreLocked(fStorage, fCTable);
 }
 
 SkMallocPixelRef::~SkMallocPixelRef() {
@@ -109,30 +31,19 @@
     }
 }
 
-bool SkMallocPixelRef::onNewLockPixels(LockRec* rec) {
-    rec->fPixels = fStorage;
-    rec->fRowBytes = fRB;
-    rec->fColorTable = fCTable;
-    return true;
+void* SkMallocPixelRef::onLockPixels(SkColorTable** ct) {
+    *ct = fCTable;
+    return fStorage;
 }
 
 void SkMallocPixelRef::onUnlockPixels() {
     // nothing to do
 }
 
-size_t SkMallocPixelRef::getAllocatedSizeInBytes() const {
-    return this->info().getSafeSize(fRB);
-}
-
 void SkMallocPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
 
-    buffer.write32(fRB);
-
-    // TODO: replace this bulk write with a chunky one that can trim off any
-    // trailing bytes on each scanline (in case rowbytes > width*size)
-    size_t size = this->info().getSafeSize(fRB);
-    buffer.writeByteArray(fStorage, size);
+    buffer.writeByteArray(fStorage, fSize);
     buffer.writeBool(fCTable != NULL);
     if (fCTable) {
         fCTable->writeToBuffer(buffer);
@@ -140,18 +51,16 @@
 }
 
 SkMallocPixelRef::SkMallocPixelRef(SkFlattenableReadBuffer& buffer)
-    : INHERITED(buffer, NULL)
-    , fOwnPixels(true)
-{
-    fRB = buffer.read32();
-    size_t size = this->info().getSafeSize(fRB);
-    fStorage = sk_malloc_throw(size);
-    buffer.readByteArray(fStorage, size);
+        : INHERITED(buffer, NULL) {
+    fSize = buffer.getArrayCount();
+    fStorage = sk_malloc_throw(fSize);
+    buffer.readByteArray(fStorage, fSize);
     if (buffer.readBool()) {
         fCTable = SkNEW_ARGS(SkColorTable, (buffer));
     } else {
         fCTable = NULL;
     }
+    fOwnPixels = true;
 
-    this->setPreLocked(fStorage, fRB, fCTable);
+    this->setPreLocked(fStorage, fCTable);
 }
diff --git a/core/SkMaskFilter.cpp b/core/SkMaskFilter.cpp
index adfed41..f062f13 100644
--- a/core/SkMaskFilter.cpp
+++ b/core/SkMaskFilter.cpp
@@ -349,14 +349,10 @@
     if (!result) {
         return false;
     }
-    SkAutoUnref aur(dst);
 
-    SkImageInfo info;
     resultBM->setConfig(srcBM.config(), dst->width(), dst->height());
-    if (resultBM->asImageInfo(&info)) {
-        return false;
-    }
-    resultBM->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, dst)))->unref();
+    resultBM->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (dst)))->unref();
+    dst->unref();
     return true;
 }
 
diff --git a/core/SkPixelRef.cpp b/core/SkPixelRef.cpp
index 60b5cfb..b5daf0b 100644
--- a/core/SkPixelRef.cpp
+++ b/core/SkPixelRef.cpp
@@ -82,32 +82,44 @@
 // just need a > 0 value, so pick a funny one to aid in debugging
 #define SKPIXELREF_PRELOCKED_LOCKCOUNT     123456789
 
-SkPixelRef::SkPixelRef(const SkImageInfo& info) {
-    this->setMutex(NULL);
-    fInfo = info;
-    fRec.zero();
+SkPixelRef::SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex) {
+    this->setMutex(mutex);
+    fPixels = NULL;
+    fColorTable = NULL; // we do not track ownership of this
     fLockCount = 0;
     this->needsNewGenID();
     fIsImmutable = false;
     fPreLocked = false;
 }
 
-SkPixelRef::SkPixelRef(const SkImageInfo& info, SkBaseMutex* mutex) {
-    this->setMutex(mutex);
-    fInfo = info;
-    fRec.zero();
+SkPixelRef::SkPixelRef(const SkImageInfo&) {
+    this->setMutex(NULL);
+    fPixels = NULL;
+    fColorTable = NULL; // we do not track ownership of this
     fLockCount = 0;
     this->needsNewGenID();
     fIsImmutable = false;
     fPreLocked = false;
 }
 
+#ifdef SK_SUPPORT_LEGACY_PIXELREF_CONSTRUCTOR
+// THIS GUY IS DEPRECATED -- don't use me!
+SkPixelRef::SkPixelRef(SkBaseMutex* mutex) {
+    this->setMutex(mutex);
+    fPixels = NULL;
+    fColorTable = NULL; // we do not track ownership of this
+    fLockCount = 0;
+    this->needsNewGenID();
+    fIsImmutable = false;
+    fPreLocked = false;
+}
+#endif
+
 SkPixelRef::SkPixelRef(SkFlattenableReadBuffer& buffer, SkBaseMutex* mutex)
         : INHERITED(buffer) {
     this->setMutex(mutex);
-
-    fInfo.unflatten(buffer);
-    fRec.zero();
+    fPixels = NULL;
+    fColorTable = NULL; // we do not track ownership of this
     fLockCount = 0;
     fIsImmutable = buffer.readBool();
     fGenerationID = buffer.readUInt();
@@ -131,13 +143,12 @@
     that.fUniqueGenerationID = false;
 }
 
-void SkPixelRef::setPreLocked(void* pixels, size_t rowBytes, SkColorTable* ctable) {
+void SkPixelRef::setPreLocked(void* pixels, SkColorTable* ctable) {
 #ifndef SK_IGNORE_PIXELREF_SETPRELOCKED
     // only call me in your constructor, otherwise fLockCount tracking can get
     // out of sync.
-    fRec.fPixels = pixels;
-    fRec.fColorTable = ctable;
-    fRec.fRowBytes = rowBytes;
+    fPixels = pixels;
+    fColorTable = ctable;
     fLockCount = SKPIXELREF_PRELOCKED_LOCKCOUNT;
     fPreLocked = true;
 #endif
@@ -145,8 +156,6 @@
 
 void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-
-    fInfo.flatten(buffer);
     buffer.writeBool(fIsImmutable);
     // We write the gen ID into the picture for within-process recording. This
     // is safe since the same genID will never refer to two different sets of
@@ -161,27 +170,16 @@
     }
 }
 
-bool SkPixelRef::lockPixels(LockRec* rec) {
+void SkPixelRef::lockPixels() {
     SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount);
-    
+
     if (!fPreLocked) {
         SkAutoMutexAcquire  ac(*fMutex);
-        
+
         if (1 == ++fLockCount) {
-            LockRec rec;
-            if (!this->onNewLockPixels(&rec)) {
-                return false;
-            }
-            fRec = rec;
+            fPixels = this->onLockPixels(&fColorTable);
         }
     }
-    *rec = fRec;
-    return true;
-}
-
-bool SkPixelRef::lockPixels() {
-    LockRec rec;
-    return this->lockPixels(&rec);
 }
 
 void SkPixelRef::unlockPixels() {
@@ -193,7 +191,8 @@
         SkASSERT(fLockCount > 0);
         if (0 == --fLockCount) {
             this->onUnlockPixels();
-            fRec.zero();
+            fPixels = NULL;
+            fColorTable = NULL;
         }
     }
 }
@@ -274,29 +273,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-#ifdef SK_SUPPORT_LEGACY_ONLOCKPIXELS
-
-void* SkPixelRef::onLockPixels(SkColorTable** ctable) {
-    return NULL;
-}
-
-bool SkPixelRef::onNewLockPixels(LockRec* rec) {
-    SkColorTable* ctable;
-    void* pixels = this->onLockPixels(&ctable);
-    if (!pixels) {
-        return false;
-    }
-
-    rec->fPixels = pixels;
-    rec->fColorTable = ctable;
-    rec->fRowBytes = 0; // callers don't currently need this (thank goodness)
-    return true;
-}
-
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
 #ifdef SK_BUILD_FOR_ANDROID
 void SkPixelRef::globalRef(void* data) {
     this->ref();
diff --git a/effects/gradients/SkGradientShader.cpp b/effects/gradients/SkGradientShader.cpp
index 5d200d1..2776199 100644
--- a/effects/gradients/SkGradientShader.cpp
+++ b/effects/gradients/SkGradientShader.cpp
@@ -513,14 +513,13 @@
 
 const SkPMColor* SkGradientShaderBase::getCache32() const {
     if (fCache32 == NULL) {
-        SkImageInfo info;
-        info.fWidth = kCache32Count;
-        info.fHeight = 4;   // for our 4 dither rows
-        info.fAlphaType = kPremul_SkAlphaType;
-        info.fColorType = kPMColor_SkColorType;
+        // double the count for dither entries
+        const int entryCount = kCache32Count * 4;
+        const size_t allocSize = sizeof(SkPMColor) * entryCount;
 
         if (NULL == fCache32PixelRef) {
-            fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL);
+            fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef,
+                                          (NULL, allocSize, NULL));
         }
         fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
         if (fColorCount == 2) {
@@ -542,7 +541,8 @@
         }
 
         if (fMapper) {
-            SkMallocPixelRef* newPR = SkMallocPixelRef::NewAllocate(info, 0, NULL);
+            SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef,
+                                                 (NULL, allocSize, NULL));
             SkPMColor* linear = fCache32;           // just computed linear data
             SkPMColor* mapped = (SkPMColor*)newPR->getAddr();    // storage for mapped data
             SkUnitMapper* map = fMapper;
diff --git a/gpu/GrSurface.cpp b/gpu/GrSurface.cpp
index 1fcc4ff..fed95f2 100644
--- a/gpu/GrSurface.cpp
+++ b/gpu/GrSurface.cpp
@@ -8,19 +8,9 @@
 #include "GrSurface.h"
 
 #include "SkBitmap.h"
-#include "SkGr.h"
 #include "SkImageEncoder.h"
 #include <stdio.h>
 
-void GrSurface::asImageInfo(SkImageInfo* info) const {
-    if (!GrPixelConfig2ColorType(this->config(), &info->fColorType)) {
-        sk_throw();
-    }
-    info->fWidth = this->width();
-    info->fHeight = this->height();
-    info->fAlphaType = kPremul_SkAlphaType;
-}
-
 bool GrSurface::savePixels(const char* filename) {
     SkBitmap bm;
     bm.setConfig(SkBitmap::kARGB_8888_Config, this->width(), this->height());
diff --git a/gpu/SkGpuDevice.cpp b/gpu/SkGpuDevice.cpp
index a413d04..ce02f2c 100644
--- a/gpu/SkGpuDevice.cpp
+++ b/gpu/SkGpuDevice.cpp
@@ -214,10 +214,7 @@
     if (NULL == surface) {
         surface = fRenderTarget;
     }
-
-    SkImageInfo info;
-    surface->asImageInfo(&info);
-    SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface, cached));
+    SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (surface, cached));
 
     this->setPixelRef(pr, 0)->unref();
 }
@@ -227,8 +224,8 @@
                          int width,
                          int height,
                          int sampleCount)
-    : SkBitmapDevice(make_bitmap(config, width, height, false /*isOpaque*/))
-{
+    : SkBitmapDevice(make_bitmap(config, width, height, false /*isOpaque*/)) {
+
     fDrawProcs = NULL;
 
     fContext = context;
@@ -248,14 +245,6 @@
     desc.fConfig = SkBitmapConfig2GrPixelConfig(config);
     desc.fSampleCnt = sampleCount;
 
-    SkImageInfo info;
-    if (!GrPixelConfig2ColorType(desc.fConfig, &info.fColorType)) {
-        sk_throw();
-    }
-    info.fWidth = width;
-    info.fHeight = height;
-    info.fAlphaType = kPremul_SkAlphaType;
-        
     SkAutoTUnref<GrTexture> texture(fContext->createUncachedTexture(desc, NULL, 0));
 
     if (NULL != texture) {
@@ -265,7 +254,7 @@
         SkASSERT(NULL != fRenderTarget);
 
         // wrap the bitmap with a pixelref to expose our texture
-        SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, texture));
+        SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (texture));
         this->setPixelRef(pr, 0)->unref();
     } else {
         GrPrintf("--- failed to create gpu-offscreen [%d %d]\n",
@@ -851,12 +840,11 @@
 }
 
 SkBitmap wrap_texture(GrTexture* texture) {
-    SkImageInfo info;
-    texture->asImageInfo(&info);
-
     SkBitmap result;
-    result.setConfig(info);
-    result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
+    bool dummy;
+    SkBitmap::Config config = grConfig2skConfig(texture->config(), &dummy);
+    result.setConfig(config, texture->width(), texture->height());
+    result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (texture)))->unref();
     return result;
 }
 
diff --git a/gpu/SkGr.cpp b/gpu/SkGr.cpp
index a3f0eef..c7ae0c8 100644
--- a/gpu/SkGr.cpp
+++ b/gpu/SkGr.cpp
@@ -258,33 +258,3 @@
             return kUnknown_GrPixelConfig;
     }
 }
-
-bool GrPixelConfig2ColorType(GrPixelConfig config, SkColorType* ctOut) {
-    SkColorType ct;
-    switch (config) {
-        case kAlpha_8_GrPixelConfig:
-            ct = kAlpha_8_SkColorType;
-            break;
-        case kIndex_8_GrPixelConfig:
-            ct = kIndex_8_SkColorType;
-            break;
-        case kRGB_565_GrPixelConfig:
-            ct = kRGB_565_SkColorType;
-            break;
-        case kRGBA_4444_GrPixelConfig:
-            ct = kARGB_4444_SkColorType;
-            break;
-        case kRGBA_8888_GrPixelConfig:
-            ct = kRGBA_8888_SkColorType;
-            break;
-        case kBGRA_8888_GrPixelConfig:
-            ct = kBGRA_8888_SkColorType;
-            break;
-        default:
-            return false;
-    }
-    if (ctOut) {
-        *ctOut = ct;
-    }
-    return true;
-}
diff --git a/gpu/SkGrPixelRef.cpp b/gpu/SkGrPixelRef.cpp
index 74b1a4f..0129426 100644
--- a/gpu/SkGrPixelRef.cpp
+++ b/gpu/SkGrPixelRef.cpp
@@ -18,29 +18,24 @@
 // to avoid deadlock with the default one provided by SkPixelRef.
 SK_DECLARE_STATIC_MUTEX(gROLockPixelsPixelRefMutex);
 
-SkROLockPixelsPixelRef::SkROLockPixelsPixelRef(const SkImageInfo& info)
-    : INHERITED(info, &gROLockPixelsPixelRefMutex) {
+SkROLockPixelsPixelRef::SkROLockPixelsPixelRef() : INHERITED(&gROLockPixelsPixelRefMutex) {
 }
 
 SkROLockPixelsPixelRef::~SkROLockPixelsPixelRef() {
 }
 
-bool SkROLockPixelsPixelRef::onNewLockPixels(LockRec* rec) {
+void* SkROLockPixelsPixelRef::onLockPixels(SkColorTable** ctable) {
+    if (ctable) {
+        *ctable = NULL;
+    }
     fBitmap.reset();
 //    SkDebugf("---------- calling readpixels in support of lockpixels\n");
     if (!this->onReadPixels(&fBitmap, NULL)) {
         SkDebugf("SkROLockPixelsPixelRef::onLockPixels failed!\n");
-        return false;
+        return NULL;
     }
     fBitmap.lockPixels();
-    if (NULL == fBitmap.getPixels()) {
-        return false;
-    }
-
-    rec->fPixels = fBitmap.getPixels();
-    rec->fColorTable = NULL;
-    rec->fRowBytes = fBitmap.rowBytes();
-    return true;
+    return fBitmap.getPixels();
 }
 
 void SkROLockPixelsPixelRef::onUnlockPixels() {
@@ -81,14 +76,6 @@
     desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
     desc.fConfig = SkBitmapConfig2GrPixelConfig(dstConfig);
 
-    SkImageInfo info;
-    if (!GrPixelConfig2ColorType(desc.fConfig, &info.fColorType)) {
-        return NULL;
-    }
-    info.fWidth = desc.fWidth;
-    info.fHeight = desc.fHeight;
-    info.fAlphaType = kPremul_SkAlphaType;
-    
     GrTexture* dst = context->createUncachedTexture(desc, NULL, 0);
     if (NULL == dst) {
         return NULL;
@@ -106,17 +93,31 @@
     dst->releaseRenderTarget();
 #endif
 
-    SkGrPixelRef* pixelRef = SkNEW_ARGS(SkGrPixelRef, (info, dst));
+    SkGrPixelRef* pixelRef = SkNEW_ARGS(SkGrPixelRef, (dst));
     SkSafeUnref(dst);
     return pixelRef;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkGrPixelRef::SkGrPixelRef(const SkImageInfo& info, GrSurface* surface,
-                           bool transferCacheLock)
-    : INHERITED(info)
-{
+SkGrPixelRef::SkGrPixelRef(GrSurface* surface, bool transferCacheLock) {
+    // TODO: figure out if this is responsible for Chrome canvas errors
+#if 0
+    // The GrTexture has a ref to the GrRenderTarget but not vice versa.
+    // If the GrTexture exists take a ref to that (rather than the render
+    // target)
+    fSurface = surface->asTexture();
+#else
+    fSurface = NULL;
+#endif
+    if (NULL == fSurface) {
+        fSurface = surface;
+    }
+    fUnlock = transferCacheLock;
+    SkSafeRef(surface);
+}
+
+SkGrPixelRef::SkGrPixelRef(const SkImageInfo&, GrSurface* surface, bool transferCacheLock) {
     // TODO: figure out if this is responsible for Chrome canvas errors
 #if 0
     // The GrTexture has a ref to the GrRenderTarget but not vice versa.
diff --git a/image/SkDataPixelRef.cpp b/image/SkDataPixelRef.cpp
index 875f933..7897bf9 100644
--- a/image/SkDataPixelRef.cpp
+++ b/image/SkDataPixelRef.cpp
@@ -9,25 +9,18 @@
 #include "SkData.h"
 #include "SkFlattenableBuffers.h"
 
-SkDataPixelRef::SkDataPixelRef(const SkImageInfo& info,
-                               SkData* data, size_t rowBytes)
-    : INHERITED(info)
-    , fData(data)
-    , fRB(rowBytes) 
-{
+SkDataPixelRef::SkDataPixelRef(SkData* data) : fData(data) {
     fData->ref();
-    this->setPreLocked(const_cast<void*>(fData->data()), rowBytes, NULL);
+    this->setPreLocked(const_cast<void*>(fData->data()), NULL);
 }
 
 SkDataPixelRef::~SkDataPixelRef() {
     fData->unref();
 }
 
-bool SkDataPixelRef::onNewLockPixels(LockRec* rec) {
-    rec->fPixels = const_cast<void*>(fData->data());
-    rec->fColorTable = NULL;
-    rec->fRowBytes = fRB;
-    return true;
+void* SkDataPixelRef::onLockPixels(SkColorTable** ct) {
+    *ct = NULL;
+    return const_cast<void*>(fData->data());
 }
 
 void SkDataPixelRef::onUnlockPixels() {
@@ -40,15 +33,11 @@
 
 void SkDataPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-    
     buffer.writeDataAsByteArray(fData);
-    buffer.write32(fRB);
 }
 
 SkDataPixelRef::SkDataPixelRef(SkFlattenableReadBuffer& buffer)
-    : INHERITED(buffer, NULL)
-{
+        : INHERITED(buffer, NULL) {
     fData = buffer.readByteArrayAsData();
-    fRB = buffer.read32();
-    this->setPreLocked(const_cast<void*>(fData->data()), fRB, NULL);
+    this->setPreLocked(const_cast<void*>(fData->data()), NULL);
 }
diff --git a/image/SkDataPixelRef.h b/image/SkDataPixelRef.h
index c2e52cd..50c8857 100644
--- a/image/SkDataPixelRef.h
+++ b/image/SkDataPixelRef.h
@@ -14,13 +14,13 @@
 
 class SkDataPixelRef : public SkPixelRef {
 public:
-            SkDataPixelRef(const SkImageInfo&, SkData* data, size_t rowBytes);
+            SkDataPixelRef(SkData* data);
     virtual ~SkDataPixelRef();
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDataPixelRef)
 
 protected:
-    virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
+    virtual void* onLockPixels(SkColorTable**) SK_OVERRIDE;
     virtual void onUnlockPixels() SK_OVERRIDE;
     virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE;
 
@@ -28,8 +28,7 @@
     virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
 
 private:
-    SkData*     fData;
-    size_t      fRB;
+    SkData* fData;
 
     typedef SkPixelRef INHERITED;
 };
diff --git a/image/SkImage_Raster.cpp b/image/SkImage_Raster.cpp
index 93de5ea..a872ae3 100644
--- a/image/SkImage_Raster.cpp
+++ b/image/SkImage_Raster.cpp
@@ -84,8 +84,10 @@
 
 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
         : INHERITED(info.fWidth, info.fHeight) {
-    fBitmap.setConfig(info, rowBytes);
-    fBitmap.setPixelRef(SkNEW_ARGS(SkDataPixelRef, (info, data, rowBytes)))->unref();
+    SkBitmap::Config config = SkImageInfoToBitmapConfig(info);
+
+    fBitmap.setConfig(config, info.fWidth, info.fHeight, rowBytes, info.fAlphaType);
+    fBitmap.setPixelRef(SkNEW_ARGS(SkDataPixelRef, (data)))->unref();
     fBitmap.setImmutable();
 }
 
diff --git a/image/SkSurface_Raster.cpp b/image/SkSurface_Raster.cpp
index 61ade6f..27db504 100644
--- a/image/SkSurface_Raster.cpp
+++ b/image/SkSurface_Raster.cpp
@@ -155,9 +155,19 @@
         return NULL;
     }
 
-    SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewAllocate(info, 0, NULL));
-    if (NULL == pr.get()) {
+    static const size_t kMaxTotalSize = SK_MaxS32;
+    size_t rowBytes = SkImageMinRowBytes(info);
+    uint64_t size64 = (uint64_t)info.fHeight * rowBytes;
+    if (size64 > kMaxTotalSize) {
         return NULL;
     }
-    return SkNEW_ARGS(SkSurface_Raster, (info, pr, info.minRowBytes()));
+
+    size_t size = (size_t)size64;
+    void* pixels = sk_malloc_throw(size);
+    if (NULL == pixels) {
+        return NULL;
+    }
+
+    SkAutoTUnref<SkPixelRef> pr(SkNEW_ARGS(SkMallocPixelRef, (pixels, size, NULL, true)));
+    return SkNEW_ARGS(SkSurface_Raster, (info, pr, rowBytes));
 }
diff --git a/images/SkImageRef.cpp b/images/SkImageRef.cpp
index 99782c4..1a8284b 100644
--- a/images/SkImageRef.cpp
+++ b/images/SkImageRef.cpp
@@ -15,14 +15,16 @@
 
 //#define DUMP_IMAGEREF_LIFECYCLE
 
+
 ///////////////////////////////////////////////////////////////////////////////
 
-SkImageRef::SkImageRef(const SkImageInfo& info, SkStreamRewindable* stream,
+SkImageRef::SkImageRef(SkStreamRewindable* stream, SkBitmap::Config config,
                        int sampleSize, SkBaseMutex* mutex)
-        : INHERITED(info, mutex), fErrorInDecoding(false) {
+        : SkPixelRef(mutex), fErrorInDecoding(false) {
     SkASSERT(stream);
     stream->ref();
     fStream = stream;
+    fConfig = config;
     fSampleSize = sampleSize;
     fDoDither = true;
     fPrev = fNext = NULL;
@@ -38,7 +40,7 @@
 
 #ifdef DUMP_IMAGEREF_LIFECYCLE
     SkDebugf("delete ImageRef %p [%d] data=%d\n",
-              this, this->info().fColorType, (int)fStream->getLength());
+              this, fConfig, (int)fStream->getLength());
 #endif
 
     fStream->unref();
@@ -90,6 +92,14 @@
         return false;
     }
 
+    /*  As soon as we really know our config, we record it, so that on
+        subsequent calls to the codec, we are sure we will always get the same
+        result.
+    */
+    if (SkBitmap::kNo_Config != fBitmap.config()) {
+        fConfig = fBitmap.config();
+    }
+
     if (NULL != fBitmap.getPixels() ||
             (SkBitmap::kNo_Config != fBitmap.config() &&
              SkImageDecoder::kDecodeBounds_Mode == mode)) {
@@ -115,7 +125,7 @@
 
         codec->setSampleSize(fSampleSize);
         codec->setDitherImage(fDoDither);
-        if (this->onDecode(codec, fStream, &fBitmap, fBitmap.config(), mode)) {
+        if (this->onDecode(codec, fStream, &fBitmap, fConfig, mode)) {
             return true;
         }
     }
@@ -133,18 +143,15 @@
     return false;
 }
 
-bool SkImageRef::onNewLockPixels(LockRec* rec) {
+void* SkImageRef::onLockPixels(SkColorTable** ct) {
     if (NULL == fBitmap.getPixels()) {
         (void)this->prepareBitmap(SkImageDecoder::kDecodePixels_Mode);
     }
 
-    if (NULL == fBitmap.getPixels()) {
-        return false;
+    if (ct) {
+        *ct = fBitmap.getColorTable();
     }
-    rec->fPixels = fBitmap.getPixels();
-    rec->fColorTable = NULL;
-    rec->fRowBytes = fBitmap.rowBytes();
-    return true;
+    return fBitmap.getPixels();
 }
 
 size_t SkImageRef::ramUsed() const {
@@ -163,6 +170,7 @@
 
 SkImageRef::SkImageRef(SkFlattenableReadBuffer& buffer, SkBaseMutex* mutex)
         : INHERITED(buffer, mutex), fErrorInDecoding(false) {
+    fConfig = (SkBitmap::Config)buffer.readUInt();
     fSampleSize = buffer.readInt();
     fDoDither = buffer.readBool();
 
@@ -177,6 +185,7 @@
 void SkImageRef::flatten(SkFlattenableWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
 
+    buffer.writeUInt(fConfig);
     buffer.writeInt(fSampleSize);
     buffer.writeBool(fDoDither);
     // FIXME: Consider moving this logic should go into writeStream itself.
diff --git a/images/SkImageRef_GlobalPool.cpp b/images/SkImageRef_GlobalPool.cpp
index f91ceba..352dd42 100644
--- a/images/SkImageRef_GlobalPool.cpp
+++ b/images/SkImageRef_GlobalPool.cpp
@@ -24,10 +24,10 @@
     return gPool;
 }
 
-SkImageRef_GlobalPool::SkImageRef_GlobalPool(const SkImageInfo& info,
-                                             SkStreamRewindable* stream,
+SkImageRef_GlobalPool::SkImageRef_GlobalPool(SkStreamRewindable* stream,
+                                             SkBitmap::Config config,
                                              int sampleSize)
-        : SkImageRef(info, stream, sampleSize, &gGlobalPoolMutex) {
+        : SkImageRef(stream, config, sampleSize, &gGlobalPoolMutex) {
     SkASSERT(&gGlobalPoolMutex == this->mutex());
     SkAutoMutexAcquire ac(gGlobalPoolMutex);
     GetGlobalPool()->addToHead(this);
diff --git a/images/SkImageRef_ashmem.cpp b/images/SkImageRef_ashmem.cpp
index 383a487..0dba1d1 100644
--- a/images/SkImageRef_ashmem.cpp
+++ b/images/SkImageRef_ashmem.cpp
@@ -31,10 +31,10 @@
     return newsize;
 }
 
-SkImageRef_ashmem::SkImageRef_ashmem(const SkImageInfo& info,
-                                     SkStreamRewindable* stream,
-                                     int sampleSize)
-        : SkImageRef(info, stream, sampleSize) {
+SkImageRef_ashmem::SkImageRef_ashmem(SkStreamRewindable* stream,
+                                             SkBitmap::Config config,
+                                             int sampleSize)
+        : SkImageRef(stream, config, sampleSize) {
 
     fRec.fFD = -1;
     fRec.fAddr = NULL;
diff --git a/images/SkImageRef_ashmem.h b/images/SkImageRef_ashmem.h
index a2652fb..efee5e7 100644
--- a/images/SkImageRef_ashmem.h
+++ b/images/SkImageRef_ashmem.h
@@ -19,7 +19,7 @@
 
 class SkImageRef_ashmem : public SkImageRef {
 public:
-    SkImageRef_ashmem(const SkImageInfo&, SkStreamRewindable*, int sampleSize = 1);
+    SkImageRef_ashmem(SkStreamRewindable*, SkBitmap::Config, int sampleSize = 1);
     virtual ~SkImageRef_ashmem();
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkImageRef_ashmem)
diff --git a/lazy/SkCachingPixelRef.cpp b/lazy/SkCachingPixelRef.cpp
index fba9845..667a949 100644
--- a/lazy/SkCachingPixelRef.cpp
+++ b/lazy/SkCachingPixelRef.cpp
@@ -8,6 +8,7 @@
 #include "SkCachingPixelRef.h"
 #include "SkScaledImageCache.h"
 
+
 bool SkCachingPixelRef::Install(SkImageGenerator* generator,
                                 SkBitmap* dst) {
     SkImageInfo info;
@@ -30,10 +31,10 @@
 SkCachingPixelRef::SkCachingPixelRef(SkImageGenerator* generator,
                                      const SkImageInfo& info,
                                      size_t rowBytes)
-    : INHERITED(info)
-    , fImageGenerator(generator)
+    : fImageGenerator(generator)
     , fErrorInDecoding(false)
     , fScaledCacheId(NULL)
+    , fInfo(info)
     , fRowBytes(rowBytes) {
     SkASSERT(fImageGenerator != NULL);
 }
@@ -43,32 +44,31 @@
     // Assert always unlock before unref.
 }
 
-bool SkCachingPixelRef::onNewLockPixels(LockRec* rec) {
+void* SkCachingPixelRef::onLockPixels(SkColorTable** colorTable) {
+    (void)colorTable;
     if (fErrorInDecoding) {
-        return false;  // don't try again.
+        return NULL;  // don't try again.
     }
-    
-    const SkImageInfo& info = this->info();
     SkBitmap bitmap;
     SkASSERT(NULL == fScaledCacheId);
     fScaledCacheId = SkScaledImageCache::FindAndLock(this->getGenerationID(),
-                                                     info.fWidth,
-                                                     info.fHeight,
+                                                     fInfo.fWidth,
+                                                     fInfo.fHeight,
                                                      &bitmap);
     if (NULL == fScaledCacheId) {
         // Cache has been purged, must re-decode.
-        if ((!bitmap.setConfig(info, fRowBytes)) || !bitmap.allocPixels()) {
+        if ((!bitmap.setConfig(fInfo, fRowBytes)) || !bitmap.allocPixels()) {
             fErrorInDecoding = true;
-            return false;
+            return NULL;
         }
         SkAutoLockPixels autoLockPixels(bitmap);
-        if (!fImageGenerator->getPixels(info, bitmap.getPixels(), fRowBytes)) {
+        if (!fImageGenerator->getPixels(fInfo, bitmap.getPixels(), fRowBytes)) {
             fErrorInDecoding = true;
-            return false;
+            return NULL;
         }
         fScaledCacheId = SkScaledImageCache::AddAndLock(this->getGenerationID(),
-                                                        info.fWidth,
-                                                        info.fHeight,
+                                                        fInfo.fWidth,
+                                                        fInfo.fHeight,
                                                         bitmap);
         SkASSERT(fScaledCacheId != NULL);
     }
@@ -78,7 +78,6 @@
     SkAutoLockPixels autoLockPixels(bitmap);
     void* pixels = bitmap.getPixels();
     SkASSERT(pixels != NULL);
-    
     // At this point, the autoLockPixels will unlockPixels()
     // to remove bitmap's lock on the pixels.  We will then
     // destroy bitmap.  The *only* guarantee that this pointer
@@ -87,10 +86,7 @@
     // bitmap (SkScaledImageCache::Rec.fBitmap) that holds a
     // reference to the concrete PixelRef while this record is
     // locked.
-    rec->fPixels = pixels;
-    rec->fColorTable = NULL;
-    rec->fRowBytes = bitmap.rowBytes();
-    return true;
+    return pixels;
 }
 
 void SkCachingPixelRef::onUnlockPixels() {
diff --git a/lazy/SkCachingPixelRef.h b/lazy/SkCachingPixelRef.h
index 75710d8..4a0387d 100644
--- a/lazy/SkCachingPixelRef.h
+++ b/lazy/SkCachingPixelRef.h
@@ -40,7 +40,7 @@
 
 protected:
     virtual ~SkCachingPixelRef();
-    virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
+    virtual void* onLockPixels(SkColorTable** colorTable) SK_OVERRIDE;
     virtual void onUnlockPixels() SK_OVERRIDE;
     virtual bool onLockPixelsAreWritable() const SK_OVERRIDE { return false; }
 
@@ -58,12 +58,12 @@
     SkImageGenerator* const fImageGenerator;
     bool                    fErrorInDecoding;
     void*                   fScaledCacheId;
+    const SkImageInfo       fInfo;
     const size_t            fRowBytes;
 
     SkCachingPixelRef(SkImageGenerator* imageGenerator,
                       const SkImageInfo& info,
                       size_t rowBytes);
-
     typedef SkPixelRef INHERITED;
 };
 
diff --git a/lazy/SkDiscardablePixelRef.cpp b/lazy/SkDiscardablePixelRef.cpp
index eb35d0f..6a9507c 100644
--- a/lazy/SkDiscardablePixelRef.cpp
+++ b/lazy/SkDiscardablePixelRef.cpp
@@ -11,15 +11,17 @@
 
 SkDiscardablePixelRef::SkDiscardablePixelRef(SkImageGenerator* generator,
                                              const SkImageInfo& info,
+                                             size_t size,
                                              size_t rowBytes,
                                              SkDiscardableMemory::Factory* fact)
-    : INHERITED(info)
-    , fGenerator(generator)
+    : fGenerator(generator)
     , fDMFactory(fact)
+    , fInfo(info)
+    , fSize(size)
     , fRowBytes(rowBytes)
-    , fDiscardableMemory(NULL)
-{
+    , fDiscardableMemory(NULL) {
     SkASSERT(fGenerator != NULL);
+    SkASSERT(fSize > 0);
     SkASSERT(fRowBytes > 0);
     // The SkImageGenerator contract requires fGenerator to always
     // decode the same image on each call to getPixels().
@@ -33,39 +35,28 @@
     SkDELETE(fGenerator);
 }
 
-bool SkDiscardablePixelRef::onNewLockPixels(LockRec* rec) {
+void* SkDiscardablePixelRef::onLockPixels(SkColorTable**) {
     if (fDiscardableMemory != NULL) {
         if (fDiscardableMemory->lock()) {
-            rec->fPixels = fDiscardableMemory->data();
-            rec->fColorTable = NULL;
-            rec->fRowBytes = fRowBytes;
-            return true;
+            return fDiscardableMemory->data();
         }
         SkDELETE(fDiscardableMemory);
         fDiscardableMemory = NULL;
     }
-    
-    const size_t size = this->info().getSafeSize(fRowBytes);
     if (fDMFactory != NULL) {
-        fDiscardableMemory = fDMFactory->create(size);
+        fDiscardableMemory = fDMFactory->create(fSize);
     } else {
-        fDiscardableMemory = SkDiscardableMemory::Create(size);
+        fDiscardableMemory = SkDiscardableMemory::Create(fSize);
     }
     if (NULL == fDiscardableMemory) {
-        return false;  // Memory allocation failed.
+        return NULL;  // Memory allocation failed.
     }
-
     void* pixels = fDiscardableMemory->data();
-    if (!fGenerator->getPixels(this->info(), pixels, fRowBytes)) {
-        return false;  // TODO(halcanary) Find out correct thing to do.
+    if (!fGenerator->getPixels(fInfo, pixels, fRowBytes)) {
+        return NULL;  // TODO(halcanary) Find out correct thing to do.
     }
-
-    rec->fPixels = pixels;
-    rec->fColorTable = NULL;
-    rec->fRowBytes = fRowBytes;
-    return true;
+    return pixels;
 }
-
 void SkDiscardablePixelRef::onUnlockPixels() {
     if (fDiscardableMemory != NULL) {
         fDiscardableMemory->unlock();
@@ -90,6 +81,7 @@
     }
     SkAutoTUnref<SkDiscardablePixelRef> ref(SkNEW_ARGS(SkDiscardablePixelRef,
                                                    (generator, info,
+                                                    dst->getSize(),
                                                     dst->rowBytes(),
                                                     factory)));
     dst->setPixelRef(ref);
diff --git a/lazy/SkDiscardablePixelRef.h b/lazy/SkDiscardablePixelRef.h
index 0a727b6..44c6df9 100644
--- a/lazy/SkDiscardablePixelRef.h
+++ b/lazy/SkDiscardablePixelRef.h
@@ -19,8 +19,7 @@
 
 protected:
     ~SkDiscardablePixelRef();
-
-    virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
+    virtual void* onLockPixels(SkColorTable**) SK_OVERRIDE;
     virtual void onUnlockPixels() SK_OVERRIDE;
     virtual bool onLockPixelsAreWritable() const SK_OVERRIDE { return false; }
 
@@ -31,6 +30,8 @@
 private:
     SkImageGenerator* const fGenerator;
     SkDiscardableMemory::Factory* const fDMFactory;
+    const SkImageInfo fInfo;
+    const size_t fSize;  // size of memory to be allocated
     const size_t fRowBytes;
     // These const members should not change over the life of the
     // PixelRef, since the SkBitmap doesn't expect them to change.
@@ -40,14 +41,12 @@
     /* Takes ownership of SkImageGenerator. */
     SkDiscardablePixelRef(SkImageGenerator* generator,
                           const SkImageInfo& info,
+                          size_t size,
                           size_t rowBytes,
                           SkDiscardableMemory::Factory* factory);
-
     friend bool SkInstallDiscardablePixelRef(SkImageGenerator*,
                                              SkBitmap*,
                                              SkDiscardableMemory::Factory*);
-
     typedef SkPixelRef INHERITED;
 };
-
 #endif  // SkDiscardablePixelRef_DEFINED