diff options
-rw-r--r-- | include/gpu/GrCaps.h | 8 | ||||
-rw-r--r-- | src/gpu/GrContextPriv.h | 15 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 93 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.h | 13 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetOpList.cpp | 7 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetOpList.h | 5 | ||||
-rw-r--r-- | src/gpu/GrTextureContext.cpp | 15 | ||||
-rw-r--r-- | src/gpu/GrTextureOpList.cpp | 7 | ||||
-rw-r--r-- | src/gpu/GrTextureOpList.h | 5 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 44 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 4 | ||||
-rw-r--r-- | src/gpu/ops/GrCopySurfaceOp.cpp | 44 | ||||
-rw-r--r-- | src/gpu/ops/GrCopySurfaceOp.h | 51 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.cpp | 6 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.h | 4 | ||||
-rw-r--r-- | tests/BlendTest.cpp | 48 | ||||
-rw-r--r-- | tools/gpu/GrTest.cpp | 4 |
17 files changed, 205 insertions, 168 deletions
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h index a7096e3fd9..0d05d4730d 100644 --- a/include/gpu/GrCaps.h +++ b/include/gpu/GrCaps.h @@ -17,7 +17,7 @@ #include "SkString.h" struct GrContextOptions; -class GrRenderTarget; +class GrRenderTargetProxy; /** * Represents the capabilities of a GrContext. @@ -187,13 +187,13 @@ public: /** * This is can be called before allocating a texture to be a dst for copySurface. This is only - * used for doing dst copies needed in blends, thus the src is always a GrRenderTarget. It will - * populate the origin, config, and flags fields of the desc such that copySurface can + * used for doing dst copies needed in blends, thus the src is always a GrRenderTargetProxy. It + * will populate the origin, config, and flags fields of the desc such that copySurface can * efficiently succeed. rectsMustMatch will be set to true if the copy operation must ensure * that the src and dest rects are identical. disallowSubrect will be set to true if copy rect * must equal src's bounds. */ - virtual bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc, + virtual bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, bool* rectsMustMatch, bool* disallowSubrect) const = 0; protected: diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index 369e8e7ff9..6ed53ff9d5 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -23,19 +23,18 @@ public: GrDrawingManager* drawingManager() { return fContext->fDrawingManager.get(); } // Create a renderTargetContext that wraps an existing renderTarget - sk_sp<GrRenderTargetContext> makeWrappedRenderTargetContext(sk_sp<GrRenderTarget> rt, - sk_sp<SkColorSpace> colorSpace, + sk_sp<GrRenderTargetContext> makeWrappedRenderTargetContext(sk_sp<GrRenderTarget>, + sk_sp<SkColorSpace>, const SkSurfaceProps* = nullptr); // Create a surfaceContext that wraps an existing texture or renderTarget - sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurface> tex); + sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurface>); - sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy, - sk_sp<SkColorSpace>); + sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy>, sk_sp<SkColorSpace>); - sk_sp<GrSurfaceContext> makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc, - SkBackingFit dstFit, - SkBudgeted isDstBudgeted); + sk_sp<GrSurfaceContext> makeDeferredSurfaceContext(const GrSurfaceDesc&, + SkBackingFit, + SkBudgeted); // TODO: Maybe add a 'surfaceProps' param (that is ignored for non-RTs) and remove // makeBackendTextureRenderTargetContext & makeBackendTextureAsRenderTargetRenderTargetContext diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index e7a9022c0c..a4b77310d0 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -135,22 +135,10 @@ bool GrRenderTargetContext::onCopy(GrSurfaceProxy* srcProxy, ASSERT_SINGLE_OWNER RETURN_FALSE_IF_ABANDONED SkDEBUGCODE(this->validate();) - GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::copy"); + GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::onCopy"); - // TODO: defer instantiation until flush time - sk_sp<GrSurface> src(sk_ref_sp(srcProxy->instantiate(fContext->resourceProvider()))); - if (!src) { - return false; - } - - // TODO: This needs to be fixed up since it ends the deferral of the GrRenderTarget. - sk_sp<GrRenderTarget> rt( - sk_ref_sp(fRenderTargetProxy->instantiate(fContext->resourceProvider()))); - if (!rt) { - return false; - } - - return this->getOpList()->copySurface(rt.get(), src.get(), srcRect, dstPoint); + return this->getOpList()->copySurface(fContext->resourceProvider(), + fRenderTargetProxy.get(), srcProxy, srcRect, dstPoint); } // TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext? @@ -1664,8 +1652,7 @@ uint32_t GrRenderTargetContext::addDrawOp(const GrClip& clip, std::unique_ptr<Gr GrXferProcessor::DstTexture dstTexture; if (op->xpRequiresDstTexture(*this->caps(), &appliedClip)) { - this->setupDstTexture(rt, clip, op->bounds(), &dstTexture); - if (!dstTexture.texture()) { + if (!this->setupDstTexture(fRenderTargetProxy.get(), clip, op->bounds(), &dstTexture)) { return SK_InvalidUniqueID; } } @@ -1720,8 +1707,7 @@ uint32_t GrRenderTargetContext::addLegacyMeshDrawOp(GrPipelineBuilder&& pipeline args.fXPInputCoverage = analysis.outputCoverage(); if (analysis.requiresDstTexture()) { - this->setupDstTexture(rt, clip, bounds, &args.fDstTexture); - if (!args.fDstTexture.texture()) { + if (!this->setupDstTexture(fRenderTargetProxy.get(), clip, bounds, &args.fDstTexture)) { return SK_InvalidUniqueID; } } @@ -1731,33 +1717,39 @@ uint32_t GrRenderTargetContext::addLegacyMeshDrawOp(GrPipelineBuilder&& pipeline return this->getOpList()->addOp(std::move(op), this); } -void GrRenderTargetContext::setupDstTexture(GrRenderTarget* rt, const GrClip& clip, +bool GrRenderTargetContext::setupDstTexture(GrRenderTargetProxy* rtProxy, const GrClip& clip, const SkRect& opBounds, GrXferProcessor::DstTexture* dstTexture) { if (this->caps()->textureBarrierSupport()) { - if (GrTexture* rtTex = rt->asTexture()) { + if (GrTextureProxy* texProxy = rtProxy->asTextureProxy()) { + // MDB TODO: remove this instantiation. Blocked on making DstTexture be proxy-based + sk_sp<GrTexture> tex(sk_ref_sp(texProxy->instantiate(fContext->resourceProvider()))); + if (!tex) { + SkDebugf("setupDstTexture: instantiation of src texture failed.\n"); + return false; // We have bigger problems now + } + // The render target is a texture, so we can read from it directly in the shader. The XP // will be responsible to detect this situation and request a texture barrier. - dstTexture->setTexture(sk_ref_sp(rtTex)); + dstTexture->setTexture(std::move(tex)); dstTexture->setOffset(0, 0); - return; + return true; } } - SkIRect copyRect = SkIRect::MakeWH(rt->width(), rt->height()); + SkIRect copyRect = SkIRect::MakeWH(rtProxy->width(), rtProxy->height()); SkIRect clippedRect; - clip.getConservativeBounds(rt->width(), rt->height(), &clippedRect); + clip.getConservativeBounds(rtProxy->width(), rtProxy->height(), &clippedRect); SkIRect drawIBounds; opBounds.roundOut(&drawIBounds); // Cover up for any precision issues by outsetting the op bounds a pixel in each direction. drawIBounds.outset(1, 1); if (!clippedRect.intersect(drawIBounds)) { #ifdef SK_DEBUG - GrCapsDebugf(this->caps(), "Missed an early reject. " - "Bailing on draw from setupDstTexture.\n"); + GrCapsDebugf(this->caps(), "setupDstTexture: Missed an early reject bailing on draw."); #endif - return; + return false; } // MSAA consideration: When there is support for reading MSAA samples in the shader we could @@ -1765,41 +1757,56 @@ void GrRenderTargetContext::setupDstTexture(GrRenderTarget* rt, const GrClip& cl GrSurfaceDesc desc; bool rectsMustMatch = false; bool disallowSubrect = false; - if (!this->caps()->initDescForDstCopy(rt, &desc, &rectsMustMatch, &disallowSubrect)) { - desc.fOrigin = kDefault_GrSurfaceOrigin; + if (!this->caps()->initDescForDstCopy(rtProxy, &desc, &rectsMustMatch, &disallowSubrect)) { + desc.fOrigin = kBottomLeft_GrSurfaceOrigin; desc.fFlags = kRenderTarget_GrSurfaceFlag; - desc.fConfig = rt->config(); + desc.fConfig = rtProxy->config(); } if (!disallowSubrect) { copyRect = clippedRect; } - SkIPoint dstPoint; - SkIPoint dstOffset; - static const uint32_t kFlags = 0; - sk_sp<GrTexture> copy; + SkIPoint dstPoint, dstOffset; + SkBackingFit fit; if (rectsMustMatch) { - SkASSERT(desc.fOrigin == rt->origin()); - desc.fWidth = rt->width(); - desc.fHeight = rt->height(); + SkASSERT(desc.fOrigin == rtProxy->origin()); + desc.fWidth = rtProxy->width(); + desc.fHeight = rtProxy->height(); dstPoint = {copyRect.fLeft, copyRect.fTop}; dstOffset = {0, 0}; - copy = fContext->resourceProvider()->createTexture(desc, SkBudgeted::kYes, kFlags); + fit = SkBackingFit::kExact; } else { desc.fWidth = copyRect.width(); desc.fHeight = copyRect.height(); dstPoint = {0, 0}; dstOffset = {copyRect.fLeft, copyRect.fTop}; - copy.reset(fContext->resourceProvider()->createApproxTexture(desc, kFlags)); + fit = SkBackingFit::kApprox; + } + + sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeDeferredSurfaceContext( + desc, + fit, + SkBudgeted::kYes); + if (!sContext) { + SkDebugf("setupDstTexture: surfaceContext creation failed.\n"); + return false; } + if (!sContext->copy(rtProxy, copyRect, dstPoint)) { + SkDebugf("setupDstTexture: copy failed.\n"); + return false; + } + + GrTextureProxy* copyProxy = sContext->asTextureProxy(); + // MDB TODO: remove this instantiation once DstTexture is proxy-backed + sk_sp<GrTexture> copy(sk_ref_sp(copyProxy->instantiate(fContext->resourceProvider()))); if (!copy) { - SkDebugf("Failed to create temporary copy of destination texture.\n"); - return; + SkDebugf("setupDstTexture: instantiation of copied texture failed.\n"); + return false; } - this->getOpList()->copySurface(copy.get(), rt, copyRect, dstPoint); dstTexture->setTexture(std::move(copy)); dstTexture->setOffset(dstOffset); + return true; } diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index fe32faf1b9..8feec78c3b 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -469,12 +469,13 @@ private: uint32_t addLegacyMeshDrawOp(GrPipelineBuilder&&, const GrClip&, std::unique_ptr<GrLegacyMeshDrawOp>); - // Makes a copy of the dst if it is necessary for the draw and returns the texture that should - // be used by GrXferProcessor to access the destination color. If the texture is nullptr then - // a texture copy could not be made. - void setupDstTexture(GrRenderTarget*, const GrClip&, const SkRect& opBounds, - GrXferProcessor::DstTexture*); - + // Makes a copy of the proxy if it is necessary for the draw and places the texture that should + // be used by GrXferProcessor to access the destination color in 'result'. If the return + // value is false then a texture copy could not be made. + bool SK_WARN_UNUSED_RESULT setupDstTexture(GrRenderTargetProxy*, + const GrClip&, + const SkRect& opBounds, + GrXferProcessor::DstTexture* result); GrRenderTargetOpList* getOpList(); diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp index daf03227ee..a003c121d1 100644 --- a/src/gpu/GrRenderTargetOpList.cpp +++ b/src/gpu/GrRenderTargetOpList.cpp @@ -236,11 +236,12 @@ void GrRenderTargetOpList::discard(GrRenderTargetContext* renderTargetContext) { //////////////////////////////////////////////////////////////////////////////// -bool GrRenderTargetOpList::copySurface(GrSurface* dst, - GrSurface* src, +bool GrRenderTargetOpList::copySurface(GrResourceProvider* resourceProvider, + GrSurfaceProxy* dst, + GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) { - std::unique_ptr<GrOp> op = GrCopySurfaceOp::Make(dst, src, srcRect, dstPoint); + std::unique_ptr<GrOp> op = GrCopySurfaceOp::Make(resourceProvider, dst, src, srcRect, dstPoint); if (!op) { return false; } diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h index 8e00df8c16..7e26490920 100644 --- a/src/gpu/GrRenderTargetOpList.h +++ b/src/gpu/GrRenderTargetOpList.h @@ -98,8 +98,9 @@ public: * depending on the type of surface, configs, etc, and the backend-specific * limitations. */ - bool copySurface(GrSurface* dst, - GrSurface* src, + bool copySurface(GrResourceProvider* resourceProvider, + GrSurfaceProxy* dst, + GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint); diff --git a/src/gpu/GrTextureContext.cpp b/src/gpu/GrTextureContext.cpp index f946290795..ca6f7a20bd 100644 --- a/src/gpu/GrTextureContext.cpp +++ b/src/gpu/GrTextureContext.cpp @@ -84,20 +84,9 @@ bool GrTextureContext::onCopy(GrSurfaceProxy* srcProxy, fContext->contextPriv().flushSurfaceWrites(srcProxy); #endif - // TODO: defer instantiation until flush time - sk_sp<GrSurface> src(sk_ref_sp(srcProxy->instantiate(fContext->resourceProvider()))); - if (!src) { - return false; - } - - // TODO: this needs to be fixed up since it ends the deferrable of the GrTexture - sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->resourceProvider()))); - if (!tex) { - return false; - } - GrTextureOpList* opList = this->getOpList(); - bool result = opList->copySurface(tex.get(), src.get(), srcRect, dstPoint); + bool result = opList->copySurface(fContext->resourceProvider(), + fTextureProxy.get(), srcProxy, srcRect, dstPoint); #ifndef ENABLE_MDB GrOpFlushState flushState(fContext->getGpu(), nullptr); diff --git a/src/gpu/GrTextureOpList.cpp b/src/gpu/GrTextureOpList.cpp index 668e8a3bc8..d2d922643a 100644 --- a/src/gpu/GrTextureOpList.cpp +++ b/src/gpu/GrTextureOpList.cpp @@ -76,11 +76,12 @@ void GrTextureOpList::reset() { //////////////////////////////////////////////////////////////////////////////// -bool GrTextureOpList::copySurface(GrSurface* dst, - GrSurface* src, +bool GrTextureOpList::copySurface(GrResourceProvider* resourceProvider, + GrSurfaceProxy* dst, + GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) { - std::unique_ptr<GrOp> op = GrCopySurfaceOp::Make(dst, src, srcRect, dstPoint); + std::unique_ptr<GrOp> op = GrCopySurfaceOp::Make(resourceProvider, dst, src, srcRect, dstPoint); if (!op) { return false; } diff --git a/src/gpu/GrTextureOpList.h b/src/gpu/GrTextureOpList.h index 954289c1e3..22828fd936 100644 --- a/src/gpu/GrTextureOpList.h +++ b/src/gpu/GrTextureOpList.h @@ -52,8 +52,9 @@ public: * depending on the type of surface, configs, etc, and the backend-specific * limitations. */ - bool copySurface(GrSurface* dst, - GrSurface* src, + bool copySurface(GrResourceProvider* resourceProvider, + GrSurfaceProxy* dst, + GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint); diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 6b3e3a72dd..bc894c30d1 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -11,6 +11,7 @@ #include "GrGLRenderTarget.h" #include "GrGLTexture.h" #include "GrShaderCaps.h" +#include "GrSurfaceProxyPriv.h" #include "SkTSearch.h" #include "SkTSort.h" #include "instanced/GLInstancedRendering.h" @@ -2071,7 +2072,7 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions, #endif } -bool GrGLCaps::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc, +bool GrGLCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, bool* rectsMustMatch, bool* disallowSubrect) const { // By default, we don't require rects to match. *rectsMustMatch = false; @@ -2081,17 +2082,22 @@ bool GrGLCaps::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc // If the src is a texture, we can implement the blit as a draw assuming the config is // renderable. - if (src->asTexture() && this->isConfigRenderable(src->config(), false)) { - desc->fOrigin = kDefault_GrSurfaceOrigin; + if (src->asTextureProxy() && this->isConfigRenderable(src->config(), false)) { + desc->fOrigin = kBottomLeft_GrSurfaceOrigin; desc->fFlags = kRenderTarget_GrSurfaceFlag; desc->fConfig = src->config(); return true; } - const GrGLTexture* srcTexture = static_cast<const GrGLTexture*>(src->asTexture()); - if (srcTexture && srcTexture->target() != GR_GL_TEXTURE_2D) { - // Not supported for FBO blit or CopyTexSubImage - return false; + { + // The only way we could see a non-GR_GL_TEXTURE_2D texture would be if it were + // wrapped. In that case the proxy would already be instantiated. + const GrTexture* srcTexture = src->priv().peekTexture(); + const GrGLTexture* glSrcTexture = static_cast<const GrGLTexture*>(srcTexture); + if (glSrcTexture && glSrcTexture->target() != GR_GL_TEXTURE_2D) { + // Not supported for FBO blit or CopyTexSubImage + return false; + } } // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are @@ -2130,18 +2136,20 @@ bool GrGLCaps::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc return false; } - const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src); - if (srcRT->renderFBOID() != srcRT->textureFBOID()) { - // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO blit or - // fail. - if (this->canConfigBeFBOColorAttachment(src->config())) { - desc->fOrigin = originForBlitFramebuffer; - desc->fConfig = src->config(); - *rectsMustMatch = rectsMustMatchForBlitFramebuffer; - *disallowSubrect = disallowSubrectForBlitFramebuffer; - return true; + { + bool srcIsMSAARenderbuffer = src->desc().fSampleCnt > 0 && this->usesMSAARenderBuffers(); + if (srcIsMSAARenderbuffer) { + // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer. Set up for FBO + // blit or fail. + if (this->canConfigBeFBOColorAttachment(src->config())) { + desc->fOrigin = originForBlitFramebuffer; + desc->fConfig = src->config(); + *rectsMustMatch = rectsMustMatchForBlitFramebuffer; + *disallowSubrect = disallowSubrectForBlitFramebuffer; + return true; + } + return false; } - return false; } // We'll do a CopyTexSubImage. Make the dst a plain old texture. diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index b8c4745a50..7439711c6d 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -359,8 +359,8 @@ public: return fRGBAToBGRAReadbackConversionsAreSlow; } - bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc, bool* rectsMustMatch, - bool* disallowSubrect) const override; + bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, + bool* rectsMustMatch, bool* disallowSubrect) const override; private: enum ExternalFormatUsage { diff --git a/src/gpu/ops/GrCopySurfaceOp.cpp b/src/gpu/ops/GrCopySurfaceOp.cpp index 87c490b110..5feed18f76 100644 --- a/src/gpu/ops/GrCopySurfaceOp.cpp +++ b/src/gpu/ops/GrCopySurfaceOp.cpp @@ -8,12 +8,12 @@ #include "GrCopySurfaceOp.h" // returns true if the read/written rect intersects the src/dst and false if not. -bool GrCopySurfaceOp::ClipSrcRectAndDstPoint(const GrSurface* dst, - const GrSurface* src, - const SkIRect& srcRect, - const SkIPoint& dstPoint, - SkIRect* clippedSrcRect, - SkIPoint* clippedDstPoint) { +static bool clip_src_rect_and_dst_point(const GrSurfaceProxy* dst, + const GrSurfaceProxy* src, + const SkIRect& srcRect, + const SkIPoint& dstPoint, + SkIRect* clippedSrcRect, + SkIPoint* clippedDstPoint) { *clippedSrcRect = srcRect; *clippedDstPoint = dstPoint; @@ -58,21 +58,37 @@ bool GrCopySurfaceOp::ClipSrcRectAndDstPoint(const GrSurface* dst, return !clippedSrcRect->isEmpty(); } -std::unique_ptr<GrOp> GrCopySurfaceOp::Make(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, +std::unique_ptr<GrOp> GrCopySurfaceOp::Make(GrResourceProvider* resourceProvider, + GrSurfaceProxy* dstProxy, GrSurfaceProxy* srcProxy, + const SkIRect& srcRect, const SkIPoint& dstPoint) { - SkASSERT(dst); - SkASSERT(src); - if (GrPixelConfigIsSint(dst->config()) != GrPixelConfigIsSint(src->config())) { + SkASSERT(dstProxy); + SkASSERT(srcProxy); + if (GrPixelConfigIsSint(dstProxy->config()) != GrPixelConfigIsSint(srcProxy->config())) { return nullptr; } - if (GrPixelConfigIsCompressed(dst->config())) { + if (GrPixelConfigIsCompressed(dstProxy->config())) { return nullptr; } SkIRect clippedSrcRect; SkIPoint clippedDstPoint; - // If the rect is outside the src or dst then we've already succeeded. - if (!ClipSrcRectAndDstPoint(dst, src, srcRect, dstPoint, &clippedSrcRect, &clippedDstPoint)) { + // If the rect is outside the srcProxy or dstProxy then we've already succeeded. + if (!clip_src_rect_and_dst_point(dstProxy, srcProxy, srcRect, dstPoint, + &clippedSrcRect, &clippedDstPoint)) { return nullptr; } - return std::unique_ptr<GrOp>(new GrCopySurfaceOp(dst, src, clippedSrcRect, clippedDstPoint)); + + // MDB TODO: remove this instantiation + GrSurface* dstTex = dstProxy->instantiate(resourceProvider); + if (!dstTex) { + return nullptr; + } + GrSurface* srcTex = srcProxy->instantiate(resourceProvider); + if (!srcTex) { + return nullptr; + } + + return std::unique_ptr<GrOp>(new GrCopySurfaceOp(dstTex, srcTex, + dstProxy->uniqueID(), srcProxy->uniqueID(), + clippedSrcRect, clippedDstPoint)); } diff --git a/src/gpu/ops/GrCopySurfaceOp.h b/src/gpu/ops/GrCopySurfaceOp.h index 4c4500b445..05ee8d0a00 100644 --- a/src/gpu/ops/GrCopySurfaceOp.h +++ b/src/gpu/ops/GrCopySurfaceOp.h @@ -8,45 +8,44 @@ #ifndef GrCopySurfaceOp_DEFINED #define GrCopySurfaceOp_DEFINED -#include "GrGpu.h" #include "GrOp.h" #include "GrOpFlushState.h" -#include "GrRenderTarget.h" class GrCopySurfaceOp final : public GrOp { public: DEFINE_OP_CLASS_ID - /** This should not really be exposed as Create() will apply this clipping, but there is - * currently a workaround in GrContext::copySurface() for non-render target dsts that relies - * on it. */ - static bool ClipSrcRectAndDstPoint(const GrSurface* dst, - const GrSurface* src, - const SkIRect& srcRect, - const SkIPoint& dstPoint, - SkIRect* clippedSrcRect, - SkIPoint* clippedDstPoint); - - static std::unique_ptr<GrOp> Make(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, + // MDB TODO: remove the resourceProvider parameter + static std::unique_ptr<GrOp> Make(GrResourceProvider*, + GrSurfaceProxy* dst, GrSurfaceProxy* src, + const SkIRect& srcRect, const SkIPoint& dstPoint); const char* name() const override { return "CopySurface"; } SkString dumpInfo() const override { SkString string; - string.printf( - "SRC: 0x%p, DST: 0x%p, SRECT: [L: %d, T: %d, R: %d, B: %d], " - "DPT:[X: %d, Y: %d]", - fDst.get(), fSrc.get(), fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, - fSrcRect.fBottom, fDstPoint.fX, fDstPoint.fY); + string.printf("src: (proxyID: %d, rtID: %d), dst: (proxyID: %d, rtID: %d), " + "srcRect: [L: %d, T: %d, R: %d, B: %d], dstPt: [X: %d, Y: %d]", + fSrcProxyID.asUInt(), fSrc.get()->uniqueID().asUInt(), + fDstProxyID.asUInt(), fDst.get()->uniqueID().asUInt(), + fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, fSrcRect.fBottom, + fDstPoint.fX, fDstPoint.fY); string.append(INHERITED::dumpInfo()); return string; } private: - GrCopySurfaceOp(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, - const SkIPoint& dstPoint) - : INHERITED(ClassID()), fDst(dst), fSrc(src), fSrcRect(srcRect), fDstPoint(dstPoint) { + GrCopySurfaceOp(GrSurface* dst, GrSurface* src, + GrSurfaceProxy::UniqueID dstID, GrSurfaceProxy::UniqueID srcID, + const SkIRect& srcRect, const SkIPoint& dstPoint) + : INHERITED(ClassID()) + , fDstProxyID(dstID) + , fSrcProxyID(srcID) + , fDst(dst) + , fSrc(src) + , fSrcRect(srcRect) + , fDstPoint(dstPoint) { SkRect bounds = SkRect::MakeXYWH(SkIntToScalar(dstPoint.fX), SkIntToScalar(dstPoint.fY), SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height())); @@ -67,10 +66,14 @@ private: } } + // MDB TODO: remove the proxy IDs once the GrSurfaceProxy carries the ref since they will + // be redundant + GrSurfaceProxy::UniqueID fDstProxyID; + GrSurfaceProxy::UniqueID fSrcProxyID; GrPendingIOResource<GrSurface, kWrite_GrIOType> fDst; - GrPendingIOResource<GrSurface, kRead_GrIOType> fSrc; - SkIRect fSrcRect; - SkIPoint fDstPoint; + GrPendingIOResource<GrSurface, kRead_GrIOType> fSrc; + SkIRect fSrcRect; + SkIPoint fDstPoint; typedef GrOp INHERITED; }; diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index bf7e5ad3ce..4f05b4fc96 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -6,7 +6,7 @@ */ #include "GrVkCaps.h" -#include "GrRenderTarget.h" +#include "GrRenderTargetProxy.h" #include "GrShaderCaps.h" #include "GrVkUtil.h" #include "vk/GrVkBackendContext.h" @@ -53,7 +53,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* this->init(contextOptions, vkInterface, physDev, featureFlags, extensionFlags); } -bool GrVkCaps::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc, +bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, bool* rectsMustMatch, bool* disallowSubrect) const { // Vk doesn't use rectsMustMatch or disallowSubrect. Always return false. *rectsMustMatch = false; @@ -64,7 +64,7 @@ bool GrVkCaps::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc // render target as well. desc->fOrigin = src->origin(); desc->fConfig = src->config(); - if (src->numColorSamples() > 1 || (src->asTexture() && this->supportsCopiesAsDraws())) { + if (src->numColorSamples() > 1 || (src->asTextureProxy() && this->supportsCopiesAsDraws())) { desc->fFlags = kRenderTarget_GrSurfaceFlag; } else { // Just going to use CopyImage here diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h index dce9ce2200..e7ffe053e0 100644 --- a/src/gpu/vk/GrVkCaps.h +++ b/src/gpu/vk/GrVkCaps.h @@ -104,8 +104,8 @@ public: return fPreferedStencilFormat; } - bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc, bool* rectsMustMatch, - bool* disallowSubrect) const override; + bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, + bool* rectsMustMatch, bool* disallowSubrect) const override; private: enum VkVendor { diff --git a/tests/BlendTest.cpp b/tests/BlendTest.cpp index 2d16fb2ff2..8f688e2d69 100644 --- a/tests/BlendTest.cpp +++ b/tests/BlendTest.cpp @@ -84,23 +84,29 @@ DEF_TEST(Blend_byte_multiply, r) { namespace { static sk_sp<SkSurface> create_gpu_surface_backend_texture_as_render_target( GrContext* context, int sampleCnt, int width, int height, GrPixelConfig config, + GrSurfaceOrigin origin, sk_sp<GrTexture>* backingSurface) { GrSurfaceDesc backingDesc; - backingDesc.fHeight = height; + backingDesc.fFlags = kRenderTarget_GrSurfaceFlag; + backingDesc.fOrigin = origin; backingDesc.fWidth = width; + backingDesc.fHeight = height; backingDesc.fConfig = config; - backingDesc.fOrigin = kDefault_GrSurfaceOrigin; - backingDesc.fFlags = kRenderTarget_GrSurfaceFlag; + backingDesc.fSampleCnt = sampleCnt; *backingSurface = context->resourceProvider()->createTexture(backingDesc, SkBudgeted::kNo); + if (!(*backingSurface)) { + return nullptr; + } GrBackendTextureDesc desc; - desc.fConfig = config; + desc.fFlags = kRenderTarget_GrBackendTextureFlag; + desc.fOrigin = origin; desc.fWidth = width; desc.fHeight = height; - desc.fFlags = kRenderTarget_GrBackendTextureFlag; - desc.fTextureHandle = (*backingSurface)->getTextureHandle(); + desc.fConfig = config; desc.fSampleCnt = sampleCnt; + desc.fTextureHandle = (*backingSurface)->getTextureHandle(); sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(context, desc, nullptr); return surface; @@ -127,31 +133,35 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(ES2BlendWithNoTexture, reporter, ctxInfo) }; struct TestCase { - RectAndSamplePoint rectAndPoints; - SkRect clip; - int sampleCnt; + RectAndSamplePoint fRectAndPoints; + SkRect fClip; + int fSampleCnt; + GrSurfaceOrigin fOrigin; }; std::vector<TestCase> testCases; - for (int sampleCnt : {0, 4}) { - for (auto rectAndPoints : allRectsAndPoints) { - for (auto clip : {SkRect::MakeXYWH(0, 0, 10, 10), SkRect::MakeXYWH(1, 1, 8, 8)}) { - testCases.push_back({rectAndPoints, clip, sampleCnt}); + for (auto origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) { + for (int sampleCnt : {0, 4}) { + for (auto rectAndPoints : allRectsAndPoints) { + for (auto clip : {SkRect::MakeXYWH(0, 0, 10, 10), SkRect::MakeXYWH(1, 1, 8, 8)}) { + testCases.push_back({rectAndPoints, clip, sampleCnt, origin}); + } } } } // Run each test case: for (auto testCase : testCases) { - int sampleCnt = testCase.sampleCnt; - SkRect paintRect = testCase.rectAndPoints.rect; - SkIPoint outPoint = testCase.rectAndPoints.outPoint; - SkIPoint inPoint = testCase.rectAndPoints.inPoint; + int sampleCnt = testCase.fSampleCnt; + SkRect paintRect = testCase.fRectAndPoints.rect; + SkIPoint outPoint = testCase.fRectAndPoints.outPoint; + SkIPoint inPoint = testCase.fRectAndPoints.inPoint; + GrSurfaceOrigin origin = testCase.fOrigin; sk_sp<GrTexture> backingSurface; // BGRA forces a framebuffer blit on ES2. sk_sp<SkSurface> surface = create_gpu_surface_backend_texture_as_render_target( - context, sampleCnt, kWidth, kHeight, kConfig, &backingSurface); + context, sampleCnt, kWidth, kHeight, kConfig, origin, &backingSurface); if (!surface && sampleCnt > 0) { // Some platforms don't support MSAA. @@ -161,7 +171,7 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(ES2BlendWithNoTexture, reporter, ctxInfo) // Fill our canvas with 0xFFFF80 SkCanvas* canvas = surface->getCanvas(); - canvas->clipRect(testCase.clip, false); + canvas->clipRect(testCase.fClip, false); SkPaint black_paint; black_paint.setColor(SkColorSetRGB(0xFF, 0xFF, 0x80)); canvas->drawRect(SkRect::MakeXYWH(0, 0, kWidth, kHeight), black_paint); diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp index 0350ff3e5a..56d47c5149 100644 --- a/tools/gpu/GrTest.cpp +++ b/tools/gpu/GrTest.cpp @@ -273,8 +273,8 @@ public: bool isConfigTexturable(GrPixelConfig config) const override { return false; } bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override { return false; } bool canConfigBeImageStorage(GrPixelConfig) const override { return false; } - bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc, bool* rectsMustMatch, - bool* disallowSubrect) const override { + bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, + bool* rectsMustMatch, bool* disallowSubrect) const override { return false; } |