Index: src/gpu/gl/GrGpuGL.cpp |
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp |
index 8bf35c1690c90dc1a2f346dfe3477025460194a5..32da5d77989aaee6078b6c5049cc77a3018f78d6 100644 |
--- a/src/gpu/gl/GrGpuGL.cpp |
+++ b/src/gpu/gl/GrGpuGL.cpp |
@@ -2362,30 +2362,47 @@ GrGLuint GrGpuGL::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLI |
return tempFBOID; |
} |
-void GrGpuGL::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) { |
+bool GrGpuGL::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) { |
+ // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If neither are |
+ // possible and we return false to fallback to creating a render target dst for render-to- |
+ // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo |
+ // creation. It isn't clear that avoiding temporary fbo creation is actually optimal. |
+ |
// Check for format issues with glCopyTexSubImage2D |
if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInternalFormat() && |
kBGRA_8888_GrPixelConfig == src->config()) { |
- // glCopyTexSubImage2D doesn't work with this config. We'll want to make it a render target |
- // in order to call glBlitFramebuffer or to copy to it by rendering. |
- INHERITED::initCopySurfaceDstDesc(src, desc); |
- return; |
+ // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit |
+ // then we set up for that, otherwise fail. |
+ if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) { |
+ desc->fOrigin = kDefault_GrSurfaceOrigin; |
+ desc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag; |
+ desc->fConfig = kBGRA_8888_GrPixelConfig; |
+ return true; |
+ } |
+ return false; |
} else if (NULL == src->asRenderTarget()) { |
- // We don't want to have to create an FBO just to use glCopyTexSubImage2D. Let the base |
- // class handle it by rendering. |
- INHERITED::initCopySurfaceDstDesc(src, desc); |
- return; |
+ // CopyTexSubImage2D or fbo blit would require creating a temp fbo for the src. |
+ return false; |
} |
const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget()); |
if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) { |
- // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. |
- INHERITED::initCopySurfaceDstDesc(src, desc); |
- } else { |
- desc->fConfig = src->config(); |
- desc->fOrigin = src->origin(); |
- desc->fFlags = kNone_GrSurfaceFlags; |
+ // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO blit or |
+ // fail. |
+ if (this->caps()->isConfigRenderable(src->config(), false)) { |
+ desc->fOrigin = kDefault_GrSurfaceOrigin; |
+ desc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag; |
+ desc->fConfig = src->config(); |
+ return true; |
+ } |
+ return false; |
} |
+ |
+ // We'll do a CopyTexSubImage. Make the dst a plain old texture. |
+ desc->fConfig = src->config(); |
+ desc->fOrigin = src->origin(); |
+ desc->fFlags = kNone_GrSurfaceFlags; |
+ return true; |
} |
bool GrGpuGL::copySurface(GrSurface* dst, |
@@ -2496,8 +2513,8 @@ bool GrGpuGL::canCopySurface(const GrSurface* dst, |
const SkIRect& srcRect, |
const SkIPoint& dstPoint) { |
// This mirrors the logic in onCopySurface. We prefer our base makes the copy if we need to |
- // create a temp fbo |
- // TODO verify this assumption, it may not be true at all |
+ // create a temp fbo. TODO verify the assumption that temp fbos are expensive; it may not be |
+ // true at all. |
bool wouldNeedTempFBO = false; |
if (can_copy_texsubimage(dst, src, this, &wouldNeedTempFBO) && !wouldNeedTempFBO) { |
return true; |