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) {