Adds read pixels to GrTexture and GrRenderTarget
Adds SkGrRenderTargetPixelRef for SkBitmaps that are backed by RTs that aren't textures.
Adds onReadPixels implementations for SkGr pixel ref types



git-svn-id: http://skia.googlecode.com/svn/trunk@1056 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrAtlas.cpp b/gpu/src/GrAtlas.cpp
index a37df9c..dfc0a69 100644
--- a/gpu/src/GrAtlas.cpp
+++ b/gpu/src/GrAtlas.cpp
@@ -142,16 +142,16 @@
     fGpu->unref();
 }
 
-static GrTexture::PixelConfig maskformat2pixelconfig(GrMaskFormat format) {
+static GrPixelConfig maskformat2pixelconfig(GrMaskFormat format) {
     switch (format) {
         case kA8_GrMaskFormat:
-            return GrTexture::kAlpha_8_PixelConfig;
+            return kAlpha_8_GrPixelConfig;
         case kA565_GrMaskFormat:
-            return GrTexture::kRGB_565_PixelConfig;
+            return kRGB_565_GrPixelConfig;
         default:
             GrAssert(!"unknown maskformat");
     }
-    return GrTexture::kUnknown_PixelConfig;
+    return kUnknown_GrPixelConfig;
 }
 
 GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index d093d7c..a0f5c51 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -206,7 +206,7 @@
             // no longer need to clamp at min RT size.
             rtDesc.fWidth  = GrNextPow2(desc.fWidth);
             rtDesc.fHeight = GrNextPow2(desc.fHeight);
-            int bpp = GrTexture::BytesPerPixel(desc.fFormat);
+            int bpp = GrBytesPerPixel(desc.fFormat);
             GrAutoSMalloc<128*128*4> stretchedPixels(bpp *
                                                      rtDesc.fWidth *
                                                      rtDesc.fHeight);
@@ -609,14 +609,39 @@
 #endif
 }
 
