aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/gpu/GrCaps.h8
-rw-r--r--src/gpu/GrContextPriv.h15
-rw-r--r--src/gpu/GrRenderTargetContext.cpp93
-rw-r--r--src/gpu/GrRenderTargetContext.h13
-rw-r--r--src/gpu/GrRenderTargetOpList.cpp7
-rw-r--r--src/gpu/GrRenderTargetOpList.h5
-rw-r--r--src/gpu/GrTextureContext.cpp15
-rw-r--r--src/gpu/GrTextureOpList.cpp7
-rw-r--r--src/gpu/GrTextureOpList.h5
-rw-r--r--src/gpu/gl/GrGLCaps.cpp44
-rw-r--r--src/gpu/gl/GrGLCaps.h4
-rw-r--r--src/gpu/ops/GrCopySurfaceOp.cpp44
-rw-r--r--src/gpu/ops/GrCopySurfaceOp.h51
-rw-r--r--src/gpu/vk/GrVkCaps.cpp6
-rw-r--r--src/gpu/vk/GrVkCaps.h4
-rw-r--r--tests/BlendTest.cpp48
-rw-r--r--tools/gpu/GrTest.cpp4
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;
}