Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(309)

Unified Diff: src/gpu/gl/GrGLGpu.cpp

Issue 893703003: Save and temp dst and src FBO on GrGLGpu and use the temp FBOs for copySurface if needed. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Clean up Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/gpu/gl/GrGLGpu.h ('K') | « src/gpu/gl/GrGLGpu.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/GrGLGpu.cpp
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 6d14e7e6c583920215ecda7f6f6100487221d7c4..df41883ace784a8a84eecda9cad80bb0abcb1b79 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -118,7 +118,9 @@ static bool gPrintStartupSpew;
GrGLGpu::GrGLGpu(const GrGLContext& ctx, GrContext* context)
: GrGpu(context)
- , fGLContext(ctx) {
+ , fGLContext(ctx)
+ , fTempSrcFBO(this)
+ , fTempDstFBO(this) {
SkASSERT(ctx.isInitialized());
fCaps.reset(SkRef(ctx.caps()));
@@ -171,6 +173,8 @@ void GrGLGpu::contextAbandoned() {
INHERITED::contextAbandoned();
fProgramCache->abandon();
fHWProgramID = 0;
+ fTempSrcFBO.reset();
+ fTempDstFBO.reset();
if (this->glCaps().pathRenderingSupport()) {
this->glPathRendering()->abandonGpuResources();
}
@@ -2452,8 +2456,7 @@ namespace {
// Determines whether glBlitFramebuffer could be used between src and dst.
inline bool can_blit_framebuffer(const GrSurface* dst,
const GrSurface* src,
- const GrGLGpu* gpu,
- bool* wouldNeedTempFBO = NULL) {
+ const GrGLGpu* gpu) {
if (gpu->glCaps().isConfigRenderable(dst->config(), dst->desc().fSampleCnt > 0) &&
gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt > 0) &&
gpu->glCaps().usesMSAARenderBuffers()) {
@@ -2463,9 +2466,6 @@ inline bool can_blit_framebuffer(const GrSurface* dst,
(src->desc().fSampleCnt > 0 || src->config() != dst->config())) {
return false;
}
- if (wouldNeedTempFBO) {
- *wouldNeedTempFBO = NULL == dst->asRenderTarget() || NULL == src->asRenderTarget();
- }
return true;
} else {
return false;
@@ -2474,8 +2474,7 @@ inline bool can_blit_framebuffer(const GrSurface* dst,
inline bool can_copy_texsubimage(const GrSurface* dst,
const GrSurface* src,
- const GrGLGpu* gpu,
- bool* wouldNeedTempFBO = NULL) {
+ const GrGLGpu* gpu) {
// Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
// and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
// many drivers would allow it to work, but ANGLE does not.
@@ -2499,9 +2498,6 @@ inline bool can_copy_texsubimage(const GrSurface* dst,
dst->asTexture() &&
dst->origin() == src->origin() &&
!GrPixelConfigIsCompressed(src->config())) {
- if (wouldNeedTempFBO) {
- *wouldNeedTempFBO = NULL == src->asRenderTarget();
- }
return true;
} else {
return false;
@@ -2512,15 +2508,21 @@ inline bool can_copy_texsubimage(const GrSurface* dst,
// If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is
// relative to is output.
-GrGLuint GrGLGpu::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport) {
+GrGLuint GrGLGpu::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
+ TempFBOTarget tempFBOTarget) {
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
GrGLuint tempFBOID;
if (NULL == rt) {
SkASSERT(surface->asTexture());
GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textureID();
- GR_GL_CALL(this->glInterface(), GenFramebuffers(1, &tempFBOID));
+ TempFBO* tempFBO = kSrc_TempFBOTarget == tempFBOTarget ? &fTempSrcFBO : &fTempDstFBO;
+
+ if (0 == tempFBO->fID) {
+ GR_GL_CALL(this->glInterface(), GenFramebuffers(1, &tempFBO->fID));
+ }
+
fGPUStats.incRenderTargetBinds();
- GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, tempFBOID));
+ GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, tempFBO->fID));
GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
GR_GL_COLOR_ATTACHMENT0,
GR_GL_TEXTURE_2D,
@@ -2539,6 +2541,14 @@ GrGLuint GrGLGpu::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLI
return tempFBOID;
}
+void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) {
+ GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
+ GR_GL_COLOR_ATTACHMENT0,
+ GR_GL_TEXTURE_2D,
+ 0,
+ 0));
+}
+
bool GrGLGpu::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-
@@ -2590,7 +2600,7 @@ bool GrGLGpu::copySurface(GrSurface* dst,
if (can_copy_texsubimage(dst, src, this)) {
GrGLuint srcFBO;
GrGLIRect srcVP;
- srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP);
+ srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture());
SkASSERT(dstTex);
// We modified the bound FBO
@@ -2617,7 +2627,7 @@ bool GrGLGpu::copySurface(GrSurface* dst,
srcGLRect.fWidth, srcGLRect.fHeight));
copied = true;
if (srcFBO) {
- GL_CALL(DeleteFramebuffers(1, &srcFBO));
+ this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER);
}
} else if (can_blit_framebuffer(dst, src, this)) {
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
@@ -2632,8 +2642,10 @@ bool GrGLGpu::copySurface(GrSurface* dst,
GrGLuint srcFBO;
GrGLIRect dstVP;
GrGLIRect srcVP;
- dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP);
- srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP);
+ dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP,
+ kDst_TempFBOTarget);
+ srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP,
+ kSrc_TempFBOTarget);
// We modified the bound FBO
fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
GrGLIRect srcGLRect;
@@ -2674,10 +2686,10 @@ bool GrGLGpu::copySurface(GrSurface* dst,
dstGLRect.fBottom + dstGLRect.fHeight,
GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
if (dstFBO) {
- GL_CALL(DeleteFramebuffers(1, &dstFBO));
+ this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER);
}
if (srcFBO) {
- GL_CALL(DeleteFramebuffers(1, &srcFBO));
+ this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER);
}
copied = true;
}
@@ -2689,14 +2701,11 @@ bool GrGLGpu::canCopySurface(const GrSurface* dst,
const GrSurface* src,
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 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) {
+ // This mirrors the logic in onCopySurface.
+ if (can_copy_texsubimage(dst, src, this)) {
return true;
}
- if (can_blit_framebuffer(dst, src, this, &wouldNeedTempFBO) && !wouldNeedTempFBO) {
+ if (can_blit_framebuffer(dst, src, this)) {
if (dst == src) {
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
srcRect.width(), srcRect.height());
« src/gpu/gl/GrGLGpu.h ('K') | « src/gpu/gl/GrGLGpu.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698