diff options
author | 2011-11-30 19:59:08 +0000 | |
---|---|---|
committer | 2011-11-30 19:59:08 +0000 | |
commit | 56d11e097b1975371d0e0b1452ac0c4d5fc46930 (patch) | |
tree | 5b07e258cf6169d98e8eea98f03354b72a4abac2 /src | |
parent | 573f22b3bd295bb2e3b9e6ab41f5dfeb557897f9 (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.cpp | 15 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 14 | ||||
-rw-r--r-- | src/gpu/GrGpuGL.cpp | 34 | ||||
-rw-r--r-- | src/gpu/GrGpuGL.h | 18 |
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; |