aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-11-30 19:59:08 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-11-30 19:59:08 +0000
commit56d11e097b1975371d0e0b1452ac0c4d5fc46930 (patch)
tree5b07e258cf6169d98e8eea98f03354b72a4abac2 /src
parent573f22b3bd295bb2e3b9e6ab41f5dfeb557897f9 (diff)
Add support for GL_ANGLE_pack_reverse_row_order
Review URL: http://codereview.appspot.com/5448063/ git-svn-id: http://skia.googlecode.com/svn/trunk@2774 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrContext.cpp15
-rw-r--r--src/gpu/GrGpu.h14
-rw-r--r--src/gpu/GrGpuGL.cpp34
-rw-r--r--src/gpu/GrGpuGL.h18
4 files changed, 65 insertions, 16 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 57f9a312b1..70c9f6de2f 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -1761,7 +1761,20 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target,
{ config }
};
- ast.set(this, desc);
+ // When a full readback is faster than a partial we could always make
+ // the scratch exactly match the passed rect. However, if we see many
+ // different size rectangles we will trash our texture cache and pay the
+ // cost of creating and destroying many textures. So, we only request
+ // an exact match when the caller is reading an entire RT.
+ ScratchTexMatch match = kApprox_ScratchTexMatch;
+ if (0 == left &&
+ 0 == top &&
+ target->width() == width &&
+ target->height() == height &&
+ fGpu->fullReadPixelsIsFasterThanPartial()) {
+ match = kExact_ScratchTexMatch;
+ }
+ ast.set(this, desc, match);
GrTexture* texture = ast.texture();
if (!texture) {
return false;
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 6741aec513..11bf1539f1 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -190,14 +190,16 @@ public:
* pre- and unpremultiplied alpha. The caller is free to ignore the result
* and call readPixels with the original config.
*/
- virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig config) {
+ virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig config)
+ const {
return config;
}
/**
* Same as above but applies to writeTexturePixels
*/
- virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig config) {
+ virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig config)
+ const {
return config;
}
@@ -222,7 +224,13 @@ public:
int left, int top,
int width, int height,
GrPixelConfig config,
- size_t rowBytes) = 0;
+ size_t rowBytes) const = 0;
+ /**
+ * This should return true if reading a NxM rectangle of pixels from a
+ * render target is faster if the target has dimensons N and M and the read
+ * rectangle has its top-left at 0,0.
+ */
+ virtual bool fullReadPixelsIsFasterThanPartial() const { return false; };
/**
* Reads a rectangle of pixels from a render target. Fails if read requires
diff --git a/src/gpu/GrGpuGL.cpp b/src/gpu/GrGpuGL.cpp
index 9025c675f6..9f7e4ec0ad 100644
--- a/src/gpu/GrGpuGL.cpp
+++ b/src/gpu/GrGpuGL.cpp
@@ -307,11 +307,14 @@ void GrGpuGL::initCaps() {
fGLCaps.fUnpackRowLengthSupport = true;
fGLCaps.fUnpackFlipYSupport = false;
fGLCaps.fPackRowLengthSupport = true;
+ fGLCaps.fPackFlipYSupport = false;
} else {
- fGLCaps.fUnpackRowLengthSupport = this->hasExtension("GL_EXT_unpack_subimage");
+ fGLCaps.fUnpackRowLengthSupport =this->hasExtension("GL_EXT_unpack_subimage");
fGLCaps.fUnpackFlipYSupport = this->hasExtension("GL_CHROMIUM_flipy");
// no extension for pack row length
fGLCaps.fPackRowLengthSupport = false;
+ fGLCaps.fPackFlipYSupport =
+ this->hasExtension("GL_ANGLE_pack_reverse_row_order");
}
if (kDesktop_GrGLBinding == this->glBinding()) {
@@ -440,7 +443,7 @@ void GrGpuGL::initStencilFormats() {
}
}
-GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig config) {
+GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig config) const {
if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && GrPixelConfigIsRGBA8888(config)) {
return GrPixelConfigSwapRAndB(config);
} else {
@@ -448,7 +451,7 @@ GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig config) {
}
}
-GrPixelConfig GrGpuGL::preferredWritePixelsConfig(GrPixelConfig config) {
+GrPixelConfig GrGpuGL::preferredWritePixelsConfig(GrPixelConfig config) const {
if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && GrPixelConfigIsRGBA8888(config)) {
return GrPixelConfigSwapRAndB(config);
} else {
@@ -456,6 +459,10 @@ GrPixelConfig GrGpuGL::preferredWritePixelsConfig(GrPixelConfig config) {
}
}
+bool GrGpuGL::fullReadPixelsIsFasterThanPartial() const {
+ return SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL);
+}
+
void GrGpuGL::onResetContext() {
if (gPrintStartupSpew && !fPrintedCaps) {
fPrintedCaps = true;
@@ -541,6 +548,9 @@ void GrGpuGL::onResetContext() {
if (this->glCaps().fUnpackFlipYSupport) {
GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
}
+ if (this->glCaps().fPackFlipYSupport) {
+ GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE));
+ }
}
GrTexture* GrGpuGL::onCreatePlatformTexture(const GrPlatformTextureDesc& desc) {
@@ -1390,8 +1400,13 @@ bool GrGpuGL::readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
int left, int top,
int width, int height,
GrPixelConfig config,
- size_t rowBytes) {
- // if we have to do memcpy to handle non-trim rowBytes then we
+ size_t rowBytes) const {
+ // if GL can do the flip then we'll never pay for it.
+ if (this->glCaps().fPackFlipYSupport) {
+ return false;
+ }
+
+ // If we have to do memcpy to handle non-trim rowBytes then we
// get the flip for free. Otherwise it costs.
if (this->glCaps().fPackRowLengthSupport) {
return true;
@@ -1475,6 +1490,9 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
readDst = scratch.get();
}
}
+ if (!invertY && this->glCaps().fPackFlipYSupport) {
+ GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1));
+ }
GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom,
readRect.fWidth, readRect.fHeight,
format, type, readDst));
@@ -1482,6 +1500,10 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
GrAssert(this->glCaps().fPackRowLengthSupport);
GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
}
+ if (!invertY && this->glCaps().fPackFlipYSupport) {
+ GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0));
+ invertY = true;
+ }
// 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
@@ -2430,4 +2452,6 @@ void GrGpuGL::GLCaps::print() const {
(fUnpackFlipYSupport ? "YES": "NO"));
GrPrintf("Pack Row length support: %s\n",
(fPackRowLengthSupport ? "YES": "NO"));
+ GrPrintf("Pack Flip Y support: %s\n",
+ (fPackFlipYSupport ? "YES": "NO"));
}
diff --git a/src/gpu/GrGpuGL.h b/src/gpu/GrGpuGL.h
index e3c72038e5..57a4d97e78 100644
--- a/src/gpu/GrGpuGL.h
+++ b/src/gpu/GrGpuGL.h
@@ -29,18 +29,18 @@ public:
GrGLBinding glBinding() const { return fGLBinding; }
GrGLVersion glVersion() const { return fGLVersion; }
+ // GrGpu overrides
virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig config)
- SK_OVERRIDE;
+ const SK_OVERRIDE;
virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig config)
- SK_OVERRIDE;
-
+ const SK_OVERRIDE;
virtual bool readPixelsWillPayForYFlip(
GrRenderTarget* renderTarget,
int left, int top,
int width, int height,
GrPixelConfig config,
- size_t rowBytes) SK_OVERRIDE;
-
+ size_t rowBytes) const SK_OVERRIDE;
+ virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
protected:
GrGpuGL(const GrGLInterface* glInterface, GrGLBinding glBinding);
@@ -56,7 +56,8 @@ protected:
, fTextureSwizzleSupport(false)
, fUnpackRowLengthSupport(false)
, fUnpackFlipYSupport(false)
- , fPackRowLengthSupport(false) {
+ , fPackRowLengthSupport(false)
+ , fPackFlipYSupport(false) {
memset(fAASamples, 0, sizeof(fAASamples));
}
SkTArray<GrGLStencilBuffer::Format, true> fStencilFormats;
@@ -108,7 +109,10 @@ protected:
// Is there support for GL_PACK_ROW_LENGTH
bool fPackRowLengthSupport;
-
+
+ // Is there support for GL_PACK_REVERSE_ROW_ORDER
+ bool fPackFlipYSupport;
+
void print() const;
} fGLCaps;