aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2018-06-26 09:12:38 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-26 15:35:12 +0000
commit493489054f85d1b7725412ad7a3cdc70c7ec5466 (patch)
tree45223f5039eefd3aba721d737cb70549baaa8d0d
parentd5506cb888858bd19fa54be50714a8d661cedf33 (diff)
Refactor GrPipeline dynamic state.
Remove scissor rect from GrPipeline. Draws can specify "fixed dynamic state" which doesn't use the dynamism at all or can specify dynamic state arrays with an entry per GrMesh. When we state other than scissor rects this will allow the caller to use a mix of truly dynamic and fixed dynamic state. So a caller that only has dynamic scissor rects doesn't need to store its remaining unvarying state in an array. Change-Id: I8fcc07eb600c72a26cc712b185755c2116021a8a Reviewed-on: https://skia-review.googlesource.com/137223 Reviewed-by: Chris Dalton <csmartdalton@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
-rw-r--r--gm/beziereffects.cpp11
-rw-r--r--gm/convexpolyeffect.cpp5
-rw-r--r--samplecode/SampleCCPRGeometry.cpp2
-rw-r--r--src/gpu/GrGpuCommandBuffer.cpp16
-rw-r--r--src/gpu/GrGpuCommandBuffer.h6
-rw-r--r--src/gpu/GrOpFlushState.cpp12
-rw-r--r--src/gpu/GrOpFlushState.h5
-rw-r--r--src/gpu/GrPathRendering.cpp3
-rw-r--r--src/gpu/GrPathRendering.h2
-rw-r--r--src/gpu/GrPipeline.cpp13
-rw-r--r--src/gpu/GrPipeline.h28
-rw-r--r--src/gpu/ccpr/GrCCCoverageProcessor.cpp10
-rw-r--r--src/gpu/ccpr/GrCCCoverageProcessor.h2
-rw-r--r--src/gpu/ccpr/GrCCDrawPathsOp.cpp8
-rw-r--r--src/gpu/ccpr/GrCCPathParser.cpp18
-rw-r--r--src/gpu/ccpr/GrCCPathParser.h2
-rw-r--r--src/gpu/ccpr/GrCCPathProcessor.cpp4
-rw-r--r--src/gpu/ccpr/GrCCPathProcessor.h9
-rw-r--r--src/gpu/ccpr/GrCCPerFlushResources.cpp2
-rw-r--r--src/gpu/gl/GrGLGpu.cpp29
-rw-r--r--src/gpu/gl/GrGLGpu.h6
-rw-r--r--src/gpu/gl/GrGLGpuCommandBuffer.h5
-rw-r--r--src/gpu/gl/GrGLPathRendering.cpp3
-rw-r--r--src/gpu/gl/GrGLPathRendering.h1
-rw-r--r--src/gpu/mock/GrMockGpuCommandBuffer.h5
-rw-r--r--src/gpu/ops/GrAAConvexPathRenderer.cpp8
-rw-r--r--src/gpu/ops/GrAAFillRectOp.cpp3
-rw-r--r--src/gpu/ops/GrAAHairLinePathRenderer.cpp8
-rw-r--r--src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp19
-rw-r--r--src/gpu/ops/GrAAStrokeRectOp.cpp3
-rw-r--r--src/gpu/ops/GrAtlasTextOp.cpp11
-rw-r--r--src/gpu/ops/GrAtlasTextOp.h1
-rw-r--r--src/gpu/ops/GrDashOp.cpp6
-rw-r--r--src/gpu/ops/GrDefaultPathRenderer.cpp13
-rw-r--r--src/gpu/ops/GrDrawAtlasOp.cpp3
-rw-r--r--src/gpu/ops/GrDrawPathOp.cpp7
-rw-r--r--src/gpu/ops/GrDrawVerticesOp.cpp3
-rw-r--r--src/gpu/ops/GrLatticeOp.cpp3
-rw-r--r--src/gpu/ops/GrMeshDrawOp.cpp7
-rw-r--r--src/gpu/ops/GrMeshDrawOp.h31
-rw-r--r--src/gpu/ops/GrNonAAFillRectOp.cpp6
-rw-r--r--src/gpu/ops/GrNonAAStrokeRectOp.cpp3
-rw-r--r--src/gpu/ops/GrOvalOpFactory.cpp18
-rw-r--r--src/gpu/ops/GrRegionOp.cpp3
-rw-r--r--src/gpu/ops/GrShadowRRectOp.cpp6
-rw-r--r--src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp18
-rw-r--r--src/gpu/ops/GrSimpleMeshDrawOpHelper.h10
-rw-r--r--src/gpu/ops/GrSmallPathRenderer.cpp10
-rw-r--r--src/gpu/ops/GrTessellatingPathRenderer.cpp3
-rw-r--r--src/gpu/ops/GrTextureOp.cpp8
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.cpp45
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.h16
-rw-r--r--src/gpu/vk/GrVkPipeline.cpp12
-rw-r--r--tests/GrMeshTest.cpp2
-rw-r--r--tests/GrPipelineDynamicStateTest.cpp16
-rw-r--r--tests/OnFlushCallbackTest.cpp3
-rw-r--r--tests/PrimitiveProcessorTest.cpp6
57 files changed, 321 insertions, 197 deletions
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 26da791746..9f3bcd74ec 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -50,7 +50,7 @@ protected:
this->setBounds(rect, HasAABloat::kYes, IsZeroArea::kNo);
}
- const GrPipeline* makePipeline(Target* target) {
+ Target::PipelineAndFixedDynamicState makePipeline(Target* target) {
return target->makePipeline(0, std::move(fProcessorSet), target->detachAppliedClip());
}
@@ -100,7 +100,8 @@ private:
}
SkRect rect = this->rect();
SkPointPriv::SetRectTriStrip(pts, rect, sizeof(SkPoint));
- helper.recordDraw(target, this->gp(), this->makePipeline(target));
+ auto pipe = this->makePipeline(target);
+ helper.recordDraw(target, this->gp(), pipe.fPipeline, pipe.fFixedDynamicState);
}
static constexpr int kVertsPerCubic = 4;
@@ -296,7 +297,8 @@ private:
SkPoint3 pt3 = {verts[v].fPosition.x(), verts[v].fPosition.y(), 1.f};
fKLM.mapHomogeneousPoints((SkPoint3* ) verts[v].fKLM, &pt3, 1);
}
- helper.recordDraw(target, this->gp(), this->makePipeline(target));
+ auto pipe = this->makePipeline(target);
+ helper.recordDraw(target, this->gp(), pipe.fPipeline, pipe.fFixedDynamicState);
}
SkMatrix fKLM;
@@ -513,7 +515,8 @@ private:
SkRect rect = this->rect();
SkPointPriv::SetRectTriStrip(&verts[0].fPosition, rect, sizeof(Vertex));
fDevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts);
- helper.recordDraw(target, this->gp(), this->makePipeline(target));
+ auto pipe = this->makePipeline(target);
+ helper.recordDraw(target, this->gp(), pipe.fPipeline, pipe.fFixedDynamicState);
}
GrPathUtils::QuadUVMatrix fDevToUV;
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 496b6b173f..3c825dc78a 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -92,9 +92,8 @@ private:
SkPointPriv::SetRectTriStrip(verts, fRect, sizeof(SkPoint));
- helper.recordDraw(
- target, gp.get(),
- target->makePipeline(0, std::move(fProcessors), target->detachAppliedClip()));
+ auto pipe = target->makePipeline(0, std::move(fProcessors), target->detachAppliedClip());
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool onCombineIfPossible(GrOp* op, const GrCaps& caps) override { return false; }
diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp
index f2f88bff45..13cc0a0690 100644
--- a/samplecode/SampleCCPRGeometry.cpp
+++ b/samplecode/SampleCCPRGeometry.cpp
@@ -359,7 +359,7 @@ void CCPRGeometryView::DrawCoverageCountOp::onExecute(GrOpFlushState* state) {
if (!mesh.empty()) {
SkASSERT(1 == mesh.count());
- proc.draw(state, pipeline, mesh.begin(), nullptr, 1, this->bounds());
+ proc.draw(state, pipeline, nullptr, mesh.begin(), 1, this->bounds());
}
if (glGpu) {
diff --git a/src/gpu/GrGpuCommandBuffer.cpp b/src/gpu/GrGpuCommandBuffer.cpp
index 617ed75ae7..42e00f355f 100644
--- a/src/gpu/GrGpuCommandBuffer.cpp
+++ b/src/gpu/GrGpuCommandBuffer.cpp
@@ -26,12 +26,10 @@ void GrGpuRTCommandBuffer::clearStencilClip(const GrFixedClip& clip, bool inside
this->onClearStencilClip(clip, insideStencilMask);
}
-bool GrGpuRTCommandBuffer::draw(const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrMesh meshes[],
- const GrPipeline::DynamicState dynamicStates[],
- int meshCount,
- const SkRect& bounds) {
+bool GrGpuRTCommandBuffer::draw(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState,
+ const GrPipeline::DynamicStateArrays* dynamicStateArrays,
+ const GrMesh meshes[], int meshCount, const SkRect& bounds) {
#ifdef SK_DEBUG
SkASSERT(!primProc.hasInstanceAttributes() || this->gpu()->caps()->instanceAttribSupport());
for (int i = 0; i < meshCount; ++i) {
@@ -41,6 +39,9 @@ bool GrGpuRTCommandBuffer::draw(const GrPrimitiveProcessor& primProc,
SkASSERT(primProc.hasInstanceAttributes() == meshes[i].isInstanced());
}
#endif
+ SkASSERT(!pipeline.isScissorEnabled() || fixedDynamicState ||
+ (dynamicStateArrays && dynamicStateArrays->fScissorRects));
+
auto resourceProvider = this->gpu()->getContext()->contextPriv().resourceProvider();
if (pipeline.isBad() || !primProc.instantiate(resourceProvider)) {
@@ -51,6 +52,7 @@ bool GrGpuRTCommandBuffer::draw(const GrPrimitiveProcessor& primProc,
this->gpu()->stats()->incNumFailedDraws();
return false;
}
- this->onDraw(primProc, pipeline, meshes, dynamicStates, meshCount, bounds);
+ this->onDraw(primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshes, meshCount,
+ bounds);
return true;
}
diff --git a/src/gpu/GrGpuCommandBuffer.h b/src/gpu/GrGpuCommandBuffer.h
index 4fae620625..fe0edc9619 100644
--- a/src/gpu/GrGpuCommandBuffer.h
+++ b/src/gpu/GrGpuCommandBuffer.h
@@ -99,8 +99,9 @@ public:
// number of vertex attributes is too large).
bool draw(const GrPrimitiveProcessor&,
const GrPipeline&,
+ const GrPipeline::FixedDynamicState*,
+ const GrPipeline::DynamicStateArrays*,
const GrMesh[],
- const GrPipeline::DynamicState[],
int meshCount,
const SkRect& bounds);
@@ -134,8 +135,9 @@ private:
// overridden by backend-specific derived class to perform the draw call.
virtual void onDraw(const GrPrimitiveProcessor&,
const GrPipeline&,
+ const GrPipeline::FixedDynamicState*,
+ const GrPipeline::DynamicStateArrays*,
const GrMesh[],
- const GrPipeline::DynamicState[],
int meshCount,
const SkRect& bounds) = 0;
diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp
index b24e89abb0..d0a8538e93 100644
--- a/src/gpu/GrOpFlushState.cpp
+++ b/src/gpu/GrOpFlushState.cpp
@@ -44,8 +44,8 @@ void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(uint32_t opID, const Sk
}
SkASSERT(fCurrDraw->fPipeline->proxy() == this->drawOpArgs().fProxy);
this->rtCommandBuffer()->draw(*fCurrDraw->fGeometryProcessor, *fCurrDraw->fPipeline,
- fMeshes.begin() + fCurrMesh, nullptr, fCurrDraw->fMeshCnt,
- opBounds);
+ fCurrDraw->fFixedDynamicState, fCurrDraw->fDynamicStateArrays,
+ fMeshes.begin() + fCurrMesh, fCurrDraw->fMeshCnt, opBounds);
fCurrMesh += fCurrDraw->fMeshCnt;
fTokenTracker->flushToken();
++fCurrDraw;
@@ -105,6 +105,7 @@ GrDeferredUploadToken GrOpFlushState::addASAPUpload(GrDeferredTextureUploadFn&&
}
void GrOpFlushState::draw(const GrGeometryProcessor* gp, const GrPipeline* pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState,
const GrMesh& mesh) {
SkASSERT(fOpArgs);
SkASSERT(fOpArgs->fOp);
@@ -114,7 +115,10 @@ void GrOpFlushState::draw(const GrGeometryProcessor* gp, const GrPipeline* pipel
Draw& lastDraw = *fDraws.begin();
// If the last draw shares a geometry processor and pipeline and there are no intervening
// uploads, add this mesh to it.
- if (lastDraw.fGeometryProcessor == gp && lastDraw.fPipeline == pipeline) {
+ // Note, we could attempt to convert fixed dynamic states into dynamic state arrays here
+ // if everything else is equal. Maybe it's better to rely on Ops to do that?
+ if (lastDraw.fGeometryProcessor == gp && lastDraw.fPipeline == pipeline &&
+ lastDraw.fFixedDynamicState == fixedDynamicState) {
if (fInlineUploads.begin() == fInlineUploads.end() ||
fInlineUploads.tail()->fUploadBeforeToken != fTokenTracker->nextDrawToken()) {
++lastDraw.fMeshCnt;
@@ -127,6 +131,8 @@ void GrOpFlushState::draw(const GrGeometryProcessor* gp, const GrPipeline* pipel
draw.fGeometryProcessor.reset(gp);
draw.fPipeline = pipeline;
+ draw.fFixedDynamicState = fixedDynamicState;
+ draw.fDynamicStateArrays = nullptr;
draw.fMeshCnt = 1;
draw.fOpID = fOpArgs->fOp->uniqueID();
if (firstDraw) {
diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h
index a6f0c26e5e..28e0f68e6a 100644
--- a/src/gpu/GrOpFlushState.h
+++ b/src/gpu/GrOpFlushState.h
@@ -74,7 +74,8 @@ public:
/** Overrides of GrMeshDrawOp::Target. */
- void draw(const GrGeometryProcessor*, const GrPipeline*, const GrMesh&) final;
+ void draw(const GrGeometryProcessor*, const GrPipeline*, const GrPipeline::FixedDynamicState*,
+ const GrMesh&) final;
void* makeVertexSpace(size_t vertexSize, int vertexCount, const GrBuffer**,
int* startVertex) final;
uint16_t* makeIndexSpace(int indexCount, const GrBuffer**, int* startIndex) final;
@@ -120,6 +121,8 @@ private:
int fMeshCnt = 0;
GrPendingProgramElement<const GrGeometryProcessor> fGeometryProcessor;
const GrPipeline* fPipeline;
+ const GrPipeline::FixedDynamicState* fFixedDynamicState;
+ const GrPipeline::DynamicStateArrays* fDynamicStateArrays;
uint32_t fOpID;
};
diff --git a/src/gpu/GrPathRendering.cpp b/src/gpu/GrPathRendering.cpp
index 1af220cd24..614d014146 100644
--- a/src/gpu/GrPathRendering.cpp
+++ b/src/gpu/GrPathRendering.cpp
@@ -51,6 +51,7 @@ void GrPathRendering::stencilPath(const StencilPathArgs& args, const GrPath* pat
void GrPathRendering::drawPath(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState& fixedDynamicState,
// Cover pass settings in pipeline.
const GrStencilSettings& stencilPassSettings,
const GrPath* path) {
@@ -58,5 +59,5 @@ void GrPathRendering::drawPath(const GrPrimitiveProcessor& primProc,
if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
fGpu->xferBarrier(pipeline.renderTarget(), barrierType);
}
- this->onDrawPath(primProc, pipeline, stencilPassSettings, path);
+ this->onDrawPath(primProc, pipeline, fixedDynamicState, stencilPassSettings, path);
}
diff --git a/src/gpu/GrPathRendering.h b/src/gpu/GrPathRendering.h
index ab13674c15..3ae52e9883 100644
--- a/src/gpu/GrPathRendering.h
+++ b/src/gpu/GrPathRendering.h
@@ -111,6 +111,7 @@ public:
void drawPath(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState&,
const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
const GrPath* path);
@@ -120,6 +121,7 @@ protected:
virtual void onStencilPath(const StencilPathArgs&, const GrPath*) = 0;
virtual void onDrawPath(const GrPrimitiveProcessor&,
const GrPipeline&,
+ const GrPipeline::FixedDynamicState&,
const GrStencilSettings&,
const GrPath*) = 0;
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index a0eceb32af..6608d7c7d2 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -16,7 +16,8 @@
#include "ops/GrOp.h"
-GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
+GrPipeline::GrPipeline(const InitArgs& args,
+ GrProcessorSet&& processors,
GrAppliedClip&& appliedClip) {
SkASSERT(args.fProxy);
SkASSERT(processors.isFinalized());
@@ -24,10 +25,13 @@ GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
fProxy.reset(args.fProxy);
fFlags = args.fFlags;
- fScissorState = appliedClip.scissorState();
if (appliedClip.hasStencilClip()) {
fFlags |= kHasStencilClip_Flag;
}
+ if (appliedClip.scissorState().enabled()) {
+ fFlags |= kScissorEnabled_Flag;
+ }
+
fWindowRectsState = appliedClip.windowRectsState();
if (!args.fUserStencil->isDisabled(fFlags & kHasStencilClip_Flag)) {
fFlags |= kStencilEnabled_Flag;
@@ -97,7 +101,6 @@ GrXferBarrierType GrPipeline::xferBarrierType(const GrCaps& caps) const {
GrPipeline::GrPipeline(GrRenderTargetProxy* proxy, ScissorState scissorState, SkBlendMode blendmode)
: fProxy(proxy)
- , fScissorState()
, fWindowRectsState()
, fUserStencilSettings(&GrUserStencilSettings::kUnused)
, fFlags()
@@ -105,7 +108,7 @@ GrPipeline::GrPipeline(GrRenderTargetProxy* proxy, ScissorState scissorState, Sk
, fFragmentProcessors()
, fNumColorProcessors(0) {
SkASSERT(proxy);
- if (ScissorState::kEnabled == scissorState) {
- fScissorState.set({0, 0, 0, 0}); // caller will use the DynamicState struct.
+ if (scissorState) {
+ fFlags |= kScissorEnabled_Flag;
}
}
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index 3ace0f0a1c..f60a6d410b 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -79,16 +79,26 @@ public:
};
/**
- * Graphics state that can change dynamically without creating a new pipeline.
+ * Some state can be changed between GrMeshes without changing GrPipelines. This is generally
+ * less expensive then using multiple pipelines. Such state is called "dynamic state". It can
+ * be specified in two ways:
+ * 1) FixedDynamicState - use this to specify state that does not vary between GrMeshes.
+ * 2) DynamicStateArrays - use this to specify per mesh values for dynamic state.
**/
- struct DynamicState {
- // Overrides the scissor rectangle (if scissor is enabled in the pipeline).
- // TODO: eventually this should be the only way to specify a scissor rectangle, as is the
- // case with the simple constructor.
+ struct FixedDynamicState {
+ FixedDynamicState(const SkIRect& scissorRect) : fScissorRect(scissorRect) {}
SkIRect fScissorRect;
};
/**
+ * Any non-null array overrides the FixedDynamicState on a mesh-by-mesh basis. Arrays must
+ * have one entry for each GrMesh.
+ */
+ struct DynamicStateArrays {
+ const SkIRect* fScissorRects = nullptr;
+ };
+
+ /**
* Creates a simple pipeline with default settings and no processors. The provided blend mode
* must be "Porter Duff" (<= kLastCoeffMode). If using ScissorState::kEnabled, the caller must
* specify a scissor rectangle through the DynamicState struct.
@@ -169,7 +179,9 @@ public:
const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
- const GrScissorState& getScissorState() const { return fScissorState; }
+ ScissorState isScissorEnabled() const {
+ return ScissorState(SkToBool(fFlags & kScissorEnabled_Flag));
+ }
const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
@@ -214,7 +226,8 @@ private:
enum PrivateFlags {
kHasStencilClip_Flag = 0x10,
kStencilEnabled_Flag = 0x20,
- kIsBad_Flag = 0x40,
+ kScissorEnabled_Flag = 0x40,
+ kIsBad_Flag = 0x80,
};
using RenderTargetProxy = GrPendingIOResource<GrRenderTargetProxy, kWrite_GrIOType>;
@@ -225,7 +238,6 @@ private:
SkIPoint fDstTextureOffset;
// MDB TODO: do we still need the destination proxy here?
RenderTargetProxy fProxy;
- GrScissorState fScissorState;
GrWindowRectsState fWindowRectsState;
const GrUserStencilSettings* fUserStencilSettings;
uint16_t fFlags;
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.cpp b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
index 94b027abe9..e9720213ec 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
@@ -224,16 +224,18 @@ void GrCCCoverageProcessor::Shader::emitFragmentCode(const GrCCCoverageProcessor
}
void GrCCCoverageProcessor::draw(GrOpFlushState* flushState, const GrPipeline& pipeline,
- const GrMesh meshes[],
- const GrPipeline::DynamicState dynamicStates[], int meshCount,
+ const SkIRect scissorRects[], const GrMesh meshes[], int meshCount,
const SkRect& drawBounds) const {
+ GrPipeline::DynamicStateArrays dynamicStateArrays;
+ dynamicStateArrays.fScissorRects = scissorRects;
GrGpuRTCommandBuffer* cmdBuff = flushState->rtCommandBuffer();
- cmdBuff->draw(*this, pipeline, meshes, dynamicStates, meshCount, drawBounds);
+ cmdBuff->draw(*this, pipeline, nullptr, &dynamicStateArrays, meshes, meshCount, drawBounds);
// Geometry shader backend draws primitives in two subpasses.
if (Impl::kGeometryShader == fImpl) {
SkASSERT(GSSubpass::kHulls == fGSSubpass);
GrCCCoverageProcessor cornerProc(*this, GSSubpass::kCorners);
- cmdBuff->draw(cornerProc, pipeline, meshes, dynamicStates, meshCount, drawBounds);
+ cmdBuff->draw(cornerProc, pipeline, nullptr, &dynamicStateArrays, meshes, meshCount,
+ drawBounds);
}
}
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.h b/src/gpu/ccpr/GrCCCoverageProcessor.h
index 89890486d3..e5b6bc1119 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.h
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.h
@@ -105,7 +105,7 @@ public:
}
}
- void draw(GrOpFlushState*, const GrPipeline&, const GrMesh[], const GrPipeline::DynamicState[],
+ void draw(GrOpFlushState*, const GrPipeline&, const SkIRect scissorRects[], const GrMesh[],
int meshCount, const SkRect& drawBounds) const;
// The Shader provides code to calculate each pixel's coverage in a RenderPass. It also
diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.cpp b/src/gpu/ccpr/GrCCDrawPathsOp.cpp
index db5ea355aa..bbe3df29eb 100644
--- a/src/gpu/ccpr/GrCCDrawPathsOp.cpp
+++ b/src/gpu/ccpr/GrCCDrawPathsOp.cpp
@@ -337,7 +337,9 @@ void GrCCDrawPathsOp::onExecute(GrOpFlushState* flushState) {
initArgs.fCaps = &flushState->caps();
initArgs.fResourceProvider = flushState->resourceProvider();
initArgs.fDstProxy = flushState->drawOpArgs().fDstProxy;
- GrPipeline pipeline(initArgs, std::move(fProcessors), flushState->detachAppliedClip());
+ auto clip = flushState->detachAppliedClip();
+ GrPipeline::FixedDynamicState fixedDynamicState(clip.scissorState().rect());
+ GrPipeline pipeline(initArgs, std::move(fProcessors), std::move(clip));
int baseInstance = fBaseInstance;
SkASSERT(baseInstance >= 0); // Make sure setupResources() has been called.
@@ -347,8 +349,8 @@ void GrCCDrawPathsOp::onExecute(GrOpFlushState* flushState) {
GrCCPathProcessor pathProc(flushState->resourceProvider(), sk_ref_sp(range.fAtlasProxy),
fViewMatrixIfUsingLocalCoords);
- pathProc.drawPaths(flushState, pipeline, *resources, baseInstance, range.fEndInstanceIdx,
- this->bounds());
+ pathProc.drawPaths(flushState, pipeline, &fixedDynamicState, *resources, baseInstance,
+ range.fEndInstanceIdx, this->bounds());
baseInstance = range.fEndInstanceIdx;
}
diff --git a/src/gpu/ccpr/GrCCPathParser.cpp b/src/gpu/ccpr/GrCCPathParser.cpp
index 6f9b2240d7..1935385eeb 100644
--- a/src/gpu/ccpr/GrCCPathParser.cpp
+++ b/src/gpu/ccpr/GrCCPathParser.cpp
@@ -517,7 +517,7 @@ bool GrCCPathParser::finalize(GrOnFlushResourceProvider* onFlushRP) {
SkASSERT(instanceIndices[1].fConics == quadEndIdx);
fMeshesScratchBuffer.reserve(fMaxMeshesPerDraw);
- fDynamicStatesScratchBuffer.reserve(fMaxMeshesPerDraw);
+ fScissorRectScratchBuffer.reserve(fMaxMeshesPerDraw);
return true;
}
@@ -564,11 +564,11 @@ void GrCCPathParser::drawPrimitives(GrOpFlushState* flushState, const GrPipeline
GrCCCoverageProcessor::PrimitiveType primitiveType,
int PrimitiveTallies::*instanceType,
const SkIRect& drawBounds) const {
- SkASSERT(pipeline.getScissorState().enabled());
+ SkASSERT(pipeline.isScissorEnabled());
// Don't call reset(), as that also resets the reserve count.
fMeshesScratchBuffer.pop_back_n(fMeshesScratchBuffer.count());
- fDynamicStatesScratchBuffer.pop_back_n(fDynamicStatesScratchBuffer.count());
+ fScissorRectScratchBuffer.pop_back_n(fScissorRectScratchBuffer.count());
GrCCCoverageProcessor proc(flushState->resourceProvider(), primitiveType);
@@ -584,8 +584,8 @@ void GrCCPathParser::drawPrimitives(GrOpFlushState* flushState, const GrPipeline
int baseInstance = fBaseInstances[(int)ScissorMode::kNonScissored].*instanceType +
previousBatch.fEndNonScissorIndices.*instanceType;
proc.appendMesh(fInstanceBuffer.get(), instanceCount, baseInstance, &fMeshesScratchBuffer);
- fDynamicStatesScratchBuffer.push_back().fScissorRect.setXYWH(0, 0, drawBounds.width(),
- drawBounds.height());
+ fScissorRectScratchBuffer.push_back().setXYWH(0, 0, drawBounds.width(),
+ drawBounds.height());
SkDEBUGCODE(totalInstanceCount += instanceCount);
}
@@ -603,17 +603,17 @@ void GrCCPathParser::drawPrimitives(GrOpFlushState* flushState, const GrPipeline
SkASSERT(instanceCount > 0);
proc.appendMesh(fInstanceBuffer.get(), instanceCount,
baseScissorInstance + startIndex, &fMeshesScratchBuffer);
- fDynamicStatesScratchBuffer.push_back().fScissorRect = scissorSubBatch.fScissor;
+ fScissorRectScratchBuffer.push_back() = scissorSubBatch.fScissor;
SkDEBUGCODE(totalInstanceCount += instanceCount);
}
- SkASSERT(fMeshesScratchBuffer.count() == fDynamicStatesScratchBuffer.count());
+ SkASSERT(fMeshesScratchBuffer.count() == fScissorRectScratchBuffer.count());
SkASSERT(fMeshesScratchBuffer.count() <= fMaxMeshesPerDraw);
SkASSERT(totalInstanceCount == batch.fTotalPrimitiveCounts.*instanceType);
if (!fMeshesScratchBuffer.empty()) {
- proc.draw(flushState, pipeline, fMeshesScratchBuffer.begin(),
- fDynamicStatesScratchBuffer.begin(), fMeshesScratchBuffer.count(),
+ proc.draw(flushState, pipeline, fScissorRectScratchBuffer.begin(),
+ fMeshesScratchBuffer.begin(), fMeshesScratchBuffer.count(),
SkRect::Make(drawBounds));
}
}
diff --git a/src/gpu/ccpr/GrCCPathParser.h b/src/gpu/ccpr/GrCCPathParser.h
index 1c09b98024..57b1ce6e97 100644
--- a/src/gpu/ccpr/GrCCPathParser.h
+++ b/src/gpu/ccpr/GrCCPathParser.h
@@ -157,7 +157,7 @@ private:
sk_sp<GrBuffer> fInstanceBuffer;
PrimitiveTallies fBaseInstances[kNumScissorModes];
mutable SkSTArray<32, GrMesh> fMeshesScratchBuffer;
- mutable SkSTArray<32, GrPipeline::DynamicState> fDynamicStatesScratchBuffer;
+ mutable SkSTArray<32, SkIRect> fScissorRectScratchBuffer;
};
inline void GrCCPathParser::PathStats::statPath(const SkPath& path) {
diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp
index e1a508619a..450b74c6a2 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPathProcessor.cpp
@@ -130,6 +130,7 @@ GrGLSLPrimitiveProcessor* GrCCPathProcessor::createGLSLInstance(const GrShaderCa
}
void GrCCPathProcessor::drawPaths(GrOpFlushState* flushState, const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState,
const GrCCPerFlushResources& resources, int baseInstance,
int endInstance, const SkRect& bounds) const {
const GrCaps& caps = flushState->caps();
@@ -147,7 +148,8 @@ void GrCCPathProcessor::drawPaths(GrOpFlushState* flushState, const GrPipeline&
enablePrimitiveRestart);
mesh.setVertexData(resources.vertexBuffer());
- flushState->rtCommandBuffer()->draw(*this, pipeline, &mesh, nullptr, 1, bounds);
+ flushState->rtCommandBuffer()->draw(*this, pipeline, fixedDynamicState, nullptr, &mesh, 1,
+ bounds);
}
void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
diff --git a/src/gpu/ccpr/GrCCPathProcessor.h b/src/gpu/ccpr/GrCCPathProcessor.h
index 54c1b7e2ed..878cd1c76d 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.h
+++ b/src/gpu/ccpr/GrCCPathProcessor.h
@@ -8,16 +8,16 @@
#ifndef GrCCPathProcessor_DEFINED
#define GrCCPathProcessor_DEFINED
+#include <array>
#include "GrCaps.h"
#include "GrGeometryProcessor.h"
+#include "GrPipeline.h"
#include "SkPath.h"
-#include <array>
class GrCCPathCacheEntry;
class GrCCPerFlushResources;
class GrOnFlushResourceProvider;
class GrOpFlushState;
-class GrPipeline;
/**
* This class draws AA paths using the coverage count masks produced by GrCCCoverageProcessor.
@@ -86,8 +86,9 @@ public:
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
- void drawPaths(GrOpFlushState*, const GrPipeline&, const GrCCPerFlushResources&,
- int baseInstance, int endInstance, const SkRect& bounds) const;
+ void drawPaths(GrOpFlushState*, const GrPipeline&, const GrPipeline::FixedDynamicState*,
+ const GrCCPerFlushResources&, int baseInstance, int endInstance,
+ const SkRect& bounds) const;
private:
const Attribute& onVertexAttribute(int i) const override { return kEdgeNormsAttrib; }
diff --git a/src/gpu/ccpr/GrCCPerFlushResources.cpp b/src/gpu/ccpr/GrCCPerFlushResources.cpp
index 362ae77d79..dd0bf1b473 100644
--- a/src/gpu/ccpr/GrCCPerFlushResources.cpp
+++ b/src/gpu/ccpr/GrCCPerFlushResources.cpp
@@ -67,7 +67,7 @@ public:
GrPipeline pipeline(flushState->proxy(), GrPipeline::ScissorState::kDisabled,
SkBlendMode::kSrc);
GrCCPathProcessor pathProc(flushState->resourceProvider(), std::move(fStashedAtlasProxy));
- pathProc.drawPaths(flushState, pipeline, *fResources, fBaseInstance, fEndInstance,
+ pathProc.drawPaths(flushState, pipeline, nullptr, *fResources, fBaseInstance, fEndInstance,
this->bounds());
// Ensure we released the stashed atlas proxy. This allows its underlying texture to be
// reused as the current flush's mainline CCPR atlas if needed.
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 97dc3d17ab..6f34912faa 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1683,7 +1683,9 @@ void GrGLGpu::flushMinSampleShading(float minSampleShading) {
}
}
-bool GrGLGpu::flushGLState(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
+bool GrGLGpu::flushGLState(const GrPrimitiveProcessor& primProc,
+ const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState,
bool willDrawPoints) {
sk_sp<GrGLProgram> program(fProgramCache->refProgram(this, primProc, pipeline, willDrawPoints));
if (!program) {
@@ -1719,7 +1721,13 @@ bool GrGLGpu::flushGLState(const GrPrimitiveProcessor& primProc, const GrPipelin
glRT->renderTargetPriv().numStencilBits());
}
this->flushStencil(stencil);
- this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), pipeline.proxy()->origin());
+ if (pipeline.isScissorEnabled()) {
+ static constexpr SkIRect kBogusScissor{0, 0, 1, 1};
+ GrScissorState state(fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor);
+ this->flushScissor(state, glRT->getViewport(), pipeline.proxy()->origin());
+ } else {
+ this->disableScissor();
+ }
this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT, pipeline.proxy()->origin());
this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !stencil.isDisabled());
@@ -2250,8 +2258,9 @@ void GrGLGpu::flushViewport(const GrGLIRect& viewport) {
void GrGLGpu::draw(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState,
+ const GrPipeline::DynamicStateArrays* dynamicStateArrays,
const GrMesh meshes[],
- const GrPipeline::DynamicState dynamicStates[],
int meshCount) {
this->handleDirtyContext();
@@ -2262,21 +2271,21 @@ void GrGLGpu::draw(const GrPrimitiveProcessor& primProc,
break;
}
}
- if (!this->flushGLState(primProc, pipeline, hasPoints)) {
+ if (!this->flushGLState(primProc, pipeline, fixedDynamicState, hasPoints)) {
return;
}
+ bool dynamicScissor =
+ pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
for (int i = 0; i < meshCount; ++i) {
if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps())) {
this->xferBarrier(pipeline.renderTarget(), barrierType);
}
- if (dynamicStates) {
- if (pipeline.getScissorState().enabled()) {
- GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.renderTarget());
- this->flushScissor(dynamicStates[i].fScissorRect,
- glRT->getViewport(), pipeline.proxy()->origin());
- }
+ if (dynamicScissor) {
+ GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.renderTarget());
+ this->flushScissor(GrScissorState(dynamicStateArrays->fScissorRects[i]),
+ glRT->getViewport(), pipeline.proxy()->origin());
}
if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
GrIsPrimTypeLines(meshes[i].primitiveType()) &&
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 782b0b0540..765d5f67ee 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -84,8 +84,9 @@ public:
// on GrGLRTGpuCommandBuffer.
void draw(const GrPrimitiveProcessor&,
const GrPipeline&,
+ const GrPipeline::FixedDynamicState*,
+ const GrPipeline::DynamicStateArrays*,
const GrMesh[],
- const GrPipeline::DynamicState[],
int meshCount);
// GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls.
@@ -253,7 +254,8 @@ private:
// Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
// willDrawPoints must be true if point primitives will be rendered after setting the GL state.
- bool flushGLState(const GrPrimitiveProcessor&, const GrPipeline&, bool willDrawPoints);
+ bool flushGLState(const GrPrimitiveProcessor&, const GrPipeline&,
+ const GrPipeline::FixedDynamicState*, bool willDrawPoints);
void flushProgram(sk_sp<GrGLProgram>);
diff --git a/src/gpu/gl/GrGLGpuCommandBuffer.h b/src/gpu/gl/GrGLGpuCommandBuffer.h
index 84e05a8998..fd3417a79b 100644
--- a/src/gpu/gl/GrGLGpuCommandBuffer.h
+++ b/src/gpu/gl/GrGLGpuCommandBuffer.h
@@ -86,12 +86,13 @@ private:
void onDraw(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState,
+ const GrPipeline::DynamicStateArrays* dynamicStateArrays,
const GrMesh mesh[],
- const GrPipeline::DynamicState dynamicStates[],
int meshCount,
const SkRect& bounds) override {
SkASSERT(pipeline.renderTarget() == fRenderTarget);
- fGpu->draw(primProc, pipeline, mesh, dynamicStates, meshCount);
+ fGpu->draw(primProc, pipeline, fixedDynamicState, dynamicStateArrays, mesh, meshCount);
}
void onClear(const GrFixedClip& clip, GrColor color) override {
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index 79481290f4..85c129f8b0 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -113,9 +113,10 @@ void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath*
void GrGLPathRendering::onDrawPath(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState& fixedDynamicState,
const GrStencilSettings& stencilPassSettings,
const GrPath* path) {
- if (!this->gpu()->flushGLState(primProc, pipeline, false)) {
+ if (!this->gpu()->flushGLState(primProc, pipeline, &fixedDynamicState, false)) {
return;
}
const GrGLPath* glPath = static_cast<const GrGLPath*>(path);
diff --git a/src/gpu/gl/GrGLPathRendering.h b/src/gpu/gl/GrGLPathRendering.h
index 1dfb756f3e..74c5fcec9c 100644
--- a/src/gpu/gl/GrGLPathRendering.h
+++ b/src/gpu/gl/GrGLPathRendering.h
@@ -67,6 +67,7 @@ protected:
void onStencilPath(const StencilPathArgs&, const GrPath*) override;
void onDrawPath(const GrPrimitiveProcessor&,
const GrPipeline&,
+ const GrPipeline::FixedDynamicState&,
const GrStencilSettings&,
const GrPath*) override;
diff --git a/src/gpu/mock/GrMockGpuCommandBuffer.h b/src/gpu/mock/GrMockGpuCommandBuffer.h
index 7a94e9a7b4..d3e26fa503 100644
--- a/src/gpu/mock/GrMockGpuCommandBuffer.h
+++ b/src/gpu/mock/GrMockGpuCommandBuffer.h
@@ -50,8 +50,9 @@ public:
void submit() override { fGpu->submitCommandBuffer(this); }
private:
- void onDraw(const GrPrimitiveProcessor&, const GrPipeline&, const GrMesh[],
- const GrPipeline::DynamicState[], int meshCount, const SkRect& bounds) override {
+ void onDraw(const GrPrimitiveProcessor&, const GrPipeline&,
+ const GrPipeline::FixedDynamicState*, const GrPipeline::DynamicStateArrays*,
+ const GrMesh[], int meshCount, const SkRect& bounds) override {
++fNumDraws;
}
void onClear(const GrFixedClip&, GrColor) override {}
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index 566eebd827..37cb23bdf8 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -807,7 +807,7 @@ private:
GrAAConvexTessellator tess;
int instanceCount = fPaths.count();
- const GrPipeline* pipeline = fHelper.makePipeline(target);
+ auto pipe = fHelper.makePipeline(target);
for (int i = 0; i < instanceCount; i++) {
tess.rewind();
@@ -843,7 +843,7 @@ private:
mesh.setIndexed(indexBuffer, tess.numIndices(), firstIndex, 0, tess.numPts() - 1,
GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(gp.get(), pipeline, mesh);
+ target->draw(gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
}
@@ -854,7 +854,7 @@ private:
return;
}
#endif
- const GrPipeline* pipeline = fHelper.makePipeline(target);
+ auto pipe = fHelper.makePipeline(target);
int instanceCount = fPaths.count();
SkMatrix invert;
@@ -931,7 +931,7 @@ private:
mesh.setIndexed(indexBuffer, draw.fIndexCnt, firstIndex, 0, draw.fVertexCnt - 1,
GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(quadProcessor.get(), pipeline, mesh);
+ target->draw(quadProcessor.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
firstIndex += draw.fIndexCnt;
firstVertex += draw.fVertexCnt;
}
diff --git a/src/gpu/ops/GrAAFillRectOp.cpp b/src/gpu/ops/GrAAFillRectOp.cpp
index 76bc8128cf..cbd1ad5c30 100644
--- a/src/gpu/ops/GrAAFillRectOp.cpp
+++ b/src/gpu/ops/GrAAFillRectOp.cpp
@@ -291,7 +291,8 @@ private:
fHelper.compatibleWithAlphaAsCoverage(), localMatrix);
info = this->next(info);
}
- helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
index 89dedc48a4..af5cb3dbbc 100644
--- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
@@ -939,7 +939,7 @@ void AAHairlineOp::onPrepareDraws(Target* target) {
return;
}
- const GrPipeline* pipeline = fHelper.makePipeline(target);
+ auto pipe = fHelper.makePipeline(target);
// do lines first
if (lineCount) {
sk_sp<GrGeometryProcessor> lineGP;
@@ -977,7 +977,7 @@ void AAHairlineOp::onPrepareDraws(Target* target) {
mesh.setIndexedPatterned(linesIndexBuffer.get(), kIdxsPerLineSeg, kLineSegNumVertices,
lineCount, kLineSegsNumInIdxBuffer);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(lineGP.get(), pipeline, mesh);
+ target->draw(lineGP.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
if (quadCount || conicCount) {
@@ -1032,7 +1032,7 @@ void AAHairlineOp::onPrepareDraws(Target* target) {
mesh.setIndexedPatterned(quadsIndexBuffer.get(), kIdxsPerQuad, kQuadNumVertices,
quadCount, kQuadsNumInIdxBuffer);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(quadGP.get(), pipeline, mesh);
+ target->draw(quadGP.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
firstVertex += quadCount * kQuadNumVertices;
}
@@ -1041,7 +1041,7 @@ void AAHairlineOp::onPrepareDraws(Target* target) {
mesh.setIndexedPatterned(quadsIndexBuffer.get(), kIdxsPerQuad, kQuadNumVertices,
conicCount, kQuadsNumInIdxBuffer);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(conicGP.get(), pipeline, mesh);
+ target->draw(conicGP.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
}
}
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
index b6b70779ff..1876d6c531 100644
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
@@ -206,9 +206,9 @@ public:
}
private:
- void draw(GrMeshDrawOp::Target* target, const GrGeometryProcessor* gp,
- const GrPipeline* pipeline, int vertexCount, size_t vertexStride, void* vertices,
- int indexCount, uint16_t* indices) const {
+ void draw(Target* target, const GrGeometryProcessor* gp, const GrPipeline* pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState, int vertexCount,
+ size_t vertexStride, void* vertices, int indexCount, uint16_t* indices) const {
if (vertexCount == 0 || indexCount == 0) {
return;
}
@@ -234,12 +234,11 @@ private:
mesh.setIndexed(indexBuffer, indexCount, firstIndex, 0, vertexCount - 1,
GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(gp, pipeline, mesh);
+ target->draw(gp, pipeline, fixedDynamicState, mesh);
}
void onPrepareDraws(Target* target) override {
- const GrPipeline* pipeline = fHelper.makePipeline(target);
-
+ auto pipe = fHelper.makePipeline(target);
// Setup GrGeometryProcessor
sk_sp<GrGeometryProcessor> gp(create_lines_only_gp(fHelper.compatibleWithAlphaAsCoverage(),
this->viewMatrix(),
@@ -275,8 +274,8 @@ private:
if (vertexCount + currentVertices > static_cast<int>(UINT16_MAX)) {
// if we added the current instance, we would overflow the indices we can store in a
// uint16_t. Draw what we've got so far and reset.
- this->draw(target, gp.get(), pipeline, vertexCount, vertexStride, vertices,
- indexCount, indices);
+ this->draw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, vertexCount,
+ vertexStride, vertices, indexCount, indices);
vertexCount = 0;
indexCount = 0;
}
@@ -307,8 +306,8 @@ private:
indexCount += currentIndices;
}
if (vertexCount <= SK_MaxS32 && indexCount <= SK_MaxS32) {
- this->draw(target, gp.get(), pipeline, vertexCount, vertexStride, vertices, indexCount,
- indices);
+ this->draw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, vertexCount,
+ vertexStride, vertices, indexCount, indices);
}
sk_free(vertices);
sk_free(indices);
diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp
index 3347227f04..651f839af8 100644
--- a/src/gpu/ops/GrAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrAAStrokeRectOp.cpp
@@ -304,7 +304,8 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) {
info.fDegenerate,
fHelper.compatibleWithAlphaAsCoverage());
}
- helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
sk_sp<const GrBuffer> AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvider,
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index fc5e5804eb..29a5938c62 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -297,9 +297,13 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
}
SkASSERT(proxies[0]);
- FlushInfo flushInfo;
- flushInfo.fPipeline =
+ auto pipe =
target->makePipeline(fSRGBFlags, std::move(fProcessors), target->detachAppliedClip());
+
+ FlushInfo flushInfo;
+ flushInfo.fPipeline = pipe.fPipeline;
+ flushInfo.fFixedDynamicState = pipe.fFixedDynamicState;
+
bool vmPerspective = fGeoData[0].fViewMatrix.hasPerspective();
if (this->usesDistanceFields()) {
flushInfo.fGeometryProcessor = this->setupDfProcessor(proxies, numActiveProxies);
@@ -419,7 +423,8 @@ void GrAtlasTextOp::flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) co
mesh.setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerGlyph, kVerticesPerGlyph,
flushInfo->fGlyphsToFlush, maxGlyphsPerDraw);
mesh.setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset);
- target->draw(flushInfo->fGeometryProcessor.get(), flushInfo->fPipeline, mesh);
+ target->draw(flushInfo->fGeometryProcessor.get(), flushInfo->fPipeline,
+ flushInfo->fFixedDynamicState, mesh);
flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
flushInfo->fGlyphsToFlush = 0;
}
diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h
index 0318a90f8f..a1f8f8965f 100644
--- a/src/gpu/ops/GrAtlasTextOp.h
+++ b/src/gpu/ops/GrAtlasTextOp.h
@@ -109,6 +109,7 @@ private:
sk_sp<const GrBuffer> fIndexBuffer;
sk_sp<GrGeometryProcessor> fGeometryProcessor;
const GrPipeline* fPipeline;
+ const GrPipeline::FixedDynamicState* fFixedDynamicState;
int fGlyphsToFlush;
int fVertexOffset;
};
diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp
index 968d169376..d38bb9f3e6 100644
--- a/src/gpu/ops/GrDashOp.cpp
+++ b/src/gpu/ops/GrDashOp.cpp
@@ -697,9 +697,9 @@ private:
if (fDisableSRGBOutputConversion) {
pipelineFlags |= GrPipeline::kDisableOutputConversionToSRGB_Flag;
}
- const GrPipeline* pipeline = target->makePipeline(pipelineFlags, std::move(fProcessorSet),
- target->detachAppliedClip());
- helper.recordDraw(target, gp.get(), pipeline);
+ auto pipe = target->makePipeline(pipelineFlags, std::move(fProcessorSet),
+ target->detachAppliedClip());
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp
index aa0963b02a..af4546cbb1 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/GrDefaultPathRenderer.cpp
@@ -63,12 +63,14 @@ namespace {
class PathGeoBuilder {
public:
PathGeoBuilder(GrPrimitiveType primitiveType, GrMeshDrawOp::Target* target,
- GrGeometryProcessor* geometryProcessor, const GrPipeline* pipeline)
+ GrGeometryProcessor* geometryProcessor, const GrPipeline* pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState)
: fMesh(primitiveType)
, fTarget(target)
, fVertexStride(sizeof(SkPoint))
, fGeometryProcessor(geometryProcessor)
, fPipeline(pipeline)
+ , fFixedDynamicState(fixedDynamicState)
, fIndexBuffer(nullptr)
, fFirstIndex(0)
, fIndicesInChunk(0)
@@ -274,7 +276,7 @@ private:
GrPrimitiveRestart::kNo);
}
fMesh.setVertexData(fVertexBuffer, fFirstVertex);
- fTarget->draw(fGeometryProcessor, fPipeline, fMesh);
+ fTarget->draw(fGeometryProcessor, fPipeline, fFixedDynamicState, fMesh);
}
fTarget->putBackIndices((size_t)(fIndicesInChunk - indexCount));
@@ -312,6 +314,7 @@ private:
size_t fVertexStride;
GrGeometryProcessor* fGeometryProcessor;
const GrPipeline* fPipeline;
+ const GrPipeline::FixedDynamicState* fFixedDynamicState;
const GrBuffer* fVertexBuffer;
int fFirstVertex;
@@ -419,9 +422,9 @@ private:
} else {
primitiveType = GrPrimitiveType::kTriangles;
}
-
- PathGeoBuilder pathGeoBuilder(primitiveType, target, gp.get(),
- fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ PathGeoBuilder pathGeoBuilder(primitiveType, target, gp.get(), pipe.fPipeline,
+ pipe.fFixedDynamicState);
// fill buffers
for (int i = 0; i < instanceCount; i++) {
diff --git a/src/gpu/ops/GrDrawAtlasOp.cpp b/src/gpu/ops/GrDrawAtlasOp.cpp
index 47bad8b2a4..4c25edc207 100644
--- a/src/gpu/ops/GrDrawAtlasOp.cpp
+++ b/src/gpu/ops/GrDrawAtlasOp.cpp
@@ -142,7 +142,8 @@ void GrDrawAtlasOp::onPrepareDraws(Target* target) {
memcpy(vertPtr, args.fVerts.begin(), allocSize);
vertPtr += allocSize;
}
- helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool GrDrawAtlasOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
diff --git a/src/gpu/ops/GrDrawPathOp.cpp b/src/gpu/ops/GrDrawPathOp.cpp
index 185b3c07f2..98a4775d5a 100644
--- a/src/gpu/ops/GrDrawPathOp.cpp
+++ b/src/gpu/ops/GrDrawPathOp.cpp
@@ -75,13 +75,16 @@ std::unique_ptr<GrDrawOp> GrDrawPathOp::Make(GrContext* context,
}
void GrDrawPathOp::onExecute(GrOpFlushState* state) {
+ GrAppliedClip appliedClip = state->detachAppliedClip();
+ GrPipeline::FixedDynamicState fixedDynamicState(appliedClip.scissorState().rect());
GrPipeline pipeline(this->pipelineInitArgs(*state), this->detachProcessors(),
- state->detachAppliedClip());
+ std::move(appliedClip));
sk_sp<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(), this->viewMatrix()));
GrStencilSettings stencil;
init_stencil_pass_settings(*state, this->fillType(), &stencil);
- state->gpu()->pathRendering()->drawPath(*pathProc, pipeline, stencil, fPath.get());
+ state->gpu()->pathRendering()->drawPath(*pathProc, pipeline, fixedDynamicState, stencil,
+ fPath.get());
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp
index 8f6ad9745d..ad5aba2b2c 100644
--- a/src/gpu/ops/GrDrawVerticesOp.cpp
+++ b/src/gpu/ops/GrDrawVerticesOp.cpp
@@ -245,7 +245,8 @@ void GrDrawVerticesOp::onPrepareDraws(Target* target) {
GrPrimitiveRestart::kNo);
}
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(gp.get(), fHelper.makePipeline(target), mesh);
+ auto pipe = fHelper.makePipeline(target);
+ target->draw(gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
bool GrDrawVerticesOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index 7bfa72ec94..92bcb0c563 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -280,7 +280,8 @@ private:
kVertsPerRect * patch.fIter->numRectsToDraw());
}
}
- helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
diff --git a/src/gpu/ops/GrMeshDrawOp.cpp b/src/gpu/ops/GrMeshDrawOp.cpp
index 0bc782c4a0..349f8327ab 100644
--- a/src/gpu/ops/GrMeshDrawOp.cpp
+++ b/src/gpu/ops/GrMeshDrawOp.cpp
@@ -40,9 +40,10 @@ void* GrMeshDrawOp::PatternHelper::init(Target* target, size_t vertexStride,
return vertices;
}
-void GrMeshDrawOp::PatternHelper::recordDraw(Target* target, const GrGeometryProcessor* gp,
- const GrPipeline* pipeline) {
- target->draw(gp, pipeline, fMesh);
+void GrMeshDrawOp::PatternHelper::recordDraw(
+ Target* target, const GrGeometryProcessor* gp, const GrPipeline* pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState) {
+ target->draw(gp, pipeline, fixedDynamicState, fMesh);
}
void* GrMeshDrawOp::QuadHelper::init(Target* target, size_t vertexStride, int quadsToDraw) {
diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h
index cb2c3326f3..ddc29f1dab 100644
--- a/src/gpu/ops/GrMeshDrawOp.h
+++ b/src/gpu/ops/GrMeshDrawOp.h
@@ -8,6 +8,7 @@
#ifndef GrMeshDrawOp_DEFINED
#define GrMeshDrawOp_DEFINED
+#include "GrAppliedClip.h"
#include "GrDrawOp.h"
#include "GrGeometryProcessor.h"
#include "GrMesh.h"
@@ -40,7 +41,8 @@ protected:
int indicesPerRepetition, int repeatCount);
/** Call after init() to issue draws to the GrMeshDrawOp::Target.*/
- void recordDraw(Target*, const GrGeometryProcessor*, const GrPipeline*);
+ void recordDraw(Target*, const GrGeometryProcessor*, const GrPipeline*,
+ const GrPipeline::FixedDynamicState*);
private:
GrMesh fMesh;
@@ -76,7 +78,8 @@ public:
virtual ~Target() {}
/** Adds a draw of a mesh. */
- virtual void draw(const GrGeometryProcessor*, const GrPipeline*, const GrMesh&) = 0;
+ virtual void draw(const GrGeometryProcessor*, const GrPipeline*,
+ const GrPipeline::FixedDynamicState*, const GrMesh&) = 0;
/**
* Makes space for vertex data. The returned pointer is the location where vertex data
@@ -129,19 +132,35 @@ public:
return this->pipelineArena()->make<GrPipeline>(std::forward<Args>(args)...);
}
+ template <typename... Args>
+ GrPipeline::FixedDynamicState* allocFixedDynamicState(Args&... args) {
+ return this->pipelineArena()->make<GrPipeline::FixedDynamicState>(
+ std::forward<Args>(args)...);
+ }
+
+ // Once we have C++17 structured bindings make this just be a tuple because then we can do:
+ // auto [pipeline, fixedDynamicState] = target->makePipeline(...);
+ // in addition to:
+ // std::tie(flushInfo.fPipeline, flushInfo.fFixedState) = target->makePipeline(...);
+ struct PipelineAndFixedDynamicState {
+ const GrPipeline* fPipeline;
+ const GrPipeline::FixedDynamicState* fFixedDynamicState;
+ };
+
/**
* Helper that makes a pipeline targeting the op's render target that incorporates the op's
- * GrAppliedClip.
+ * GrAppliedClip and uses a fixed dynamic state.
*/
- GrPipeline* makePipeline(uint32_t pipelineFlags, GrProcessorSet&& processorSet,
- GrAppliedClip&& clip) {
+ PipelineAndFixedDynamicState makePipeline(uint32_t pipelineFlags, GrProcessorSet&& processorSet,
+ GrAppliedClip&& clip) {
GrPipeline::InitArgs pipelineArgs;
pipelineArgs.fFlags = pipelineFlags;
pipelineArgs.fProxy = this->proxy();
pipelineArgs.fDstProxy = this->dstProxy();
pipelineArgs.fCaps = &this->caps();
pipelineArgs.fResourceProvider = this->resourceProvider();
- return this->allocPipeline(pipelineArgs, std::move(processorSet), std::move(clip));
+ const auto* state = this->allocFixedDynamicState(clip.scissorState().rect());
+ return {this->allocPipeline(pipelineArgs, std::move(processorSet), std::move(clip)), state};
}
virtual GrRenderTargetProxy* proxy() const = 0;
diff --git a/src/gpu/ops/GrNonAAFillRectOp.cpp b/src/gpu/ops/GrNonAAFillRectOp.cpp
index d4ebedc6e1..8af9651a46 100644
--- a/src/gpu/ops/GrNonAAFillRectOp.cpp
+++ b/src/gpu/ops/GrNonAAFillRectOp.cpp
@@ -203,7 +203,8 @@ private:
tesselate(verts, kVertexStride, fRects[i].fColor, &fRects[i].fViewMatrix,
fRects[i].fRect, &fRects[i].fLocalQuad);
}
- helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
@@ -339,7 +340,8 @@ private:
tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect, nullptr);
}
}
- helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
diff --git a/src/gpu/ops/GrNonAAStrokeRectOp.cpp b/src/gpu/ops/GrNonAAStrokeRectOp.cpp
index 11c2f8cda5..4090e3437d 100644
--- a/src/gpu/ops/GrNonAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrNonAAStrokeRectOp.cpp
@@ -191,7 +191,8 @@ private:
GrMesh mesh(primType);
mesh.setNonIndexedNonInstanced(vertexCount);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(gp.get(), fHelper.makePipeline(target), mesh);
+ auto pipe = fHelper.makePipeline(target);
+ target->draw(gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
bool onCombineIfPossible(GrOp* t, const GrCaps&) override {
diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp
index 1655b76326..ca209e02fe 100644
--- a/src/gpu/ops/GrOvalOpFactory.cpp
+++ b/src/gpu/ops/GrOvalOpFactory.cpp
@@ -1445,7 +1445,8 @@ private:
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(gp.get(), fHelper.makePipeline(target), mesh);
+ auto pipe = fHelper.makePipeline(target);
+ target->draw(gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
@@ -1761,7 +1762,8 @@ private:
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(gp.get(), fHelper.makePipeline(target), mesh);
+ auto pipe = fHelper.makePipeline(target);
+ target->draw(gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
@@ -2005,7 +2007,8 @@ private:
verts += kVerticesPerQuad;
}
- helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
@@ -2239,7 +2242,8 @@ private:
verts += kVerticesPerQuad;
}
- helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
@@ -2695,7 +2699,8 @@ private:
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(gp.get(), fHelper.makePipeline(target), mesh);
+ auto pipe = fHelper.makePipeline(target);
+ target->draw(gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
@@ -2953,7 +2958,8 @@ private:
verts++;
}
}
- helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
diff --git a/src/gpu/ops/GrRegionOp.cpp b/src/gpu/ops/GrRegionOp.cpp
index 9a9814e0be..cd51152b8c 100644
--- a/src/gpu/ops/GrRegionOp.cpp
+++ b/src/gpu/ops/GrRegionOp.cpp
@@ -142,7 +142,8 @@ private:
int numRectsInRegion = fRegions[i].fRegion.computeRegionComplexity();
verts += numRectsInRegion * kVertsPerInstance * kVertexStride;
}
- helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
+ auto pipe = fHelper.makePipeline(target);
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp
index afb084dc36..220556ffdb 100644
--- a/src/gpu/ops/GrShadowRRectOp.cpp
+++ b/src/gpu/ops/GrShadowRRectOp.cpp
@@ -625,14 +625,14 @@ private:
}
static const uint32_t kPipelineFlags = 0;
- const GrPipeline* pipeline = target->makePipeline(
- kPipelineFlags, GrProcessorSet::MakeEmptySet(), target->detachAppliedClip());
+ auto pipe = target->makePipeline(kPipelineFlags, GrProcessorSet::MakeEmptySet(),
+ target->detachAppliedClip());
GrMesh mesh(GrPrimitiveType::kTriangles);
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(gp.get(), pipeline, mesh);
+ target->draw(gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
index 8b83271105..fc54475bb6 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
@@ -134,17 +134,21 @@ GrPipeline::InitArgs GrSimpleMeshDrawOpHelper::pipelineInitArgs(
return args;
}
-GrPipeline* GrSimpleMeshDrawOpHelper::internalMakePipeline(GrMeshDrawOp::Target* target,
- const GrPipeline::InitArgs& args) {
+auto GrSimpleMeshDrawOpHelper::internalMakePipeline(GrMeshDrawOp::Target* target,
+ const GrPipeline::InitArgs& args)
+ -> PipelineAndFixedDynamicState {
// A caller really should only call this once as the processor set and applied clip get
// moved into the GrPipeline.
SkASSERT(!fMadePipeline);
SkDEBUGCODE(fMadePipeline = true);
+ auto clip = target->detachAppliedClip();
+ auto* dynamicState = target->allocFixedDynamicState(clip.scissorState().rect());
if (fProcessors) {
- return target->allocPipeline(args, std::move(*fProcessors), target->detachAppliedClip());
+ return {target->allocPipeline(args, std::move(*fProcessors), std::move(clip)),
+ dynamicState};
} else {
- return target->allocPipeline(args, GrProcessorSet::MakeEmptySet(),
- target->detachAppliedClip());
+ return {target->allocPipeline(args, GrProcessorSet::MakeEmptySet(), std::move(clip)),
+ dynamicState};
}
}
@@ -169,8 +173,8 @@ bool GrSimpleMeshDrawOpHelperWithStencil::isCompatible(
fStencilSettings == that.fStencilSettings;
}
-const GrPipeline* GrSimpleMeshDrawOpHelperWithStencil::makePipeline(
- GrMeshDrawOp::Target* target) {
+auto GrSimpleMeshDrawOpHelperWithStencil::makePipeline(GrMeshDrawOp::Target* target)
+ -> PipelineAndFixedDynamicState {
auto args = INHERITED::pipelineInitArgs(target);
args.fUserStencil = fStencilSettings;
return this->internalMakePipeline(target, args);
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
index e5229a713a..cbf41a7128 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
@@ -88,8 +88,9 @@ public:
bool compatibleWithAlphaAsCoverage() const { return fCompatibleWithAlphaAsCoveage; }
+ using PipelineAndFixedDynamicState = GrOpFlushState::PipelineAndFixedDynamicState;
/** Makes a pipeline that consumes the processor set and the op's applied clip. */
- GrPipeline* makePipeline(GrMeshDrawOp::Target* target) {
+ PipelineAndFixedDynamicState makePipeline(GrMeshDrawOp::Target* target) {
return this->internalMakePipeline(target, this->pipelineInitArgs(target));
}
@@ -117,7 +118,8 @@ protected:
GrPipeline::InitArgs pipelineInitArgs(GrMeshDrawOp::Target* target) const;
- GrPipeline* internalMakePipeline(GrMeshDrawOp::Target*, const GrPipeline::InitArgs&);
+ PipelineAndFixedDynamicState internalMakePipeline(GrMeshDrawOp::Target*,
+ const GrPipeline::InitArgs&);
private:
GrProcessorSet* fProcessors;
@@ -139,6 +141,8 @@ class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper {
public:
using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs;
using Flags = GrSimpleMeshDrawOpHelper::Flags;
+ using PipelineAndFixedDynamicState = GrOpFlushState::PipelineAndFixedDynamicState;
+
using GrSimpleMeshDrawOpHelper::visitProxies;
// using declarations can't be templated, so this is a pass through function instead.
@@ -161,7 +165,7 @@ public:
bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps&,
const SkRect& thisBounds, const SkRect& thatBounds) const;
- const GrPipeline* makePipeline(GrMeshDrawOp::Target*);
+ PipelineAndFixedDynamicState makePipeline(GrMeshDrawOp::Target*);
SkString dumpInfo() const;
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index a0c9f9cf2b..0cd99d7469 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -303,6 +303,7 @@ private:
sk_sp<const GrBuffer> fIndexBuffer;
sk_sp<GrGeometryProcessor> fGeometryProcessor;
const GrPipeline* fPipeline;
+ const GrPipeline::FixedDynamicState* fFixedDynamicState;
int fVertexOffset;
int fInstancesToFlush;
};
@@ -310,8 +311,12 @@ private:
void onPrepareDraws(Target* target) override {
int instanceCount = fShapes.count();
+ auto pipe = fHelper.makePipeline(target);
+
FlushInfo flushInfo;
- flushInfo.fPipeline = fHelper.makePipeline(target);
+ flushInfo.fPipeline = pipe.fPipeline;
+ flushInfo.fFixedDynamicState = pipe.fFixedDynamicState;
+
// Setup GrGeometryProcessor
const SkMatrix& ctm = fShapes[0].fViewMatrix;
if (fUsesDistanceField) {
@@ -821,7 +826,8 @@ private:
kVerticesPerQuad, flushInfo->fInstancesToFlush,
maxInstancesPerDraw);
mesh.setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset);
- target->draw(flushInfo->fGeometryProcessor.get(), flushInfo->fPipeline, mesh);
+ target->draw(flushInfo->fGeometryProcessor.get(), flushInfo->fPipeline,
+ flushInfo->fFixedDynamicState, mesh);
flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush;
flushInfo->fInstancesToFlush = 0;
}
diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp
index 4c436c291d..ed59834a87 100644
--- a/src/gpu/ops/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp
@@ -358,7 +358,8 @@ private:
GrMesh mesh(TESSELLATOR_WIREFRAME ? GrPrimitiveType::kLines : GrPrimitiveType::kTriangles);
mesh.setNonIndexedNonInstanced(count);
mesh.setVertexData(vb, firstVertex);
- target->draw(gp, fHelper.makePipeline(target), mesh);
+ auto pipe = fHelper.makePipeline(target);
+ target->draw(gp, pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
bool onCombineIfPossible(GrOp*, const GrCaps&) override { return false; }
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index a895230241..bced31dbc5 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -793,8 +793,10 @@ __attribute__((no_sanitize("float-cast-overflow")))
args.fFlags |= GrPipeline::kHWAntialias_Flag;
}
- const GrPipeline* pipeline = target->allocPipeline(args, GrProcessorSet::MakeEmptySet(),
- target->detachAppliedClip());
+ auto clip = target->detachAppliedClip();
+ const auto* fixedDynamicState = target->allocFixedDynamicState(clip.scissorState().rect());
+ const auto* pipeline =
+ target->allocPipeline(args, GrProcessorSet::MakeEmptySet(), std::move(clip));
using TessFn =
decltype(&TextureOp::tess<SkPoint, MultiTexture::kNo, Domain::kNo, GrAA::kNo>);
#define TESS_FN_AND_VERTEX_SIZE(Point, MT, Domain, AA) \
@@ -866,7 +868,7 @@ __attribute__((no_sanitize("float-cast-overflow")))
mesh.setNonIndexedNonInstanced(4);
}
mesh.setVertexData(vbuffer, vstart);
- target->draw(gp.get(), pipeline, mesh);
+ target->draw(gp.get(), pipeline, fixedDynamicState, mesh);
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index 95bcb13cbf..91adb5a778 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -560,10 +560,12 @@ void GrVkGpuRTCommandBuffer::bindGeometry(const GrBuffer* indexBuffer,
}
}
-GrVkPipelineState* GrVkGpuRTCommandBuffer::prepareDrawState(const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- GrPrimitiveType primitiveType,
- bool hasDynamicState) {
+GrVkPipelineState* GrVkGpuRTCommandBuffer::prepareDrawState(
+ const GrPrimitiveProcessor& primProc,
+ const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState,
+ const GrPipeline::DynamicStateArrays* dynamicStateArrays,
+ GrPrimitiveType primitiveType) {
CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
SkASSERT(cbInfo.fRenderPass);
@@ -589,14 +591,15 @@ GrVkPipelineState* GrVkGpuRTCommandBuffer::prepareDrawState(const GrPrimitivePro
GrRenderTarget* rt = pipeline.renderTarget();
- if (!pipeline.getScissorState().enabled()) {
+ if (!pipeline.isScissorEnabled()) {
GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
rt, pipeline.proxy()->origin(),
SkIRect::MakeWH(rt->width(), rt->height()));
- } else if (!hasDynamicState) {
- GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
- rt, pipeline.proxy()->origin(),
- pipeline.getScissorState().rect());
+ } else if (!dynamicStateArrays || !dynamicStateArrays->fScissorRects) {
+ SkASSERT(fixedDynamicState);
+ GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), rt,
+ pipeline.proxy()->origin(),
+ fixedDynamicState->fScissorRect);
}
GrVkPipeline::SetDynamicViewportState(fGpu, cbInfo.currentCmdBuf(), rt);
GrVkPipeline::SetDynamicBlendConstantState(fGpu, cbInfo.currentCmdBuf(), rt->config(),
@@ -631,8 +634,9 @@ static void prepare_sampled_images(const GrResourceIOProcessor& processor,
void GrVkGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
+ const GrPipeline::FixedDynamicState* fixedDynamicState,
+ const GrPipeline::DynamicStateArrays* dynamicStateArrays,
const GrMesh meshes[],
- const GrPipeline::DynamicState dynamicStates[],
int meshCount,
const SkRect& bounds) {
SkASSERT(pipeline.renderTarget() == fRenderTarget);
@@ -653,12 +657,15 @@ void GrVkGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
}
GrPrimitiveType primitiveType = meshes[0].primitiveType();
- GrVkPipelineState* pipelineState =
- this->prepareDrawState(primProc, pipeline, primitiveType, SkToBool(dynamicStates));
+ GrVkPipelineState* pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
+ dynamicStateArrays, primitiveType);
if (!pipelineState) {
return;
}
+ bool dynamicScissor =
+ pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
+
for (int i = 0; i < meshCount; ++i) {
const GrMesh& mesh = meshes[i];
if (mesh.primitiveType() != primitiveType) {
@@ -668,19 +675,17 @@ void GrVkGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
pipelineState->freeTempResources(fGpu);
SkDEBUGCODE(pipelineState = nullptr);
primitiveType = mesh.primitiveType();
- pipelineState = this->prepareDrawState(
- primProc, pipeline, primitiveType, SkToBool(dynamicStates));
+ pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
+ dynamicStateArrays, primitiveType);
if (!pipelineState) {
return;
}
}
- if (dynamicStates) {
- if (pipeline.getScissorState().enabled()) {
- GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
- fRenderTarget, pipeline.proxy()->origin(),
- dynamicStates[i].fScissorRect);
- }
+ if (dynamicScissor) {
+ GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget,
+ pipeline.proxy()->origin(),
+ dynamicStateArrays->fScissorRects[i]);
}
SkASSERT(pipelineState);
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.h b/src/gpu/vk/GrVkGpuCommandBuffer.h
index b56d157d25..01b2693ba3 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.h
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.h
@@ -88,13 +88,15 @@ private:
GrVkPipelineState* prepareDrawState(const GrPrimitiveProcessor&,
const GrPipeline&,
- GrPrimitiveType,
- bool hasDynamicState);
-
- void onDraw(const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrMesh mesh[],
- const GrPipeline::DynamicState[],
+ const GrPipeline::FixedDynamicState*,
+ const GrPipeline::DynamicStateArrays*,
+ GrPrimitiveType);
+
+ void onDraw(const GrPrimitiveProcessor&,
+ const GrPipeline&,
+ const GrPipeline::FixedDynamicState*,
+ const GrPipeline::DynamicStateArrays*,
+ const GrMesh[],
int meshCount,
const SkRect& bounds) override;
diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp
index 385cc8b48b..91f42ade37 100644
--- a/src/gpu/vk/GrVkPipeline.cpp
+++ b/src/gpu/vk/GrVkPipeline.cpp
@@ -441,15 +441,11 @@ static void setup_dynamic_state(VkPipelineDynamicStateCreateInfo* dynamicInfo,
dynamicInfo->pDynamicStates = dynamicStates;
}
-GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrStencilSettings& stencil,
+GrVkPipeline* GrVkPipeline::Create(GrVkGpu* gpu, const GrPrimitiveProcessor& primProc,
+ const GrPipeline& pipeline, const GrStencilSettings& stencil,
VkPipelineShaderStageCreateInfo* shaderStageInfo,
- int shaderStageCount,
- GrPrimitiveType primitiveType,
- const GrVkRenderPass& renderPass,
- VkPipelineLayout layout,
+ int shaderStageCount, GrPrimitiveType primitiveType,
+ const GrVkRenderPass& renderPass, VkPipelineLayout layout,
VkPipelineCache cache) {
VkPipelineVertexInputStateCreateInfo vertexInputInfo;
SkSTArray<2, VkVertexInputBindingDescription, true> bindingDescs;
diff --git a/tests/GrMeshTest.cpp b/tests/GrMeshTest.cpp
index af6633fce7..aa951c0364 100644
--- a/tests/GrMeshTest.cpp
+++ b/tests/GrMeshTest.cpp
@@ -394,7 +394,7 @@ void DrawMeshHelper::drawMesh(const GrMesh& mesh) {
GrRenderTargetProxy* proxy = fState->drawOpArgs().fProxy;
GrPipeline pipeline(proxy, GrPipeline::ScissorState::kDisabled, SkBlendMode::kSrc);
GrMeshTestProcessor mtp(mesh.isInstanced(), mesh.hasVertexData());
- fState->rtCommandBuffer()->draw(mtp, pipeline, &mesh, nullptr, 1,
+ fState->rtCommandBuffer()->draw(mtp, pipeline, nullptr, nullptr, &mesh, 1,
SkRect::MakeIWH(kImageWidth, kImageHeight));
}
diff --git a/tests/GrPipelineDynamicStateTest.cpp b/tests/GrPipelineDynamicStateTest.cpp
index b8e893be6e..b2aaecc48b 100644
--- a/tests/GrPipelineDynamicStateTest.cpp
+++ b/tests/GrPipelineDynamicStateTest.cpp
@@ -35,11 +35,11 @@ static constexpr int kNumMeshes = 4;
static constexpr int kScreenSplitX = kScreenSize/2;
static constexpr int kScreenSplitY = kScreenSize/2;
-static const GrPipeline::DynamicState kDynamicStates[kNumMeshes] = {
- {SkIRect::MakeLTRB(0, 0, kScreenSplitX, kScreenSplitY)},
- {SkIRect::MakeLTRB(0, kScreenSplitY, kScreenSplitX, kScreenSize)},
- {SkIRect::MakeLTRB(kScreenSplitX, 0, kScreenSize, kScreenSplitY)},
- {SkIRect::MakeLTRB(kScreenSplitX, kScreenSplitY, kScreenSize, kScreenSize)},
+static const SkIRect kDynamicScissors[kNumMeshes] = {
+ SkIRect::MakeLTRB(0, 0, kScreenSplitX, kScreenSplitY),
+ SkIRect::MakeLTRB(0, kScreenSplitY, kScreenSplitX, kScreenSize),
+ SkIRect::MakeLTRB(kScreenSplitX, 0, kScreenSize, kScreenSplitY),
+ SkIRect::MakeLTRB(kScreenSplitX, kScreenSplitY, kScreenSize, kScreenSize),
};
static const GrColor kMeshColors[kNumMeshes] {
@@ -148,8 +148,10 @@ private:
mesh.setNonIndexedNonInstanced(4);
mesh.setVertexData(fVertexBuffer.get(), 4 * i);
}
- state->rtCommandBuffer()->draw(GrPipelineDynamicStateTestProcessor(), pipeline,
- meshes.begin(), kDynamicStates, 4,
+ GrPipeline::DynamicStateArrays dynamicState;
+ dynamicState.fScissorRects = kDynamicScissors;
+ state->rtCommandBuffer()->draw(GrPipelineDynamicStateTestProcessor(), pipeline, nullptr,
+ &dynamicState, meshes.begin(), 4,
SkRect::MakeIWH(kScreenSize, kScreenSize));
}
diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp
index a8752057c8..c60ae7c7da 100644
--- a/tests/OnFlushCallbackTest.cpp
+++ b/tests/OnFlushCallbackTest.cpp
@@ -163,7 +163,8 @@ private:
mesh.setIndexed(indexBuffer, 6, firstIndex, 0, 3, GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex);
- target->draw(gp.get(), fHelper.makePipeline(target), mesh);
+ auto pipe = fHelper.makePipeline(target);
+ target->draw(gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
}
Helper fHelper;
diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp
index 60b2205cf7..e9fbfd101a 100644
--- a/tests/PrimitiveProcessorTest.cpp
+++ b/tests/PrimitiveProcessorTest.cpp
@@ -111,9 +111,9 @@ private:
SkASSERT(vertexStride == gp->debugOnly_vertexStride());
SkPoint* vertices = reinterpret_cast<SkPoint*>(helper.init(target, vertexStride, 1));
SkPointPriv::SetRectTriStrip(vertices, 0.f, 0.f, 1.f, 1.f, vertexStride);
- helper.recordDraw(target, gp.get(),
- target->makePipeline(0, GrProcessorSet::MakeEmptySet(),
- target->detachAppliedClip()));
+ auto pipe = target->makePipeline(0, GrProcessorSet::MakeEmptySet(),
+ target->detachAppliedClip());
+ helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
}
int fNumAttribs;