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>
This commit is contained in:
Robert Phillips 2019-10-08 12:32:56 -04:00 committed by Skia Commit-Bot
parent e7bc084498
commit 901aff018b
56 changed files with 669 additions and 653 deletions

View File

@ -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 @@ private:
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;

View File

@ -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 @@ private:
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 @@ private:
}
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;

View File

@ -235,11 +235,17 @@ private:
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;

View File

@ -120,6 +120,8 @@ skia_gpu_sources = [
"$_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 @@ skia_gpu_sources = [
"$_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 @@ skia_gpu_sources = [
"$_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",

View File

@ -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 @@ void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(
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;
}

View File

@ -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 @@ void GrOpsRenderPass::clearStencilClip(const GrFixedClip& clip, bool insideStenc
}
#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 @@ static void assert_msaa_and_mips_are_resolved(
}
};
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 @@ bool GrOpsRenderPass::draw(const GrPrimitiveProcessor& primProc, const GrPipelin
}
}
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)

View File

@ -18,6 +18,7 @@ class GrGpu;
class GrMesh;
class GrPipeline;
class GrPrimitiveProcessor;
class GrProgramInfo;
class GrRenderTarget;
class GrSemaphore;
struct SkIRect;
@ -55,13 +56,7 @@ public:
// 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 @@ private:
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.

View File

@ -412,11 +412,10 @@ void GrOpsTask::onPrepare(GrOpFlushState* flushState) {
#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);

View File

@ -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 @@ void GrPathRendering::stencilPath(const StencilPathArgs& args, const GrPath* pat
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);
}

View File

@ -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 @@ public:
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 @@ protected:
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;

View File

@ -42,10 +42,8 @@ void GrGLPathRendering::setProjectionMatrix(const SkMatrix&, const SkISize&, GrS
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*) {}

View File

@ -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 @@ static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc,
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 @@ bool GrProgramDesc::Build(
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 @@ bool GrProgramDesc::Build(
processorFeatures |= xp.requestedFeatures();
if (processorFeatures & GrProcessor::CustomFeatures::kSampleLocations) {
SkASSERT(pipeline.isHWAntialiasState());
SkASSERT(programInfo.pipeline().isHWAntialiasState());
b.add32(renderTarget->renderTargetPriv().getSamplePatternKey());
}
@ -249,17 +250,18 @@ bool GrProgramDesc::Build(
// 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;
}

View File

@ -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 @@ public:
* 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)) {

117
src/gpu/GrProgramInfo.h Normal file
View File

@ -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

View File

@ -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 @@ void GrCCCoverageProcessor::draw(
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);
}

View File

@ -141,8 +141,14 @@ void GrCCPathProcessor::drawPaths(GrOpFlushState* flushState, const GrPipeline&
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) {

View File

@ -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 @@ void GrCCStroker::flushBufferedMeshesAsStrokes(const GrPrimitiveProcessor& proce
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.

View File

@ -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 @@ void GrStencilAtlasOp::onExecute(GrOpFlushState* flushState, const SkRect& chain
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));
}

View File

@ -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 @@ void GrGLGpu::disableWindowRectangles() {
}
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 @@ bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget,
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 @@ void GrGLGpu::flushViewport(int width, int height) {
#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 @@ void GrGLGpu::draw(GrRenderTarget* renderTarget, int numSamples, GrSurfaceOrigin
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()) &&

View File

@ -75,13 +75,7 @@ public:
// 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 @@ private:
// 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 @@ private:
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:

View File

@ -47,30 +47,29 @@ void GrGLGpu::ProgramCache::reset() {
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 @@ GrGLProgram* GrGLGpu::ProgramCache::refProgram(GrGLGpu* gpu,
(*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;
}

View File

@ -52,15 +52,9 @@ public:
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 {

View File

@ -112,14 +112,10 @@ void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath*
}
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);

View File

@ -65,11 +65,7 @@ public:
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:

View File

@ -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::abandon() {
///////////////////////////////////////////////////////////////////////////////
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 @@ void GrGLProgram::updateUniformsAndTextureBindings(const GrRenderTarget* renderT
// 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);

View File

@ -18,6 +18,7 @@ class GrGLSLPrimitiveProcessor;
class GrGLSLXferProcessor;
class GrPipeline;
class GrPrimitiveProcessor;
class GrProgramInfo;
class GrRenderTarget;
class GrTextureProxy;
@ -118,9 +119,7 @@ public:
*
* 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[]);

View File

@ -18,10 +18,7 @@ GrGLSLVaryingHandler::VaryingHandle GrGLVaryingHandler::addPathProcessingVarying
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();

View File

@ -46,23 +46,18 @@ static void cleanup_program(GrGLGpu* gpu, GrGLuint programID,
}
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 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(GrRenderTarget* renderTarget,
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 @@ void GrGLProgramBuilder::storeShaderInCache(const SkSL::Program::Inputs& inputs,
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;

View File

@ -48,11 +48,7 @@ public:
* @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 @@ public:
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,

View File

@ -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 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(SkString* outputColor,
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 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn,
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 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn,
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 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn,
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

View File

@ -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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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);

View File

@ -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 GrGLSLVertexGeoBuilder::emitNormalizedSkPosition(SkString* out, const char*
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());

View File

@ -35,9 +35,8 @@ public:
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;
}

View File

@ -44,16 +44,9 @@ public:
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;

View File

@ -53,50 +53,34 @@ void GrMtlOpsRenderPass::submit() {
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 @@ void GrMtlOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
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 @@ void GrMtlOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
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);

View File

@ -46,9 +46,7 @@ public:
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&);

View File

@ -58,23 +58,23 @@ GrMtlPipelineState::GrMtlPipelineState(
}
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 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
{
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 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
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());
}
}

