Driver bug workaround: unbind_attachments_on_bound_render_fbo_delete
Bug: chromium: 829614 Change-Id: Ic6bc276d1203d24f96fe92b41655871e25f69623 Reviewed-on: https://skia-review.googlesource.com/128395 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Adrienne Walker <enne@chromium.org>
This commit is contained in:
parent
160e93dc19
commit
4ee88511bc
@ -5,21 +5,23 @@
|
||||
// This file is auto-generated from build_workaround_header.py
|
||||
// DO NOT EDIT!
|
||||
|
||||
#define GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP) \
|
||||
GPU_OP(DISABLE_BLEND_EQUATION_ADVANCED, \
|
||||
disable_blend_equation_advanced) \
|
||||
GPU_OP(DISABLE_DISCARD_FRAMEBUFFER, \
|
||||
disable_discard_framebuffer) \
|
||||
GPU_OP(DISALLOW_LARGE_INSTANCED_DRAW, \
|
||||
disallow_large_instanced_draw) \
|
||||
GPU_OP(GL_CLEAR_BROKEN, \
|
||||
gl_clear_broken) \
|
||||
GPU_OP(MAX_MSAA_SAMPLE_COUNT_4, \
|
||||
max_msaa_sample_count_4) \
|
||||
GPU_OP(MAX_TEXTURE_SIZE_LIMIT_4096, \
|
||||
max_texture_size_limit_4096) \
|
||||
GPU_OP(PACK_PARAMETERS_WORKAROUND_WITH_PACK_BUFFER, \
|
||||
pack_parameters_workaround_with_pack_buffer) \
|
||||
GPU_OP(RESTORE_SCISSOR_ON_FBO_CHANGE, \
|
||||
restore_scissor_on_fbo_change) \
|
||||
#define GPU_DRIVER_BUG_WORKAROUNDS(GPU_OP) \
|
||||
GPU_OP(DISABLE_BLEND_EQUATION_ADVANCED, \
|
||||
disable_blend_equation_advanced) \
|
||||
GPU_OP(DISABLE_DISCARD_FRAMEBUFFER, \
|
||||
disable_discard_framebuffer) \
|
||||
GPU_OP(DISALLOW_LARGE_INSTANCED_DRAW, \
|
||||
disallow_large_instanced_draw) \
|
||||
GPU_OP(GL_CLEAR_BROKEN, \
|
||||
gl_clear_broken) \
|
||||
GPU_OP(MAX_MSAA_SAMPLE_COUNT_4, \
|
||||
max_msaa_sample_count_4) \
|
||||
GPU_OP(MAX_TEXTURE_SIZE_LIMIT_4096, \
|
||||
max_texture_size_limit_4096) \
|
||||
GPU_OP(PACK_PARAMETERS_WORKAROUND_WITH_PACK_BUFFER, \
|
||||
pack_parameters_workaround_with_pack_buffer) \
|
||||
GPU_OP(RESTORE_SCISSOR_ON_FBO_CHANGE, \
|
||||
restore_scissor_on_fbo_change) \
|
||||
GPU_OP(UNBIND_ATTACHMENTS_ON_BOUND_RENDER_FBO_DELETE, \
|
||||
unbind_attachments_on_bound_render_fbo_delete) \
|
||||
// The End
|
||||
|
@ -257,13 +257,13 @@ GrGLGpu::~GrGLGpu() {
|
||||
}
|
||||
|
||||
if (fTempSrcFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
|
||||
this->deleteFramebuffer(fTempSrcFBOID);
|
||||
}
|
||||
if (fTempDstFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
|
||||
this->deleteFramebuffer(fTempDstFBOID);
|
||||
}
|
||||
if (fStencilClearFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
|
||||
this->deleteFramebuffer(fStencilClearFBOID);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
|
||||
@ -296,13 +296,13 @@ void GrGLGpu::disconnect(DisconnectType type) {
|
||||
GL_CALL(UseProgram(0));
|
||||
}
|
||||
if (fTempSrcFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID));
|
||||
this->deleteFramebuffer(fTempSrcFBOID);
|
||||
}
|
||||
if (fTempDstFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID));
|
||||
this->deleteFramebuffer(fTempDstFBOID);
|
||||
}
|
||||
if (fStencilClearFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
|
||||
this->deleteFramebuffer(fStencilClearFBOID);
|
||||
}
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
|
||||
if (fCopyPrograms[i].fProgram) {
|
||||
@ -1317,8 +1317,7 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
|
||||
desc.fWidth, desc.fHeight)) {
|
||||
goto FAILED;
|
||||
}
|
||||
fStats.incRenderTargetBinds();
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID));
|
||||
this->bindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fRTFBOID);
|
||||
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
|
||||
GR_GL_COLOR_ATTACHMENT0,
|
||||
GR_GL_RENDERBUFFER,
|
||||
@ -1331,8 +1330,7 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
|
||||
fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig);
|
||||
}
|
||||
}
|
||||
fStats.incRenderTargetBinds();
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID));
|
||||
this->bindFramebuffer(GR_GL_FRAMEBUFFER, idDesc->fTexFBOID);
|
||||
|
||||
if (this->glCaps().usesImplicitMSAAResolve() && desc.fSampleCnt > 1) {
|
||||
GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
|
||||
@ -1353,7 +1351,6 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
|
||||
fGLContext->caps()->markConfigAsValidColorAttachment(desc.fConfig);
|
||||
}
|
||||
|
||||
this->didBindFramebuffer();
|
||||
return true;
|
||||
|
||||
FAILED:
|
||||
@ -1361,10 +1358,10 @@ FAILED:
|
||||
GL_CALL(DeleteRenderbuffers(1, &idDesc->fMSColorRenderbufferID));
|
||||
}
|
||||
if (idDesc->fRTFBOID != idDesc->fTexFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &idDesc->fRTFBOID));
|
||||
this->deleteFramebuffer(idDesc->fRTFBOID);
|
||||
}
|
||||
if (idDesc->fTexFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &idDesc->fTexFBOID));
|
||||
this->deleteFramebuffer(idDesc->fTexFBOID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1567,7 +1564,7 @@ int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) {
|
||||
// Create Framebuffer
|
||||
GrGLuint fb = 0;
|
||||
GL_CALL(GenFramebuffers(1, &fb));
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fb));
|
||||
this->bindFramebuffer(GR_GL_FRAMEBUFFER, fb);
|
||||
fHWBoundRenderTargetUniqueID.makeInvalid();
|
||||
GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
|
||||
GR_GL_COLOR_ATTACHMENT0,
|
||||
@ -1619,8 +1616,8 @@ int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) {
|
||||
GL_CALL(DeleteRenderbuffers(1, &sbRBID));
|
||||
}
|
||||
GL_CALL(DeleteTextures(1, &colorID));
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0));
|
||||
GL_CALL(DeleteFramebuffers(1, &fb));
|
||||
this->bindFramebuffer(GR_GL_FRAMEBUFFER, 0);
|
||||
this->deleteFramebuffer(fb);
|
||||
fGLContext->caps()->setStencilFormatIndexForConfig(config, firstWorkingStencilFormatIndex);
|
||||
}
|
||||
return this->glCaps().getStencilFormatIndexForConfig(config);
|
||||
@ -2348,8 +2345,7 @@ bool GrGLGpu::onReadPixels(GrSurface* surface, GrSurfaceOrigin origin, int left,
|
||||
case GrGLRenderTarget::kCanResolve_ResolveType:
|
||||
this->onResolveRenderTarget(renderTarget);
|
||||
// we don't track the state of the READ FBO ID.
|
||||
fStats.incRenderTargetBinds();
|
||||
GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, renderTarget->textureFBOID()));
|
||||
this->bindFramebuffer(GR_GL_READ_FRAMEBUFFER, renderTarget->textureFBOID());
|
||||
break;
|
||||
default:
|
||||
SK_ABORT("Unknown resolve type");
|
||||
@ -2474,9 +2470,7 @@ void GrGLGpu::flushRenderTargetNoColorWrites(GrGLRenderTarget* target, bool disa
|
||||
SkASSERT(target);
|
||||
GrGpuResource::UniqueID rtID = target->uniqueID();
|
||||
if (fHWBoundRenderTargetUniqueID != rtID) {
|
||||
fStats.incRenderTargetBinds();
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID()));
|
||||
this->didBindFramebuffer();
|
||||
this->bindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID());
|
||||
#ifdef SK_DEBUG
|
||||
// don't do this check in Chromium -- this is causing
|
||||
// lots of repeated command buffer flushes when the compositor is
|
||||
@ -2701,10 +2695,9 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) {
|
||||
if (this->glCaps().usesMSAARenderBuffers()) {
|
||||
SkASSERT(rt->textureFBOID() != rt->renderFBOID());
|
||||
SkASSERT(rt->textureFBOID() != 0 && rt->renderFBOID() != 0);
|
||||
fStats.incRenderTargetBinds();
|
||||
fStats.incRenderTargetBinds();
|
||||
GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
|
||||
GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()));
|
||||
this->bindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID());
|
||||
this->bindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID());
|
||||
|
||||
// make sure we go through flushRenderTarget() since we've modified
|
||||
// the bound DRAW FBO ID.
|
||||
fHWBoundRenderTargetUniqueID.makeInvalid();
|
||||
@ -3364,8 +3357,7 @@ void GrGLGpu::bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget,
|
||||
GR_GL_CALL(this->glInterface(), GenFramebuffers(1, tempFBOID));
|
||||
}
|
||||
|
||||
fStats.incRenderTargetBinds();
|
||||
GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, *tempFBOID));
|
||||
this->bindFramebuffer(fboTarget, *tempFBOID);
|
||||
GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
|
||||
GR_GL_COLOR_ATTACHMENT0,
|
||||
target,
|
||||
@ -3377,11 +3369,9 @@ void GrGLGpu::bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget,
|
||||
viewport->fWidth = surface->width();
|
||||
viewport->fHeight = surface->height();
|
||||
} else {
|
||||
fStats.incRenderTargetBinds();
|
||||
GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBOID()));
|
||||
this->bindFramebuffer(fboTarget, rt->renderFBOID());
|
||||
*viewport = rt->getViewport();
|
||||
}
|
||||
this->didBindFramebuffer();
|
||||
}
|
||||
|
||||
void GrGLGpu::unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface) {
|
||||
@ -3397,7 +3387,13 @@ void GrGLGpu::unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLGpu::didBindFramebuffer() {
|
||||
void GrGLGpu::bindFramebuffer(GrGLenum target, GrGLuint fboid) {
|
||||
fStats.incRenderTargetBinds();
|
||||
GL_CALL(BindFramebuffer(target, fboid));
|
||||
if (target == GR_GL_FRAMEBUFFER || target == GR_GL_DRAW_FRAMEBUFFER) {
|
||||
fBoundDrawFramebuffer = fboid;
|
||||
}
|
||||
|
||||
if (!this->caps()->workarounds().restore_scissor_on_fbo_change) {
|
||||
return;
|
||||
}
|
||||
@ -3410,6 +3406,24 @@ void GrGLGpu::didBindFramebuffer() {
|
||||
GL_CALL(Flush());
|
||||
}
|
||||
|
||||
void GrGLGpu::deleteFramebuffer(GrGLuint fboid) {
|
||||
if (fboid == fBoundDrawFramebuffer &&
|
||||
this->caps()->workarounds().unbind_attachments_on_bound_render_fbo_delete) {
|
||||
// This workaround only applies to deleting currently bound framebuffers
|
||||
// on Adreno 420. Because this is a somewhat rare case, instead of
|
||||
// tracking all the attachments of every framebuffer instead just always
|
||||
// unbind all attachments.
|
||||
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0,
|
||||
GR_GL_RENDERBUFFER, 0));
|
||||
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT,
|
||||
GR_GL_RENDERBUFFER, 0));
|
||||
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_DEPTH_ATTACHMENT,
|
||||
GR_GL_RENDERBUFFER, 0));
|
||||
}
|
||||
|
||||
GL_CALL(DeleteFramebuffers(1, &fboid));
|
||||
}
|
||||
|
||||
bool GrGLGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
|
||||
GrSurface* src, GrSurfaceOrigin srcOrigin,
|
||||
const SkIRect& srcRect, const SkIPoint& dstPoint,
|
||||
@ -4195,7 +4209,7 @@ bool GrGLGpu::generateMipmap(GrGLTexture* texture, GrSurfaceOrigin textureOrigin
|
||||
if (0 == fTempDstFBOID) {
|
||||
GL_CALL(GenFramebuffers(1, &fTempDstFBOID));
|
||||
}
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID));
|
||||
this->bindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID);
|
||||
fHWBoundRenderTargetUniqueID.makeInvalid();
|
||||
|
||||
// Bind the texture, to get things configured for filtering.
|
||||
@ -4442,7 +4456,7 @@ GrBackendRenderTarget GrGLGpu::createTestingOnlyBackendRenderTarget(int w, int h
|
||||
|
||||
this->invalidateBoundRenderTarget();
|
||||
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID));
|
||||
this->bindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID);
|
||||
GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, rbIDs[0]));
|
||||
GL_ALLOC_CALL(this->glInterface(),
|
||||
RenderbufferStorage(GR_GL_RENDERBUFFER, colorBufferFormat, w, h));
|
||||
@ -4462,14 +4476,14 @@ GrBackendRenderTarget GrGLGpu::createTestingOnlyBackendRenderTarget(int w, int h
|
||||
// We don't want to have to recover the renderbuffer IDs later to delete them. OpenGL has this
|
||||
// rule that if a renderbuffer is deleted and a FBO other than the current FBO has the RB
|
||||
// attached then deletion is delayed. So we unbind the FBO here and delete the renderbuffers.
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0));
|
||||
this->bindFramebuffer(GR_GL_FRAMEBUFFER, 0);
|
||||
GL_CALL(DeleteRenderbuffers(2, rbIDs));
|
||||
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID));
|
||||
this->bindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID);
|
||||
GrGLenum status;
|
||||
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
|
||||
if (GR_GL_FRAMEBUFFER_COMPLETE != status) {
|
||||
GL_CALL(DeleteFramebuffers(1, &info.fFBOID));
|
||||
this->deleteFramebuffer(info.fFBOID);
|
||||
return {};
|
||||
}
|
||||
auto stencilBits = SkToInt(this->glCaps().stencilFormats()[sFormatIdx].fStencilBits);
|
||||
@ -4481,7 +4495,7 @@ void GrGLGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&
|
||||
GrGLFramebufferInfo info;
|
||||
if (backendRT.getGLFramebufferInfo(&info)) {
|
||||
if (info.fFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &info.fFBOID));
|
||||
this->deleteFramebuffer(info.fFBOID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +179,8 @@ public:
|
||||
|
||||
void insertEventMarker(const char*);
|
||||
|
||||
void didBindFramebuffer();
|
||||
void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid);
|
||||
void deleteFramebuffer(GrGLuint fboid);
|
||||
|
||||
private:
|
||||
GrGLGpu(std::unique_ptr<GrGLContext>, GrContext*);
|
||||
@ -575,6 +576,8 @@ private:
|
||||
TriState fHWSRGBFramebuffer;
|
||||
SkTArray<GrGpuResource::UniqueID, true> fHWBoundTextureUniqueIDs;
|
||||
|
||||
GrGLuint fBoundDrawFramebuffer = 0;
|
||||
|
||||
struct BufferTexture {
|
||||
BufferTexture() : fTextureID(0), fKnownBound(false),
|
||||
fAttachedBufferUniqueID(SK_InvalidUniqueID),
|
||||
|
@ -128,8 +128,7 @@ bool GrGLRenderTarget::completeStencilAttachment() {
|
||||
GrGLuint rb = glStencil->renderbufferID();
|
||||
|
||||
gpu->invalidateBoundRenderTarget();
|
||||
gpu->stats()->incRenderTargetBinds();
|
||||
GR_GL_CALL(interface, BindFramebuffer(GR_GL_FRAMEBUFFER, this->renderFBOID()));
|
||||
gpu->bindFramebuffer(GR_GL_FRAMEBUFFER, this->renderFBOID());
|
||||
GR_GL_CALL(interface, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
|
||||
GR_GL_STENCIL_ATTACHMENT,
|
||||
GR_GL_RENDERBUFFER, rb));
|
||||
@ -143,7 +142,6 @@ bool GrGLRenderTarget::completeStencilAttachment() {
|
||||
GR_GL_RENDERBUFFER, 0));
|
||||
}
|
||||
|
||||
gpu->didBindFramebuffer();
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
if (kChromium_GrGLDriver != gpu->glContext().driver()) {
|
||||
@ -160,11 +158,12 @@ bool GrGLRenderTarget::completeStencilAttachment() {
|
||||
|
||||
void GrGLRenderTarget::onRelease() {
|
||||
if (GrBackendObjectOwnership::kBorrowed != fRTFBOOwnership) {
|
||||
GrGLGpu* gpu = this->getGLGpu();
|
||||
if (fTexFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &fTexFBOID));
|
||||
gpu->deleteFramebuffer(fTexFBOID);
|
||||
}
|
||||
if (fRTFBOID && fRTFBOID != fTexFBOID) {
|
||||
GL_CALL(DeleteFramebuffers(1, &fRTFBOID));
|
||||
gpu->deleteFramebuffer(fRTFBOID);
|
||||
}
|
||||
if (fMSColorRenderbufferID) {
|
||||
GL_CALL(DeleteRenderbuffers(1, &fMSColorRenderbufferID));
|
||||
|
@ -6,3 +6,4 @@ max_msaa_sample_count_4
|
||||
max_texture_size_limit_4096
|
||||
pack_parameters_workaround_with_pack_buffer
|
||||
restore_scissor_on_fbo_change
|
||||
unbind_attachments_on_bound_render_fbo_delete
|
||||
|
Loading…
Reference in New Issue
Block a user