-bool GrContext::readPixels(int left, int top, int width, int height,
-                           GrTexture::PixelConfig config, void* buffer) {
-    this->flush(true);
-    return fGpu->readPixels(left, top, width, height, config, buffer);
+bool GrContext::readTexturePixels(GrTexture* texture,
+                                  int left, int top, int width, int height,
+                                  GrPixelConfig config, void* buffer) {
+
+    // TODO: code read pixels for textures that aren't rendertargets
+
+    this->flush();
+    GrRenderTarget* target = texture->asRenderTarget();
+    if (NULL != target) {
+        return fGpu->readPixels(target,
+                                left, top, width, height, 
+                                config, buffer);
+    } else {
+        return false;
+    }
+}
+
+bool GrContext::readRenderTargetPixels(GrRenderTarget* target,
+                                      int left, int top, int width, int height,
+                                      GrPixelConfig config, void* buffer) {
+    uint32_t flushFlags = 0;
+    if (NULL == target) { 
+        flushFlags |= GrContext::kForceCurrentRenderTarget_FlushBit;
+    }
+
+    this->flush(flushFlags);
+    return fGpu->readPixels(target,
+                            left, top, width, height, 
+                            config, buffer);
 }
 
 void GrContext::writePixels(int left, int top, int width, int height,
-                            GrTexture::PixelConfig config, const void* buffer,
+                            GrPixelConfig config, const void* buffer,
                             size_t stride) {
 
     // TODO: when underlying api has a direct way to do this we should use it
@@ -764,6 +789,7 @@
 
     fGpu = gpu;
     fGpu->ref();
+    fGpu->setContext(this);
 
     fCustomPathRenderer = GrPathRenderer::CreatePathRenderer();
     fGpu->setClipPathRenderer(fCustomPathRenderer);
diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp
index 7973361..bf4b91d 100644
--- a/gpu/src/GrDrawTarget.cpp
+++ b/gpu/src/GrDrawTarget.cpp
@@ -492,10 +492,10 @@
     for (int s = 0; s < kNumStages; ++s) {
         if (VertexUsesStage(s, fGeometrySrc.fVertexLayout)) {
             GrAssert(NULL != fCurrDrawState.fTextures[s]);
-            GrTexture::PixelConfig config = fCurrDrawState.fTextures[s]->config();
+            GrPixelConfig config = fCurrDrawState.fTextures[s]->config();
 
-            if (GrTexture::kRGB_565_PixelConfig != config &&
-                GrTexture::kRGBX_8888_PixelConfig != config) {
+            if (kRGB_565_GrPixelConfig != config &&
+                kRGBX_8888_GrPixelConfig != config) {
                 return false;
             }
         }
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 31e4d99..06de3ac 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -28,42 +28,6 @@
 static const size_t VERTEX_POOL_VB_SIZE = 1 << 12;
 static const int VERTEX_POOL_VB_COUNT = 1;
 
-////////////////////////////////////////////////////////////////////////////////
-
-size_t GrTexture::BytesPerPixel(PixelConfig config) {
-    switch (config) {
-        case kAlpha_8_PixelConfig:
-        case kIndex_8_PixelConfig:
-            return 1;
-        case kRGB_565_PixelConfig:
-        case kRGBA_4444_PixelConfig:
-            return 2;
-        case kRGBA_8888_PixelConfig:
-        case kRGBX_8888_PixelConfig:
-            return 4;
-        default:
-            return 0;
-    }
-}
-
-bool GrTexture::PixelConfigIsOpaque(PixelConfig config) {
-    switch (config) {
-        case GrTexture::kRGB_565_PixelConfig:
-        case GrTexture::kRGBX_8888_PixelConfig:
-            return true;
-        default:
-            return false;
-    }
-}
-
-bool GrTexture::PixelConfigIsAlphaOnly(PixelConfig config) {
-    switch (config) {
-        case GrTexture::kAlpha_8_PixelConfig:
-            return true;
-        default:
-            return false;
-    }
-}
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -75,6 +39,7 @@
     , fCurrPoolStartVertex(0)
     , fCurrPoolIndexBuffer(NULL)
     , fCurrPoolStartIndex(0)
+    , fContext(NULL)
     , fVertexPool(NULL)
     , fIndexPool(NULL)
     , fQuadIndexBuffer(NULL)
@@ -85,6 +50,7 @@
     , fVertexPoolInUse(false)
     , fIndexPoolInUse(false)
     , fResourceHead(NULL) {
+
 #if GR_DEBUG
     //gr_run_unittests();
 #endif
@@ -210,10 +176,17 @@
     this->forceRenderTargetFlushHelper();
 }
 
-bool GrGpu::readPixels(int left, int top, int width, int height,
-                       GrTexture::PixelConfig config, void* buffer) {
+bool GrGpu::readPixels(GrRenderTarget* target,
+                       int left, int top, int width, int height,
+                       GrPixelConfig config, void* buffer) {
+
     this->handleDirtyContext();
+    GrRenderTarget* prevTarget = fCurrDrawState.fRenderTarget;
+    if (NULL != target) {
+        fCurrDrawState.fRenderTarget = target;
+    }
     return this->readPixelsHelper(left, top, width, height, config, buffer);
+    fCurrDrawState.fRenderTarget = prevTarget;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -775,12 +748,6 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-
-GrTexture::~GrTexture() {
-    // use this to set a break-point if needed
-//    Gr_clz(3);
-}
-
 const GrSamplerState GrSamplerState::gClampNoFilter(
     GrSamplerState::kClamp_WrapMode,
     GrSamplerState::kClamp_WrapMode,
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index 1d159e3..e5f9fa2 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -666,7 +666,7 @@
         return return_null_texture();
     }
 
-    glDesc.fUploadByteCount = GrTexture::BytesPerPixel(desc.fFormat);
+    glDesc.fUploadByteCount = GrBytesPerPixel(desc.fFormat);
 
     // in case we need a temporary, trimmed copy of the src pixels
     GrAutoSMalloc<128 * 128> trimStorage;
@@ -728,7 +728,7 @@
                         DEFAULT_PARAMS.fWrapT));
 
     GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, glDesc.fUploadByteCount));
-    if (GrTexture::kIndex_8_PixelConfig == desc.fFormat &&
+    if (kIndex_8_GrPixelConfig == desc.fFormat &&
         supports8BitPalette()) {
         // ES only supports CompressedTexImage2D, not CompressedTexSubimage2D
         GrAssert(desc.fWidth == glDesc.fAllocWidth);
@@ -1155,7 +1155,7 @@
 }
 
 bool GrGpuGL::readPixelsHelper(int left, int top, int width, int height,
-                               GrTexture::PixelConfig config, void* buffer) {
+                               GrPixelConfig config, void* buffer) {
     GrGLenum internalFormat;  // we don't use this for glReadPixels
     GrGLenum format;
     GrGLenum type;
@@ -1180,7 +1180,7 @@
     // now reverse the order of the rows, since GL's are bottom-to-top, but our
     // API presents top-to-bottom
     {
-        size_t stride = width * GrTexture::BytesPerPixel(config);
+        size_t stride = width * GrBytesPerPixel(config);
         GrAutoMalloc rowStorage(stride);
         void* tmp = rowStorage.get();
 
@@ -1767,13 +1767,13 @@
     }
 }
 
-bool GrGpuGL::canBeTexture(GrTexture::PixelConfig config,
+bool GrGpuGL::canBeTexture(GrPixelConfig config,
                            GrGLenum* internalFormat,
                            GrGLenum* format,
                            GrGLenum* type) {
     switch (config) {
-        case GrTexture::kRGBA_8888_PixelConfig:
-        case GrTexture::kRGBX_8888_PixelConfig: // todo: can we tell it our X?
+        case kRGBA_8888_GrPixelConfig:
+        case kRGBX_8888_GrPixelConfig: // todo: can we tell it our X?
             *format = GR_GL_32BPP_COLOR_FORMAT;
             if (GR_GL_SUPPORT_ES) {
                 // according to GL_EXT_texture_format_BGRA8888 the *internal*
@@ -1784,17 +1784,17 @@
             }
             *type = GR_GL_UNSIGNED_BYTE;
             break;
-        case GrTexture::kRGB_565_PixelConfig:
+        case kRGB_565_GrPixelConfig:
             *format = GR_GL_RGB;
             *internalFormat = GR_GL_RGB;
             *type = GR_GL_UNSIGNED_SHORT_5_6_5;
             break;
-        case GrTexture::kRGBA_4444_PixelConfig:
+        case kRGBA_4444_GrPixelConfig:
             *format = GR_GL_RGBA;
             *internalFormat = GR_GL_RGBA;
             *type = GR_GL_UNSIGNED_SHORT_4_4_4_4;
             break;
-        case GrTexture::kIndex_8_PixelConfig:
+        case kIndex_8_GrPixelConfig:
             if (this->supports8BitPalette()) {
                 *format = GR_GL_PALETTE8_RGBA8;
                 *internalFormat = GR_GL_PALETTE8_RGBA8;
@@ -1803,7 +1803,7 @@
                 return false;
             }
             break;
-        case GrTexture::kAlpha_8_PixelConfig:
+        case kAlpha_8_GrPixelConfig:
             *format = GR_GL_ALPHA;
             *internalFormat = GR_GL_ALPHA;
             *type = GR_GL_UNSIGNED_BYTE;
@@ -1835,23 +1835,23 @@
    RenderBufferStorage* has to be a specific format (not a base format like
    GL_RGBA).
  */
-bool GrGpuGL::fboInternalFormat(GrTexture::PixelConfig config, GrGLenum* format) {
+bool GrGpuGL::fboInternalFormat(GrPixelConfig config, GrGLenum* format) {
     switch (config) {
-        case GrTexture::kRGBA_8888_PixelConfig:
-        case GrTexture::kRGBX_8888_PixelConfig:
+        case kRGBA_8888_GrPixelConfig:
+        case kRGBX_8888_GrPixelConfig:
             if (fRGBA8Renderbuffer) {
                 *format = GR_GL_RGBA8;
                 return true;
             } else {
                 return false;
             }
-        case GrTexture::kRGB_565_PixelConfig:
+        case kRGB_565_GrPixelConfig:
             GrAssert(GR_GL_SUPPORT_ES);  // ES2 supports 565. ES1 supports it
                                          // with FBO extension desktop GL has
                                          // no such internal format
             *format = GR_GL_RGB565;
             return true;
-        case GrTexture::kRGBA_4444_PixelConfig:
+        case kRGBA_4444_GrPixelConfig:
             *format = GR_GL_RGBA4;
             return true;
         default:
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
index 25414e4..3eedabf 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -87,7 +87,7 @@
     virtual void forceRenderTargetFlushHelper();
 
     virtual bool readPixelsHelper(int left, int top, int width, int height,
-                                  GrTexture::PixelConfig, void* buffer);
+                                  GrPixelConfig, void* buffer);
 
     virtual void drawIndexedHelper(GrPrimitiveType type,
                                    uint32_t startVertex,
@@ -149,11 +149,11 @@
     void flushStencil();
     void resolveTextureRenderTarget(GrGLTexture* texture);
 
-    bool canBeTexture(GrTexture::PixelConfig config,
+    bool canBeTexture(GrPixelConfig config,
                       GrGLenum* internalFormat,
                       GrGLenum* format,
                       GrGLenum* type);
-    bool fboInternalFormat(GrTexture::PixelConfig config, GrGLenum* format);
+    bool fboInternalFormat(GrPixelConfig config, GrGLenum* format);
 
     friend class GrGLVertexBuffer;
     friend class GrGLIndexBuffer;
diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp
index 3e6d909..446949f 100644
--- a/gpu/src/GrGpuGLFixed.cpp
+++ b/gpu/src/GrGpuGLFixed.cpp
@@ -192,7 +192,7 @@
             GrGLTexture* texture = (GrGLTexture*)fCurrDrawState.fTextures[s];
             if (NULL != texture) {
                 TextureEnvRGBOperands nextRGBOperand0 =
-                    (texture->config() == GrTexture::kAlpha_8_PixelConfig) ?
+                    (GrPixelConfigIsAlphaOnly(texture->config())) ?
                         kAlpha_TextureEnvRGBOperand :
                         kColor_TextureEnvRGBOperand;
                 if (fHWRGBOperand0[s] != nextRGBOperand0) {
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index e4d9b3e..37931e3 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -508,7 +508,7 @@
                 break;
             }
 
-            if (GrTexture::kAlpha_8_PixelConfig == texture->config()) {
+            if (GrPixelConfigIsAlphaOnly(texture->config())) {
                 stage.fModulation = GrGLProgram::ProgramDesc::StageDesc::kAlpha_Modulation;
             } else {
                 stage.fModulation = GrGLProgram::ProgramDesc::StageDesc::kColor_Modulation;
diff --git a/gpu/src/GrGpuGLShaders2.cpp b/gpu/src/GrGpuGLShaders2.cpp
index a56e511..4deecd4 100644
--- a/gpu/src/GrGpuGLShaders2.cpp
+++ b/gpu/src/GrGpuGLShaders2.cpp
@@ -1042,7 +1042,7 @@
                 GrAssert(!"Unexpected sample mode!");
                 break;
             }
-            if (GrTexture::kAlpha_8_PixelConfig == texture->config()) {
+            if (GrPixelConfigIsAlphaOnly(texture->config())) {
                 stage.fModulation = StageDesc::kAlpha_Modulation;
             } else {
                 stage.fModulation = StageDesc::kColor_Modulation;
diff --git a/gpu/src/GrTextContext.cpp b/gpu/src/GrTextContext.cpp
index e2c81c7..09113e0 100644
--- a/gpu/src/GrTextContext.cpp
+++ b/gpu/src/GrTextContext.cpp
@@ -47,7 +47,7 @@
         GrAssert(fCurrTexture);
         fDrawTarget->setTexture(TEXT_STAGE, fCurrTexture);
 
-        if (!GrTexture::PixelConfigIsAlphaOnly(fCurrTexture->config())) {
+        if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
             if (kOne_BlendCoeff != fPaint.fSrcBlendCoeff ||
                 kISA_BlendCoeff != fPaint.fDstBlendCoeff ||
                 NULL != fPaint.getTexture()) {
diff --git a/gpu/src/GrTexture.cpp b/gpu/src/GrTexture.cpp
new file mode 100644
index 0000000..7c5f87f
--- /dev/null
+++ b/gpu/src/GrTexture.cpp
@@ -0,0 +1,45 @@
+/*
+    Copyright 2011 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#include "GrTexture.h"
+#include "GrContext.h"
+
+bool GrRenderTarget::readPixels(int left, int top, int width, int height,
+                                GrPixelConfig config, void* buffer) {
+    // go through context so that all necessary flushing occurs
+    GrContext* context = this->getGpu()->getContext();
+    GrAssert(NULL != context);
+    return context->readRenderTargetPixels(this,
+                                           left, top, 
+                                           width, height,
+                                           config, buffer);
+}
+
+GrTexture::~GrTexture() {
+    // use this to set a break-point if needed
+//    Gr_clz(3);
+}
+
+bool GrTexture::readPixels(int left, int top, int width, int height,
+                           GrPixelConfig config, void* buffer) {
+    // go through context so that all necessary flushing occurs
+    GrContext* context = this->getGpu()->getContext();
+    GrAssert(NULL != context);
+    return context->readTexturePixels(this,
+                                        left, top, 
+                                        width, height,
+                                        config, buffer);
+}