diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index cba23b4539..52bad77d53 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -343,7 +343,7 @@ GrSemaphoresSubmitted GrDrawingManager::prepareSurfaceForExternalIO( GrSurface* surface = proxy->priv().peekSurface(); if (gpu && surface->asRenderTarget()) { - gpu->resolveRenderTarget(surface->asRenderTarget(), proxy->origin()); + gpu->resolveRenderTarget(surface->asRenderTarget()); } return result; } diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index d9b3b87397..ea13c851ad 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -300,7 +300,7 @@ bool GrGpu::writePixels(GrSurface* surface, GrSurfaceOrigin origin, if (this->onWritePixels(surface, origin, left, top, width, height, config, texels, mipLevelCount)) { SkIRect rect = SkIRect::MakeXYWH(left, top, width, height); - this->didWriteToSurface(surface, &rect, mipLevelCount); + this->didWriteToSurface(surface, origin, &rect, mipLevelCount); fStats.incTextureUploads(); return true; } @@ -333,7 +333,7 @@ bool GrGpu::transferPixels(GrTexture* texture, if (this->onTransferPixels(texture, left, top, width, height, config, transferBuffer, offset, rowBytes)) { SkIRect rect = SkIRect::MakeXYWH(left, top, width, height); - this->didWriteToSurface(texture, &rect); + this->didWriteToSurface(texture, kTopLeft_GrSurfaceOrigin, &rect); fStats.incTransfersToTexture(); return true; @@ -341,17 +341,24 @@ bool GrGpu::transferPixels(GrTexture* texture, return false; } -void GrGpu::resolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin origin) { +void GrGpu::resolveRenderTarget(GrRenderTarget* target) { SkASSERT(target); this->handleDirtyContext(); - this->onResolveRenderTarget(target, origin); + this->onResolveRenderTarget(target); } -void GrGpu::didWriteToSurface(GrSurface* surface, const SkIRect* bounds, uint32_t mipLevels) const { +void GrGpu::didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkIRect* bounds, + uint32_t mipLevels) const { SkASSERT(surface); // 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(); diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 6527064b93..baeb46ae75 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -149,7 +149,7 @@ public: /** * Resolves MSAA. */ - void resolveRenderTarget(GrRenderTarget*, GrSurfaceOrigin); + void resolveRenderTarget(GrRenderTarget*); /** Info struct returned by getReadPixelsInfo about performing intermediate draws before reading pixels for performance or correctness. */ @@ -525,8 +525,9 @@ protected: *preference = SkTMax(*preference, elevation); } - // Handles cases where a surface will be updated without a call to flushRenderTarget - void didWriteToSurface(GrSurface* surface, const SkIRect* bounds, uint32_t mipLevels = 1) const; + // Handles cases where a surface will be updated without a call to flushRenderTarget. + void didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkIRect* bounds, + uint32_t mipLevels = 1) const; Stats fStats; std::unique_ptr fPathRendering; @@ -596,7 +597,7 @@ private: size_t offset, size_t rowBytes) = 0; // overridden by backend-specific derived class to perform the resolve - virtual void onResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin) = 0; + virtual void onResolveRenderTarget(GrRenderTarget* target) = 0; // overridden by backend specific derived class to perform the copy surface virtual bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 30a8d7a4fa..1eb2c1de95 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -1851,7 +1851,7 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso // This must come after textures are flushed because a texture may need // to be msaa-resolved (which will modify bound FBO state). - this->flushRenderTarget(glRT, nullptr, pipeline.getDisableOutputConversionToSRGB()); + this->flushRenderTarget(glRT, pipeline.getDisableOutputConversionToSRGB()); return true; } @@ -1987,7 +1987,11 @@ void GrGLGpu::clear(const GrFixedClip& clip, GrColor color, GrGLRenderTarget* glRT = static_cast(target); - this->flushRenderTarget(glRT, clip.scissorEnabled() ? &clip.scissorRect() : nullptr); + if (clip.scissorEnabled()) { + this->flushRenderTarget(glRT, origin, clip.scissorRect()); + } else { + this->flushRenderTarget(glRT); + } this->flushScissor(clip.scissorState(), glRT->getViewport(), origin); this->flushWindowRectangles(clip.windowRectsState(), glRT, origin); @@ -2015,7 +2019,7 @@ void GrGLGpu::clearStencil(GrRenderTarget* target, int clearValue) { SkASSERT(sb); GrGLRenderTarget* glRT = static_cast(target); - this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); + this->flushRenderTargetNoColorWrites(glRT); this->disableScissor(); this->disableWindowRectangles(); @@ -2063,7 +2067,7 @@ void GrGLGpu::clearStencilClip(const GrFixedClip& clip, value = 0; } GrGLRenderTarget* glRT = static_cast(target); - this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); + this->flushRenderTargetNoColorWrites(glRT); this->flushScissor(clip.scissorState(), glRT->getViewport(), origin); this->flushWindowRectangles(clip.windowRectsState(), glRT, origin); @@ -2112,7 +2116,7 @@ bool GrGLGpu::readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConf } #endif auto bindRenderTarget = [this, target]() -> bool { - this->flushRenderTarget(static_cast(target), &SkIRect::EmptyIRect()); + this->flushRenderTargetNoColorWrites(static_cast(target)); return true; }; auto unbindRenderTarget = []{}; @@ -2138,7 +2142,7 @@ bool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConf return false; } GrGLRenderTarget* glrt = static_cast(temp->asRenderTarget()); - this->flushRenderTarget(glrt, &SkIRect::EmptyIRect()); + this->flushRenderTargetNoColorWrites(glrt); return true; } else if (this->glCaps().canConfigBeFBOColorAttachment(rtConfig)) { desc.fOrigin = kTopLeft_GrSurfaceOrigin; @@ -2380,10 +2384,10 @@ bool GrGLGpu::onReadPixels(GrSurface* surface, GrSurfaceOrigin origin, case GrGLRenderTarget::kCantResolve_ResolveType: return false; case GrGLRenderTarget::kAutoResolves_ResolveType: - this->flushRenderTarget(renderTarget, &SkIRect::EmptyIRect()); + this->flushRenderTargetNoColorWrites(renderTarget); break; case GrGLRenderTarget::kCanResolve_ResolveType: - this->onResolveRenderTarget(renderTarget, origin); + 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())); @@ -2496,9 +2500,19 @@ GrGpuTextureCommandBuffer* GrGLGpu::createCommandBuffer(GrTexture* texture, return new GrGLGpuTextureCommandBuffer(this, texture, origin); } -void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bounds, bool disableSRGB) { - SkASSERT(target); +void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, GrSurfaceOrigin origin, + const SkIRect& bounds, bool disableSRGB) { + this->flushRenderTargetNoColorWrites(target, disableSRGB); + this->didWriteToSurface(target, origin, &bounds); +} +void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, bool disableSRGB) { + this->flushRenderTargetNoColorWrites(target, disableSRGB); + this->didWriteToSurface(target, kTopLeft_GrSurfaceOrigin, nullptr); +} + +void GrGLGpu::flushRenderTargetNoColorWrites(GrGLRenderTarget* target, bool disableSRGB) { + SkASSERT(target); GrGpuResource::UniqueID rtID = target->uniqueID(); if (fHWBoundRenderTargetUniqueID != rtID) { fStats.incRenderTargetBinds(); @@ -2523,8 +2537,6 @@ void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bounds, if (this->glCaps().srgbWriteControl()) { this->flushFramebufferSRGB(GrPixelConfigIsSRGB(target->config()) && !disableSRGB); } - - this->didWriteToSurface(target, bounds); } void GrGLGpu::flushFramebufferSRGB(bool enable) { @@ -2705,7 +2717,7 @@ void GrGLGpu::sendIndexedInstancedMeshToGpu(const GrPrimitiveProcessor& primProc fStats.incNumDraws(); } -void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin origin) { +void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) { GrGLRenderTarget* rt = static_cast(target); if (rt->needsResolve()) { // Some extensions automatically resolves the texture when it is read. @@ -2721,12 +2733,14 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin orig fHWBoundRenderTargetUniqueID.makeInvalid(); const GrGLIRect& vp = rt->getViewport(); const SkIRect dirtyRect = rt->getResolveRect(); - + // The dirty rect tracked on the RT is always stored in the native coordinates of the + // surface. Choose kTopLeft so no adjustments are made + static constexpr auto kDirtyRectOrigin = kTopLeft_GrSurfaceOrigin; if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) { // Apple's extension uses the scissor as the blit bounds. GrScissorState scissorState; scissorState.set(dirtyRect); - this->flushScissor(scissorState, vp, origin); + this->flushScissor(scissorState, vp, kDirtyRectOrigin); this->disableWindowRectangles(); GL_CALL(ResolveMultisampleFramebuffer()); } else { @@ -2739,7 +2753,7 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin orig t = target->height(); } else { GrGLIRect rect; - rect.setRelativeTo(vp, dirtyRect, origin); + rect.setRelativeTo(vp, dirtyRect, kDirtyRectOrigin); l = rect.fLeft; b = rect.fBottom; r = rect.fLeft + rect.fWidth; @@ -3039,7 +3053,7 @@ void GrGLGpu::bindTexture(int unitIdx, const GrSamplerState& samplerState, bool // out of the "last != next" check. GrGLRenderTarget* texRT = static_cast(texture->asRenderTarget()); if (texRT) { - this->onResolveRenderTarget(texRT, textureOrigin); + this->onResolveRenderTarget(texRT); } GrGpuResource::UniqueID textureID = texture->uniqueID(); @@ -3212,7 +3226,7 @@ void GrGLGpu::generateMipmaps(const GrSamplerState& params, bool allowSRGBInputs // from the rt it will still be the last bound texture, but it needs resolving. GrGLRenderTarget* texRT = static_cast(texture->asRenderTarget()); if (texRT) { - this->onResolveRenderTarget(texRT, textureOrigin); + this->onResolveRenderTarget(texRT); } GrGLenum target = texture->target(); @@ -3872,7 +3886,7 @@ void GrGLGpu::clearStencilClipAsDraw(const GrFixedClip& clip, bool insideStencil } GrGLRenderTarget* glRT = static_cast(rt->asRenderTarget()); - this->flushRenderTarget(glRT, nullptr); + this->flushRenderTarget(glRT); GL_CALL(UseProgram(fStencilClipClearProgram)); fHWProgramID = fStencilClipClearProgram; @@ -4015,7 +4029,7 @@ void GrGLGpu::clearColorAsDraw(const GrFixedClip& clip, GrGLfloat r, GrGLfloat g GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst); - this->didWriteToSurface(dst, clip.scissorEnabled() ? &clip.scissorRect() : nullptr); + this->didWriteToSurface(dst, origin, clip.scissorEnabled() ? &clip.scissorRect() : nullptr); } bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin, @@ -4101,7 +4115,7 @@ bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin, GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, dst); - this->didWriteToSurface(dst, &dstRect); + this->didWriteToSurface(dst, dstOrigin, &dstRect); return true; } @@ -4135,7 +4149,7 @@ void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOr this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, src); SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, srcRect.width(), srcRect.height()); - this->didWriteToSurface(dst, &dstRect); + this->didWriteToSurface(dst, dstOrigin, &dstRect); } bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOrigin, @@ -4188,7 +4202,7 @@ bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOr GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); this->unbindTextureFBOForPixelOps(GR_GL_DRAW_FRAMEBUFFER, dst); this->unbindTextureFBOForPixelOps(GR_GL_READ_FRAMEBUFFER, src); - this->didWriteToSurface(dst, &dstRect); + this->didWriteToSurface(dst, dstOrigin, &dstRect); return true; } @@ -4349,7 +4363,7 @@ void GrGLGpu::onQueryMultisampleSpecs(GrRenderTarget* rt, GrSurfaceOrigin rtOrig this->flushStencil(stencil); this->flushHWAAState(rt, true, !stencil.isDisabled()); - this->flushRenderTarget(static_cast(rt), &SkIRect::EmptyIRect()); + this->flushRenderTargetNoColorWrites(static_cast(rt)); if (0 != this->caps()->maxRasterSamples()) { GR_GL_GetIntegerv(this->glInterface(), GR_GL_EFFECTIVE_RASTER_SAMPLES, effectiveSampleCnt); diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 7f3809eb28..48a0e2bcf9 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -261,7 +261,7 @@ private: // PIXEL_UNPACK_BUFFER is unbound. void unbindCpuToGpuXferBuffer(); - void onResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin) override; + void onResolveRenderTarget(GrRenderTarget* target) override; bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src, GrSurfaceOrigin srcOrigin, @@ -362,9 +362,14 @@ private: // ensures that such operations don't negatively interact with tracking bound textures. void setScratchTextureUnit(); - // bounds is region that may be modified. - // nullptr means whole target. Can be an empty rect. - void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds, bool disableSRGB = false); + // The passed bounds contains the render target's color values that will subsequently be + // written. + void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds, + bool disableSRGB = false); + // This version has an implicit bounds of the entire render target. + void flushRenderTarget(GrGLRenderTarget*, bool disableSRGB = false); + // This version can be used when the render target's colors will not be written. + void flushRenderTargetNoColorWrites(GrGLRenderTarget*, bool disableSRGB = false); // Need not be called if flushRenderTarget is used. void flushViewport(const GrGLIRect&); diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp index d907e86559..8ff9da0d33 100644 --- a/src/gpu/gl/GrGLPathRendering.cpp +++ b/src/gpu/gl/GrGLPathRendering.cpp @@ -124,7 +124,7 @@ void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath* this->setProjectionMatrix(*args.fViewMatrix, size, args.fProxy->origin()); gpu->flushScissor(*args.fScissor, rt->getViewport(), args.fProxy->origin()); gpu->flushHWAAState(rt, args.fUseHWAA, true); - gpu->flushRenderTarget(rt, nullptr); + gpu->flushRenderTarget(rt); const GrGLPath* glPath = static_cast(path); diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h index 5185ce28f0..6221d9178f 100644 --- a/src/gpu/mock/GrMockGpu.h +++ b/src/gpu/mock/GrMockGpu.h @@ -121,7 +121,7 @@ private: return true; } - void onResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin) override { return; } + void onResolveRenderTarget(GrRenderTarget* target) override { return; } void onFinishFlush(bool insertedSemaphores) override {} diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h index 5a5289b6e1..28927d0719 100644 --- a/src/gpu/mtl/GrMtlGpu.h +++ b/src/gpu/mtl/GrMtlGpu.h @@ -130,7 +130,7 @@ private: return false; } - void onResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin) override { return; } + void onResolveRenderTarget(GrRenderTarget* target) override { return; } void onFinishFlush(bool insertedSemaphores) override {} diff --git a/src/gpu/vk/GrVkCopyManager.cpp b/src/gpu/vk/GrVkCopyManager.cpp index 3093c69989..02d1ca0a91 100644 --- a/src/gpu/vk/GrVkCopyManager.cpp +++ b/src/gpu/vk/GrVkCopyManager.cpp @@ -290,7 +290,7 @@ bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu, GrVkRenderTarget* texRT = static_cast(srcTex->asRenderTarget()); if (texRT) { - gpu->onResolveRenderTarget(texRT, srcOrigin); + gpu->onResolveRenderTarget(texRT); } GrVkPrimaryCommandBuffer* cmdBuffer = gpu->currentCommandBuffer(); diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index 362ac1fa2b..9d95c211f5 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -492,9 +492,8 @@ bool GrVkGpu::onTransferPixels(GrTexture* texture, return true; } -void GrVkGpu::resolveImage(GrSurface* dst, GrSurfaceOrigin dstOrigin, - GrVkRenderTarget* src, GrSurfaceOrigin srcOrigin, - const SkIRect& srcRect, const SkIPoint& dstPoint) { +void GrVkGpu::resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect, + const SkIPoint& dstPoint) { SkASSERT(dst); SkASSERT(src && src->numColorSamples() > 1 && src->msaaImage()); @@ -502,23 +501,12 @@ void GrVkGpu::resolveImage(GrSurface* dst, GrSurfaceOrigin dstOrigin, this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue); } - // Flip rect if necessary - SkIRect srcVkRect = srcRect; - int32_t dstY = dstPoint.fY; - - if (kBottomLeft_GrSurfaceOrigin == srcOrigin) { - SkASSERT(kBottomLeft_GrSurfaceOrigin == dstOrigin); - srcVkRect.fTop = src->height() - srcRect.fBottom; - srcVkRect.fBottom = src->height() - srcRect.fTop; - dstY = dst->height() - dstPoint.fY - srcVkRect.height(); - } - VkImageResolve resolveInfo; - resolveInfo.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; - resolveInfo.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; - resolveInfo.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; - resolveInfo.dstOffset = { dstPoint.fX, dstY, 0 }; - resolveInfo.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 }; + resolveInfo.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; + resolveInfo.srcOffset = {srcRect.fLeft, srcRect.fTop, 0}; + resolveInfo.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; + resolveInfo.dstOffset = {dstPoint.fX, dstPoint.fY, 0}; + resolveInfo.extent = {(uint32_t)srcRect.width(), (uint32_t)srcRect.height(), 1}; GrVkImage* dstImage; GrRenderTarget* dstRT = dst->asRenderTarget(); @@ -544,8 +532,7 @@ void GrVkGpu::resolveImage(GrSurface* dst, GrSurfaceOrigin dstOrigin, fCurrentCmdBuffer->resolveImage(this, *src->msaaImage(), *dstImage, 1, &resolveInfo); } -void GrVkGpu::internalResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin origin, - bool requiresSubmit) { +void GrVkGpu::internalResolveRenderTarget(GrRenderTarget* target, bool requiresSubmit) { if (target->needsResolve()) { SkASSERT(target->numColorSamples() > 1); GrVkRenderTarget* rt = static_cast(target); @@ -553,8 +540,7 @@ void GrVkGpu::internalResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigi const SkIRect& srcRect = rt->getResolveRect(); - this->resolveImage(target, origin, rt, origin, srcRect, - SkIPoint::Make(srcRect.fLeft, srcRect.fTop)); + this->resolveImage(target, rt, srcRect, SkIPoint::Make(srcRect.fLeft, srcRect.fTop)); rt->flagAsResolved(); @@ -1010,7 +996,7 @@ void GrVkGpu::generateMipmap(GrVkTexture* tex, GrSurfaceOrigin texOrigin) { // We may need to resolve the texture first if it is also a render target GrVkRenderTarget* texRT = static_cast(tex->asRenderTarget()); if (texRT) { - this->internalResolveRenderTarget(texRT, texOrigin, false); + this->internalResolveRenderTarget(texRT, false); } int width = tex->width(); @@ -1691,7 +1677,7 @@ void GrVkGpu::copySurfaceAsCopyImage(GrSurface* dst, GrSurfaceOrigin dstOrigin, SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, srcRect.width(), srcRect.height()); - this->didWriteToSurface(dst, &dstRect); + this->didWriteToSurface(dst, dstOrigin, &dstRect); } inline bool can_copy_as_blit(const GrSurface* dst, @@ -1782,7 +1768,7 @@ void GrVkGpu::copySurfaceAsBlit(GrSurface* dst, GrSurfaceOrigin dstOrigin, &blitRegion, VK_FILTER_NEAREST); // We never scale so any filter works here - this->didWriteToSurface(dst, &dstRect); + this->didWriteToSurface(dst, dstOrigin, &dstRect); } inline bool can_copy_as_resolve(const GrSurface* dst, GrSurfaceOrigin dstOrigin, @@ -1808,12 +1794,19 @@ inline bool can_copy_as_resolve(const GrSurface* dst, GrSurfaceOrigin dstOrigin, return true; } -void GrVkGpu::copySurfaceAsResolve(GrSurface* dst, GrSurfaceOrigin dstOrigin, - GrSurface* src, GrSurfaceOrigin srcOrigin, - const SkIRect& srcRect, - const SkIPoint& dstPoint) { +void GrVkGpu::copySurfaceAsResolve(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src, + GrSurfaceOrigin srcOrigin, const SkIRect& origSrcRect, + const SkIPoint& origDstPoint) { GrVkRenderTarget* srcRT = static_cast(src->asRenderTarget()); - this->resolveImage(dst, dstOrigin, srcRT, srcOrigin, srcRect, dstPoint); + SkIRect srcRect = origSrcRect; + SkIPoint dstPoint = origDstPoint; + if (kBottomLeft_GrSurfaceOrigin == srcOrigin) { + SkASSERT(kBottomLeft_GrSurfaceOrigin == dstOrigin); + srcRect = {origSrcRect.fLeft, src->height() - origSrcRect.fBottom, + origSrcRect.fRight, src->height() - origSrcRect.fTop}; + dstPoint.fY = dst->height() - dstPoint.fY - srcRect.height(); + } + this->resolveImage(dst, srcRT, srcRect, dstPoint); } bool GrVkGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, @@ -1933,7 +1926,7 @@ bool GrVkGpu::onReadPixels(GrSurface* surface, GrSurfaceOrigin origin, case GrVkRenderTarget::kAutoResolves_ResolveType: break; case GrVkRenderTarget::kCanResolve_ResolveType: - this->internalResolveRenderTarget(rt, origin, false); + this->internalResolveRenderTarget(rt, false); break; default: SK_ABORT("Unknown resolve type"); @@ -2122,7 +2115,7 @@ void GrVkGpu::submitSecondaryCommandBuffer(const SkTArrayendRenderPass(this); - this->didWriteToSurface(target, &bounds); + this->didWriteToSurface(target, origin, &bounds); } GrFence SK_WARN_UNUSED_RESULT GrVkGpu::insertFence() { diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index 8cc98d9da1..5481bf2c42 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -120,8 +120,8 @@ public: return fCompiler; } - void onResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin origin) override { - this->internalResolveRenderTarget(target, origin, true); + void onResolveRenderTarget(GrRenderTarget* target) override { + this->internalResolveRenderTarget(target, true); } void submitSecondaryCommandBuffer(const SkTArray&, @@ -218,7 +218,7 @@ private: // wait semaphores to the submission of this command buffer. void submitCommandBuffer(SyncQueue sync); - void internalResolveRenderTarget(GrRenderTarget*, GrSurfaceOrigin origin, bool requiresSubmit); + void internalResolveRenderTarget(GrRenderTarget*, bool requiresSubmit); void copySurfaceAsCopyImage(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src, GrSurfaceOrigin srcOrigin, @@ -248,9 +248,8 @@ private: GrPixelConfig dataConfig, const GrMipLevel texels[], int mipLevelCount); - void resolveImage(GrSurface* dst, GrSurfaceOrigin dstOrigin, - GrVkRenderTarget* src, GrSurfaceOrigin srcOrigin, - const SkIRect& srcRect, const SkIPoint& dstPoint); + void resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect, + const SkIPoint& dstPoint); sk_sp fBackendContext; sk_sp fVkCaps; diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp index 52dfede267..f6ef5a7920 100644 --- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp +++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp @@ -562,7 +562,7 @@ static void prepare_sampled_images(const GrResourceIOProcessor& processor, GrVkG // We may need to resolve the texture first if it is also a render target GrVkRenderTarget* texRT = static_cast(vkTexture->asRenderTarget()); if (texRT) { - gpu->onResolveRenderTarget(texRT, sampler.proxy()->origin()); + gpu->onResolveRenderTarget(texRT); } // Check if we need to regenerate any mip maps