Add GrProgramInfo to centralize management of program information
This is the first step in moving the marshaling of program information earlier in renderTask processing (i.e., to onPrePrepare).
Change-Id: I91e3baed9a128e845bd32f9dbbacd9b21d852a3d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/244118
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/gm/clockwise.cpp b/gm/clockwise.cpp
index 8b7b0de..ab72288 100644
--- a/gm/clockwise.cpp
+++ b/gm/clockwise.cpp
@@ -36,6 +36,7 @@
#include "src/gpu/GrPrimitiveProcessor.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/GrProcessorSet.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrRenderTargetContextPriv.h"
@@ -165,9 +166,16 @@
GrMesh mesh(GrPrimitiveType::kTriangleStrip);
mesh.setNonIndexedNonInstanced(4);
mesh.setVertexData(std::move(fVertexBuffer));
- flushState->opsRenderPass()->draw(ClockwiseTestProcessor(fReadSkFragCoord), pipeline,
- nullptr, nullptr, &mesh, 1,
- SkRect::MakeXYWH(0, fY, 100, 100));
+
+ ClockwiseTestProcessor primProc(fReadSkFragCoord);
+
+ GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
+ flushState->drawOpArgs().origin(),
+ pipeline,
+ primProc,
+ nullptr, nullptr);
+
+ flushState->opsRenderPass()->draw(programInfo, &mesh, 1, SkRect::MakeXYWH(0, fY, 100, 100));
}
sk_sp<GrBuffer> fVertexBuffer;
diff --git a/gm/fwidth_squircle.cpp b/gm/fwidth_squircle.cpp
index 598e830..e75891e 100644
--- a/gm/fwidth_squircle.cpp
+++ b/gm/fwidth_squircle.cpp
@@ -30,6 +30,7 @@
#include "src/gpu/GrPrimitiveProcessor.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/GrProcessorSet.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrRenderTargetContextPriv.h"
@@ -150,7 +151,7 @@
this->setBounds(SkRect::MakeIWH(kWidth, kHeight), HasAABloat::kNo, IsHairline::kNo);
}
- const char* name() const override { return "ClockwiseTestOp"; }
+ const char* name() const override { return "FwidthSquircleTestOp"; }
FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
GrProcessorSet::Analysis finalize(
const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType) override {
@@ -172,12 +173,19 @@
}
GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
flushState->drawOpArgs().outputSwizzle());
+
+ FwidthSquircleTestProcessor primProc(fViewMatrix);
+
+ GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
+ flushState->drawOpArgs().origin(),
+ pipeline,
+ primProc,
+ nullptr, nullptr);
+
GrMesh mesh(GrPrimitiveType::kTriangleStrip);
mesh.setNonIndexedNonInstanced(4);
mesh.setVertexData(std::move(fVertexBuffer));
- flushState->opsRenderPass()->draw(FwidthSquircleTestProcessor(fViewMatrix), pipeline,
- nullptr, nullptr, &mesh, 1, SkRect::MakeIWH(kWidth,
- kHeight));
+ flushState->opsRenderPass()->draw(programInfo, &mesh, 1, SkRect::MakeIWH(kWidth, kHeight));
}
sk_sp<GrBuffer> fVertexBuffer;
diff --git a/gm/samplelocations.cpp b/gm/samplelocations.cpp
index e930d0a..c7cc73c 100644
--- a/gm/samplelocations.cpp
+++ b/gm/samplelocations.cpp
@@ -235,11 +235,17 @@
flushState->drawOpArgs().outputSwizzle(),
GrPipeline::InputFlags::kHWAntialias, &kStencilWrite);
+ SampleLocationsTestProcessor primProc(fGradType);
+
+ GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
+ flushState->drawOpArgs().origin(),
+ pipeline,
+ primProc,
+ nullptr, nullptr);
+
GrMesh mesh(GrPrimitiveType::kTriangleStrip);
mesh.setInstanced(nullptr, 200*200, 0, 4);
- flushState->opsRenderPass()->draw(
- SampleLocationsTestProcessor(fGradType), pipeline, nullptr, nullptr, &mesh, 1,
- SkRect::MakeIWH(200, 200));
+ flushState->opsRenderPass()->draw(programInfo, &mesh, 1, SkRect::MakeIWH(200, 200));
}
const GradType fGradType;
diff --git a/gn/gpu.gni b/gn/gpu.gni
index 01d1ef7..a612881 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -120,6 +120,8 @@
"$_src/gpu/GrMesh.h",
"$_src/gpu/GrNativeRect.h",
"$_src/gpu/GrNonAtomicRef.h",
+ "$_src/gpu/GrOnFlushResourceProvider.cpp",
+ "$_src/gpu/GrOnFlushResourceProvider.h",
"$_src/gpu/GrOpFlushState.cpp",
"$_src/gpu/GrOpFlushState.h",
"$_src/gpu/GrOpsRenderPass.cpp",
@@ -132,8 +134,6 @@
"$_src/gpu/GrPathRendererChain.h",
"$_src/gpu/GrPathRenderer.cpp",
"$_src/gpu/GrPathRenderer.h",
- "$_src/gpu/GrOnFlushResourceProvider.cpp",
- "$_src/gpu/GrOnFlushResourceProvider.h",
"$_src/gpu/GrPipeline.cpp",
"$_src/gpu/GrPipeline.h",
"$_src/gpu/GrPrimitiveProcessor.cpp",
@@ -142,6 +142,7 @@
"$_src/gpu/GrProcessorSet.h",
"$_src/gpu/GrProgramDesc.cpp",
"$_src/gpu/GrProgramDesc.h",
+ "$_src/gpu/GrProgramInfo.h",
"$_src/gpu/GrProcessor.cpp",
"$_src/gpu/GrProcessor.h",
"$_src/gpu/GrProcessorAnalysis.cpp",
diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp
index 8e10019..93a6026 100644
--- a/src/gpu/GrOpFlushState.cpp
+++ b/src/gpu/GrOpFlushState.cpp
@@ -13,6 +13,7 @@
#include "src/gpu/GrDrawOpAtlas.h"
#include "src/gpu/GrGpu.h"
#include "src/gpu/GrImageInfo.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrResourceProvider.h"
//////////////////////////////////////////////////////////////////////////////
@@ -52,10 +53,16 @@
this->opsRenderPass()->inlineUpload(this, fCurrUpload->fUpload);
++fCurrUpload;
}
- this->opsRenderPass()->draw(
- *fCurrDraw->fGeometryProcessor, *pipeline, fCurrDraw->fFixedDynamicState,
- fCurrDraw->fDynamicStateArrays, fCurrDraw->fMeshes, fCurrDraw->fMeshCnt,
- chainBounds);
+
+ GrProgramInfo programInfo(this->proxy()->numSamples(),
+ this->proxy()->origin(),
+ *pipeline,
+ *fCurrDraw->fGeometryProcessor,
+ fCurrDraw->fFixedDynamicState,
+ fCurrDraw->fDynamicStateArrays);
+
+ this->opsRenderPass()->draw(programInfo, fCurrDraw->fMeshes,
+ fCurrDraw->fMeshCnt, chainBounds);
fTokenTracker->flushToken();
++fCurrDraw;
}
diff --git a/src/gpu/GrOpsRenderPass.cpp b/src/gpu/GrOpsRenderPass.cpp
index 3728426..fd4345b 100644
--- a/src/gpu/GrOpsRenderPass.cpp
+++ b/src/gpu/GrOpsRenderPass.cpp
@@ -15,6 +15,7 @@
#include "src/gpu/GrGpu.h"
#include "src/gpu/GrMesh.h"
#include "src/gpu/GrPrimitiveProcessor.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrRenderTargetPriv.h"
#include "src/gpu/GrTexturePriv.h"
@@ -35,10 +36,7 @@
}
#ifdef SK_DEBUG
-static void assert_msaa_and_mips_are_resolved(
- const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- const GrPipeline::DynamicStateArrays* dynamicStateArrays, int meshCount) {
+static void assert_msaa_and_mips_are_resolved(const GrProgramInfo& programInfo, int meshCount) {
auto assertResolved = [](GrTexture* tex, const GrSamplerState& sampler) {
SkASSERT(tex);
@@ -52,68 +50,81 @@
}
};
- if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
- for (int m = 0, i = 0; m < meshCount; ++m) {
- for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) {
- auto* tex = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture();
- assertResolved(tex, primProc.textureSampler(s).samplerState());
+ if (programInfo.hasDynamicPrimProcTextures()) {
+ for (int m = 0; m < meshCount; ++m) {
+ auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m);
+
+ for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
+ auto* tex = dynamicPrimProcTextures[s]->peekTexture();
+ assertResolved(tex, programInfo.primProc().textureSampler(s).samplerState());
}
}
- } else {
- for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
- auto* tex = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
- assertResolved(tex, primProc.textureSampler(i).samplerState());
+ } else if (programInfo.hasFixedPrimProcTextures()) {
+ auto fixedPrimProcTextures = programInfo.fixedPrimProcTextures();
+
+ for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
+ auto* tex = fixedPrimProcTextures[s]->peekTexture();
+ assertResolved(tex, programInfo.primProc().textureSampler(s).samplerState());
}
}
- GrFragmentProcessor::Iter iter(pipeline);
+ GrFragmentProcessor::Iter iter(programInfo.pipeline());
while (const GrFragmentProcessor* fp = iter.next()) {
- for (int i = 0; i < fp->numTextureSamplers(); ++i) {
- const auto& textureSampler = fp->textureSampler(i);
+ for (int s = 0; s < fp->numTextureSamplers(); ++s) {
+ const auto& textureSampler = fp->textureSampler(s);
assertResolved(textureSampler.peekTexture(), textureSampler.samplerState());
}
}
}
#endif
-bool GrOpsRenderPass::draw(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- const GrPipeline::DynamicStateArrays* dynamicStateArrays,
+bool GrOpsRenderPass::draw(const GrProgramInfo& programInfo,
const GrMesh meshes[], int meshCount, const SkRect& bounds) {
+ if (!meshCount) {
+ return true;
+ }
+
#ifdef SK_DEBUG
- SkASSERT(!primProc.hasInstanceAttributes() || this->gpu()->caps()->instanceAttribSupport());
+ SkASSERT(!programInfo.primProc().hasInstanceAttributes() ||
+ this->gpu()->caps()->instanceAttribSupport());
for (int i = 0; i < meshCount; ++i) {
- SkASSERT(primProc.hasVertexAttributes() == meshes[i].hasVertexData());
- SkASSERT(primProc.hasInstanceAttributes() == meshes[i].hasInstanceData());
+ SkASSERT(programInfo.primProc().hasVertexAttributes() == meshes[i].hasVertexData());
+ SkASSERT(programInfo.primProc().hasInstanceAttributes() == meshes[i].hasInstanceData());
}
- SkASSERT(!pipeline.isScissorEnabled() || fixedDynamicState ||
- (dynamicStateArrays && dynamicStateArrays->fScissorRects));
+ SkASSERT(!programInfo.pipeline().isScissorEnabled() || programInfo.fixedDynamicState() ||
+ (programInfo.dynamicStateArrays() && programInfo.dynamicStateArrays()->fScissorRects));
- SkASSERT(!pipeline.isBad());
+ SkASSERT(!programInfo.pipeline().isBad());
- if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
- GrTextureProxy** processorProxies = fixedDynamicState->fPrimitiveProcessorTextures;
- for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
- SkASSERT(processorProxies[i]->isInstantiated());
+ if (programInfo.hasFixedPrimProcTextures()) {
+ auto fixedPrimProcTextures = programInfo.fixedPrimProcTextures();
+ for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
+ SkASSERT(fixedPrimProcTextures[s]->isInstantiated());
}
}
- if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
- int n = primProc.numTextureSamplers() * meshCount;
- const auto* textures = dynamicStateArrays->fPrimitiveProcessorTextures;
- for (int i = 0; i < n; ++i) {
- SkASSERT(textures[i]->isInstantiated());
+
+ if (programInfo.hasDynamicPrimProcTextures()) {
+ for (int m = 0; m < meshCount; ++m) {
+ auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m);
+ for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
+ SkASSERT(dynamicPrimProcTextures[s]->isInstantiated());
+ }
}
- SkASSERT(meshCount >= 1);
- const GrTextureProxy* const* primProcProxies =
- dynamicStateArrays->fPrimitiveProcessorTextures;
- for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
- const GrBackendFormat& format = primProcProxies[i]->backendFormat();
- GrTextureType type = primProcProxies[i]->textureType();
- GrPixelConfig config = primProcProxies[i]->config();
- for (int j = 1; j < meshCount; ++j) {
- const GrTextureProxy* testProxy =
- primProcProxies[j*primProc.numTextureSamplers() + i];
+
+ // Check that, for a given sampler, the properties of the dynamic textures remain
+ // the same for all the meshes
+ for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
+ auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(0);
+
+ const GrBackendFormat& format = dynamicPrimProcTextures[s]->backendFormat();
+ GrTextureType type = dynamicPrimProcTextures[s]->textureType();
+ GrPixelConfig config = dynamicPrimProcTextures[s]->config();
+
+ for (int m = 1; m < meshCount; ++m) {
+ dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m);
+
+ auto testProxy = dynamicPrimProcTextures[s];
SkASSERT(testProxy->backendFormat() == format);
SkASSERT(testProxy->textureType() == type);
SkASSERT(testProxy->config() == config);
@@ -121,22 +132,17 @@
}
}
- assert_msaa_and_mips_are_resolved(
- primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshCount);
+ assert_msaa_and_mips_are_resolved(programInfo, meshCount);
#endif
- if (primProc.numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
+ if (programInfo.primProc().numVertexAttributes() > this->gpu()->caps()->maxVertexAttributes()) {
this->gpu()->stats()->incNumFailedDraws();
return false;
}
- this->onDraw(primProc, pipeline, fixedDynamicState, dynamicStateArrays, meshes, meshCount,
- bounds);
+ this->onDraw(programInfo, meshes, meshCount, bounds);
+
#ifdef SK_DEBUG
- GrProcessor::CustomFeatures processorFeatures = primProc.requestedFeatures();
- for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
- processorFeatures |= pipeline.getFragmentProcessor(i).requestedFeatures();
- }
- processorFeatures |= pipeline.getXferProcessor().requestedFeatures();
+ GrProcessor::CustomFeatures processorFeatures = programInfo.requestedFeatures();
if (GrProcessor::CustomFeatures::kSampleLocations & processorFeatures) {
// Verify we always have the same sample pattern key, regardless of graphics state.
SkASSERT(this->gpu()->findOrAssignSamplePatternKey(fRenderTarget)
diff --git a/src/gpu/GrOpsRenderPass.h b/src/gpu/GrOpsRenderPass.h
index b23ee56..e3d24a7 100644
--- a/src/gpu/GrOpsRenderPass.h
+++ b/src/gpu/GrOpsRenderPass.h
@@ -18,6 +18,7 @@
class GrMesh;
class GrPipeline;
class GrPrimitiveProcessor;
+class GrProgramInfo;
class GrRenderTarget;
class GrSemaphore;
struct SkIRect;
@@ -55,13 +56,7 @@
// GrMesh object and emit a draw for it. Each draw will use the same GrPipeline and
// GrPrimitiveProcessor. This may fail if the draw would exceed any resource limits (e.g.
// number of vertex attributes is too large).
- bool draw(const GrPrimitiveProcessor&,
- const GrPipeline&,
- const GrPipeline::FixedDynamicState*,
- const GrPipeline::DynamicStateArrays*,
- const GrMesh[],
- int meshCount,
- const SkRect& bounds);
+ bool draw(const GrProgramInfo&, const GrMesh[], int meshCount, const SkRect& bounds);
// Performs an upload of vertex data in the middle of a set of a set of draws
virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0;
@@ -100,12 +95,7 @@
virtual GrGpu* gpu() = 0;
// 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[],
- int meshCount,
+ virtual void onDraw(const GrProgramInfo&, const GrMesh[], int meshCount,
const SkRect& bounds) = 0;
// overridden by backend-specific derived class to perform the clear.
diff --git a/src/gpu/GrOpsTask.cpp b/src/gpu/GrOpsTask.cpp
index 5670bd1..35bfcb6 100644
--- a/src/gpu/GrOpsTask.cpp
+++ b/src/gpu/GrOpsTask.cpp
@@ -412,11 +412,10 @@
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
TRACE_EVENT0("skia.gpu", chain.head()->name());
#endif
- GrOpFlushState::OpArgs opArgs(
- chain.head(),
- fTarget->asRenderTargetProxy(),
- chain.appliedClip(),
- chain.dstProxy());
+ GrOpFlushState::OpArgs opArgs(chain.head(),
+ fTarget->asRenderTargetProxy(),
+ chain.appliedClip(),
+ chain.dstProxy());
flushState->setOpArgs(&opArgs);
chain.head()->prepare(flushState);
diff --git a/src/gpu/GrPathRendering.cpp b/src/gpu/GrPathRendering.cpp
index 6dd3153..5e44531 100644
--- a/src/gpu/GrPathRendering.cpp
+++ b/src/gpu/GrPathRendering.cpp
@@ -12,6 +12,7 @@
#include "src/core/SkScalerContext.h"
#include "src/gpu/GrGpu.h"
#include "src/gpu/GrPathRendering.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRenderTarget.h"
const GrUserStencilSettings& GrPathRendering::GetStencilPassSettings(FillType fill) {
@@ -50,18 +51,15 @@
this->onStencilPath(args, path);
}
-void GrPathRendering::drawPath(GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState& fixedDynamicState,
+void GrPathRendering::drawPath(GrRenderTarget* renderTarget,
+ const GrProgramInfo& programInfo,
// Cover pass settings in pipeline.
const GrStencilSettings& stencilPassSettings,
const GrPath* path) {
fGpu->handleDirtyContext();
- if (GrXferBarrierType barrierType = pipeline.xferBarrierType(renderTarget->asTexture(),
- *fGpu->caps())) {
+ if (auto barrierType = programInfo.pipeline().xferBarrierType(renderTarget->asTexture(),
+ *fGpu->caps())) {
fGpu->xferBarrier(renderTarget, barrierType);
}
- this->onDrawPath(renderTarget, numSamples, origin, primProc, pipeline, fixedDynamicState,
- stencilPassSettings, path);
+ this->onDrawPath(renderTarget, programInfo, stencilPassSettings, path);
}
diff --git a/src/gpu/GrPathRendering.h b/src/gpu/GrPathRendering.h
index f12d9f5..3e143e4 100644
--- a/src/gpu/GrPathRendering.h
+++ b/src/gpu/GrPathRendering.h
@@ -9,12 +9,16 @@
#define GrPathRendering_DEFINED
#include "include/core/SkPath.h"
-#include "src/gpu/GrPipeline.h"
class GrGpu;
class GrPath;
+class GrProgramInfo;
+class GrRenderTarget;
+class GrRenderTargetProxy;
+class GrScissorState;
class GrStencilSettings;
class GrStyle;
+struct GrUserStencilSettings;
struct SkScalerContextEffects;
class SkDescriptor;
class SkTypeface;
@@ -108,10 +112,8 @@
void stencilPath(const StencilPathArgs& args, const GrPath* path);
- void drawPath(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState&,
+ void drawPath(GrRenderTarget*,
+ const GrProgramInfo&,
const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
const GrPath* path);
@@ -119,10 +121,8 @@
GrPathRendering(GrGpu* gpu) : fGpu(gpu) { }
virtual void onStencilPath(const StencilPathArgs&, const GrPath*) = 0;
- virtual void onDrawPath(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPrimitiveProcessor&,
- const GrPipeline&,
- const GrPipeline::FixedDynamicState&,
+ virtual void onDrawPath(GrRenderTarget*,
+ const GrProgramInfo&,
const GrStencilSettings&,
const GrPath*) = 0;
diff --git a/src/gpu/GrPathRendering_none.cpp b/src/gpu/GrPathRendering_none.cpp
index ea7fa78..3c2878d 100644
--- a/src/gpu/GrPathRendering_none.cpp
+++ b/src/gpu/GrPathRendering_none.cpp
@@ -42,10 +42,8 @@
sk_sp<GrPath> GrGLPathRendering::createPath(const SkPath&, const GrStyle&) { return nullptr; }
-void GrGLPathRendering::onDrawPath(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPrimitiveProcessor&,
- const GrPipeline&,
- const GrPipeline::FixedDynamicState&,
+void GrGLPathRendering::onDrawPath(GrRenderTarget*,
+ const GrProgramInfo&,
const GrStencilSettings&,
const GrPath*) {}
diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp
index acc0fd1..ac7b8b9 100644
--- a/src/gpu/GrProgramDesc.cpp
+++ b/src/gpu/GrProgramDesc.cpp
@@ -12,6 +12,7 @@
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrPrimitiveProcessor.h"
#include "src/gpu/GrProcessor.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRenderTargetPriv.h"
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/GrTexturePriv.h"
@@ -188,10 +189,8 @@
fp.numCoordTransforms()), b);
}
-bool GrProgramDesc::Build(
- GrProgramDesc* desc, const GrRenderTarget* renderTarget,
- const GrPrimitiveProcessor& primProc, bool hasPointSize, const GrPipeline& pipeline,
- GrGpu* gpu) {
+bool GrProgramDesc::Build(GrProgramDesc* desc, const GrRenderTarget* renderTarget,
+ const GrProgramInfo& programInfo, bool hasPointSize, GrGpu* gpu) {
// The descriptor is used as a cache key. Thus when a field of the
// descriptor will not affect program generation (because of the attribute
// bindings in use or other descriptor field settings) it should be set
@@ -206,28 +205,30 @@
GrProcessorKeyBuilder b(&desc->key());
- primProc.getGLSLProcessorKey(shaderCaps, &b);
- primProc.getAttributeKey(&b);
- if (!gen_meta_key(primProc, shaderCaps, 0, &b)) {
+ programInfo.primProc().getGLSLProcessorKey(shaderCaps, &b);
+ programInfo.primProc().getAttributeKey(&b);
+ if (!gen_meta_key(programInfo.primProc(), shaderCaps, 0, &b)) {
desc->key().reset();
return false;
}
- GrProcessor::CustomFeatures processorFeatures = primProc.requestedFeatures();
- for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
- const GrFragmentProcessor& fp = pipeline.getFragmentProcessor(i);
- if (!gen_frag_proc_and_meta_keys(primProc, fp, gpu, shaderCaps, &b)) {
+ // TODO: use programInfo.requestedFeatures here
+ GrProcessor::CustomFeatures processorFeatures = programInfo.primProc().requestedFeatures();
+
+ for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
+ const GrFragmentProcessor& fp = programInfo.pipeline().getFragmentProcessor(i);
+ if (!gen_frag_proc_and_meta_keys(programInfo.primProc(), fp, gpu, shaderCaps, &b)) {
desc->key().reset();
return false;
}
processorFeatures |= fp.requestedFeatures();
}
- const GrXferProcessor& xp = pipeline.getXferProcessor();
+ const GrXferProcessor& xp = programInfo.pipeline().getXferProcessor();
const GrSurfaceOrigin* originIfDstTexture = nullptr;
GrSurfaceOrigin origin;
- if (pipeline.dstTextureProxy()) {
- origin = pipeline.dstTextureProxy()->origin();
+ if (programInfo.pipeline().dstTextureProxy()) {
+ origin = programInfo.pipeline().dstTextureProxy()->origin();
originIfDstTexture = &origin;
}
xp.getGLSLProcessorKey(shaderCaps, &b, originIfDstTexture);
@@ -238,7 +239,7 @@
processorFeatures |= xp.requestedFeatures();
if (processorFeatures & GrProcessor::CustomFeatures::kSampleLocations) {
- SkASSERT(pipeline.isHWAntialiasState());
+ SkASSERT(programInfo.pipeline().isHWAntialiasState());
b.add32(renderTarget->renderTargetPriv().getSamplePatternKey());
}
@@ -249,17 +250,18 @@
// make sure any padding in the header is zeroed.
memset(header, 0, kHeaderSize);
- header->fOutputSwizzle = pipeline.outputSwizzle().asKey();
- header->fColorFragmentProcessorCnt = pipeline.numColorFragmentProcessors();
- header->fCoverageFragmentProcessorCnt = pipeline.numCoverageFragmentProcessors();
+ header->fOutputSwizzle = programInfo.pipeline().outputSwizzle().asKey();
+ header->fColorFragmentProcessorCnt = programInfo.pipeline().numColorFragmentProcessors();
+ header->fCoverageFragmentProcessorCnt = programInfo.pipeline().numCoverageFragmentProcessors();
// Fail if the client requested more processors than the key can fit.
- if (header->fColorFragmentProcessorCnt != pipeline.numColorFragmentProcessors() ||
- header->fCoverageFragmentProcessorCnt != pipeline.numCoverageFragmentProcessors()) {
+ if (header->fColorFragmentProcessorCnt != programInfo.pipeline().numColorFragmentProcessors() ||
+ header->fCoverageFragmentProcessorCnt !=
+ programInfo.pipeline().numCoverageFragmentProcessors()) {
return false;
}
header->fProcessorFeatures = (uint8_t)processorFeatures;
SkASSERT(header->processorFeatures() == processorFeatures); // Ensure enough bits.
- header->fSnapVerticesToPixelCenters = pipeline.snapVerticesToPixelCenters();
+ header->fSnapVerticesToPixelCenters = programInfo.pipeline().snapVerticesToPixelCenters();
header->fHasPointSize = hasPointSize ? 1 : 0;
return true;
}
diff --git a/src/gpu/GrProgramDesc.h b/src/gpu/GrProgramDesc.h
index 63cd46d..75c763c 100644
--- a/src/gpu/GrProgramDesc.h
+++ b/src/gpu/GrProgramDesc.h
@@ -15,9 +15,8 @@
#include "src/gpu/GrColor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+class GrProgramInfo;
class GrShaderCaps;
-class GrPipeline;
-class GrPrimitiveProcessor;
/** This class describes a program to generate. It also serves as a program cache key */
class GrProgramDesc {
@@ -29,18 +28,14 @@
* Builds a program descriptor. Before the descriptor can be used, the client must call finalize
* on the returned GrProgramDesc.
*
- * @param GrPrimitiveProcessor The geometry
+ * @param desc The built and finalized descriptor
+ * @param renderTarget The target of the draw
+ * @param programInfo Program information need to build the key
* @param hasPointSize Controls whether the shader will output a point size.
- * @param GrPipeline The optimized drawstate. The descriptor will represent a program
- * which this optstate can use to draw with. The optstate contains
- * general draw information, as well as the specific color, geometry,
- * and coverage stages which will be used to generate the GL Program for
- * this optstate.
- * @param GrGpu Ptr to the GrGpu object the program will be used with.
- * @param GrProgramDesc The built and finalized descriptor
+ * @param gpu Pointer to the GrGpu object the program will be used with.
**/
- static bool Build(GrProgramDesc*, const GrRenderTarget*, const GrPrimitiveProcessor&,
- bool hasPointSize, const GrPipeline&, GrGpu*);
+ static bool Build(GrProgramDesc*, const GrRenderTarget*, const GrProgramInfo&,
+ bool hasPointSize, GrGpu*);
static bool BuildFromData(GrProgramDesc* desc, const void* keyData, size_t keyLength) {
if (!SkTFitsIn<int>(keyLength)) {
diff --git a/src/gpu/GrProgramInfo.h b/src/gpu/GrProgramInfo.h
new file mode 100644
index 0000000..ec1d3b3
--- /dev/null
+++ b/src/gpu/GrProgramInfo.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProgramInfo_DEFINED
+#define GrProgramInfo_DEFINED
+
+#include "include/gpu/GrTypes.h"
+#include "src/gpu/GrPipeline.h"
+#include "src/gpu/GrPrimitiveProcessor.h"
+
+class GrProgramInfo {
+public:
+ GrProgramInfo(int numSamples,
+ GrSurfaceOrigin origin,
+ const GrPipeline& pipeline,
+ const GrPrimitiveProcessor& primProc,
+ const GrPipeline::FixedDynamicState* fixedDynamicState,
+ const GrPipeline::DynamicStateArrays* dynamicStateArrays)
+ : fNumSamples(numSamples)
+ , fOrigin(origin)
+ , fPipeline(pipeline)
+ , fPrimProc(primProc)
+ , fFixedDynamicState(fixedDynamicState)
+ , fDynamicStateArrays(dynamicStateArrays) {
+ }
+
+ int numSamples() const { return fNumSamples; }
+ GrSurfaceOrigin origin() const { return fOrigin; }
+ const GrPipeline& pipeline() const { return fPipeline; }
+ const GrPrimitiveProcessor& primProc() const { return fPrimProc; }
+ const GrPipeline::FixedDynamicState* fixedDynamicState() const { return fFixedDynamicState; }
+ const GrPipeline::DynamicStateArrays* dynamicStateArrays() const { return fDynamicStateArrays; }
+
+ // TODO: can this be removed?
+ const GrTextureProxy* const* primProcProxies() const {
+ const GrTextureProxy* const* primProcProxies = nullptr;
+ if (fDynamicStateArrays && fDynamicStateArrays->fPrimitiveProcessorTextures) {
+ primProcProxies = fDynamicStateArrays->fPrimitiveProcessorTextures;
+ } else if (fFixedDynamicState) {
+ primProcProxies = fFixedDynamicState->fPrimitiveProcessorTextures;
+ }
+
+ SkASSERT(SkToBool(primProcProxies) == SkToBool(fPrimProc.numTextureSamplers()));
+ return primProcProxies;
+ }
+
+ bool hasDynamicScissors() const {
+ return fPipeline.isScissorEnabled() &&
+ fDynamicStateArrays && fDynamicStateArrays->fScissorRects;
+ }
+
+ const SkIRect& dynamicScissor(int i) const {
+ SkASSERT(this->hasDynamicScissors());
+
+ return fDynamicStateArrays->fScissorRects[i];
+ }
+
+ bool hasFixedScissor() const { return fPipeline.isScissorEnabled() && fFixedDynamicState; }
+
+ const SkIRect& fixedScissor() const {
+ SkASSERT(this->hasFixedScissor());
+
+ return fFixedDynamicState->fScissorRect;
+ }
+
+ bool hasDynamicPrimProcTextures() const {
+ return fDynamicStateArrays && fDynamicStateArrays->fPrimitiveProcessorTextures;
+ }
+
+ const GrTextureProxy* const* dynamicPrimProcTextures(int i) const {
+ SkASSERT(this->hasDynamicPrimProcTextures());
+
+ return fDynamicStateArrays->fPrimitiveProcessorTextures +
+ i * fPrimProc.numTextureSamplers();
+ }
+
+ bool hasFixedPrimProcTextures() const {
+ return fFixedDynamicState && fFixedDynamicState->fPrimitiveProcessorTextures;
+ }
+
+ const GrTextureProxy* const* fixedPrimProcTextures() const {
+ SkASSERT(this->hasFixedPrimProcTextures());
+
+ return fFixedDynamicState->fPrimitiveProcessorTextures;
+ }
+
+#ifdef SK_DEBUG
+ bool isNVPR() const {
+ return fPrimProc.isPathRendering() && !fPrimProc.willUseGeoShader() &&
+ !fPrimProc.numVertexAttributes() && !fPrimProc.numInstanceAttributes();
+ }
+
+ // TODO: calculate this once in the ctor and use more widely
+ GrProcessor::CustomFeatures requestedFeatures() const {
+ GrProcessor::CustomFeatures requestedFeatures = fPrimProc.requestedFeatures();
+ for (int i = 0; i < fPipeline.numFragmentProcessors(); ++i) {
+ requestedFeatures |= fPipeline.getFragmentProcessor(i).requestedFeatures();
+ }
+ requestedFeatures |= fPipeline.getXferProcessor().requestedFeatures();
+ return requestedFeatures;
+ }
+#endif
+
+private:
+ const int fNumSamples;
+ const GrSurfaceOrigin fOrigin;
+ const GrPipeline& fPipeline;
+ const GrPrimitiveProcessor& fPrimProc;
+ const GrPipeline::FixedDynamicState* fFixedDynamicState;
+ const GrPipeline::DynamicStateArrays* fDynamicStateArrays;
+};
+
+#endif
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.cpp b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
index b6ec180..c36075e 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
@@ -10,6 +10,7 @@
#include "src/core/SkMakeUnique.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrOpsRenderPass.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/ccpr/GrCCConicShader.h"
#include "src/gpu/ccpr/GrCCCubicShader.h"
#include "src/gpu/ccpr/GrCCQuadraticShader.h"
@@ -201,5 +202,14 @@
GrPipeline::DynamicStateArrays dynamicStateArrays;
dynamicStateArrays.fScissorRects = scissorRects;
GrOpsRenderPass* renderPass = flushState->opsRenderPass();
- renderPass->draw(*this, pipeline, nullptr, &dynamicStateArrays, meshes, meshCount, drawBounds);
+
+ GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
+ flushState->drawOpArgs().origin(),
+ pipeline,
+ *this,
+ nullptr,
+ &dynamicStateArrays);
+
+
+ renderPass->draw(programInfo, meshes, meshCount, drawBounds);
}
diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp
index acc5613..4a7a136 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPathProcessor.cpp
@@ -141,8 +141,14 @@
baseInstance, enablePrimitiveRestart);
mesh.setVertexData(resources.refVertexBuffer());
- flushState->opsRenderPass()->draw(*this, pipeline, fixedDynamicState, nullptr, &mesh, 1,
- bounds);
+ GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
+ flushState->drawOpArgs().origin(),
+ pipeline,
+ *this,
+ fixedDynamicState,
+ nullptr);
+
+ flushState->opsRenderPass()->draw(programInfo, &mesh, 1, bounds);
}
void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
diff --git a/src/gpu/ccpr/GrCCStroker.cpp b/src/gpu/ccpr/GrCCStroker.cpp
index 98b8038..c768991 100644
--- a/src/gpu/ccpr/GrCCStroker.cpp
+++ b/src/gpu/ccpr/GrCCStroker.cpp
@@ -11,6 +11,7 @@
#include "src/core/SkPathPriv.h"
#include "src/gpu/GrOnFlushResourceProvider.h"
#include "src/gpu/GrOpsRenderPass.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/ccpr/GrCCCoverageProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
@@ -775,7 +776,15 @@
SkASSERT(fMeshesBuffer.count() == fScissorsBuffer.count());
GrPipeline::DynamicStateArrays dynamicStateArrays;
dynamicStateArrays.fScissorRects = fScissorsBuffer.begin();
- flushState->opsRenderPass()->draw(processor, pipeline, nullptr, &dynamicStateArrays,
+
+ GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
+ flushState->drawOpArgs().origin(),
+ pipeline,
+ processor,
+ nullptr,
+ &dynamicStateArrays);
+
+ flushState->opsRenderPass()->draw(programInfo,
fMeshesBuffer.begin(), fMeshesBuffer.count(),
SkRect::Make(drawBounds));
// Don't call reset(), as that also resets the reserve count.
diff --git a/src/gpu/ccpr/GrStencilAtlasOp.cpp b/src/gpu/ccpr/GrStencilAtlasOp.cpp
index 990cabc..2701ce4 100644
--- a/src/gpu/ccpr/GrStencilAtlasOp.cpp
+++ b/src/gpu/ccpr/GrStencilAtlasOp.cpp
@@ -10,6 +10,7 @@
#include "include/private/GrRecordingContext.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrOpsRenderPass.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/ccpr/GrCCPerFlushResources.h"
#include "src/gpu/ccpr/GrSampleMaskProcessor.h"
@@ -147,6 +148,15 @@
mesh.setInstanced(fResources->refStencilResolveBuffer(),
fEndStencilResolveInstance - fBaseStencilResolveInstance,
fBaseStencilResolveInstance, 4);
- flushState->opsRenderPass()->draw(StencilResolveProcessor(), resolvePipeline, &scissorRectState,
- nullptr, &mesh, 1, SkRect::Make(drawBoundsRect));
+
+ StencilResolveProcessor primProc;
+
+ GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
+ flushState->drawOpArgs().origin(),
+ resolvePipeline,
+ primProc,
+ &scissorRectState,
+ nullptr);
+
+ flushState->opsRenderPass()->draw(programInfo, &mesh, 1, SkRect::Make(drawBoundsRect));
}
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 0c1559c..bf2b81a 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -26,6 +26,7 @@
#include "src/gpu/GrGpuResourcePriv.h"
#include "src/gpu/GrMesh.h"
#include "src/gpu/GrPipeline.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRenderTargetPriv.h"
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/GrSurfaceProxyPriv.h"
@@ -1658,28 +1659,11 @@
}
bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- const GrPipeline::DynamicStateArrays* dynamicStateArrays,
- int dynamicStateArraysLength,
+ const GrProgramInfo& programInfo,
bool willDrawPoints) {
- const GrTextureProxy* const* primProcProxies = nullptr;
- const GrTextureProxy* const* primProcProxiesToBind = nullptr;
- if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
- primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
- } else if (fixedDynamicState && fixedDynamicState->fPrimitiveProcessorTextures) {
- primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
- primProcProxiesToBind = fixedDynamicState->fPrimitiveProcessorTextures;
- }
- SkASSERT(SkToBool(primProcProxies) == SkToBool(primProc.numTextureSamplers()));
-
- sk_sp<GrGLProgram> program(fProgramCache->refProgram(
- this, renderTarget, numSamples, origin, primProc, primProcProxies, pipeline,
- willDrawPoints));
+ sk_sp<GrGLProgram> program(fProgramCache->refProgram(this, renderTarget, programInfo,
+ willDrawPoints));
if (!program) {
GrCapsDebugf(this->caps(), "Failed to create program!\n");
return false;
@@ -1688,30 +1672,32 @@
this->flushProgram(std::move(program));
// Swizzle the blend to match what the shader will output.
- this->flushBlendAndColorWrite(
- pipeline.getXferProcessor().getBlendInfo(), pipeline.outputSwizzle());
+ this->flushBlendAndColorWrite(programInfo.pipeline().getXferProcessor().getBlendInfo(),
+ programInfo.pipeline().outputSwizzle());
- fHWProgram->updateUniformsAndTextureBindings(renderTarget, origin,
- primProc, pipeline, primProcProxiesToBind);
+ fHWProgram->updateUniformsAndTextureBindings(renderTarget, programInfo);
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
GrStencilSettings stencil;
- if (pipeline.isStencilEnabled()) {
+ if (programInfo.pipeline().isStencilEnabled()) {
// TODO: attach stencil and create settings during render target flush.
SkASSERT(glRT->renderTargetPriv().getStencilAttachment());
- stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
+ stencil.reset(*programInfo.pipeline().getUserStencil(),
+ programInfo.pipeline().hasStencilClip(),
glRT->renderTargetPriv().numStencilBits());
}
- this->flushStencil(stencil, origin);
- if (pipeline.isScissorEnabled()) {
+ this->flushStencil(stencil, programInfo.origin());
+ if (programInfo.pipeline().isScissorEnabled()) {
static constexpr SkIRect kBogusScissor{0, 0, 1, 1};
- GrScissorState state(fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor);
- this->flushScissor(state, glRT->width(), glRT->height(), origin);
+ GrScissorState state(programInfo.fixedDynamicState() ? programInfo.fixedScissor()
+ : kBogusScissor);
+ this->flushScissor(state, glRT->width(), glRT->height(), programInfo.origin());
} else {
this->disableScissor();
}
- this->flushWindowRectangles(pipeline.getWindowRectsState(), glRT, origin);
- this->flushHWAAState(glRT, pipeline.isHWAntialiasState());
+ this->flushWindowRectangles(programInfo.pipeline().getWindowRectsState(),
+ glRT, programInfo.origin());
+ this->flushHWAAState(glRT, programInfo.pipeline().isHWAntialiasState());
// This must come after textures are flushed because a texture may need
// to be msaa-resolved (which will modify bound FBO state).
@@ -2180,15 +2166,16 @@
#endif
#endif
-void GrGLGpu::draw(GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- const GrPipeline::DynamicStateArrays* dynamicStateArrays,
+void GrGLGpu::draw(GrRenderTarget* renderTarget,
+ const GrProgramInfo& programInfo,
const GrMesh meshes[],
int meshCount) {
this->handleDirtyContext();
+ if (meshCount == 0) {
+ return;
+ }
+
bool hasPoints = false;
for (int i = 0; i < meshCount; ++i) {
if (meshes[i].primitiveType() == GrPrimitiveType::kPoints) {
@@ -2196,32 +2183,28 @@
break;
}
}
- if (!this->flushGLState(renderTarget, numSamples, origin, primProc, pipeline, fixedDynamicState,
- dynamicStateArrays, meshCount, hasPoints)) {
+ if (!this->flushGLState(renderTarget, programInfo, hasPoints)) {
return;
}
- bool dynamicScissor = false;
- bool dynamicPrimProcTextures = false;
- if (dynamicStateArrays) {
- dynamicScissor = pipeline.isScissorEnabled() && dynamicStateArrays->fScissorRects;
- dynamicPrimProcTextures = dynamicStateArrays->fPrimitiveProcessorTextures;
- }
+ bool hasDynamicScissors = programInfo.hasDynamicScissors();
+ bool hasDynamicPrimProcTextures = programInfo.hasDynamicPrimProcTextures();
+
for (int m = 0; m < meshCount; ++m) {
- if (GrXferBarrierType barrierType = pipeline.xferBarrierType(renderTarget->asTexture(),
- *this->caps())) {
+ if (auto barrierType = programInfo.pipeline().xferBarrierType(renderTarget->asTexture(),
+ *this->caps())) {
this->xferBarrier(renderTarget, barrierType);
}
- if (dynamicScissor) {
+ if (hasDynamicScissors) {
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
- this->flushScissor(GrScissorState(dynamicStateArrays->fScissorRects[m]),
- glRT->width(), glRT->height(), origin);
+ this->flushScissor(GrScissorState(programInfo.dynamicScissor(m)),
+ glRT->width(), glRT->height(), programInfo.origin());
}
- if (dynamicPrimProcTextures) {
- auto texProxyArray = dynamicStateArrays->fPrimitiveProcessorTextures +
- m * primProc.numTextureSamplers();
- fHWProgram->updatePrimitiveProcessorTextureBindings(primProc, texProxyArray);
+ if (hasDynamicPrimProcTextures) {
+ auto texProxyArray = programInfo.dynamicPrimProcTextures(m);
+ fHWProgram->updatePrimitiveProcessorTextureBindings(programInfo.primProc(),
+ texProxyArray);
}
if (this->glCaps().requiresCullFaceEnableDisableWhenDrawingLinesAfterNonLines() &&
GrIsPrimTypeLines(meshes[m].primitiveType()) &&
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 8fba42a..8633c32 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -75,13 +75,7 @@
// The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
// Thus this is the implementation of the draw call for the corresponding passthrough function
// on GrGLOpsRenderPass.
- void draw(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPrimitiveProcessor&,
- const GrPipeline&,
- const GrPipeline::FixedDynamicState*,
- const GrPipeline::DynamicStateArrays*,
- const GrMesh[],
- int meshCount);
+ void draw(GrRenderTarget*, const GrProgramInfo&, const GrMesh[], int meshCount);
// GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls.
// Marked final as a hint to the compiler to not use virtual dispatch.
@@ -280,10 +274,7 @@
// willDrawPoints must be true if point primitives will be rendered after setting the GL state.
// If DynamicStateArrays is not null then dynamicStateArraysLength is the number of dynamic
// state entries in each array.
- bool flushGLState(GrRenderTarget*, int numSamples, GrSurfaceOrigin, const GrPrimitiveProcessor&,
- const GrPipeline&, const GrPipeline::FixedDynamicState*,
- const GrPipeline::DynamicStateArrays*, int dynamicStateArraysLength,
- bool willDrawPoints);
+ bool flushGLState(GrRenderTarget*, const GrProgramInfo&, bool willDrawPoints);
void flushProgram(sk_sp<GrGLProgram>);
@@ -321,10 +312,7 @@
void abandon();
void reset();
- GrGLProgram* refProgram(GrGLGpu*, GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline&, bool hasPointSize);
+ GrGLProgram* refProgram(GrGLGpu*, GrRenderTarget*, const GrProgramInfo&, bool hasPointSize);
bool precompileShader(const SkData& key, const SkData& data);
private:
diff --git a/src/gpu/gl/GrGLGpuProgramCache.cpp b/src/gpu/gl/GrGLGpuProgramCache.cpp
index 484048a..61ac321 100644
--- a/src/gpu/gl/GrGLGpuProgramCache.cpp
+++ b/src/gpu/gl/GrGLGpuProgramCache.cpp
@@ -47,30 +47,29 @@
GrGLProgram* GrGLGpu::ProgramCache::refProgram(GrGLGpu* gpu,
GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline& pipeline,
+ const GrProgramInfo& programInfo,
bool isPoints) {
+
+
+ // TODO: can this be unified between GL and Vk?
// Get GrGLProgramDesc
GrProgramDesc desc;
- if (!GrProgramDesc::Build(&desc, renderTarget, primProc, isPoints, pipeline, gpu)) {
+ if (!GrProgramDesc::Build(&desc, renderTarget, programInfo, isPoints, gpu)) {
GrCapsDebugf(gpu->caps(), "Failed to gl program descriptor!\n");
return nullptr;
}
// If we knew the shader won't depend on origin, we could skip this (and use the same program
// for both origins). Instrumenting all fragment processors would be difficult and error prone.
- desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
+ desc.setSurfaceOriginKey(
+ GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(programInfo.origin()));
std::unique_ptr<Entry>* entry = fMap.find(desc);
if (entry && !(*entry)->fProgram) {
// We've pre-compiled the GL program, but don't have the GrGLProgram scaffolding
const GrGLPrecompiledProgram* precompiledProgram = &((*entry)->fPrecompiledProgram);
SkASSERT(precompiledProgram->fProgramID != 0);
- GrGLProgram* program = GrGLProgramBuilder::CreateProgram(renderTarget, numSamples, origin,
- primProc, primProcProxies,
- pipeline, &desc, fGpu,
+ GrGLProgram* program = GrGLProgramBuilder::CreateProgram(renderTarget, programInfo,
+ &desc, fGpu,
precompiledProgram);
if (nullptr == program) {
// Should we purge the program ID from the cache at this point?
@@ -80,9 +79,8 @@
(*entry)->fProgram.reset(program);
} else if (!entry) {
// We have a cache miss
- GrGLProgram* program = GrGLProgramBuilder::CreateProgram(renderTarget, numSamples, origin,
- primProc, primProcProxies,
- pipeline, &desc, fGpu);
+ GrGLProgram* program = GrGLProgramBuilder::CreateProgram(renderTarget, programInfo,
+ &desc, fGpu);
if (nullptr == program) {
return nullptr;
}
diff --git a/src/gpu/gl/GrGLOpsRenderPass.h b/src/gpu/gl/GrGLOpsRenderPass.h
index cd7e5a0..fc04883 100644
--- a/src/gpu/gl/GrGLOpsRenderPass.h
+++ b/src/gpu/gl/GrGLOpsRenderPass.h
@@ -52,15 +52,9 @@
private:
GrGpu* gpu() override { return fGpu; }
- void onDraw(const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- const GrPipeline::DynamicStateArrays* dynamicStateArrays,
- const GrMesh mesh[],
- int meshCount,
+ void onDraw(const GrProgramInfo& programInfo, const GrMesh mesh[], int meshCount,
const SkRect& bounds) override {
- fGpu->draw(fRenderTarget, fRenderTarget->numSamples(), fOrigin, primProc, pipeline,
- fixedDynamicState, dynamicStateArrays, mesh, meshCount);
+ fGpu->draw(fRenderTarget, programInfo, mesh, meshCount);
}
void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override {
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index 9dc4437..327c8d2 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -112,14 +112,10 @@
}
void GrGLPathRendering::onDrawPath(GrRenderTarget* renderTarget,
- int numSamples, GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState& fixedDynamicState,
+ const GrProgramInfo& programInfo,
const GrStencilSettings& stencilPassSettings,
const GrPath* path) {
- if (!this->gpu()->flushGLState(renderTarget, numSamples, origin, primProc, pipeline,
- &fixedDynamicState, nullptr, 1, false)) {
+ if (!this->gpu()->flushGLState(renderTarget, programInfo, 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 167aa402..14284b4 100644
--- a/src/gpu/gl/GrGLPathRendering.h
+++ b/src/gpu/gl/GrGLPathRendering.h
@@ -65,11 +65,7 @@
protected:
void onStencilPath(const StencilPathArgs&, const GrPath*) override;
- void onDrawPath(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPrimitiveProcessor&,
- const GrPipeline&,
- const GrPipeline::FixedDynamicState&,
- const GrStencilSettings&,
+ void onDrawPath(GrRenderTarget*, const GrProgramInfo&, const GrStencilSettings&,
const GrPath*) override;
private:
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index e96ffa3..74cf539 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -10,6 +10,7 @@
#include "src/gpu/GrPathProcessor.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrProcessor.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrTexturePriv.h"
#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/gl/GrGLBuffer.h"
@@ -73,11 +74,9 @@
///////////////////////////////////////////////////////////////////////////////
void GrGLProgram::updateUniformsAndTextureBindings(const GrRenderTarget* renderTarget,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrTextureProxy* const primProcTextures[]) {
- this->setRenderTargetState(renderTarget, origin, primProc);
+ const GrProgramInfo& programInfo) {
+
+ this->setRenderTargetState(renderTarget, programInfo.origin(), programInfo.primProc());
// we set the textures, and uniforms for installed processors in a generic way, but subclasses
// of GLProgram determine how to set coord transforms
@@ -85,23 +84,24 @@
// We must bind to texture units in the same order in which we set the uniforms in
// GrGLProgramDataManager. That is, we bind textures for processors in this order:
// primProc, fragProcs, XP.
- fPrimitiveProcessor->setData(fProgramDataManager, primProc,
- GrFragmentProcessor::CoordTransformIter(pipeline));
- if (primProcTextures) {
- this->updatePrimitiveProcessorTextureBindings(primProc, primProcTextures);
+ fPrimitiveProcessor->setData(fProgramDataManager, programInfo.primProc(),
+ GrFragmentProcessor::CoordTransformIter(programInfo.pipeline()));
+ if (programInfo.hasFixedPrimProcTextures()) {
+ this->updatePrimitiveProcessorTextureBindings(programInfo.primProc(),
+ programInfo.fixedPrimProcTextures());
}
- int nextTexSamplerIdx = primProc.numTextureSamplers();
+ int nextTexSamplerIdx = programInfo.primProc().numTextureSamplers();
- this->setFragmentData(pipeline, &nextTexSamplerIdx);
+ this->setFragmentData(programInfo.pipeline(), &nextTexSamplerIdx);
- const GrXferProcessor& xp = pipeline.getXferProcessor();
+ const GrXferProcessor& xp = programInfo.pipeline().getXferProcessor();
SkIPoint offset;
- GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
+ GrTexture* dstTexture = programInfo.pipeline().peekDstTexture(&offset);
fXferProcessor->setData(fProgramDataManager, xp, dstTexture, offset);
if (dstTexture) {
fGpu->bindTexture(nextTexSamplerIdx++, GrSamplerState::ClampNearest(),
- pipeline.dstTextureProxy()->textureSwizzle(),
+ programInfo.pipeline().dstTextureProxy()->textureSwizzle(),
static_cast<GrGLTexture*>(dstTexture));
}
SkASSERT(nextTexSamplerIdx == fNumTextureSamplers);
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index b28bedb..cf2e2aa 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -18,6 +18,7 @@
class GrGLSLXferProcessor;
class GrPipeline;
class GrPrimitiveProcessor;
+class GrProgramInfo;
class GrRenderTarget;
class GrTextureProxy;
@@ -118,9 +119,7 @@
*
* It is the caller's responsibility to ensure the program is bound before calling.
*/
- void updateUniformsAndTextureBindings(const GrRenderTarget*, GrSurfaceOrigin,
- const GrPrimitiveProcessor&, const GrPipeline&,
- const GrTextureProxy* const primitiveProcessorTextures[]);
+ void updateUniformsAndTextureBindings(const GrRenderTarget*, const GrProgramInfo&);
void updatePrimitiveProcessorTextureBindings(const GrPrimitiveProcessor&,
const GrTextureProxy* const[]);
diff --git a/src/gpu/gl/GrGLVaryingHandler.cpp b/src/gpu/gl/GrGLVaryingHandler.cpp
index 8f48a21..76ab128 100644
--- a/src/gpu/gl/GrGLVaryingHandler.cpp
+++ b/src/gpu/gl/GrGLVaryingHandler.cpp
@@ -18,10 +18,7 @@
GrGLProgramBuilder* glPB = (GrGLProgramBuilder*) fProgramBuilder;
// This call is not used for non-NVPR backends.
SkASSERT(glPB->gpu()->glCaps().shaderCaps()->pathRenderingSupport() &&
- glPB->fPrimProc.isPathRendering() &&
- !glPB->fPrimProc.willUseGeoShader() &&
- !glPB->fPrimProc.numVertexAttributes() &&
- !glPB->fPrimProc.numInstanceAttributes());
+ fProgramBuilder->fProgramInfo.isNVPR());
#endif
this->addVarying(name, v);
auto varyingInfo = fPathProcVaryingInfos.push_back();
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index 507d210..07ea39c 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -46,23 +46,18 @@
}
GrGLProgram* GrGLProgramBuilder::CreateProgram(GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline& pipeline,
+ const GrProgramInfo& programInfo,
GrProgramDesc* desc,
GrGLGpu* gpu,
const GrGLPrecompiledProgram* precompiledProgram) {
- SkASSERT(!pipeline.isBad());
+ SkASSERT(!programInfo.pipeline().isBad());
ATRACE_ANDROID_FRAMEWORK("Shader Compile");
GrAutoLocaleSetter als("C");
// create a builder. This will be handed off to effects so they can use it to add
// uniforms, varyings, textures, etc
- GrGLProgramBuilder builder(gpu, renderTarget, numSamples, origin,
- pipeline, primProc, primProcProxies, desc);
+ GrGLProgramBuilder builder(gpu, renderTarget, programInfo, desc);
auto persistentCache = gpu->getContext()->priv().getPersistentCache();
if (persistentCache && !precompiledProgram) {
@@ -82,13 +77,9 @@
GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu,
GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPipeline& pipeline,
- const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const primProcProxies[],
+ const GrProgramInfo& programInfo,
GrProgramDesc* desc)
- : INHERITED(renderTarget, numSamples, origin, primProc, primProcProxies, pipeline, desc)
+ : INHERITED(renderTarget, programInfo, desc)
, fGpu(gpu)
, fVaryingHandler(this)
, fUniformHandler(this)
@@ -170,7 +161,7 @@
if (!this->gpu()->getContext()->priv().getPersistentCache()) {
return;
}
- sk_sp<SkData> key = SkData::MakeWithoutCopy(desc()->asKey(), desc()->keyLength());
+ sk_sp<SkData> key = SkData::MakeWithoutCopy(this->desc()->asKey(), this->desc()->keyLength());
if (fGpu->glCaps().programBinarySupport()) {
// binary cache
GrGLsizei length = 0;
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index b0fa41f..800c64a 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -48,11 +48,7 @@
* @return true if generation was successful.
*/
static GrGLProgram* CreateProgram(GrRenderTarget*,
- int numSamples,
- GrSurfaceOrigin,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline&,
+ const GrProgramInfo&,
GrProgramDesc*,
GrGLGpu*,
const GrGLPrecompiledProgram* = nullptr);
@@ -64,9 +60,7 @@
GrGLGpu* gpu() const { return fGpu; }
private:
- GrGLProgramBuilder(GrGLGpu*, GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPipeline&, const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[], GrProgramDesc*);
+ GrGLProgramBuilder(GrGLGpu*, GrRenderTarget*, const GrProgramInfo&, GrProgramDesc*);
void addInputVars(const SkSL::Program::Inputs& inputs);
bool compileAndAttachShaders(const SkSL::String& glsl,
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 25ac628..9621e14 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -21,22 +21,14 @@
const int GrGLSLProgramBuilder::kVarsPerBlock = 8;
GrGLSLProgramBuilder::GrGLSLProgramBuilder(GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline& pipeline,
- GrProgramDesc* desc)
+ const GrProgramInfo& programInfo,
+ const GrProgramDesc* desc)
: fVS(this)
, fGS(this)
, fFS(this)
, fStageIndex(-1)
, fRenderTarget(renderTarget)
- , fNumSamples(numSamples)
- , fOrigin(origin)
- , fPipeline(pipeline)
- , fPrimProc(primProc)
- , fPrimProcProxies(primProcProxies)
+ , fProgramInfo(programInfo)
, fDesc(desc)
, fGeometryProcessor(nullptr)
, fXferProcessor(nullptr)
@@ -115,7 +107,7 @@
name.c_str());
}
- GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline,
+ GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(this->pipeline(),
&fTransformedCoordVars);
GrGLSLGeometryProcessor::EmitArgs args(&fVS,
proc.willUseGeoShader() ? &fGS : nullptr,
@@ -229,7 +221,7 @@
AutoStageAdvance adv(this);
SkASSERT(!fXferProcessor);
- const GrXferProcessor& xp = fPipeline.getXferProcessor();
+ const GrXferProcessor& xp = this->pipeline().getXferProcessor();
fXferProcessor.reset(xp.createGLSLInstance());
// Enable dual source secondary output if we have one
@@ -248,13 +240,13 @@
SamplerHandle dstTextureSamplerHandle;
GrSurfaceOrigin dstTextureOrigin = kTopLeft_GrSurfaceOrigin;
- if (GrTexture* dstTexture = fPipeline.peekDstTexture()) {
+ if (GrTexture* dstTexture = this->pipeline().peekDstTexture()) {
// GrProcessor::TextureSampler sampler(dstTexture);
- SkASSERT(fPipeline.dstTextureProxy());
- const GrSwizzle& swizzle = fPipeline.dstTextureProxy()->textureSwizzle();
+ SkASSERT(this->pipeline().dstTextureProxy());
+ const GrSwizzle& swizzle = this->pipeline().dstTextureProxy()->textureSwizzle();
dstTextureSamplerHandle =
this->emitSampler(dstTexture, GrSamplerState(), swizzle, "DstTextureSampler");
- dstTextureOrigin = fPipeline.dstTextureProxy()->origin();
+ dstTextureOrigin = this->pipeline().dstTextureProxy()->origin();
SkASSERT(dstTexture->texturePriv().textureType() != GrTextureType::kExternal);
}
@@ -270,7 +262,7 @@
fFS.getSecondaryColorOutputName(),
dstTextureSamplerHandle,
dstTextureOrigin,
- this->desc()->header().fOutputSwizzle);
+ this->header().fOutputSwizzle);
fXferProcessor->emitCode(args);
// We have to check that effects and the code they emit are consistent, ie if an effect
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index dec6d11..b9bc61b 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -11,6 +11,7 @@
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrProgramDesc.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrRenderTargetPriv.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
@@ -36,8 +37,13 @@
virtual const GrCaps* caps() const = 0;
const GrShaderCaps* shaderCaps() const { return this->caps()->shaderCaps(); }
- const GrPrimitiveProcessor& primitiveProcessor() const { return fPrimProc; }
- const GrTextureProxy* const* primProcProxies() const { return fPrimProcProxies; }
+ int numSamples() const { return fProgramInfo.numSamples(); }
+ GrSurfaceOrigin origin() const { return fProgramInfo.origin(); }
+ const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); }
+ const GrPrimitiveProcessor& primitiveProcessor() const { return fProgramInfo.primProc(); }
+ const GrTextureProxy* const* primProcProxies() const { return fProgramInfo.primProcProxies(); }
+
+ // TODO: stop passing in the renderTarget for just the sampleLocations
int effectiveSampleCnt() const {
SkASSERT(GrProcessor::CustomFeatures::kSampleLocations & header().processorFeatures());
return fRenderTarget->renderTargetPriv().getSampleLocations().count();
@@ -45,10 +51,8 @@
const SkTArray<SkPoint>& getSampleLocations() const {
return fRenderTarget->renderTargetPriv().getSampleLocations();
}
- int numSamples() const { return fNumSamples; }
- GrSurfaceOrigin origin() const { return fOrigin; }
- const GrPipeline& pipeline() const { return fPipeline; }
- GrProgramDesc* desc() { return fDesc; }
+
+ const GrProgramDesc* desc() const { return fDesc; }
const GrProgramDesc::KeyHeader& header() const { return fDesc->header(); }
void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
@@ -95,14 +99,10 @@
int fStageIndex;
- const GrRenderTarget* fRenderTarget;
- const int fNumSamples;
- const GrSurfaceOrigin fOrigin;
- const GrPipeline& fPipeline;
- const GrPrimitiveProcessor& fPrimProc;
- const GrTextureProxy* const* fPrimProcProxies;
+ const GrRenderTarget* fRenderTarget; // TODO: remove this
+ const GrProgramInfo& fProgramInfo;
- GrProgramDesc* fDesc;
+ const GrProgramDesc* fDesc;
GrGLSLBuiltinUniformHandles fUniformHandles;
@@ -112,13 +112,7 @@
int fFragmentProcessorCnt;
protected:
- explicit GrGLSLProgramBuilder(GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline&,
- GrProgramDesc*);
+ explicit GrGLSLProgramBuilder(GrRenderTarget*, const GrProgramInfo&, const GrProgramDesc*);
void addFeature(GrShaderFlags shaders, uint32_t featureBit, const char* extensionName);
diff --git a/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp b/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp
index 733ea50..8edd4ba 100644
--- a/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp
@@ -14,7 +14,7 @@
void GrGLSLVertexGeoBuilder::emitNormalizedSkPosition(SkString* out, const char* devPos,
const char* rtAdjustName,
GrSLType devPosType) {
- if (this->getProgramBuilder()->desc()->header().fSnapVerticesToPixelCenters) {
+ if (this->getProgramBuilder()->header().fSnapVerticesToPixelCenters) {
if (kFloat3_GrSLType == devPosType) {
const char* p = devPos;
out->appendf("{float2 _posTmp = float2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p);
@@ -37,7 +37,7 @@
void GrGLSLVertexBuilder::onFinalize() {
// We could have the GrGeometryProcessor do this, but its just easier to have it performed
// here. If we ever need to set variable pointsize, then we can reinvestigate.
- if (this->getProgramBuilder()->desc()->header().fHasPointSize) {
+ if (this->getProgramBuilder()->header().fHasPointSize) {
this->codeAppend("sk_PointSize = 1.0;");
}
fProgramBuilder->varyingHandler()->getVertexDecls(&this->inputs(), &this->outputs());
diff --git a/src/gpu/mock/GrMockOpsRenderPass.h b/src/gpu/mock/GrMockOpsRenderPass.h
index 020bdc3..659dfba 100644
--- a/src/gpu/mock/GrMockOpsRenderPass.h
+++ b/src/gpu/mock/GrMockOpsRenderPass.h
@@ -35,9 +35,8 @@
int numDraws() const { return fNumDraws; }
private:
- void onDraw(const GrPrimitiveProcessor&, const GrPipeline&,
- const GrPipeline::FixedDynamicState*, const GrPipeline::DynamicStateArrays*,
- const GrMesh[], int meshCount, const SkRect& bounds) override {
+ void onDraw(const GrProgramInfo&, const GrMesh[], int meshCount,
+ const SkRect& bounds) override {
this->markRenderTargetDirty();
++fNumDraws;
}
diff --git a/src/gpu/mtl/GrMtlOpsRenderPass.h b/src/gpu/mtl/GrMtlOpsRenderPass.h
index 5e6f221..702bf29 100644
--- a/src/gpu/mtl/GrMtlOpsRenderPass.h
+++ b/src/gpu/mtl/GrMtlOpsRenderPass.h
@@ -44,16 +44,9 @@
private:
GrGpu* gpu() override { return fGpu; }
- GrMtlPipelineState* prepareDrawState(
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- GrPrimitiveType primType);
+ GrMtlPipelineState* prepareDrawState(const GrProgramInfo&, GrPrimitiveType);
- void onDraw(const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- const GrPipeline::DynamicStateArrays* dynamicStateArrays,
+ void onDraw(const GrProgramInfo& programInfo,
const GrMesh mesh[],
int meshCount,
const SkRect& bounds) override;
diff --git a/src/gpu/mtl/GrMtlOpsRenderPass.mm b/src/gpu/mtl/GrMtlOpsRenderPass.mm
index b6823b1..13d7fc8 100644
--- a/src/gpu/mtl/GrMtlOpsRenderPass.mm
+++ b/src/gpu/mtl/GrMtlOpsRenderPass.mm
@@ -53,50 +53,34 @@
fGpu->submitIndirectCommandBuffer(fRenderTarget, fOrigin, &iBounds);
}
-GrMtlPipelineState* GrMtlOpsRenderPass::prepareDrawState(
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- GrPrimitiveType primType) {
+GrMtlPipelineState* GrMtlOpsRenderPass::prepareDrawState(const GrProgramInfo& programInfo,
+ GrPrimitiveType primType) {
// TODO: resolve textures and regenerate mipmaps as needed
- const GrTextureProxy* const* primProcProxies = nullptr;
- if (fixedDynamicState) {
- primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
- }
- SkASSERT(SkToBool(primProcProxies) == SkToBool(primProc.numTextureSamplers()));
-
GrMtlPipelineState* pipelineState =
fGpu->resourceProvider().findOrCreateCompatiblePipelineState(fRenderTarget,
- fRenderTarget->numSamples(),
- fOrigin,
- pipeline,
- primProc,
- primProcProxies,
+ programInfo,
primType);
if (!pipelineState) {
return nullptr;
}
- pipelineState->setData(fRenderTarget, fOrigin, primProc, pipeline, primProcProxies);
- fCurrentVertexStride = primProc.vertexStride();
+
+ pipelineState->setData(fRenderTarget, programInfo);
+ fCurrentVertexStride = programInfo.primProc().vertexStride();
return pipelineState;
}
-void GrMtlOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- const GrPipeline::DynamicStateArrays* dynamicStateArrays,
- const GrMesh meshes[],
- int meshCount,
- const SkRect& bounds) {
+void GrMtlOpsRenderPass::onDraw(const GrProgramInfo& programInfo,
+ const GrMesh meshes[],
+ int meshCount,
+ const SkRect& bounds) {
if (!meshCount) {
return;
}
GrPrimitiveType primitiveType = meshes[0].primitiveType();
- GrMtlPipelineState* pipelineState = this->prepareDrawState(primProc, pipeline,
- fixedDynamicState, primitiveType);
+ GrMtlPipelineState* pipelineState = this->prepareDrawState(programInfo, primitiveType);
if (!pipelineState) {
return;
}
@@ -107,21 +91,23 @@
SkASSERT(fActiveRenderCmdEncoder);
[fActiveRenderCmdEncoder setRenderPipelineState:pipelineState->mtlPipelineState()];
- pipelineState->setDrawState(fActiveRenderCmdEncoder, pipeline.outputSwizzle(),
- pipeline.getXferProcessor());
+ pipelineState->setDrawState(fActiveRenderCmdEncoder,
+ programInfo.pipeline().outputSwizzle(),
+ programInfo.pipeline().getXferProcessor());
- bool dynamicScissor =
- pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
- if (!pipeline.isScissorEnabled()) {
+ bool hasDynamicScissors = programInfo.hasDynamicScissors();
+
+ if (!programInfo.pipeline().isScissorEnabled()) {
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder,
fRenderTarget, fOrigin,
SkIRect::MakeWH(fRenderTarget->width(),
fRenderTarget->height()));
- } else if (!dynamicScissor) {
- SkASSERT(fixedDynamicState);
+ } else if (!hasDynamicScissors) {
+ SkASSERT(programInfo.hasFixedScissor());
+
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder,
fRenderTarget, fOrigin,
- fixedDynamicState->fScissorRect);
+ programInfo.fixedScissor());
}
for (int i = 0; i < meshCount; ++i) {
@@ -130,21 +116,21 @@
if (mesh.primitiveType() != primitiveType) {
SkDEBUGCODE(pipelineState = nullptr);
primitiveType = mesh.primitiveType();
- pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
- primitiveType);
+ pipelineState = this->prepareDrawState(programInfo, primitiveType);
if (!pipelineState) {
return;
}
[fActiveRenderCmdEncoder setRenderPipelineState:pipelineState->mtlPipelineState()];
- pipelineState->setDrawState(fActiveRenderCmdEncoder, pipeline.outputSwizzle(),
- pipeline.getXferProcessor());
+ pipelineState->setDrawState(fActiveRenderCmdEncoder,
+ programInfo.pipeline().outputSwizzle(),
+ programInfo.pipeline().getXferProcessor());
}
- if (dynamicScissor) {
+ if (hasDynamicScissors) {
GrMtlPipelineState::SetDynamicScissorRectState(fActiveRenderCmdEncoder, fRenderTarget,
fOrigin,
- dynamicStateArrays->fScissorRects[i]);
+ programInfo.dynamicScissor(i));
}
mesh.sendToGpu(this);
diff --git a/src/gpu/mtl/GrMtlPipelineState.h b/src/gpu/mtl/GrMtlPipelineState.h
index 4726fdb..e71aee2 100644
--- a/src/gpu/mtl/GrMtlPipelineState.h
+++ b/src/gpu/mtl/GrMtlPipelineState.h
@@ -46,9 +46,7 @@
id<MTLRenderPipelineState> mtlPipelineState() { return fPipelineState; }
- void setData(const GrRenderTarget*, GrSurfaceOrigin,
- const GrPrimitiveProcessor& primPRoc, const GrPipeline& pipeline,
- const GrTextureProxy* const primProcTextures[]);
+ void setData(const GrRenderTarget*, const GrProgramInfo&);
void setDrawState(id<MTLRenderCommandEncoder>, const GrSwizzle& outputSwizzle,
const GrXferProcessor&);
diff --git a/src/gpu/mtl/GrMtlPipelineState.mm b/src/gpu/mtl/GrMtlPipelineState.mm
index 9fe2db2..96ecb18 100644
--- a/src/gpu/mtl/GrMtlPipelineState.mm
+++ b/src/gpu/mtl/GrMtlPipelineState.mm
@@ -58,23 +58,23 @@
}
void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrTextureProxy* const primProcTextures[]) {
- SkASSERT(primProcTextures || !primProc.numTextureSamplers());
+ const GrProgramInfo& programInfo) {
+ SkASSERT(programInfo.primProcProxies() || !programInfo.primProc().numTextureSamplers());
- this->setRenderTargetState(renderTarget, origin);
- fGeometryProcessor->setData(fDataManager, primProc,
- GrFragmentProcessor::CoordTransformIter(pipeline));
+ // Note: the Metal backend currently only supports fixed primProc textures
+ const GrTextureProxy* const* primProcProxies = programInfo.primProcProxies();
+
+ this->setRenderTargetState(renderTarget, programInfo.origin());
+ fGeometryProcessor->setData(fDataManager, programInfo.primProc(),
+ GrFragmentProcessor::CoordTransformIter(programInfo.pipeline()));
fSamplerBindings.reset();
- for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
- const auto& sampler = primProc.textureSampler(i);
- auto texture = static_cast<GrMtlTexture*>(primProcTextures[i]->peekTexture());
+ for (int i = 0; i < programInfo.primProc().numTextureSamplers(); ++i) {
+ const auto& sampler = programInfo.primProc().textureSampler(i);
+ auto texture = static_cast<GrMtlTexture*>(primProcProxies[i]->peekTexture());
fSamplerBindings.emplace_back(sampler.samplerState(), texture, fGpu);
}
- GrFragmentProcessor::Iter iter(pipeline);
+ GrFragmentProcessor::Iter iter(programInfo.pipeline());
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
const GrFragmentProcessor* fp = iter.next();
GrGLSLFragmentProcessor* glslFP = glslIter.next();
@@ -91,12 +91,13 @@
{
SkIPoint offset;
- GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
+ GrTexture* dstTexture = programInfo.pipeline().peekDstTexture(&offset);
- fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
+ fXferProcessor->setData(fDataManager, programInfo.pipeline().getXferProcessor(),
+ dstTexture, offset);
}
- if (GrTextureProxy* dstTextureProxy = pipeline.dstTextureProxy()) {
+ if (GrTextureProxy* dstTextureProxy = programInfo.pipeline().dstTextureProxy()) {
fSamplerBindings.emplace_back(GrSamplerState::ClampNearest(),
dstTextureProxy->peekTexture(),
fGpu);
@@ -105,9 +106,10 @@
SkASSERT(fNumSamplers == fSamplerBindings.count());
fDataManager.resetDirtyBits();
- if (pipeline.isStencilEnabled()) {
+ if (programInfo.pipeline().isStencilEnabled()) {
SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
- fStencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
+ fStencil.reset(*programInfo.pipeline().getUserStencil(),
+ programInfo.pipeline().hasStencilClip(),
renderTarget->renderTargetPriv().numStencilBits());
}
}
diff --git a/src/gpu/mtl/GrMtlPipelineStateBuilder.h b/src/gpu/mtl/GrMtlPipelineStateBuilder.h
index e44dae5b..fda1e65 100644
--- a/src/gpu/mtl/GrMtlPipelineStateBuilder.h
+++ b/src/gpu/mtl/GrMtlPipelineStateBuilder.h
@@ -17,6 +17,7 @@
#import <Metal/Metal.h>
+class GrProgramInfo;
class GrMtlGpu;
class GrMtlPipelineState;
@@ -35,12 +36,8 @@
*/
class Desc : public GrProgramDesc {
public:
- static bool Build(Desc*,
- GrRenderTarget*,
- const GrPrimitiveProcessor&,
- const GrPipeline&,
- GrPrimitiveType,
- GrMtlGpu* gpu);
+ static bool Build(Desc*, GrRenderTarget*,
+ const GrProgramInfo&, GrPrimitiveType, GrMtlGpu* gpu);
size_t shaderKeyLength() const { return fShaderKeyLength; }
@@ -59,23 +56,14 @@
* @return true if generation was successful.
*/
static GrMtlPipelineState* CreatePipelineState(GrMtlGpu*,
- GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline&,
+ GrRenderTarget*,
+ const GrProgramInfo&,
Desc*);
private:
- GrMtlPipelineStateBuilder(GrMtlGpu*, GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPipeline&,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
- GrProgramDesc*);
+ GrMtlPipelineStateBuilder(GrMtlGpu*, GrRenderTarget*, const GrProgramInfo&, GrProgramDesc*);
- GrMtlPipelineState* finalize(GrRenderTarget* renderTarget,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- Desc*);
+ GrMtlPipelineState* finalize(GrRenderTarget*, const GrProgramInfo&, Desc*);
const GrCaps* caps() const override;
diff --git a/src/gpu/mtl/GrMtlPipelineStateBuilder.mm b/src/gpu/mtl/GrMtlPipelineStateBuilder.mm
index 16d4b94..820eed6 100644
--- a/src/gpu/mtl/GrMtlPipelineStateBuilder.mm
+++ b/src/gpu/mtl/GrMtlPipelineStateBuilder.mm
@@ -22,31 +22,23 @@
#error This file must be compiled with Arc. Use -fobjc-arc flag
#endif
-GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState(
- GrMtlGpu* gpu,
- GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline& pipeline,
- Desc* desc) {
- GrMtlPipelineStateBuilder builder(gpu, renderTarget, numSamples, origin, pipeline, primProc,
- primProcProxies, desc);
+GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState(GrMtlGpu* gpu,
+ GrRenderTarget* renderTarget,
+ const GrProgramInfo& programInfo,
+ Desc* desc) {
+ GrMtlPipelineStateBuilder builder(gpu, renderTarget, programInfo, desc);
if (!builder.emitAndInstallProcs()) {
return nullptr;
}
- return builder.finalize(renderTarget, primProc, pipeline, desc);
+ return builder.finalize(renderTarget, programInfo, desc);
}
GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPipeline& pipeline,
- const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const primProcProxies[],
+ const GrProgramInfo& programInfo,
GrProgramDesc* desc)
- : INHERITED(renderTarget, numSamples, origin, primProc, primProcProxies, pipeline, desc)
+ : INHERITED(renderTarget, programInfo, desc)
, fGpu(gpu)
, fUniformHandler(this)
, fVaryingHandler(this) {
@@ -348,8 +340,7 @@
}
GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTarget,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
+ const GrProgramInfo& programInfo,
Desc* desc) {
auto pipelineDescriptor = [MTLRenderPipelineDescriptor new];
@@ -397,9 +388,9 @@
pipelineDescriptor.vertexFunction = vertexFunction;
pipelineDescriptor.fragmentFunction = fragmentFunction;
- pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(primProc);
+ pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(programInfo.primProc());
pipelineDescriptor.colorAttachments[0] = create_color_attachment(renderTarget->config(),
- pipeline);
+ programInfo.pipeline());
pipelineDescriptor.sampleCount = renderTarget->numSamples();
bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment());
GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps();
@@ -455,12 +446,11 @@
bool GrMtlPipelineStateBuilder::Desc::Build(Desc* desc,
GrRenderTarget* renderTarget,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
+ const GrProgramInfo& programInfo,
GrPrimitiveType primitiveType,
GrMtlGpu* gpu) {
- if (!INHERITED::Build(desc, renderTarget, primProc,
- GrPrimitiveType::kLines == primitiveType, pipeline, gpu)) {
+ if (!GrProgramDesc::Build(desc, renderTarget, programInfo,
+ GrPrimitiveType::kPoints == primitiveType, gpu)) {
return false;
}
@@ -475,10 +465,10 @@
bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment());
b.add32(hasStencilAttachment ? gpu->mtlCaps().preferredStencilFormat().fInternalFormat
: MTLPixelFormatInvalid);
- b.add32((uint32_t)pipeline.isStencilEnabled());
+ b.add32((uint32_t)programInfo.pipeline().isStencilEnabled());
// Stencil samples don't seem to be tracked in the MTLRenderPipeline
- b.add32(pipeline.getBlendInfoKey());
+ b.add32(programInfo.pipeline().getBlendInfoKey());
b.add32((uint32_t)primitiveType);
diff --git a/src/gpu/mtl/GrMtlResourceProvider.h b/src/gpu/mtl/GrMtlResourceProvider.h
index c1e88f8..c6ce35a 100644
--- a/src/gpu/mtl/GrMtlResourceProvider.h
+++ b/src/gpu/mtl/GrMtlResourceProvider.h
@@ -24,12 +24,9 @@
public:
GrMtlResourceProvider(GrMtlGpu* gpu);
- GrMtlPipelineState* findOrCreateCompatiblePipelineState(
- GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPipeline&,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
- GrPrimitiveType);
+ GrMtlPipelineState* findOrCreateCompatiblePipelineState(GrRenderTarget*,
+ const GrProgramInfo&,
+ GrPrimitiveType);
// Finds or creates a compatible MTLDepthStencilState based on the GrStencilSettings.
GrMtlDepthStencil* findOrCreateCompatibleDepthStencilState(const GrStencilSettings&,
@@ -55,10 +52,7 @@
~PipelineStateCache();
void release();
- GrMtlPipelineState* refPipelineState(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline&,
+ GrMtlPipelineState* refPipelineState(GrRenderTarget*, const GrProgramInfo&,
GrPrimitiveType);
private:
diff --git a/src/gpu/mtl/GrMtlResourceProvider.mm b/src/gpu/mtl/GrMtlResourceProvider.mm
index 1c070b6..1074622 100644
--- a/src/gpu/mtl/GrMtlResourceProvider.mm
+++ b/src/gpu/mtl/GrMtlResourceProvider.mm
@@ -38,11 +38,10 @@
}
GrMtlPipelineState* GrMtlResourceProvider::findOrCreateCompatiblePipelineState(
- GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin origin,
- const GrPipeline& pipeline, const GrPrimitiveProcessor& proc,
- const GrTextureProxy* const primProcProxies[], GrPrimitiveType primType) {
- return fPipelineStateCache->refPipelineState(renderTarget, numSamples, origin, proc,
- primProcProxies, pipeline, primType);
+ GrRenderTarget* renderTarget,
+ const GrProgramInfo& programInfo,
+ GrPrimitiveType primType) {
+ return fPipelineStateCache->refPipelineState(renderTarget, programInfo, primType);
}
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -137,25 +136,23 @@
GrMtlPipelineState* GrMtlResourceProvider::PipelineStateCache::refPipelineState(
GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline& pipeline,
+ const GrProgramInfo& programInfo,
GrPrimitiveType primType) {
#ifdef GR_PIPELINE_STATE_CACHE_STATS
++fTotalRequests;
#endif
+
+ // TODO: unify GL, VK and Mtl
// Get GrMtlProgramDesc
GrMtlPipelineStateBuilder::Desc desc;
- if (!GrMtlPipelineStateBuilder::Desc::Build(&desc, renderTarget, primProc, pipeline, primType,
- fGpu)) {
+ if (!GrMtlPipelineStateBuilder::Desc::Build(&desc, renderTarget, programInfo, primType, fGpu)) {
GrCapsDebugf(fGpu->caps(), "Failed to build mtl program descriptor!\n");
return nullptr;
}
// If we knew the shader won't depend on origin, we could skip this (and use the same program
// for both origins). Instrumenting all fragment processors would be difficult and error prone.
- desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
+ desc.setSurfaceOriginKey(
+ GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(programInfo.origin()));
std::unique_ptr<Entry>* entry = fMap.find(desc);
if (!entry) {
@@ -163,8 +160,8 @@
++fCacheMisses;
#endif
GrMtlPipelineState* pipelineState(GrMtlPipelineStateBuilder::CreatePipelineState(
- fGpu, renderTarget, numSamples, origin, primProc, primProcProxies, pipeline, &desc));
- if (nullptr == pipelineState) {
+ fGpu, renderTarget, programInfo, &desc));
+ if (!pipelineState) {
return nullptr;
}
entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(fGpu, pipelineState)));
diff --git a/src/gpu/ops/GrDrawPathOp.cpp b/src/gpu/ops/GrDrawPathOp.cpp
index d7bb20d..d6700d3 100644
--- a/src/gpu/ops/GrDrawPathOp.cpp
+++ b/src/gpu/ops/GrDrawPathOp.cpp
@@ -9,6 +9,7 @@
#include "include/private/SkTemplates.h"
#include "src/gpu/GrAppliedClip.h"
#include "src/gpu/GrMemoryPool.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrRenderTargetPriv.h"
@@ -92,13 +93,17 @@
std::move(appliedClip));
sk_sp<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(), this->viewMatrix()));
+ GrProgramInfo programInfo(state->drawOpArgs().numSamples(),
+ state->drawOpArgs().origin(),
+ pipeline,
+ *pathProc,
+ &fixedDynamicState,
+ nullptr);
+
GrStencilSettings stencil;
init_stencil_pass_settings(*state, this->fillType(), &stencil);
state->gpu()->pathRendering()->drawPath(state->drawOpArgs().renderTarget(),
- state->drawOpArgs().renderTarget()->numSamples(),
- state->drawOpArgs().origin(),
- *pathProc, pipeline, fixedDynamicState, stencil,
- fPath.get());
+ programInfo, stencil, fPath.get());
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/ops/GrFillRRectOp.cpp b/src/gpu/ops/GrFillRRectOp.cpp
index bbed9f2..c3f86a3 100644
--- a/src/gpu/ops/GrFillRRectOp.cpp
+++ b/src/gpu/ops/GrFillRRectOp.cpp
@@ -13,6 +13,7 @@
#include "src/gpu/GrMemoryPool.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrOpsRenderPass.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
@@ -750,13 +751,19 @@
std::move(fProcessors),
std::move(clip));
+ GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
+ flushState->drawOpArgs().origin(),
+ *pipeline,
+ *proc,
+ fixedDynamicState,
+ nullptr);
+
GrMesh* mesh = flushState->allocator()->make<GrMesh>(GrPrimitiveType::kTriangles);
mesh->setIndexedInstanced(
std::move(fIndexBuffer), fIndexCount, std::move(fInstanceBuffer), fInstanceCount,
fBaseInstance, GrPrimitiveRestart::kNo);
mesh->setVertexData(std::move(fVertexBuffer));
- flushState->opsRenderPass()->draw(
- *proc, *pipeline, fixedDynamicState, nullptr, mesh, 1, this->bounds());
+ flushState->opsRenderPass()->draw(programInfo, mesh, 1, this->bounds());
fIndexCount = 0;
}
diff --git a/src/gpu/ops/GrStencilPathOp.h b/src/gpu/ops/GrStencilPathOp.h
index b46b29a..2d4f37f 100644
--- a/src/gpu/ops/GrStencilPathOp.h
+++ b/src/gpu/ops/GrStencilPathOp.h
@@ -10,6 +10,7 @@
#include "src/gpu/GrPath.h"
#include "src/gpu/GrPathRendering.h"
+#include "src/gpu/GrScissorState.h"
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/ops/GrOp.h"
diff --git a/src/gpu/vk/GrVkOpsRenderPass.cpp b/src/gpu/vk/GrVkOpsRenderPass.cpp
index c28e385..bd2c48e 100644
--- a/src/gpu/vk/GrVkOpsRenderPass.cpp
+++ b/src/gpu/vk/GrVkOpsRenderPass.cpp
@@ -374,8 +374,7 @@
SkToBool(fCurrentSecondaryCommandBuffer));
}
-void GrVkOpsRenderPass::inlineUpload(GrOpFlushState* state,
- GrDeferredTextureUploadFn& upload) {
+void GrVkOpsRenderPass::inlineUpload(GrOpFlushState* state, GrDeferredTextureUploadFn& upload) {
if (fCurrentSecondaryCommandBuffer) {
fCurrentSecondaryCommandBuffer->end(fGpu);
fGpu->submitSecondaryCommandBuffer(std::move(fCurrentSecondaryCommandBuffer));
@@ -428,10 +427,7 @@
}
GrVkPipelineState* GrVkOpsRenderPass::prepareDrawState(
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- const GrPipeline::DynamicStateArrays* dynamicStateArrays,
+ const GrProgramInfo& programInfo,
GrPrimitiveType primitiveType,
const SkIRect& renderPassScissorRect) {
GrVkCommandBuffer* currentCB = this->currentCommandBuffer();
@@ -439,22 +435,9 @@
VkRenderPass compatibleRenderPass = fCurrentRenderPass->vkRenderPass();
- const GrTextureProxy* const* primProcProxies = nullptr;
- if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
- primProcProxies = dynamicStateArrays->fPrimitiveProcessorTextures;
- } else if (fixedDynamicState) {
- primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
- }
-
- SkASSERT(SkToBool(primProcProxies) == SkToBool(primProc.numTextureSamplers()));
-
GrVkPipelineState* pipelineState =
fGpu->resourceProvider().findOrCreateCompatiblePipelineState(fRenderTarget,
- fRenderTarget->numSamples(),
- fOrigin,
- pipeline,
- primProc,
- primProcProxies,
+ programInfo,
primitiveType,
compatibleRenderPass);
if (!pipelineState) {
@@ -463,30 +446,38 @@
pipelineState->bindPipeline(fGpu, currentCB);
- pipelineState->setAndBindUniforms(fGpu, fRenderTarget, fOrigin, primProc, pipeline, currentCB);
+ // Both the 'programInfo' and this renderPass have an origin. Since they come from the
+ // same place (i.e., the target renderTargetProxy) that had best agree.
+ SkASSERT(programInfo.origin() == fOrigin);
+
+ // TODO: just pass in GrProgramInfo
+ pipelineState->setAndBindUniforms(fGpu, fRenderTarget, fOrigin,
+ programInfo.primProc(), programInfo.pipeline(), currentCB);
// Check whether we need to bind textures between each GrMesh. If not we can bind them all now.
- bool setTextures = !(dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures);
- if (setTextures) {
- pipelineState->setAndBindTextures(fGpu, primProc, pipeline, primProcProxies, currentCB);
+ if (!programInfo.hasDynamicPrimProcTextures()) {
+ // TODO: just pass in GrProgramInfo
+ pipelineState->setAndBindTextures(fGpu, programInfo.primProc(), programInfo.pipeline(),
+ programInfo.primProcProxies(), currentCB);
}
- if (!pipeline.isScissorEnabled()) {
+ if (!programInfo.pipeline().isScissorEnabled()) {
GrVkPipeline::SetDynamicScissorRectState(fGpu, currentCB, fRenderTarget, fOrigin,
renderPassScissorRect);
- } else if (!dynamicStateArrays || !dynamicStateArrays->fScissorRects) {
- SkASSERT(fixedDynamicState);
+ } else if (!programInfo.hasDynamicScissors()) {
+ SkASSERT(programInfo.hasFixedScissor());
+
SkIRect combinedScissorRect;
- if (!combinedScissorRect.intersect(renderPassScissorRect,
- fixedDynamicState->fScissorRect)) {
+ if (!combinedScissorRect.intersect(renderPassScissorRect, programInfo.fixedScissor())) {
combinedScissorRect = SkIRect::MakeEmpty();
}
GrVkPipeline::SetDynamicScissorRectState(fGpu, currentCB, fRenderTarget, fOrigin,
combinedScissorRect);
}
GrVkPipeline::SetDynamicViewportState(fGpu, currentCB, fRenderTarget);
- GrVkPipeline::SetDynamicBlendConstantState(fGpu, currentCB, pipeline.outputSwizzle(),
- pipeline.getXferProcessor());
+ GrVkPipeline::SetDynamicBlendConstantState(fGpu, currentCB,
+ programInfo.pipeline().outputSwizzle(),
+ programInfo.pipeline().getXferProcessor());
return pipelineState;
}
@@ -500,41 +491,46 @@
#endif
-void GrVkOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- const GrPipeline::FixedDynamicState* fixedDynamicState,
- const GrPipeline::DynamicStateArrays* dynamicStateArrays,
- const GrMesh meshes[],
- int meshCount,
- const SkRect& bounds) {
+void GrVkOpsRenderPass::onDraw(const GrProgramInfo& programInfo,
+ const GrMesh meshes[], int meshCount,
+ const SkRect& bounds) {
if (!meshCount) {
return;
}
#ifdef SK_DEBUG
- if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
- for (int m = 0, i = 0; m < meshCount; ++m) {
- for (int s = 0; s < primProc.numTextureSamplers(); ++s, ++i) {
- auto texture = dynamicStateArrays->fPrimitiveProcessorTextures[i]->peekTexture();
+ if (programInfo.hasDynamicPrimProcTextures()) {
+ for (int m = 0; m < meshCount; ++m) {
+ auto dynamicPrimProcTextures = programInfo.dynamicPrimProcTextures(m);
+
+ for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
+ auto texture = dynamicPrimProcTextures[s]->peekTexture();
check_sampled_texture(texture, fRenderTarget, fGpu);
}
}
- } else {
- for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
- auto texture = fixedDynamicState->fPrimitiveProcessorTextures[i]->peekTexture();
+ } else if (programInfo.hasFixedPrimProcTextures()) {
+ auto fixedPrimProcTextures = programInfo.fixedPrimProcTextures();
+
+ for (int s = 0; s < programInfo.primProc().numTextureSamplers(); ++s) {
+ auto texture = fixedPrimProcTextures[s]->peekTexture();
check_sampled_texture(texture, fRenderTarget, fGpu);
}
}
- GrFragmentProcessor::Iter iter(pipeline);
+
+ GrFragmentProcessor::Iter iter(programInfo.pipeline());
while (const GrFragmentProcessor* fp = iter.next()) {
for (int i = 0; i < fp->numTextureSamplers(); ++i) {
const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
check_sampled_texture(sampler.peekTexture(), fRenderTarget, fGpu);
}
}
- if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
+ if (GrTexture* dstTexture = programInfo.pipeline().peekDstTexture()) {
check_sampled_texture(dstTexture, fRenderTarget, fGpu);
}
+
+ // Both the 'programInfo' and this renderPass have an origin. Since they come from the
+ // same place (i.e., the target renderTargetProxy) that had best agree.
+ SkASSERT(programInfo.origin() == fOrigin);
#endif
SkRect scissorRect = SkRect::Make(fBounds);
@@ -544,45 +540,41 @@
}
GrPrimitiveType primitiveType = meshes[0].primitiveType();
- GrVkPipelineState* pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
- dynamicStateArrays, primitiveType,
+ GrVkPipelineState* pipelineState = this->prepareDrawState(programInfo, primitiveType,
renderPassScissorRect);
if (!pipelineState) {
return;
}
- bool dynamicScissor =
- pipeline.isScissorEnabled() && dynamicStateArrays && dynamicStateArrays->fScissorRects;
-
- bool dynamicTextures = dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures;
+ bool hasDynamicScissors = programInfo.hasDynamicScissors();
+ bool hasDynamicTextures = programInfo.hasDynamicPrimProcTextures();
for (int i = 0; i < meshCount; ++i) {
const GrMesh& mesh = meshes[i];
if (mesh.primitiveType() != primitiveType) {
SkDEBUGCODE(pipelineState = nullptr);
primitiveType = mesh.primitiveType();
- pipelineState = this->prepareDrawState(primProc, pipeline, fixedDynamicState,
- dynamicStateArrays, primitiveType,
+ pipelineState = this->prepareDrawState(programInfo, primitiveType,
renderPassScissorRect);
if (!pipelineState) {
return;
}
}
- if (dynamicScissor) {
+ if (hasDynamicScissors) {
SkIRect combinedScissorRect;
if (!combinedScissorRect.intersect(renderPassScissorRect,
- dynamicStateArrays->fScissorRects[i])) {
+ programInfo.dynamicScissor(i))) {
combinedScissorRect = SkIRect::MakeEmpty();
}
GrVkPipeline::SetDynamicScissorRectState(fGpu, this->currentCommandBuffer(),
fRenderTarget, fOrigin,
combinedScissorRect);
}
- if (dynamicTextures) {
- GrTextureProxy* const* meshProxies = dynamicStateArrays->fPrimitiveProcessorTextures +
- primProc.numTextureSamplers() * i;
- pipelineState->setAndBindTextures(fGpu, primProc, pipeline, meshProxies,
+ if (hasDynamicTextures) {
+ auto meshProxies = programInfo.dynamicPrimProcTextures(i);
+ pipelineState->setAndBindTextures(fGpu, programInfo.primProc(), programInfo.pipeline(),
+ meshProxies,
this->currentCommandBuffer());
}
SkASSERT(pipelineState);
diff --git a/src/gpu/vk/GrVkOpsRenderPass.h b/src/gpu/vk/GrVkOpsRenderPass.h
index 9211288..65d6b5b 100644
--- a/src/gpu/vk/GrVkOpsRenderPass.h
+++ b/src/gpu/vk/GrVkOpsRenderPass.h
@@ -70,19 +70,10 @@
const GrGpuBuffer* vertexBuffer,
const GrGpuBuffer* instanceBuffer);
- GrVkPipelineState* prepareDrawState(const GrPrimitiveProcessor&,
- const GrPipeline&,
- const GrPipeline::FixedDynamicState*,
- const GrPipeline::DynamicStateArrays*,
- GrPrimitiveType,
+ GrVkPipelineState* prepareDrawState(const GrProgramInfo&, GrPrimitiveType,
const SkIRect& renderPassScissorRect);
- void onDraw(const GrPrimitiveProcessor&,
- const GrPipeline&,
- const GrPipeline::FixedDynamicState*,
- const GrPipeline::DynamicStateArrays*,
- const GrMesh[],
- int meshCount,
+ void onDraw(const GrProgramInfo&, const GrMesh[], int meshCount,
const SkRect& bounds) override;
// GrMesh::SendToGpuImpl methods. These issue the actual Vulkan draw commands.
diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp
index 96e2ee5..6868ff5 100644
--- a/src/gpu/vk/GrVkPipeline.cpp
+++ b/src/gpu/vk/GrVkPipeline.cpp
@@ -278,17 +278,15 @@
SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount);
}
-static void setup_multisample_state(int numColorSamples,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
+static void setup_multisample_state(const GrProgramInfo& programInfo,
const GrCaps* caps,
VkPipelineMultisampleStateCreateInfo* multisampleInfo) {
memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo));
multisampleInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampleInfo->pNext = nullptr;
multisampleInfo->flags = 0;
- SkAssertResult(GrSampleCountToVkSampleCount(numColorSamples,
- &multisampleInfo->rasterizationSamples));
+ SkAssertResult(GrSampleCountToVkSampleCount(programInfo.numSamples(),
+ &multisampleInfo->rasterizationSamples));
multisampleInfo->sampleShadingEnable = VK_FALSE;
multisampleInfo->minSampleShading = 0.0f;
multisampleInfo->pSampleMask = nullptr;
@@ -498,38 +496,40 @@
}
GrVkPipeline* GrVkPipeline::Create(
- GrVkGpu* gpu, int numColorSamples, const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline, const GrStencilSettings& stencil, GrSurfaceOrigin origin,
+ GrVkGpu* gpu,
+ const GrProgramInfo& programInfo,
+ const GrStencilSettings& stencil,
VkPipelineShaderStageCreateInfo* shaderStageInfo, int shaderStageCount,
GrPrimitiveType primitiveType, VkRenderPass compatibleRenderPass, VkPipelineLayout layout,
VkPipelineCache cache) {
VkPipelineVertexInputStateCreateInfo vertexInputInfo;
SkSTArray<2, VkVertexInputBindingDescription, true> bindingDescs;
SkSTArray<16, VkVertexInputAttributeDescription> attributeDesc;
- int totalAttributeCnt = primProc.numVertexAttributes() + primProc.numInstanceAttributes();
+ int totalAttributeCnt = programInfo.primProc().numVertexAttributes() +
+ programInfo.primProc().numInstanceAttributes();
SkASSERT(totalAttributeCnt <= gpu->vkCaps().maxVertexAttributes());
VkVertexInputAttributeDescription* pAttribs = attributeDesc.push_back_n(totalAttributeCnt);
- setup_vertex_input_state(primProc, &vertexInputInfo, &bindingDescs, pAttribs);
+ setup_vertex_input_state(programInfo.primProc(), &vertexInputInfo, &bindingDescs, pAttribs);
VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo;
setup_input_assembly_state(primitiveType, &inputAssemblyInfo);
VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
- setup_depth_stencil_state(stencil, origin, &depthStencilInfo);
+ setup_depth_stencil_state(stencil, programInfo.origin(), &depthStencilInfo);
VkPipelineViewportStateCreateInfo viewportInfo;
setup_viewport_scissor_state(&viewportInfo);
VkPipelineMultisampleStateCreateInfo multisampleInfo;
- setup_multisample_state(numColorSamples, primProc, pipeline, gpu->caps(), &multisampleInfo);
+ setup_multisample_state(programInfo, gpu->caps(), &multisampleInfo);
// We will only have one color attachment per pipeline.
VkPipelineColorBlendAttachmentState attachmentStates[1];
VkPipelineColorBlendStateCreateInfo colorBlendInfo;
- setup_color_blend_state(pipeline, &colorBlendInfo, attachmentStates);
+ setup_color_blend_state(programInfo.pipeline(), &colorBlendInfo, attachmentStates);
VkPipelineRasterizationStateCreateInfo rasterInfo;
- setup_raster_state(pipeline, gpu->caps(), &rasterInfo);
+ setup_raster_state(programInfo.pipeline(), gpu->caps(), &rasterInfo);
VkDynamicState dynamicStates[3];
VkPipelineDynamicStateCreateInfo dynamicInfo;
diff --git a/src/gpu/vk/GrVkPipeline.h b/src/gpu/vk/GrVkPipeline.h
index 2911f5a4..ce33a49 100644
--- a/src/gpu/vk/GrVkPipeline.h
+++ b/src/gpu/vk/GrVkPipeline.h
@@ -25,11 +25,8 @@
class GrVkPipeline : public GrVkResource {
public:
static GrVkPipeline* Create(GrVkGpu*,
- int numColorSamples,
- const GrPrimitiveProcessor&,
- const GrPipeline& pipeline,
+ const GrProgramInfo&,
const GrStencilSettings&,
- GrSurfaceOrigin,
VkPipelineShaderStageCreateInfo* shaderStageInfo,
int shaderStageCount,
GrPrimitiveType primitiveType,
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
index cdfaf47..3398f3f 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
@@ -22,19 +22,14 @@
GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
GrVkGpu* gpu,
GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline& pipeline,
+ const GrProgramInfo& programInfo,
const GrStencilSettings& stencil,
GrPrimitiveType primitiveType,
Desc* desc,
VkRenderPass compatibleRenderPass) {
// create a builder. This will be handed off to effects so they can use it to add
// uniforms, varyings, textures, etc
- GrVkPipelineStateBuilder builder(gpu, renderTarget, numSamples, origin, pipeline, primProc,
- primProcProxies, desc);
+ GrVkPipelineStateBuilder builder(gpu, renderTarget, programInfo, desc);
if (!builder.emitAndInstallProcs()) {
return nullptr;
@@ -45,13 +40,9 @@
GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPipeline& pipeline,
- const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const primProcProxies[],
+ const GrProgramInfo& programInfo,
GrProgramDesc* desc)
- : INHERITED(renderTarget, numSamples, origin, primProc, primProcProxies, pipeline, desc)
+ : INHERITED(renderTarget, programInfo, desc)
, fGpu(gpu)
, fVaryingHandler(this)
, fUniformHandler(this) {}
@@ -142,7 +133,7 @@
void GrVkPipelineStateBuilder::storeShadersInCache(const SkSL::String shaders[],
const SkSL::Program::Inputs inputs[],
bool isSkSL) {
- Desc* desc = static_cast<Desc*>(this->desc());
+ const Desc* desc = static_cast<const Desc*>(this->desc());
sk_sp<SkData> key = SkData::MakeWithoutCopy(desc->asKey(), desc->shaderKeyLength());
sk_sp<SkData> data = GrPersistentCacheUtils::PackCachedShaders(isSkSL ? kSKSL_Tag : kSPIRV_Tag,
shaders,
@@ -294,8 +285,7 @@
this->storeShadersInCache(shaders, inputs, isSkSL);
}
}
- GrVkPipeline* pipeline = resourceProvider.createPipeline(
- fNumSamples, fPrimProc, fPipeline, stencil, this->origin(),
+ GrVkPipeline* pipeline = resourceProvider.createPipeline(fProgramInfo, stencil,
shaderStageInfo, numShaderStages, primitiveType, compatibleRenderPass, pipelineLayout);
for (int i = 0; i < kGrShaderTypeCount; ++i) {
// This if check should not be needed since calling destroy on a VK_NULL_HANDLE is allowed.
@@ -329,13 +319,12 @@
bool GrVkPipelineStateBuilder::Desc::Build(Desc* desc,
GrRenderTarget* renderTarget,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
+ const GrProgramInfo& programInfo,
const GrStencilSettings& stencil,
GrPrimitiveType primitiveType,
GrVkGpu* gpu) {
- if (!INHERITED::Build(desc, renderTarget, primProc,
- primitiveType == GrPrimitiveType::kPoints, pipeline, gpu)) {
+ if (!GrProgramDesc::Build(desc, renderTarget, programInfo,
+ primitiveType == GrPrimitiveType::kPoints, gpu)) {
return false;
}
@@ -351,7 +340,7 @@
stencil.genKey(&b);
- b.add32(pipeline.getBlendInfoKey());
+ b.add32(programInfo.pipeline().getBlendInfoKey());
b.add32((uint32_t)primitiveType);
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.h b/src/gpu/vk/GrVkPipelineStateBuilder.h
index 769202d..0ba7fc5 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.h
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.h
@@ -40,8 +40,7 @@
public:
static bool Build(Desc*,
GrRenderTarget*,
- const GrPrimitiveProcessor&,
- const GrPipeline&,
+ const GrProgramInfo&,
const GrStencilSettings&,
GrPrimitiveType primitiveType,
GrVkGpu* gpu);
@@ -64,11 +63,7 @@
*/
static GrVkPipelineState* CreatePipelineState(GrVkGpu*,
GrRenderTarget*,
- int numSamples,
- GrSurfaceOrigin,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline&,
+ const GrProgramInfo&,
const GrStencilSettings&,
GrPrimitiveType,
Desc*,
@@ -82,13 +77,7 @@
void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) override;
private:
- GrVkPipelineStateBuilder(GrVkGpu*, GrRenderTarget*,
- int numSamples,
- GrSurfaceOrigin,
- const GrPipeline&,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
- GrProgramDesc*);
+ GrVkPipelineStateBuilder(GrVkGpu*, GrRenderTarget*, const GrProgramInfo&, GrProgramDesc*);
GrVkPipelineState* finalize(const GrStencilSettings&,
GrPrimitiveType primitiveType,
diff --git a/src/gpu/vk/GrVkPipelineStateCache.cpp b/src/gpu/vk/GrVkPipelineStateCache.cpp
index 5449a45..fb4cfa8a 100644
--- a/src/gpu/vk/GrVkPipelineStateCache.cpp
+++ b/src/gpu/vk/GrVkPipelineStateCache.cpp
@@ -78,34 +78,33 @@
GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::refPipelineState(
GrRenderTarget* renderTarget,
- int numSamples,
- GrSurfaceOrigin origin,
- const GrPrimitiveProcessor& primProc,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline& pipeline,
+ const GrProgramInfo& programInfo,
GrPrimitiveType primitiveType,
VkRenderPass compatibleRenderPass) {
#ifdef GR_PIPELINE_STATE_CACHE_STATS
++fTotalRequests;
#endif
GrStencilSettings stencil;
- if (pipeline.isStencilEnabled()) {
+ if (programInfo.pipeline().isStencilEnabled()) {
// TODO: attach stencil and create settings during render target flush.
SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
- stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(),
+ stencil.reset(*programInfo.pipeline().getUserStencil(),
+ programInfo.pipeline().hasStencilClip(),
renderTarget->renderTargetPriv().numStencilBits());
}
+ // TODO: can this be unified between Vulkan and GL?
// Get GrVkProgramDesc
GrVkPipelineStateBuilder::Desc desc;
- if (!GrVkPipelineStateBuilder::Desc::Build(&desc, renderTarget, primProc, pipeline, stencil,
+ if (!GrVkPipelineStateBuilder::Desc::Build(&desc, renderTarget, programInfo, stencil,
primitiveType, fGpu)) {
GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
return nullptr;
}
// If we knew the shader won't depend on origin, we could skip this (and use the same program
// for both origins). Instrumenting all fragment processors would be difficult and error prone.
- desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
+ desc.setSurfaceOriginKey(
+ GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(programInfo.origin()));
std::unique_ptr<Entry>* entry = fMap.find(desc);
if (!entry) {
@@ -113,9 +112,9 @@
++fCacheMisses;
#endif
GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
- fGpu, renderTarget, numSamples, origin, primProc, primProcProxies, pipeline,
+ fGpu, renderTarget, programInfo,
stencil, primitiveType, &desc, compatibleRenderPass));
- if (nullptr == pipelineState) {
+ if (!pipelineState) {
return nullptr;
}
entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(fGpu, pipelineState)));
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index 9a02cf3..5f21dbd 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -91,19 +91,16 @@
fUniformDSHandle = GrVkDescriptorSetManager::Handle(0);
}
-GrVkPipeline* GrVkResourceProvider::createPipeline(int numColorSamples,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
+GrVkPipeline* GrVkResourceProvider::createPipeline(const GrProgramInfo& programInfo,
const GrStencilSettings& stencil,
- GrSurfaceOrigin origin,
VkPipelineShaderStageCreateInfo* shaderStageInfo,
int shaderStageCount,
GrPrimitiveType primitiveType,
VkRenderPass compatibleRenderPass,
VkPipelineLayout layout) {
- return GrVkPipeline::Create(
- fGpu, numColorSamples, primProc, pipeline, stencil, origin, shaderStageInfo,
- shaderStageCount, primitiveType, compatibleRenderPass, layout, this->pipelineCache());
+ return GrVkPipeline::Create(fGpu, programInfo, stencil, shaderStageInfo,
+ shaderStageCount, primitiveType, compatibleRenderPass,
+ layout, this->pipelineCache());
}
// To create framebuffers, we first need to create a simple RenderPass that is
@@ -228,13 +225,12 @@
}
GrVkPipelineState* GrVkResourceProvider::findOrCreateCompatiblePipelineState(
- GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin origin,
- const GrPipeline& pipeline, const GrPrimitiveProcessor& proc,
- const GrTextureProxy* const primProcProxies[], GrPrimitiveType primitiveType,
+ GrRenderTarget* renderTarget,
+ const GrProgramInfo& programInfo,
+ GrPrimitiveType primitiveType,
VkRenderPass compatibleRenderPass) {
- return fPipelineStateCache->refPipelineState(renderTarget, numSamples, origin, proc,
- primProcProxies, pipeline, primitiveType,
- compatibleRenderPass);
+ return fPipelineStateCache->refPipelineState(renderTarget, programInfo,
+ primitiveType, compatibleRenderPass);
}
void GrVkResourceProvider::getSamplerDescriptorSetHandle(VkDescriptorType type,
diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h
index 696245c..44755d7 100644
--- a/src/gpu/vk/GrVkResourceProvider.h
+++ b/src/gpu/vk/GrVkResourceProvider.h
@@ -43,11 +43,8 @@
// Set up any initial vk objects
void init();
- GrVkPipeline* createPipeline(int numColorSamples,
- const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
+ GrVkPipeline* createPipeline(const GrProgramInfo&,
const GrStencilSettings& stencil,
- GrSurfaceOrigin,
VkPipelineShaderStageCreateInfo* shaderStageInfo,
int shaderStageCount,
GrPrimitiveType primitiveType,
@@ -114,10 +111,8 @@
const GrVkYcbcrConversionInfo& ycbcrInfo);
GrVkPipelineState* findOrCreateCompatiblePipelineState(
- GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPipeline&,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
+ GrRenderTarget*,
+ const GrProgramInfo&,
GrPrimitiveType,
VkRenderPass compatibleRenderPass);
@@ -197,10 +192,8 @@
void abandon();
void release();
- GrVkPipelineState* refPipelineState(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
- const GrPrimitiveProcessor&,
- const GrTextureProxy* const primProcProxies[],
- const GrPipeline&,
+ GrVkPipelineState* refPipelineState(GrRenderTarget*,
+ const GrProgramInfo&,
GrPrimitiveType,
VkRenderPass compatibleRenderPass);
diff --git a/tests/DrawOpAtlasTest.cpp b/tests/DrawOpAtlasTest.cpp
index cbd0917..ec6068c 100644
--- a/tests/DrawOpAtlasTest.cpp
+++ b/tests/DrawOpAtlasTest.cpp
@@ -211,11 +211,10 @@
TestingUploadTarget uploadTarget;
GrOpFlushState flushState(gpu, resourceProvider, uploadTarget.writeableTokenTracker());
- GrOpFlushState::OpArgs opArgs(
- op.get(),
- rtc->asRenderTargetProxy(),
- nullptr,
- GrXferProcessor::DstProxy(nullptr, SkIPoint::Make(0, 0)));
+ GrOpFlushState::OpArgs opArgs(op.get(),
+ rtc->asRenderTargetProxy(),
+ nullptr,
+ GrXferProcessor::DstProxy(nullptr, SkIPoint::Make(0, 0)));
// Cripple the atlas manager so it can't allocate any pages. This will force a failure
// in the preparation of the text op
diff --git a/tests/GrMeshTest.cpp b/tests/GrMeshTest.cpp
index 3b39cd7..16ceaeb 100644
--- a/tests/GrMeshTest.cpp
+++ b/tests/GrMeshTest.cpp
@@ -20,6 +20,7 @@
#include "src/gpu/GrMemoryPool.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrOpsRenderPass.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrRenderTargetContextPriv.h"
#include "src/gpu/GrResourceProvider.h"
@@ -410,7 +411,14 @@
void DrawMeshHelper::drawMesh(const GrMesh& mesh) {
GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kSrc, GrSwizzle::RGBA());
GrMeshTestProcessor mtp(mesh.isInstanced(), mesh.hasVertexData());
- fState->opsRenderPass()->draw(mtp, pipeline, nullptr, nullptr, &mesh, 1,
+
+ GrProgramInfo programInfo(fState->drawOpArgs().numSamples(),
+ fState->drawOpArgs().origin(),
+ pipeline,
+ mtp,
+ nullptr, nullptr);
+
+ fState->opsRenderPass()->draw(programInfo, &mesh, 1,
SkRect::MakeIWH(kImageWidth, kImageHeight));
}
diff --git a/tests/GrPipelineDynamicStateTest.cpp b/tests/GrPipelineDynamicStateTest.cpp
index 8a4064c..46d834c 100644
--- a/tests/GrPipelineDynamicStateTest.cpp
+++ b/tests/GrPipelineDynamicStateTest.cpp
@@ -18,6 +18,7 @@
#include "src/gpu/GrMemoryPool.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrOpsRenderPass.h"
+#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrRenderTargetContextPriv.h"
@@ -140,8 +141,9 @@
return GrProcessorSet::EmptySetAnalysis();
}
void onPrepare(GrOpFlushState*) override {}
- void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {
- GrPipeline pipeline(fScissorTest, SkBlendMode::kSrc, state->drawOpArgs().outputSwizzle());
+ void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
+ GrPipeline pipeline(fScissorTest, SkBlendMode::kSrc,
+ flushState->drawOpArgs().outputSwizzle());
SkSTArray<kNumMeshes, GrMesh> meshes;
for (int i = 0; i < kNumMeshes; ++i) {
GrMesh& mesh = meshes.emplace_back(GrPrimitiveType::kTriangleStrip);
@@ -150,9 +152,18 @@
}
GrPipeline::DynamicStateArrays dynamicState;
dynamicState.fScissorRects = kDynamicScissors;
- state->opsRenderPass()->draw(GrPipelineDynamicStateTestProcessor(), pipeline, nullptr,
- &dynamicState, meshes.begin(), 4,
- SkRect::MakeIWH(kScreenSize, kScreenSize));
+
+ GrPipelineDynamicStateTestProcessor primProc;
+
+ GrProgramInfo programInfo(flushState->drawOpArgs().numSamples(),
+ flushState->drawOpArgs().origin(),
+ pipeline,
+ primProc,
+ nullptr,
+ &dynamicState);
+
+ flushState->opsRenderPass()->draw(programInfo, meshes.begin(), 4,
+ SkRect::MakeIWH(kScreenSize, kScreenSize));
}
GrScissorTest fScissorTest;