aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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;