Revert r2584 (new test fails in fixed pt builds)



git-svn-id: http://skia.googlecode.com/svn/trunk@2585 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 3fc5d7d..7028c91 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -1637,16 +1637,15 @@
     if (NULL != target) {
         return fGpu->readPixels(target,
                                 left, top, width, height, 
-                                config, buffer, 0);
+                                config, buffer);
     } else {
         return false;
     }
 }
 
 bool GrContext::readRenderTargetPixels(GrRenderTarget* target,
-                                       int left, int top, int width, int height,
-                                       GrPixelConfig config, void* buffer,
-                                       size_t rowBytes) {
+                                      int left, int top, int width, int height,
+                                      GrPixelConfig config, void* buffer) {
     SK_TRACE_EVENT0("GrContext::readRenderTargetPixels");
     uint32_t flushFlags = 0;
     if (NULL == target) { 
@@ -1656,7 +1655,7 @@
     this->flush(flushFlags);
     return fGpu->readPixels(target,
                             left, top, width, height, 
-                            config, buffer, rowBytes);
+                            config, buffer);
 }
 
 void GrContext::writePixels(int left, int top, int width, int height,
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 1fc8d47..f0808d3 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -221,12 +221,10 @@
 
 bool GrGpu::readPixels(GrRenderTarget* target,
                        int left, int top, int width, int height,
-                       GrPixelConfig config, void* buffer,
-                       size_t rowBytes) {
+                       GrPixelConfig config, void* buffer) {
 
     this->handleDirtyContext();
-    return this->onReadPixels(target, left, top, width, height,
-                              config, buffer, rowBytes);
+    return this->onReadPixels(target, left, top, width, height, config, buffer);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index cf29ed7..9107554 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -180,8 +180,6 @@
      * @param height        height of rectangle to read in pixels.
      * @param config        the pixel config of the destination buffer
      * @param buffer        memory to read the rectangle into.
-     * @param rowBytes      the number of bytes between consecutive rows. Zero
-     *                      means rows are tightly packed.
      *
      * @return true if the read succeeded, false if not. The read can fail
      *              because of a unsupported pixel config or because no render
@@ -189,7 +187,7 @@
      */
     bool readPixels(GrRenderTarget* renderTarget,
                     int left, int top, int width, int height,
-                    GrPixelConfig config, void* buffer, size_t rowBytes);
+                    GrPixelConfig config, void* buffer);
 
     const GrGpuStats& getStats() const;
     void resetStats();
@@ -323,7 +321,7 @@
     // overridden by API-specific derived class to perform the read pixels.
     virtual bool onReadPixels(GrRenderTarget* target,
                               int left, int top, int width, int height,
-                              GrPixelConfig, void* buffer, size_t rowBytes) = 0;
+                              GrPixelConfig, void* buffer) = 0;
 
     // called to program the vertex data, indexCount will be 0 if drawing non-
     // indexed geometry. The subclass may adjust the startVertex and/or
diff --git a/src/gpu/GrGpuGL.cpp b/src/gpu/GrGpuGL.cpp
index dc4d78a..7865592 100644
--- a/src/gpu/GrGpuGL.cpp
+++ b/src/gpu/GrGpuGL.cpp
@@ -1384,18 +1384,14 @@
 }
 
 bool GrGpuGL::onReadPixels(GrRenderTarget* target,
-                           int left, int top,
-                           int width, int height,
-                           GrPixelConfig config, 
-                           void* buffer, size_t rowBytes) {
+                           int left, int top, int width, int height,
+                           GrPixelConfig config, void* buffer) {
     GrGLenum internalFormat;  // we don't use this for glReadPixels
     GrGLenum format;
     GrGLenum type;
     if (!this->canBeTexture(config, &internalFormat, &format, &type)) {
         return false;
-    }
-    
-    // resolve the render target if necessary
+    }    
     GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target);
     GrAutoTPtrValueRestore<GrRenderTarget*> autoTargetRestore;
     switch (tgt->getResolveType()) {
@@ -1421,62 +1417,26 @@
     // the read rect is viewport-relative
     GrGLIRect readRect;
     readRect.setRelativeTo(glvp, left, top, width, height);
-    
-    size_t tightRowBytes = GrBytesPerPixel(config) * width;
-    if (0 == rowBytes) {
-        rowBytes = tightRowBytes;
-    }
-    size_t readDstRowBytes = tightRowBytes;
-    void* readDst = buffer;
-    
-    // determine if GL can read using the passed rowBytes or if we need
-    // a scratch buffer.
-    SkAutoSMalloc<32 * sizeof(GrColor)> scratch;
-    if (rowBytes != tightRowBytes) {
-        if (kDesktop_GrGLBinding == this->glBinding()) {
-            GrAssert(!(rowBytes % sizeof(GrColor)));
-            GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, rowBytes / sizeof(GrColor)));
-            readDstRowBytes = rowBytes;
-        } else {
-            scratch.reset(tightRowBytes * height);
-            readDst = scratch.get();
-        }
-    }
     GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom,
                        readRect.fWidth, readRect.fHeight,
