diff options
author | Brian Salomon <bsalomon@google.com> | 2017-03-06 16:17:12 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-03-07 15:11:24 +0000 |
commit | 467921e5e6479fe9cebba125657d8e33d89004ae (patch) | |
tree | bffd056e5d9ad99a50c1876d658f4b31d6721d15 | |
parent | 894d5611e54cbf62a03ff9ffb48a2302dda9ab86 (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.gni | 2 | ||||
-rw-r--r-- | include/gpu/GrCaps.h | 10 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 8 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 234 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.h (renamed from include/gpu/GrRenderTargetContext.h) | 11 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetOpList.cpp | 211 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetOpList.h | 38 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 61 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 59 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.h | 2 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.cpp | 20 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.h | 2 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.cpp | 17 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.h | 2 | ||||
-rw-r--r-- | tools/gpu/GrTest.cpp | 13 |
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(), ©Rect); + + 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(), ©Rect); - - 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; |