Allow texture-backed bitmaps to perform a read-back when lockPixels is called.
This means we have to be even more cautious about when we call lock, and we should
always check getTexture() first if we can handle a texture directly, rather than
forcing the read-back to get the bits.



git-svn-id: http://skia.googlecode.com/svn/trunk@1815 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/SkGrTexturePixelRef.cpp b/src/gpu/SkGrTexturePixelRef.cpp
index 8becfd4..4fc03ab 100644
--- a/src/gpu/SkGrTexturePixelRef.cpp
+++ b/src/gpu/SkGrTexturePixelRef.cpp
@@ -16,11 +16,42 @@
 
 
 #include "SkGrTexturePixelRef.h"
-
 #include "GrTexture.h"
-
 #include "SkRect.h"
-#include "SkBitmap.h"
+
+// since we call lockPixels recursively on fBitmap, we need a distinct mutex,
+// to avoid deadlock with the default one provided by SkPixelRef.
+static SkMutex  gROLockPixelsPixelRefMutex;
+
+SkROLockPixelsPixelRef::SkROLockPixelsPixelRef() : INHERITED(&gROLockPixelsPixelRefMutex) {
+}
+
+SkROLockPixelsPixelRef::~SkROLockPixelsPixelRef() {
+}
+
+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 NULL;
+    }
+    fBitmap.lockPixels();
+    return fBitmap.getPixels();
+}
+
+void SkROLockPixelsPixelRef::onUnlockPixels() {
+    fBitmap.unlockPixels();
+}
+
+bool SkROLockPixelsPixelRef::onLockPixelsAreWritable() const {
+    return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 
 SkGrTexturePixelRef::SkGrTexturePixelRef(GrTexture* tex) {
     fTexture = tex;
@@ -31,6 +62,10 @@
     GrSafeUnref(fTexture);
 }
 
+SkGpuTexture* SkGrTexturePixelRef::getTexture() {
+    return (SkGpuTexture*)fTexture;
+}
+
 bool SkGrTexturePixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
     if (NULL != fTexture && fTexture->isValid()) {
         int left, top, width, height;
@@ -57,7 +92,7 @@
     }
 }
 
-////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
 
 SkGrRenderTargetPixelRef::SkGrRenderTargetPixelRef(GrRenderTarget* rt) {
     fRenderTarget = rt;
@@ -100,3 +135,4 @@
         return false;
     }
 }
+