-                       format, type, readDst));
-    if (readDstRowBytes != tightRowBytes) {
-        GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
-    }
+                       format, type, buffer));
 
     // now reverse the order of the rows, since GL's are bottom-to-top, but our
-    // API presents top-to-bottom. We must preserve the padding contents. Note
-    // that the above readPixels did not overwrite the padding.
-    if (readDst == buffer) {
-        GrAssert(rowBytes == readDstRowBytes);
-        scratch.reset(tightRowBytes);
-        void* tmpRow = scratch.get();
-        // flip y in-place by rows
+    // API presents top-to-bottom
+    {
+        size_t stride = width * GrBytesPerPixel(config);
+        SkAutoMalloc rowStorage(stride);
+        void* tmp = rowStorage.get();
+
         const int halfY = height >> 1;
         char* top = reinterpret_cast<char*>(buffer);
-        char* bottom = top + (height - 1) * rowBytes;
+        char* bottom = top + (height - 1) * stride;
         for (int y = 0; y < halfY; y++) {
-            memcpy(tmpRow, top, tightRowBytes);
-            memcpy(top, bottom, tightRowBytes);
-            memcpy(bottom, tmpRow, tightRowBytes);
-            top += rowBytes;
-            bottom -= rowBytes;
-        }
-    } else {
-        GrAssert(readDst != buffer);
-        // copy from readDst to buffer while flipping y
-        const int halfY = height >> 1;
-        const char* src = reinterpret_cast<const char*>(readDst);
-        char* dst = reinterpret_cast<char*>(buffer) + (height-1) * rowBytes;
-        for (int y = 0; y < height; y++) {
-            memcpy(dst, src, tightRowBytes);
-            src += readDstRowBytes;
-            dst -= rowBytes;
+            memcpy(tmp, top, stride);
+            memcpy(top, bottom, stride);
+            memcpy(bottom, tmp, stride);
+            top += stride;
+            bottom -= stride;
         }
     }
     return true;
diff --git a/src/gpu/GrGpuGL.h b/src/gpu/GrGpuGL.h
index 51eb4ae..2d246e8 100644
--- a/src/gpu/GrGpuGL.h
+++ b/src/gpu/GrGpuGL.h
@@ -90,10 +90,8 @@
     virtual void onForceRenderTargetFlush();
 
     virtual bool onReadPixels(GrRenderTarget* target,
-                              int left, int top, 
-                              int width, int height,
-                              GrPixelConfig, 
-                              void* buffer, size_t rowBytes) SK_OVERRIDE;
+                              int left, int top, int width, int height,
+                              GrPixelConfig, void* buffer);
 
     virtual void onGpuDrawIndexed(GrPrimitiveType type,
                                   uint32_t startVertex,
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 790cf6d..d758383 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -256,19 +256,36 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-bool SkGpuDevice::onReadPixels(const SkBitmap* bitmap, int x, int y) {
-    SkASSERT(SkBitmap::kARGB_8888_Config == bitmap->config());
-    SkASSERT(!bitmap->isNull());
-    SkASSERT(SkIRect::MakeWH(this->width(), this->height()).contains(SkIRect::MakeXYWH(x, y, bitmap->width(), bitmap->height())));
+bool SkGpuDevice::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
+    SkIRect bounds;
+    bounds.set(0, 0, this->width(), this->height());
+    if (!bounds.intersect(srcRect)) {
+        return false;
+    }
 
-    SkAutoLockPixels alp(*bitmap);
-    return fContext->readRenderTargetPixels(fRenderTarget,
-                                            x, y,
-                                            bitmap->width(),
-                                            bitmap->height(),
-                                            kRGBA_8888_GrPixelConfig,
-                                            bitmap->getPixels(),
-                                            bitmap->rowBytes());
+    const int w = bounds.width();
+    const int h = bounds.height();
+    SkBitmap tmp;
+    // note we explicitly specify our rowBytes to be snug (no gap between rows)
+    tmp.setConfig(SkBitmap::kARGB_8888_Config, w, h, w * 4);
+    if (!tmp.allocPixels()) {
+        return false;
+    }
+
+    tmp.lockPixels();
+
+    bool read = fContext->readRenderTargetPixels(fRenderTarget,
+                                                 bounds.fLeft, bounds.fTop,
+                                                 bounds.width(), bounds.height(),
+                                                 kRGBA_8888_GrPixelConfig,
+                                                 tmp.getPixels());
+    tmp.unlockPixels();
+    if (!read) {
+        return false;
+    }
+
+    tmp.swap(*bitmap);
+    return true;
 }
 
 void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y) {