diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index cb80efa9b7..40be00406a 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -581,7 +581,6 @@ bool GrGpu::regenerateMipMapLevels(GrTexture* texture) { SkASSERT(texture); SkASSERT(this->caps()->mipMapSupport()); SkASSERT(texture->texturePriv().mipMapped() == GrMipMapped::kYes); - SkASSERT(!texture->asRenderTarget() || !texture->asRenderTarget()->needsResolve()); if (!texture->texturePriv().mipMapsAreDirty()) { // This can happen when the proxy expects mipmaps to be dirty, but they are not dirty on the // actual target. This may be caused by things that the drawingManager could not predict, @@ -607,19 +606,6 @@ void GrGpu::resetTextureBindings() { void GrGpu::resolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect, GrSurfaceOrigin origin, ForExternalIO forExternalIO) { SkASSERT(target); - if (!target->needsResolve()) { - // This can happen when the proxy expects MSAA to be dirty, but it is not dirty on the - // actual target. This may be caused by things that the drawingManager could not predict, - // i.e., ops that don't draw anything, aborting a draw for exceptional circumstances, etc. - // NOTE: This goes away once we quit tracking dirty state on the actual render target. - return; - } -#ifdef SK_DEBUG - auto nativeResolveRect = GrNativeRect::MakeRelativeTo(origin, target->height(), resolveRect); - // The proxy will often track a tighter resolve rect than GrRenderTarget, but it should never be - // the other way around. - SkASSERT(target->getResolveRect().contains(nativeResolveRect.asSkIRect())); -#endif this->handleDirtyContext(); this->onResolveRenderTarget(target, resolveRect, origin, forExternalIO); } @@ -630,15 +616,6 @@ void GrGpu::didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkASSERT(!surface->readOnly()); // Mark any MIP chain and resolve buffer as dirty if and only if there is a non-empty bounds. if (nullptr == bounds || !bounds->isEmpty()) { - if (GrRenderTarget* target = surface->asRenderTarget()) { - SkIRect flippedBounds; - if (kBottomLeft_GrSurfaceOrigin == origin && bounds) { - flippedBounds = {bounds->fLeft, surface->height() - bounds->fBottom, - bounds->fRight, surface->height() - bounds->fTop}; - bounds = &flippedBounds; - } - target->flagAsNeedingResolve(bounds); - } GrTexture* texture = surface->asTexture(); if (texture && 1 == mipLevels) { texture->texturePriv().markMipMapsDirty(); diff --git a/src/gpu/GrOpsRenderPass.cpp b/src/gpu/GrOpsRenderPass.cpp index dcc53b644e..60cf377d53 100644 --- a/src/gpu/GrOpsRenderPass.cpp +++ b/src/gpu/GrOpsRenderPass.cpp @@ -42,9 +42,6 @@ static void assert_msaa_and_mips_are_resolved( auto assertResolved = [](GrTexture* tex, const GrSamplerState& sampler) { SkASSERT(tex); - // Ensure msaa was resolved ahead of time by the DAG. - SkASSERT(!tex->asRenderTarget() || !tex->asRenderTarget()->needsResolve()); - // Ensure mipmaps were all resolved ahead of time by the DAG. if (GrSamplerState::Filter::kMipMap == sampler.filter() && (tex->width() != 1 || tex->height() != 1)) { diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp index 1b5796cb1a..2197d63239 100644 --- a/src/gpu/GrRenderTarget.cpp +++ b/src/gpu/GrRenderTarget.cpp @@ -25,28 +25,10 @@ GrRenderTarget::GrRenderTarget(GrGpu* gpu, const SkISize& size, GrPixelConfig co , fSampleCnt(sampleCount) , fSamplePatternKey(GrSamplePatternDictionary::kInvalidSamplePatternKey) , fStencilAttachment(stencil) { - fResolveRect = SkRectPriv::MakeILargestInverted(); } GrRenderTarget::~GrRenderTarget() = default; -void GrRenderTarget::flagAsNeedingResolve(const SkIRect* rect) { - if (kCanResolve_ResolveType == getResolveType()) { - if (rect) { - fResolveRect.join(*rect); - if (!fResolveRect.intersect({0, 0, this->width(), this->height()})) { - fResolveRect.setEmpty(); - } - } else { - fResolveRect.setLTRB(0, 0, this->width(), this->height()); - } - } -} - -void GrRenderTarget::flagAsResolved() { - fResolveRect = SkRectPriv::MakeILargestInverted(); -} - void GrRenderTarget::onRelease() { fStencilAttachment = nullptr; diff --git a/src/gpu/GrRenderTarget.h b/src/gpu/GrRenderTarget.h index 4e594229c9..c9e173eec1 100644 --- a/src/gpu/GrRenderTarget.h +++ b/src/gpu/GrRenderTarget.h @@ -25,8 +25,9 @@ class GrBackendRenderTarget; */ class GrRenderTarget : virtual public GrSurface { public: - // Make setRequiresManualMSAAResolve publicly accessible from GrRenderTarget. + // Make manual MSAA resolve publicly accessible from GrRenderTarget. using GrSurface::setRequiresManualMSAAResolve; + using GrSurface::requiresManualMSAAResolve; virtual bool alwaysClearStencil() const { return false; } @@ -39,44 +40,6 @@ public: */ int numSamples() const { return fSampleCnt; } - /** - * Call to indicate the multisample contents were modified such that the - * render target needs to be resolved before it can be used as texture. Gr - * tracks this for its own drawing and thus this only needs to be called - * when the render target has been modified outside of Gr. This has no - * effect on wrapped backend render targets. - * - * @param rect a rect bounding the area needing resolve. NULL indicates - * the whole RT needs resolving. - */ - void flagAsNeedingResolve(const SkIRect* rect = nullptr); - - /** - * Call to indicate that GrRenderTarget was externally resolved. This may - * allow Gr to skip a redundant resolve step. - */ - void flagAsResolved(); - - /** - * @return true if the GrRenderTarget requires MSAA resolving - */ - bool needsResolve() const { return !fResolveRect.isEmpty(); } - - /** - * Returns a rect bounding the region needing resolving. - */ - const SkIRect& getResolveRect() const { return fResolveRect; } - - // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO - // 0 in GL), or be unresolvable because the client didn't give us the - // resolve destination. - enum ResolveType { - kCanResolve_ResolveType, - kAutoResolves_ResolveType, - kCantResolve_ResolveType, - }; - virtual ResolveType getResolveType() const = 0; - virtual GrBackendRenderTarget getBackendRenderTarget() const = 0; // Checked when this object is asked to attach a stencil buffer. @@ -107,7 +70,6 @@ private: int fSampleCnt; int fSamplePatternKey; sk_sp fStencilAttachment; - SkIRect fResolveRect; typedef GrSurface INHERITED; }; diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp index e2a149ebac..c2e62f9e7b 100644 --- a/src/gpu/GrResourceProvider.cpp +++ b/src/gpu/GrResourceProvider.cpp @@ -269,9 +269,6 @@ sk_sp GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc if (resource) { fGpu->stats()->incNumScratchTexturesReused(); GrSurface* surface = static_cast(resource); - if (GrRenderTarget* rt = surface->asRenderTarget()) { - rt->flagAsResolved(); // Scratch textures always start without dirty MSAA. - } return sk_sp(surface->asTexture()); } } diff --git a/src/gpu/GrTextureResolveRenderTask.cpp b/src/gpu/GrTextureResolveRenderTask.cpp index 92e505e699..e12bbc8e30 100644 --- a/src/gpu/GrTextureResolveRenderTask.cpp +++ b/src/gpu/GrTextureResolveRenderTask.cpp @@ -69,12 +69,10 @@ bool GrTextureResolveRenderTask::onExecute(GrOpFlushState* flushState) { for (const auto& resolve : fResolves) { if (GrSurfaceProxy::ResolveFlags::kMSAA & resolve.fFlags) { // peekRenderTarget might be null if there was an instantiation error. - GrRenderTarget* renderTarget = resolve.fProxy->peekRenderTarget(); - if (renderTarget && renderTarget->needsResolve()) { + if (GrRenderTarget* renderTarget = resolve.fProxy->peekRenderTarget()) { flushState->gpu()->resolveRenderTarget(renderTarget, resolve.fMSAAResolveRect, resolve.fProxy->origin(), GrGpu::ForExternalIO::kNo); - SkASSERT(!renderTarget->needsResolve()); } } } diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index c982a0f512..50445cd23b 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -1949,20 +1949,17 @@ bool GrGLGpu::readOrTransferPixelsFrom(GrSurface* surface, int left, int top, in } if (renderTarget) { - // resolve the render target if necessary - switch (renderTarget->getResolveType()) { - case GrGLRenderTarget::kCantResolve_ResolveType: - return false; - case GrGLRenderTarget::kAutoResolves_ResolveType: - this->flushRenderTargetNoColorWrites(renderTarget); - break; - case GrGLRenderTarget::kCanResolve_ResolveType: - SkASSERT(!renderTarget->needsResolve()); - // we don't track the state of the READ FBO ID. - this->bindFramebuffer(GR_GL_READ_FRAMEBUFFER, renderTarget->textureFBOID()); - break; - default: - SK_ABORT("Unknown resolve type"); + if (renderTarget->numSamples() <= 1 || + renderTarget->renderFBOID() == renderTarget->textureFBOID()) { // Also catches FBO 0. + SkASSERT(!renderTarget->requiresManualMSAAResolve()); + this->flushRenderTargetNoColorWrites(renderTarget); + } else if (GrGLRenderTarget::kUnresolvableFBOID == renderTarget->textureFBOID()) { + SkASSERT(!renderTarget->requiresManualMSAAResolve()); + return false; + } else { + SkASSERT(renderTarget->requiresManualMSAAResolve()); + // we don't track the state of the READ FBO ID. + this->bindFramebuffer(GR_GL_READ_FRAMEBUFFER, renderTarget->textureFBOID()); } } else { // Use a temporary FBO. @@ -2283,50 +2280,46 @@ void GrGLGpu::sendIndexedInstancedMeshToGpu(GrPrimitiveType primitiveType, void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect, GrSurfaceOrigin resolveOrigin, ForExternalIO) { + // Some extensions automatically resolves the texture when it is read. + SkASSERT(this->glCaps().usesMSAARenderBuffers()); + GrGLRenderTarget* rt = static_cast(target); - if (rt->needsResolve()) { - // Some extensions automatically resolves the texture when it is read. - if (this->glCaps().usesMSAARenderBuffers()) { - SkASSERT(rt->textureFBOID() != rt->renderFBOID()); - SkASSERT(rt->textureFBOID() != 0 && rt->renderFBOID() != 0); - this->bindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()); - this->bindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()); + SkASSERT(rt->textureFBOID() != rt->renderFBOID()); + SkASSERT(rt->textureFBOID() != 0 && rt->renderFBOID() != 0); + 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(); - if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { - // Apple's extension uses the scissor as the blit bounds. - GrScissorState scissorState; - scissorState.set(resolveRect); - this->flushScissor(scissorState, rt->width(), rt->height(), resolveOrigin); - this->disableWindowRectangles(); - GL_CALL(ResolveMultisampleFramebuffer()); - } else { - int l, b, r, t; - if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & - this->glCaps().blitFramebufferSupportFlags()) { - l = 0; - b = 0; - r = target->width(); - t = target->height(); - } else { - auto rect = GrNativeRect::MakeRelativeTo( - resolveOrigin, rt->height(), resolveRect); - l = rect.fX; - b = rect.fY; - r = rect.fX + rect.fWidth; - t = rect.fY + rect.fHeight; - } - - // BlitFrameBuffer respects the scissor, so disable it. - this->disableScissor(); - this->disableWindowRectangles(); - GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t, - GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); - } + // make sure we go through flushRenderTarget() since we've modified + // the bound DRAW FBO ID. + fHWBoundRenderTargetUniqueID.makeInvalid(); + if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { + // Apple's extension uses the scissor as the blit bounds. + GrScissorState scissorState; + scissorState.set(resolveRect); + this->flushScissor(scissorState, rt->width(), rt->height(), resolveOrigin); + this->disableWindowRectangles(); + GL_CALL(ResolveMultisampleFramebuffer()); + } else { + int l, b, r, t; + if (GrGLCaps::kResolveMustBeFull_BlitFrambufferFlag & + this->glCaps().blitFramebufferSupportFlags()) { + l = 0; + b = 0; + r = target->width(); + t = target->height(); + } else { + auto rect = GrNativeRect::MakeRelativeTo( + resolveOrigin, rt->height(), resolveRect); + l = rect.fX; + b = rect.fY; + r = rect.fX + rect.fWidth; + t = rect.fY + rect.fHeight; } - rt->flagAsResolved(); + + // BlitFrameBuffer respects the scissor, so disable it. + this->disableScissor(); + this->disableWindowRectangles(); + GL_CALL(BlitFramebuffer(l, b, r, t, l, b, r, t, GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); } } @@ -2533,7 +2526,6 @@ static void get_gl_swizzle_values(const GrSwizzle& swizzle, GrGLenum glValues[4] void GrGLGpu::bindTexture(int unitIdx, GrSamplerState samplerState, const GrSwizzle& swizzle, GrGLTexture* texture) { SkASSERT(texture); - SkASSERT(!texture->asRenderTarget() || !texture->asRenderTarget()->needsResolve()); #ifdef SK_DEBUG if (!this->caps()->npotTextureTileSupport()) { diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h index 9bd038ed9d..5349e536db 100644 --- a/src/gpu/gl/GrGLRenderTarget.h +++ b/src/gpu/gl/GrGLRenderTarget.h @@ -47,20 +47,6 @@ public: // FBO ID that has texture ID attached. GrGLuint textureFBOID() const { return fTexFBOID; } - // override of GrRenderTarget - ResolveType getResolveType() const override { - if (this->numSamples() <= 1 || fRTFBOID == fTexFBOID) { // Also catches FBO 0. - SkASSERT(!this->requiresManualMSAAResolve()); - return kAutoResolves_ResolveType; - } else if (kUnresolvableFBOID == fTexFBOID) { - SkASSERT(!this->requiresManualMSAAResolve()); - return kCantResolve_ResolveType; - } else { - SkASSERT(this->requiresManualMSAAResolve()); - return kCanResolve_ResolveType; - } - } - GrBackendRenderTarget getBackendRenderTarget() const override; GrBackendFormat backendFormat() const override; diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h index 3dd2682896..cfb27a5b18 100644 --- a/src/gpu/mock/GrMockGpu.h +++ b/src/gpu/mock/GrMockGpu.h @@ -119,9 +119,7 @@ private: bool onRegenerateMipMapLevels(GrTexture*) override { return true; } void onResolveRenderTarget(GrRenderTarget* target, const SkIRect&, GrSurfaceOrigin, - ForExternalIO) override { - target->flagAsResolved(); - } + ForExternalIO) override {} void onFinishFlush(GrSurfaceProxy*[], int n, SkSurface::BackendSurfaceAccess access, const GrFlushInfo& info, const GrPrepareForExternalIORequests&) override { diff --git a/src/gpu/mock/GrMockOpsRenderPass.h b/src/gpu/mock/GrMockOpsRenderPass.h index 863f989b0f..020bdc36f9 100644 --- a/src/gpu/mock/GrMockOpsRenderPass.h +++ b/src/gpu/mock/GrMockOpsRenderPass.h @@ -50,7 +50,6 @@ private: if (auto* tex = fRenderTarget->asTexture()) { tex->texturePriv().markMipMapsDirty(); } - fRenderTarget->flagAsNeedingResolve(); } GrMockGpu* fGpu; diff --git a/src/gpu/mock/GrMockTexture.h b/src/gpu/mock/GrMockTexture.h index edb231e129..d624de6dae 100644 --- a/src/gpu/mock/GrMockTexture.h +++ b/src/gpu/mock/GrMockTexture.h @@ -93,10 +93,6 @@ public: this->registerWithCacheWrapped(GrWrapCacheable::kNo); } - ResolveType getResolveType() const override { - return (this->requiresManualMSAAResolve()) ? - kCanResolve_ResolveType : kAutoResolves_ResolveType; - } bool canAttemptStencilAttachment() const override { return true; } bool completeStencilAttachment() override { return true; } diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm index 16d0d42af8..9f3d66dbac 100644 --- a/src/gpu/mtl/GrMtlGpu.mm +++ b/src/gpu/mtl/GrMtlGpu.mm @@ -1048,29 +1048,17 @@ bool GrMtlGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in size_t transBufferRowBytes = bpp * width; id mtlTexture; - GrMtlRenderTarget* rt = static_cast(surface->asRenderTarget()); - if (rt) { - // resolve the render target if necessary - switch (rt->getResolveType()) { - case GrMtlRenderTarget::kCantResolve_ResolveType: - return false; - case GrMtlRenderTarget::kAutoResolves_ResolveType: - mtlTexture = rt->mtlColorTexture(); - break; - case GrMtlRenderTarget::kCanResolve_ResolveType: - SkASSERT(!rt->needsResolve()); - mtlTexture = rt->mtlResolveTexture(); - break; - default: - SK_ABORT("Unknown resolve type"); - } - } else { - GrMtlTexture* texture = static_cast(surface->asTexture()); - if (texture) { - mtlTexture = texture->mtlTexture(); + if (GrMtlRenderTarget* rt = static_cast(surface->asRenderTarget())) { + if (rt->numSamples() > 1) { + SkASSERT(rt->requiresManualMSAAResolve()); // msaa-render-to-texture not yet supported. + mtlTexture = rt->mtlResolveTexture(); + } else { + SkASSERT(!rt->requiresManualMSAAResolve()); + mtlTexture = rt->mtlColorTexture(); } + } else if (GrMtlTexture* texture = static_cast(surface->asTexture())) { + mtlTexture = texture->mtlTexture(); } - if (!mtlTexture) { return false; } @@ -1195,17 +1183,14 @@ void GrMtlGpu::waitSemaphore(sk_sp semaphore) { void GrMtlGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect&, GrSurfaceOrigin, ForExternalIO forExternalIO) { - if (target->needsResolve()) { - this->resolveTexture(static_cast(target)->mtlResolveTexture(), - static_cast(target)->mtlColorTexture()); - target->flagAsResolved(); + this->resolveTexture(static_cast(target)->mtlResolveTexture(), + static_cast(target)->mtlColorTexture()); - if (ForExternalIO::kYes == forExternalIO) { - // This resolve is called when we are preparing an msaa surface for external I/O. It is - // called after flushing, so we need to make sure we submit the command buffer after - // doing the resolve so that the resolve actually happens. - this->submitCommandBuffer(kSkip_SyncQueue); - } + if (ForExternalIO::kYes == forExternalIO) { + // This resolve is called when we are preparing an msaa surface for external I/O. It is + // called after flushing, so we need to make sure we submit the command buffer after + // doing the resolve so that the resolve actually happens. + this->submitCommandBuffer(kSkip_SyncQueue); } } diff --git a/src/gpu/mtl/GrMtlRenderTarget.h b/src/gpu/mtl/GrMtlRenderTarget.h index abf4c44dc9..ba225d081d 100644 --- a/src/gpu/mtl/GrMtlRenderTarget.h +++ b/src/gpu/mtl/GrMtlRenderTarget.h @@ -25,16 +25,6 @@ public: ~GrMtlRenderTarget() override; - // override of GrRenderTarget - ResolveType getResolveType() const override { - if (this->numSamples() > 1) { - SkASSERT(this->requiresManualMSAAResolve()); - return kCanResolve_ResolveType; - } - SkASSERT(!this->requiresManualMSAAResolve()); - return kAutoResolves_ResolveType; - } - bool canAttemptStencilAttachment() const override { return true; } diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index e1e6d3a5fa..539cc03b88 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -616,8 +616,6 @@ void GrVkGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resol this->resolveImage(target, rt, nativeResolveRect.asSkIRect(), SkIPoint::Make(nativeResolveRect.fX, nativeResolveRect.fY)); - rt->flagAsResolved(); - if (ForExternalIO::kYes == forExternalIO) { // This resolve is called when we are preparing an msaa surface for external I/O. It is // called after flushing, so we need to make sure we submit the command buffer after doing diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h index 2572e65812..92369ba5af 100644 --- a/src/gpu/vk/GrVkRenderTarget.h +++ b/src/gpu/vk/GrVkRenderTarget.h @@ -73,16 +73,6 @@ public: return fSecondaryCommandBuffer; } - // override of GrRenderTarget - ResolveType getResolveType() const override { - if (this->numSamples() > 1) { - SkASSERT(this->requiresManualMSAAResolve()); - return kCanResolve_ResolveType; - } - SkASSERT(!this->requiresManualMSAAResolve()); - return kAutoResolves_ResolveType; - } - bool canAttemptStencilAttachment() const override { // We don't know the status of the stencil attachment for wrapped external secondary command // buffers so we just assume we don't have one.