Track dirty rects on GrRenderTargets in native space rather than origin-relative
Change-Id: Icccf2fcb5d468696c42c5a0ccf405e30e5e9bc65 Reviewed-on: https://skia-review.googlesource.com/105980 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
df430053e0
commit
1fabd51f58
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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<GrPathRendering> 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,
|
||||
|
@ -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<GrGLRenderTarget*>(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<GrGLRenderTarget*>(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<GrGLRenderTarget*>(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<GrGLRenderTarget*>(target), &SkIRect::EmptyIRect());
|
||||
this->flushRenderTargetNoColorWrites(static_cast<GrGLRenderTarget*>(target));
|
||||
return true;
|
||||
};
|
||||
auto unbindRenderTarget = []{};
|
||||
@ -2138,7 +2142,7 @@ bool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConf
|
||||
return false;
|
||||
}
|
||||
GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(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<GrGLRenderTarget*>(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<GrGLRenderTarget*>(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<GrGLRenderTarget*>(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<GrGLRenderTarget*>(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<GrGLRenderTarget*>(rt), &SkIRect::EmptyIRect());
|
||||
this->flushRenderTargetNoColorWrites(static_cast<GrGLRenderTarget*>(rt));
|
||||
|
||||
if (0 != this->caps()->maxRasterSamples()) {
|
||||
GR_GL_GetIntegerv(this->glInterface(), GR_GL_EFFECTIVE_RASTER_SAMPLES, effectiveSampleCnt);
|
||||
|
@ -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&);
|
||||
|
@ -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<const GrGLPath*>(path);
|
||||
|
||||
|
@ -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 {}
|
||||
|
||||
|
@ -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 {}
|
||||
|
||||
|
@ -290,7 +290,7 @@ bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu,
|
||||
|
||||
GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(srcTex->asRenderTarget());
|
||||
if (texRT) {
|
||||
gpu->onResolveRenderTarget(texRT, srcOrigin);
|
||||
gpu->onResolveRenderTarget(texRT);
|
||||
}
|
||||
|
||||
GrVkPrimaryCommandBuffer* cmdBuffer = gpu->currentCommandBuffer();
|
||||
|
@ -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<GrVkRenderTarget*>(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<GrVkRenderTarget*>(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<GrVkRenderTarget*>(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 SkTArray<GrVkSecondaryCommandBu
|
||||
}
|
||||
fCurrentCmdBuffer->endRenderPass(this);
|
||||
|
||||
this->didWriteToSurface(target, &bounds);
|
||||
this->didWriteToSurface(target, origin, &bounds);
|
||||
}
|
||||
|
||||
GrFence SK_WARN_UNUSED_RESULT GrVkGpu::insertFence() {
|
||||
|
@ -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<GrVkSecondaryCommandBuffer*>&,
|
||||
@ -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<const GrVkBackendContext> fBackendContext;
|
||||
sk_sp<GrVkCaps> fVkCaps;
|
||||
|
@ -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<GrVkRenderTarget*>(vkTexture->asRenderTarget());
|
||||
if (texRT) {
|
||||
gpu->onResolveRenderTarget(texRT, sampler.proxy()->origin());
|
||||
gpu->onResolveRenderTarget(texRT);
|
||||
}
|
||||
|
||||
// Check if we need to regenerate any mip maps
|
||||
|
Loading…
Reference in New Issue
Block a user