aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-03-06 16:17:12 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-07 15:11:24 +0000
commit467921e5e6479fe9cebba125657d8e33d89004ae (patch)
treebffd056e5d9ad99a50c1876d658f4b31d6721d15
parent894d5611e54cbf62a03ff9ffb48a2302dda9ab86 (diff)
Move GrDrawOp pipeline/clip processing to GrRenderTargetContext
This is currently done in GrOpList. However, it can trigger resource creation, which in turn can trigger a flush. In the future flushing may destroy the op list. Change-Id: I21cb1e10060bf31c95431c0511fcfff637cd6498 Reviewed-on: https://skia-review.googlesource.com/9304 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
-rw-r--r--gn/gpu.gni2
-rw-r--r--include/gpu/GrCaps.h10
-rw-r--r--src/gpu/GrGpu.h8
-rw-r--r--src/gpu/GrRenderTargetContext.cpp234
-rw-r--r--src/gpu/GrRenderTargetContext.h (renamed from include/gpu/GrRenderTargetContext.h)11
-rw-r--r--src/gpu/GrRenderTargetOpList.cpp211
-rw-r--r--src/gpu/GrRenderTargetOpList.h38
-rw-r--r--src/gpu/gl/GrGLCaps.cpp61
-rw-r--r--src/gpu/gl/GrGLCaps.h2
-rw-r--r--src/gpu/gl/GrGLGpu.cpp59
-rw-r--r--src/gpu/gl/GrGLGpu.h2
-rw-r--r--src/gpu/vk/GrVkCaps.cpp20
-rw-r--r--src/gpu/vk/GrVkCaps.h2
-rw-r--r--src/gpu/vk/GrVkGpu.cpp17
-rw-r--r--src/gpu/vk/GrVkGpu.h2
-rw-r--r--tools/gpu/GrTest.cpp13
16 files changed, 307 insertions, 385 deletions
diff --git a/gn/gpu.gni b/gn/gpu.gni
index 7c1ad9d628..4cab21f811 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -27,7 +27,6 @@ skia_gpu_sources = [
"$_include/gpu/GrProgramElement.h",
"$_include/gpu/GrGpuResourceRef.h",
"$_include/gpu/GrRenderTarget.h",
- "$_include/gpu/GrRenderTargetContext.h",
"$_include/gpu/GrResourceKey.h",
"$_include/gpu/GrShaderCaps.h",
"$_include/gpu/GrShaderVar.h",
@@ -162,6 +161,7 @@ skia_gpu_sources = [
"$_src/gpu/GrReducedClip.cpp",
"$_src/gpu/GrReducedClip.h",
"$_src/gpu/GrRenderTargetContext.cpp",
+ "$_src/gpu/GrRenderTargetContext.h",
"$_src/gpu/GrRenderTargetContextPriv.h",
"$_src/gpu/GrPathRenderingRenderTargetContext.cpp",
"$_src/gpu/GrPathRenderingRenderTargetContext.h",
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index 23f870dfe0..239d4a4ea9 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -17,7 +17,7 @@
#include "SkString.h"
struct GrContextOptions;
-
+class GrRenderTarget;
/**
* Represents the capabilities of a GrContext.
@@ -185,6 +185,14 @@ public:
bool fenceSyncSupport() const { return fFenceSyncSupport; }
bool crossContextTextureSupport() const { return fCrossContextTextureSupport; }
+ /**
+ * 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
+ * efficiently succeed.
+ */
+ virtual bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const = 0;
+
protected:
/** Subclasses must call this at the end of their constructors in order to apply caps
overrides requested by the client. Note that overrides will only reduce the caps never
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 5b69ead462..ed77fcd0d3 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -307,14 +307,6 @@ public:
GrPixelConfig config, GrBuffer* transferBuffer,
size_t offset, size_t rowBytes, GrFence* fence);
- /**
- * 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
- * efficiently succeed.
- */
- virtual bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const = 0;
-
// After the client interacts directly with the 3D context state the GrGpu
// must resync its internal state and assumptions about 3D context state.
// Each time this occurs the GrGpu bumps a timestamp.
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 1ddf8df511..bae2ea6307 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -6,8 +6,8 @@
*/
#include "GrRenderTargetContext.h"
+#include "GrAppliedClip.h"
#include "GrColor.h"
-#include "GrDrawOpTest.h"
#include "GrDrawingManager.h"
#include "GrFixedClip.h"
#include "GrGpuResourcePriv.h"
@@ -17,9 +17,14 @@
#include "GrRenderTargetContextPriv.h"
#include "GrRenderTargetPriv.h"
#include "GrResourceProvider.h"
+#include "GrStencilAttachment.h"
+#include "SkLatticeIter.h"
+#include "SkMatrixPriv.h"
#include "SkSurfacePriv.h"
-
+#include "effects/GrRRectEffect.h"
+#include "instanced/InstancedRendering.h"
#include "ops/GrClearOp.h"
+#include "ops/GrDrawOp.h"
#include "ops/GrDrawAtlasOp.h"
#include "ops/GrDrawVerticesOp.h"
#include "ops/GrLatticeOp.h"
@@ -28,20 +33,11 @@
#include "ops/GrRectOpFactory.h"
#include "ops/GrRegionOp.h"
#include "ops/GrShadowRRectOp.h"
-
-#include "effects/GrRRectEffect.h"
-
-#include "instanced/InstancedRendering.h"
-
+#include "ops/GrStencilPathOp.h"
#include "text/GrAtlasTextContext.h"
#include "text/GrStencilAndCoverTextContext.h"
-
#include "../private/GrAuditTrail.h"
-#include "SkGr.h"
-#include "SkLatticeIter.h"
-#include "SkMatrixPriv.h"
-
#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this->drawingManager()->getContext())
#define ASSERT_SINGLE_OWNER \
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
@@ -523,7 +519,7 @@ bool GrRenderTargetContext::drawFilledRect(const GrClip& clip,
if (ss) {
pipelineBuilder.setUserStencil(ss);
}
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return true;
}
}
@@ -540,7 +536,7 @@ bool GrRenderTargetContext::drawFilledRect(const GrClip& clip,
if (ss) {
pipelineBuilder.setUserStencil(ss);
}
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return true;
}
}
@@ -663,7 +659,7 @@ void GrRenderTargetContext::drawRect(const GrClip& clip,
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
pipelineBuilder.setSnapVerticesToPixelCenters(snapToPixelCenters);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return;
}
}
@@ -699,9 +695,55 @@ void GrRenderTargetContextPriv::stencilPath(const GrClip& clip,
GrAAType aaType,
const SkMatrix& viewMatrix,
const GrPath* path) {
+ ASSERT_SINGLE_OWNER_PRIV
+ RETURN_IF_ABANDONED_PRIV
+ SkDEBUGCODE(fRenderTargetContext->validate();)
+ GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
+ "GrRenderTargetContext::stencilPath");
+
SkASSERT(aaType != GrAAType::kCoverage);
- fRenderTargetContext->getOpList()->stencilPath(fRenderTargetContext, clip, aaType, viewMatrix,
- path);
+
+ bool useHWAA = GrAATypeIsHW(aaType);
+ // TODO: extract portions of checkDraw that are relevant to path stenciling.
+ SkASSERT(path);
+ SkASSERT(fRenderTargetContext->caps()->shaderCaps()->pathRenderingSupport());
+
+ // FIXME: Use path bounds instead of this WAR once
+ // https://bugs.chromium.org/p/skia/issues/detail?id=5640 is resolved.
+ SkRect bounds = SkRect::MakeIWH(fRenderTargetContext->width(), fRenderTargetContext->height());
+
+ // Setup clip
+ GrAppliedClip appliedClip(bounds);
+ if (!clip.apply(fRenderTargetContext->fContext, fRenderTargetContext, useHWAA, true,
+ &appliedClip)) {
+ return;
+ }
+
+ // Coverage AA does not make sense when rendering to the stencil buffer. The caller should never
+ // attempt this in a situation that would require coverage AA.
+ SkASSERT(!appliedClip.clipCoverageFragmentProcessor());
+
+ GrRenderTarget* rt = fRenderTargetContext->accessRenderTarget();
+ if (!rt) {
+ return;
+ }
+ GrStencilAttachment* stencilAttachment =
+ fRenderTargetContext->fContext->resourceProvider()->attachStencilAttachment(rt);
+ if (!stencilAttachment) {
+ SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
+ return;
+ }
+
+ std::unique_ptr<GrOp> op = GrStencilPathOp::Make(viewMatrix,
+ useHWAA,
+ path->getFillType(),
+ appliedClip.hasStencilClip(),
+ stencilAttachment->bits(),
+ appliedClip.scissorState(),
+ fRenderTargetContext->accessRenderTarget(),
+ path);
+ op->setClippedBounds(appliedClip.clippedDrawBounds());
+ fRenderTargetContext->getOpList()->recordOp(std::move(op), fRenderTargetContext);
}
void GrRenderTargetContextPriv::stencilRect(const GrClip& clip,
@@ -779,7 +821,7 @@ void GrRenderTargetContext::fillRectToRect(const GrClip& clip,
&aaType));
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return;
}
}
@@ -838,7 +880,7 @@ void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip,
&aaType));
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return;
}
}
@@ -854,7 +896,7 @@ void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip,
std::unique_ptr<GrDrawOp> op =
GrAAFillRectOp::Make(paint.getColor(), viewMatrix, localMatrix, croppedRect);
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return;
}
@@ -904,7 +946,7 @@ void GrRenderTargetContext::drawVertices(const GrClip& clip,
return;
}
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
}
void GrRenderTargetContext::drawVertices(const GrClip& clip,
@@ -926,7 +968,7 @@ void GrRenderTargetContext::drawVertices(const GrClip& clip,
return;
}
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
}
///////////////////////////////////////////////////////////////////////////////
@@ -948,7 +990,7 @@ void GrRenderTargetContext::drawAtlas(const GrClip& clip,
std::unique_ptr<GrDrawOp> op =
GrDrawAtlasOp::Make(paint.getColor(), viewMatrix, spriteCount, xform, texRect, colors);
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
}
///////////////////////////////////////////////////////////////////////////////
@@ -993,7 +1035,7 @@ void GrRenderTargetContext::drawRRect(const GrClip& origClip,
fInstancedPipelineInfo, &aaType));
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, *clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, *clip, std::move(op));
return;
}
}
@@ -1009,7 +1051,7 @@ void GrRenderTargetContext::drawRRect(const GrClip& origClip,
shaderCaps);
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, *clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, *clip, std::move(op));
return;
}
}
@@ -1047,7 +1089,7 @@ void GrRenderTargetContext::drawShadowRRect(const GrClip& clip,
blurRadius, stroke, shaderCaps);
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return;
}
}
@@ -1071,7 +1113,7 @@ bool GrRenderTargetContext::drawFilledDRRect(const GrClip& clip,
&aaType));
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return true;
}
}
@@ -1191,7 +1233,7 @@ void GrRenderTargetContext::drawRegion(const GrClip& clip,
std::unique_ptr<GrDrawOp> op = GrRegionOp::Make(paint.getColor(), viewMatrix, region);
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
}
void GrRenderTargetContext::drawOval(const GrClip& clip,
@@ -1222,7 +1264,7 @@ void GrRenderTargetContext::drawOval(const GrClip& clip,
fInstancedPipelineInfo, &aaType));
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return;
}
}
@@ -1234,7 +1276,7 @@ void GrRenderTargetContext::drawOval(const GrClip& clip,
GrOvalOpFactory::MakeOvalOp(paint.getColor(), viewMatrix, oval, stroke, shaderCaps);
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return;
}
}
@@ -1274,7 +1316,7 @@ void GrRenderTargetContext::drawArc(const GrClip& clip,
shaderCaps);
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return;
}
}
@@ -1302,7 +1344,7 @@ void GrRenderTargetContext::drawImageLattice(const GrClip& clip,
imageHeight, std::move(iter), dst);
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
}
void GrRenderTargetContext::prepareForExternalIO() {
@@ -1339,7 +1381,7 @@ void GrRenderTargetContext::drawNonAAFilledRect(const GrClip& clip,
if (ss) {
pipelineBuilder.setUserStencil(ss);
}
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
}
// Can 'path' be drawn as a pair of filled nested rectangles?
@@ -1419,7 +1461,7 @@ void GrRenderTargetContext::drawPath(const GrClip& clip,
GrRectOpFactory::MakeAAFillNestedRects(paint.getColor(), viewMatrix, rects);
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
}
return;
}
@@ -1433,7 +1475,7 @@ void GrRenderTargetContext::drawPath(const GrClip& clip,
paint.getColor(), viewMatrix, ovalRect, style.strokeRec(), shaderCaps);
if (op) {
GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ this->addDrawOp(pipelineBuilder, clip, std::move(op));
return;
}
}
@@ -1605,6 +1647,32 @@ void GrRenderTargetContext::internalDrawPath(const GrClip& clip,
pr->drawPath(args);
}
+static void op_bounds(SkRect* bounds, const GrOp* op) {
+ *bounds = op->bounds();
+ if (op->hasZeroArea()) {
+ if (op->hasAABloat()) {
+ bounds->outset(0.5f, 0.5f);
+ } else {
+ // We don't know which way the particular GPU will snap lines or points at integer
+ // coords. So we ensure that the bounds is large enough for either snap.
+ SkRect before = *bounds;
+ bounds->roundOut(bounds);
+ if (bounds->fLeft == before.fLeft) {
+ bounds->fLeft -= 1;
+ }
+ if (bounds->fTop == before.fTop) {
+ bounds->fTop -= 1;
+ }
+ if (bounds->fRight == before.fRight) {
+ bounds->fRight += 1;
+ }
+ if (bounds->fBottom == before.fBottom) {
+ bounds->fBottom += 1;
+ }
+ }
+ }
+}
+
void GrRenderTargetContext::addDrawOp(const GrPipelineBuilder& pipelineBuilder, const GrClip& clip,
std::unique_ptr<GrDrawOp> op) {
ASSERT_SINGLE_OWNER
@@ -1612,5 +1680,99 @@ void GrRenderTargetContext::addDrawOp(const GrPipelineBuilder& pipelineBuilder,
SkDEBUGCODE(this->validate();)
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::addDrawOp");
- this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
+ // Setup clip
+ SkRect bounds;
+ op_bounds(&bounds, op.get());
+ GrAppliedClip appliedClip(bounds);
+ if (!clip.apply(fContext, this, pipelineBuilder.isHWAntialias(),
+ pipelineBuilder.hasUserStencilSettings(), &appliedClip)) {
+ return;
+ }
+
+ // This forces instantiation of the render target. Pipeline creation is moving to flush time
+ // by which point instantiation must have occurred anyway.
+ GrRenderTarget* rt = this->accessRenderTarget();
+ if (!rt) {
+ return;
+ }
+
+ GrResourceProvider* resourceProvider = fContext->resourceProvider();
+ if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) {
+ if (!resourceProvider->attachStencilAttachment(this->accessRenderTarget())) {
+ SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
+ return;
+ }
+ }
+
+ GrProcessorSet::FragmentProcessorAnalysis analysis;
+ op->analyzeProcessors(&analysis, pipelineBuilder.processors(), appliedClip, *this->caps());
+
+ GrPipeline::InitArgs args;
+ pipelineBuilder.getPipelineInitArgs(&args);
+ args.fAppliedClip = &appliedClip;
+ args.fRenderTarget = rt;
+ args.fCaps = this->caps();
+ args.fAnalysis = &analysis;
+
+ if (pipelineBuilder.willXPNeedDstTexture(*this->caps(), analysis)) {
+ this->setupDstTexture(rt, clip, bounds, &args.fDstTexture);
+ if (!args.fDstTexture.texture()) {
+ return;
+ }
+ }
+ op->initPipeline(args);
+ // TODO: We need to add pipeline dependencies on textures, etc before recording this op.
+ op->setClippedBounds(appliedClip.clippedDrawBounds());
+ this->getOpList()->addOp(std::move(op), this);
+}
+
+void GrRenderTargetContext::setupDstTexture(GrRenderTarget* rt, const GrClip& clip,
+ const SkRect& opBounds,
+ GrXferProcessor::DstTexture* dstTexture) {
+ if (this->caps()->textureBarrierSupport()) {
+ if (GrTexture* rtTex = rt->asTexture()) {
+ // 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->setOffset(0, 0);
+ return;
+ }
+ }
+
+ SkIRect copyRect;
+ clip.getConservativeBounds(rt->width(), rt->height(), &copyRect);
+
+ SkIRect drawIBounds;
+ opBounds.roundOut(&drawIBounds);
+ if (!copyRect.intersect(drawIBounds)) {
+#ifdef SK_DEBUG
+ GrCapsDebugf(this->caps(), "Missed an early reject. "
+ "Bailing on draw from setupDstTexture.\n");
+#endif
+ return;
+ }
+
+ // MSAA consideration: When there is support for reading MSAA samples in the shader we could
+ // have per-sample dst values by making the copy multisampled.
+ GrSurfaceDesc desc;
+ if (!this->caps()->initDescForDstCopy(rt, &desc)) {
+ desc.fOrigin = kDefault_GrSurfaceOrigin;
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
+ desc.fConfig = rt->config();
+ }
+
+ desc.fWidth = copyRect.width();
+ desc.fHeight = copyRect.height();
+
+ static const uint32_t kFlags = 0;
+ sk_sp<GrTexture> copy(fContext->resourceProvider()->createApproxTexture(desc, kFlags));
+
+ if (!copy) {
+ SkDebugf("Failed to create temporary copy of destination texture.\n");
+ return;
+ }
+ SkIPoint dstPoint = {0, 0};
+ this->getOpList()->copySurface(copy.get(), rt, copyRect, dstPoint);
+ dstTexture->setTexture(std::move(copy));
+ dstTexture->setOffset(copyRect.fLeft, copyRect.fTop);
}
diff --git a/include/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index f976e8e4a8..d711c81456 100644
--- a/include/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -12,6 +12,7 @@
#include "GrContext.h"
#include "GrPaint.h"
#include "GrSurfaceContext.h"
+#include "GrXferProcessor.h"
#include "SkRefCnt.h"
#include "SkSurfaceProps.h"
#include "../private/GrInstancedPipelineInfo.h"
@@ -471,9 +472,17 @@ private:
bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
size_t srcRowBytes, int x, int y, uint32_t flags) override;
- // This entry point allows the GrTextContext-derived classes to add their ops to the GrOpList.
+ // This performs processing specific to GrDrawOp-derived ops before recording them into the
+ // op list.
void addDrawOp(const GrPipelineBuilder&, const GrClip&, std::unique_ptr<GrDrawOp>);
+ // 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*);
+
+
GrRenderTargetOpList* getOpList();
sk_sp<GrRenderTargetProxy> fRenderTargetProxy;
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index 2b05a16b50..2c28406fd0 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -6,35 +6,17 @@
*/
#include "GrRenderTargetOpList.h"
-
-#include "GrAppliedClip.h"
#include "GrAuditTrail.h"
#include "GrCaps.h"
-#include "GrRenderTargetContext.h"
#include "GrGpu.h"
#include "GrGpuCommandBuffer.h"
-#include "GrPath.h"
-#include "GrPipeline.h"
-#include "GrMemoryPool.h"
-#include "GrPipelineBuilder.h"
#include "GrRenderTarget.h"
+#include "GrRenderTargetContext.h"
#include "GrResourceProvider.h"
-#include "GrRenderTargetPriv.h"
-#include "GrStencilAttachment.h"
-#include "GrSurfacePriv.h"
-#include "GrTexture.h"
-
-#include "SkStrokeRec.h"
-
#include "ops/GrClearOp.h"
#include "ops/GrClearStencilClipOp.h"
#include "ops/GrCopySurfaceOp.h"
#include "ops/GrDiscardOp.h"
-#include "ops/GrDrawOp.h"
-#include "ops/GrDrawPathOp.h"
-#include "ops/GrRectOpFactory.h"
-#include "ops/GrStencilPathOp.h"
-
#include "instanced/InstancedRendering.h"
using gr_instanced::InstancedRendering;
@@ -52,8 +34,6 @@ GrRenderTargetOpList::GrRenderTargetOpList(GrRenderTargetProxy* rtp, GrGpu* gpu,
, fGpu(SkRef(gpu))
, fResourceProvider(resourceProvider)
, fLastClipStackGenID(SK_InvalidUniqueID) {
- // TODO: Stop extracting the context (currently needed by GrClip)
- fContext = fGpu->getContext();
fMaxOpLookback = (options.fMaxOpCombineLookback < 0) ? kDefaultMaxOpLookback
: options.fMaxOpCombineLookback;
@@ -92,58 +72,6 @@ void GrRenderTargetOpList::dump() const {
}
#endif
-void GrRenderTargetOpList::setupDstTexture(GrRenderTarget* rt,
- const GrClip& clip,
- const SkRect& opBounds,
- GrXferProcessor::DstTexture* dstTexture) {
- if (this->caps()->textureBarrierSupport()) {
- if (GrTexture* rtTex = rt->asTexture()) {
- // 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->setOffset(0, 0);
- return;
- }
- }
-
- SkIRect copyRect;
- clip.getConservativeBounds(rt->width(), rt->height(), &copyRect);
-
- SkIRect drawIBounds;
- opBounds.roundOut(&drawIBounds);
- if (!copyRect.intersect(drawIBounds)) {
-#ifdef SK_DEBUG
- GrCapsDebugf(this->caps(), "Missed an early reject. "
- "Bailing on draw from setupDstTexture.\n");
-#endif
- return;
- }
-
- // MSAA consideration: When there is support for reading MSAA samples in the shader we could
- // have per-sample dst values by making the copy multisampled.
- GrSurfaceDesc desc;
- if (!fGpu->initDescForDstCopy(rt, &desc)) {
- desc.fOrigin = kDefault_GrSurfaceOrigin;
- desc.fFlags = kRenderTarget_GrSurfaceFlag;
- desc.fConfig = rt->config();
- }
-
- desc.fWidth = copyRect.width();
- desc.fHeight = copyRect.height();
-
- static const uint32_t kFlags = 0;
- sk_sp<GrTexture> copy(fResourceProvider->createApproxTexture(desc, kFlags));
-
- if (!copy) {
- SkDebugf("Failed to create temporary copy of destination texture.\n");
- return;
- }
- SkIPoint dstPoint = {0, 0};
- this->copySurface(copy.get(), rt, copyRect, dstPoint);
- dstTexture->setTexture(std::move(copy));
- dstTexture->setOffset(copyRect.fLeft, copyRect.fTop);
-}
-
void GrRenderTargetOpList::prepareOps(GrOpFlushState* flushState) {
// Semi-usually the GrOpLists are already closed at this point, but sometimes Ganesh
// needs to flush mid-draw. In that case, the SkGpuDevice's GrOpLists won't be closed
@@ -216,152 +144,19 @@ void GrRenderTargetOpList::reset() {
}
void GrRenderTargetOpList::abandonGpuResources() {
- if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
+ if (GrCaps::InstancedSupport::kNone != this->caps()->instancedSupport()) {
InstancedRendering* ir = this->instancedRendering();
ir->resetGpuResources(InstancedRendering::ResetType::kAbandon);
}
}
void GrRenderTargetOpList::freeGpuResources() {
- if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
+ if (GrCaps::InstancedSupport::kNone != this->caps()->instancedSupport()) {
InstancedRendering* ir = this->instancedRendering();
ir->resetGpuResources(InstancedRendering::ResetType::kDestroy);
}
}
-static void op_bounds(SkRect* bounds, const GrOp* op) {
- *bounds = op->bounds();
- if (op->hasZeroArea()) {
- if (op->hasAABloat()) {
- bounds->outset(0.5f, 0.5f);
- } else {
- // We don't know which way the particular GPU will snap lines or points at integer
- // coords. So we ensure that the bounds is large enough for either snap.
- SkRect before = *bounds;
- bounds->roundOut(bounds);
- if (bounds->fLeft == before.fLeft) {
- bounds->fLeft -= 1;
- }
- if (bounds->fTop == before.fTop) {
- bounds->fTop -= 1;
- }
- if (bounds->fRight == before.fRight) {
- bounds->fRight += 1;
- }
- if (bounds->fBottom == before.fBottom) {
- bounds->fBottom += 1;
- }
- }
- }
-}
-
-void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder,
- GrRenderTargetContext* renderTargetContext,
- const GrClip& clip,
- std::unique_ptr<GrDrawOp> op) {
- // Setup clip
- SkRect bounds;
- op_bounds(&bounds, op.get());
- GrAppliedClip appliedClip(bounds);
- if (!clip.apply(fContext, renderTargetContext, pipelineBuilder.isHWAntialias(),
- pipelineBuilder.hasUserStencilSettings(), &appliedClip)) {
- return;
- }
-
- if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) {
- if (!renderTargetContext->accessRenderTarget()) {
- return;
- }
-
- if (!fResourceProvider->attachStencilAttachment(
- renderTargetContext->accessRenderTarget())) {
- SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
- return;
- }
- }
-
- GrProcessorSet::FragmentProcessorAnalysis analysis;
- op->analyzeProcessors(&analysis, pipelineBuilder.processors(), appliedClip, *this->caps());
-
- GrPipeline::InitArgs args;
- pipelineBuilder.getPipelineInitArgs(&args);
- args.fAppliedClip = &appliedClip;
- // This forces instantiation of the render target. Pipeline creation is moving to flush time
- // by which point instantiation must have occurred anyway.
- args.fRenderTarget = renderTargetContext->accessRenderTarget();
- if (!args.fRenderTarget) {
- return;
- }
- args.fCaps = this->caps();
- args.fAnalysis = &analysis;
-
- if (!renderTargetContext->accessRenderTarget()) {
- return;
- }
-
- if (pipelineBuilder.willXPNeedDstTexture(*this->caps(), analysis)) {
- this->setupDstTexture(renderTargetContext->accessRenderTarget(), clip, bounds,
- &args.fDstTexture);
- if (!args.fDstTexture.texture()) {
- return;
- }
- }
- op->initPipeline(args);
-
-#ifdef ENABLE_MDB
- SkASSERT(fSurface);
- op->pipeline()->addDependenciesTo(fSurface);
-#endif
- op->setClippedBounds(appliedClip.clippedDrawBounds());
- this->recordOp(std::move(op), renderTargetContext);
-}
-
-void GrRenderTargetOpList::stencilPath(GrRenderTargetContext* renderTargetContext,
- const GrClip& clip,
- GrAAType aaType,
- const SkMatrix& viewMatrix,
- const GrPath* path) {
- bool useHWAA = GrAATypeIsHW(aaType);
- // TODO: extract portions of checkDraw that are relevant to path stenciling.
- SkASSERT(path);
- SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
-
- // FIXME: Use path bounds instead of this WAR once
- // https://bugs.chromium.org/p/skia/issues/detail?id=5640 is resolved.
- SkRect bounds = SkRect::MakeIWH(renderTargetContext->width(), renderTargetContext->height());
-
- // Setup clip
- GrAppliedClip appliedClip(bounds);
- if (!clip.apply(fContext, renderTargetContext, useHWAA, true, &appliedClip)) {
- return;
- }
-
- // Coverage AA does not make sense when rendering to the stencil buffer. The caller should never
- // attempt this in a situation that would require coverage AA.
- SkASSERT(!appliedClip.clipCoverageFragmentProcessor());
-
- if (!renderTargetContext->accessRenderTarget()) {
- return;
- }
- GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAttachment(
- renderTargetContext->accessRenderTarget());
- if (!stencilAttachment) {
- SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
- return;
- }
-
- std::unique_ptr<GrOp> op = GrStencilPathOp::Make(viewMatrix,
- useHWAA,
- path->getFillType(),
- appliedClip.hasStencilClip(),
- stencilAttachment->bits(),
- appliedClip.scissorState(),
- renderTargetContext->accessRenderTarget(),
- path);
- op->setClippedBounds(appliedClip.clippedDrawBounds());
- this->recordOp(std::move(op), renderTargetContext);
-}
-
void GrRenderTargetOpList::fullClear(GrRenderTargetContext* renderTargetContext, GrColor color) {
GrRenderTarget* renderTarget = renderTargetContext->accessRenderTarget();
// Currently this just inserts or updates the last clear op. However, once in MDB this can
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index 36bdc6bf55..e232547f70 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -8,19 +8,11 @@
#ifndef GrRenderTargetOpList_DEFINED
#define GrRenderTargetOpList_DEFINED
-#include "GrClip.h"
-#include "GrContext.h"
#include "GrOpList.h"
-#include "GrPathProcessor.h"
#include "GrPrimitiveProcessor.h"
#include "GrPathRendering.h"
-#include "GrXferProcessor.h"
-
-#include "ops/GrDrawOp.h"
-
#include "SkClipStack.h"
#include "SkMatrix.h"
-#include "SkPath.h"
#include "SkStringUtils.h"
#include "SkStrokeRec.h"
#include "SkTArray.h"
@@ -29,10 +21,8 @@
class GrAuditTrail;
class GrClearOp;
-class GrClip;
class GrCaps;
-class GrPath;
-class GrDrawPathOpBase;
+class GrClip;
class GrOp;
class GrPipelineBuilder;
class GrRenderTargetProxy;
@@ -77,26 +67,10 @@ public:
*/
const GrCaps* caps() const { return fGpu->caps(); }
- void addDrawOp(const GrPipelineBuilder&, GrRenderTargetContext*, const GrClip&,
- std::unique_ptr<GrDrawOp>);
-
void addOp(std::unique_ptr<GrOp> op, GrRenderTargetContext* renderTargetContext) {
this->recordOp(std::move(op), renderTargetContext);
}
- /**
- * Draws the path into user stencil bits. Upon return, all user stencil values
- * inside the path will be nonzero. The path's fill must be either even/odd or
- * winding (notnverse or hairline).It will respect the HW antialias boolean (if
- * possible in the 3D API). Note, we will never have an inverse fill with
- * stencil path.
- */
- void stencilPath(GrRenderTargetContext*,
- const GrClip&,
- GrAAType aa,
- const SkMatrix& viewMatrix,
- const GrPath*);
-
/** Clears the entire render target */
void fullClear(GrRenderTargetContext*, GrColor color);
@@ -136,14 +110,6 @@ private:
void forwardCombine();
- // 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*);
-
// Used only via GrRenderTargetContextPriv.
void clearStencilClip(const GrFixedClip&, bool insideStencilMask, GrRenderTargetContext*);
@@ -159,8 +125,6 @@ private:
GrClearOp* fLastFullClearOp = nullptr;
GrGpuResource::UniqueID fLastFullClearRenderTargetID = GrGpuResource::UniqueID::InvalidID();
- // The context is only in service of the GrClip, remove once it doesn't need this.
- GrContext* fContext;
GrGpu* fGpu;
GrResourceProvider* fResourceProvider;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index d2e18995a3..cb0d7899e7 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -5,16 +5,15 @@
* found in the LICENSE file.
*/
-
#include "GrGLCaps.h"
-
#include "GrContextOptions.h"
#include "GrGLContext.h"
#include "GrGLRenderTarget.h"
+#include "GrGLTexture.h"
#include "GrShaderCaps.h"
-#include "instanced/GLInstancedRendering.h"
#include "SkTSearch.h"
#include "SkTSort.h"
+#include "instanced/GLInstancedRendering.h"
GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
const GrGLContextInfo& ctxInfo,
@@ -2068,6 +2067,62 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
#endif
}
+bool GrGLCaps::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const {
+ // 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;
+ 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;
+ }
+
+ // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
+ // possible and we return false to fallback to creating a render target dst for render-to-
+ // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
+ // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
+ GrSurfaceOrigin originForBlitFramebuffer = kDefault_GrSurfaceOrigin;
+ if (this->blitFramebufferSupportFlags() & kNoScalingOrMirroring_BlitFramebufferFlag) {
+ originForBlitFramebuffer = src->origin();
+ }
+
+ // Check for format issues with glCopyTexSubImage2D
+ if (this->bgraIsInternalFormat() && kBGRA_8888_GrPixelConfig == src->config()) {
+ // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
+ // then we set up for that, otherwise fail.
+ if (this->canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
+ desc->fOrigin = originForBlitFramebuffer;
+ desc->fConfig = kBGRA_8888_GrPixelConfig;
+ return true;
+ }
+ 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();
+ return true;
+ }
+ return false;
+ }
+
+ // We'll do a CopyTexSubImage. Make the dst a plain old texture.
+ desc->fConfig = src->config();
+ desc->fOrigin = src->origin();
+ desc->fFlags = kNone_GrSurfaceFlags;
+ return true;
+}
+
void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
if (options.fEnableInstancedRendering) {
fInstancedSupport = gr_instanced::GLInstancedRendering::CheckSupport(*this);
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 8a83e02222..a659435784 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -359,6 +359,8 @@ public:
return fRGBAToBGRAReadbackConversionsAreSlow;
}
+ bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const override;
+
private:
enum ExternalFormatUsage {
kTexImage_ExternalFormatUsage,
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index bda1c16b59..7a811d1c8f 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -3464,65 +3464,6 @@ void GrGLGpu::unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface
}
}
-bool GrGLGpu::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const {
- // If the src is a texture, we can implement the blit as a draw assuming the config is
- // renderable.
- if (src->asTexture() && this->caps()->isConfigRenderable(src->config(), false)) {
- desc->fOrigin = kDefault_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;
- }
-
- // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
- // possible and we return false to fallback to creating a render target dst for render-to-
- // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
- // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
-
- GrSurfaceOrigin originForBlitFramebuffer = kDefault_GrSurfaceOrigin;
- if (this->glCaps().blitFramebufferSupportFlags() &
- GrGLCaps::kNoScalingOrMirroring_BlitFramebufferFlag) {
- originForBlitFramebuffer = src->origin();
- }
-
- // Check for format issues with glCopyTexSubImage2D
- if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInternalFormat() &&
- kBGRA_8888_GrPixelConfig == src->config()) {
- // glCopyTexSubImage2D doesn't work with this config. If the bgra can be used with fbo blit
- // then we set up for that, otherwise fail.
- if (this->glCaps().canConfigBeFBOColorAttachment(kBGRA_8888_GrPixelConfig)) {
- desc->fOrigin = originForBlitFramebuffer;
- desc->fConfig = kBGRA_8888_GrPixelConfig;
- return true;
- }
- 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->glCaps().canConfigBeFBOColorAttachment(src->config())) {
- desc->fOrigin = originForBlitFramebuffer;
- desc->fConfig = src->config();
- return true;
- }
- return false;
- }
-
- // We'll do a CopyTexSubImage. Make the dst a plain old texture.
- desc->fConfig = src->config();
- desc->fOrigin = src->origin();
- desc->fFlags = kNone_GrSurfaceFlags;
- return true;
-}
-
bool GrGLGpu::onCopySurface(GrSurface* dst,
GrSurface* src,
const SkIRect& srcRect,
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 564ed7629a..6a175d51e9 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -75,8 +75,6 @@ public:
GrPixelConfig srcConfig, DrawPreference*,
WritePixelTempDrawInfo*) override;
- bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const override;
-
// These functions should be used to bind GL objects. They track the GL state and skip redundant
// bindings. Making the equivalent glBind calls directly will confuse the state tracking.
void bindVertexArray(GrGLuint id) {
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index fd454ad544..16a91c1a1f 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -6,11 +6,11 @@
*/
#include "GrVkCaps.h"
-
+#include "GrRenderTarget.h"
#include "GrShaderCaps.h"
#include "GrVkUtil.h"
-#include "vk/GrVkInterface.h"
#include "vk/GrVkBackendContext.h"
+#include "vk/GrVkInterface.h"
GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags)
@@ -52,6 +52,22 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
this->init(contextOptions, vkInterface, physDev, featureFlags, extensionFlags);
}
+bool GrVkCaps::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const {
+ // We can always succeed here with either a CopyImage (none msaa src) or ResolveImage (msaa).
+ // For CopyImage we can make a simple texture, for ResolveImage we require the dst to be a
+ // render target as well.
+ desc->fOrigin = src->origin();
+ desc->fConfig = src->config();
+ if (src->numColorSamples() > 1 || (src->asTexture() && this->supportsCopiesAsDraws())) {
+ desc->fFlags = kRenderTarget_GrSurfaceFlag;
+ } else {
+ // Just going to use CopyImage here
+ desc->fFlags = kNone_GrSurfaceFlags;
+ }
+
+ return true;
+}
+
void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags) {
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 6d030f69a1..6ef0796257 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -87,6 +87,8 @@ public:
return fPreferedStencilFormat;
}
+ bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const override;
+
private:
enum VkVendor {
kQualcomm_VkVendor = 20803,
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index b85aa2da4e..4008c7c162 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -1590,23 +1590,6 @@ bool GrVkGpu::onCopySurface(GrSurface* dst,
return false;
}
-bool GrVkGpu::initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const {
- // We can always succeed here with either a CopyImage (none msaa src) or ResolveImage (msaa).
- // For CopyImage we can make a simple texture, for ResolveImage we require the dst to be a
- // render target as well.
- desc->fOrigin = src->origin();
- desc->fConfig = src->config();
- if (src->numColorSamples() > 1 ||
- (src->asTexture() && this->vkCaps().supportsCopiesAsDraws())) {
- desc->fFlags = kRenderTarget_GrSurfaceFlag;
- } else {
- // Just going to use CopyImage here
- desc->fFlags = kNone_GrSurfaceFlags;
- }
-
- return true;
-}
-
void GrVkGpu::onQueryMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&,
int* effectiveSampleCnt, SamplePattern*) {
// TODO: stub.
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 7203bf1f8b..9556d85f58 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -79,8 +79,6 @@ public:
void onQueryMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings&,
int* effectiveSampleCnt, SamplePattern*) override;
- bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const override;
-
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
GrBackendObject createTestingOnlyBackendTexture(void* pixels, int w, int h,
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index ef3cc48e57..55529d85e1 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -237,8 +237,7 @@ int GrResourceCache::countUniqueKeysWithTag(const char* tag) const {
void GrRenderTargetContextPriv::testingOnly_addDrawOp(GrPaint&& paint,
GrAAType aaType,
- std::unique_ptr<GrDrawOp>
- op,
+ std::unique_ptr<GrDrawOp> op,
const GrUserStencilSettings* uss,
bool snapToCenters) {
ASSERT_SINGLE_OWNER
@@ -253,8 +252,7 @@ void GrRenderTargetContextPriv::testingOnly_addDrawOp(GrPaint&& paint,
}
pipelineBuilder.setSnapVerticesToPixelCenters(snapToCenters);
- fRenderTargetContext->getOpList()->addDrawOp(pipelineBuilder, fRenderTargetContext, GrNoClip(),
- std::move(op));
+ fRenderTargetContext->addDrawOp(pipelineBuilder, GrNoClip(), std::move(op));
}
#undef ASSERT_SINGLE_OWNER
@@ -280,6 +278,9 @@ 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) const override {
+ return false;
+ }
private:
typedef GrCaps INHERITED;
@@ -310,10 +311,6 @@ public:
*effectiveSampleCnt = rt->desc().fSampleCnt;
}
- bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const override {
- return false;
- }
-
GrGpuCommandBuffer* createCommandBuffer(const GrGpuCommandBuffer::LoadAndStoreInfo&,
const GrGpuCommandBuffer::LoadAndStoreInfo&) override {
return nullptr;