View File

@ -17,6 +17,7 @@
#import <Metal/Metal.h>
class GrProgramInfo;
class GrMtlGpu;
class GrMtlPipelineState;
@ -35,12 +36,8 @@ public:
*/
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 @@ public:
* @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;

View File

@ -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 @@ uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment) {
}
GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTarget,
const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
const GrProgramInfo& programInfo,
Desc* desc) {
auto pipelineDescriptor = [MTLRenderPipelineDescriptor new];
@ -397,9 +388,9 @@ GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTa
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 @@ GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTa
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 GrMtlPipelineStateBuilder::Desc::Build(Desc* desc,
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);

View File

@ -24,12 +24,9 @@ class GrMtlResourceProvider {
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 @@ private:
~PipelineStateCache();
void release();
GrMtlPipelineState* refPipelineState(GrRenderTarget*, int numSamples, GrSurfaceOrigin,
const GrPrimitiveProcessor&,
const GrTextureProxy* const primProcProxies[],
const GrPipeline&,
GrMtlPipelineState* refPipelineState(GrRenderTarget*, const GrProgramInfo&,
GrPrimitiveType);
private:

View File

@ -38,11 +38,10 @@ GrMtlResourceProvider::GrMtlResourceProvider(GrMtlGpu* gpu)
}
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 @@ void GrMtlResourceProvider::PipelineStateCache::release() {
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 @@ GrMtlPipelineState* GrMtlResourceProvider::PipelineStateCache::refPipelineState(
++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)));

View File

@ -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 @@ void GrDrawPathOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
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());
}
//////////////////////////////////////////////////////////////////////////////

View File

@ -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 @@ void GrFillRRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBou
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;
}

View File

@ -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"

View File

@ -374,8 +374,7 @@ void GrVkOpsRenderPass::addAdditionalRenderPass(bool mustUseSecondaryCommandBuff
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 @@ void GrVkOpsRenderPass::bindGeometry(const GrGpuBuffer* indexBuffer,
}
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 @@ GrVkPipelineState* GrVkOpsRenderPass::prepareDrawState(
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 @@ GrVkPipelineState* GrVkOpsRenderPass::prepareDrawState(
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 @@ void check_sampled_texture(GrTexture* tex, GrRenderTarget* rt, GrVkGpu* gpu) {
#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 @@ void GrVkOpsRenderPass::onDraw(const GrPrimitiveProcessor& primProc,
}
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);

View File

@ -70,19 +70,10 @@ private:
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.

View File

@ -278,17 +278,15 @@ static void setup_viewport_scissor_state(VkPipelineViewportStateCreateInfo* view
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 @@ static void setup_dynamic_state(VkPipelineDynamicStateCreateInfo* dynamicInfo,
}
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;

View File

@ -25,11 +25,8 @@ struct SkIRect;
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,

View File

@ -22,19 +22,14 @@ typedef size_t shader_size;
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 @@ GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
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 @@ int GrVkPipelineStateBuilder::loadShadersFromCache(SkReader32* cached,
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 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s
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 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s
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 @@ bool GrVkPipelineStateBuilder::Desc::Build(Desc* desc,
stencil.genKey(&b);
b.add32(pipeline.getBlendInfoKey());
b.add32(programInfo.pipeline().getBlendInfoKey());
b.add32((uint32_t)primitiveType);

View File

@ -40,8 +40,7 @@ public:
public:
static bool Build(Desc*,
GrRenderTarget*,
const GrPrimitiveProcessor&,
const GrPipeline&,
const GrProgramInfo&,
const GrStencilSettings&,
GrPrimitiveType primitiveType,
GrVkGpu* gpu);
@ -64,11 +63,7 @@ public:
*/
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 @@ public:
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,

View File

@ -78,34 +78,33 @@ void GrVkResourceProvider::PipelineStateCache::release() {
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 @@ GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::refPipelineState(
++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)));

View File

@ -91,19 +91,16 @@ void GrVkResourceProvider::init() {
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 @@ GrVkSamplerYcbcrConversion* GrVkResourceProvider::findOrCreateCompatibleSamplerY
}
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,

View File

@ -43,11 +43,8 @@ public:
// 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 @@ public:
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 @@ private:
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);

View File

@ -211,11 +211,10 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrAtlasTextOpPreparation, reporter, ctxInfo)
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

View File

@ -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 @@ sk_sp<const GrBuffer> DrawMeshHelper::getIndexBuffer() {
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));
}

View File

@ -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 @@ private:
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 @@ private:
}
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;