Add computation of requestedFeatures to GrProgramInfo and use it

This is a deferred TODO/code review request. In general, this improves the encapsulation of program information w/in GrProgramInfo. Additionally, it is desirable to stop using the Desc/Key to access this information.

Bug: skia:9455
Change-Id: I854ff3225a49657d3a523e88e4bfa549128ee486
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/247336
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2019-10-09 15:44:54 -04:00 committed by Skia Commit-Bot
parent 957bf97414
commit 7de1333df7
5 changed files with 22 additions and 36 deletions

View File

@ -212,16 +212,12 @@ bool GrProgramDesc::Build(GrProgramDesc* desc, const GrRenderTarget* renderTarge
return false;
}
// 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 = programInfo.pipeline().getXferProcessor();
@ -236,9 +232,8 @@ bool GrProgramDesc::Build(GrProgramDesc* desc, const GrRenderTarget* renderTarge
desc->key().reset();
return false;
}
processorFeatures |= xp.requestedFeatures();
if (processorFeatures & GrProcessor::CustomFeatures::kSampleLocations) {
if (programInfo.requestedFeatures() & GrProcessor::CustomFeatures::kSampleLocations) {
SkASSERT(programInfo.pipeline().isHWAntialiasState());
b.add32(renderTarget->renderTargetPriv().getSamplePatternKey());
}
@ -262,9 +257,10 @@ bool GrProgramDesc::Build(GrProgramDesc* desc, const GrRenderTarget* renderTarge
// 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.
header->fSurfaceOriginKey =
GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(programInfo.origin());
header->fProcessorFeatures = (uint8_t)processorFeatures;
SkASSERT(header->processorFeatures() == processorFeatures); // Ensure enough bits.
GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(programInfo.origin());
header->fProcessorFeatures = (uint8_t)programInfo.requestedFeatures();
// Ensure enough bits.
SkASSERT(header->fProcessorFeatures == (int) programInfo.requestedFeatures());
header->fSnapVerticesToPixelCenters = programInfo.pipeline().snapVerticesToPixelCenters();
header->fHasPointSize = hasPointSize ? 1 : 0;
return true;

View File

@ -86,12 +86,6 @@ public:
}
struct KeyHeader {
SkDEBUGCODE(bool hasSurfaceOriginKey() const { return SkToBool(fSurfaceOriginKey); })
GrProcessor::CustomFeatures processorFeatures() const {
return (GrProcessor::CustomFeatures)fProcessorFeatures;
}
// Set to uniquely idenitify any swizzling of the shader's output color(s).
uint16_t fOutputSwizzle;
uint8_t fColorFragmentProcessorCnt; // Can be packed into 4 bits if required.

View File

@ -29,9 +29,16 @@ public:
, fPrimProc(primProc)
, fFixedDynamicState(fixedDynamicState)
, fDynamicStateArrays(dynamicStateArrays) {
fRequestedFeatures = fPrimProc.requestedFeatures();
for (int i = 0; i < fPipeline.numFragmentProcessors(); ++i) {
fRequestedFeatures |= fPipeline.getFragmentProcessor(i).requestedFeatures();
}
fRequestedFeatures |= fPipeline.getXferProcessor().requestedFeatures();
SkDEBUGCODE(this->validate();)
}
GrProcessor::CustomFeatures requestedFeatures() const { return fRequestedFeatures; }
int numSamples() const { return fNumSamples; }
GrSurfaceOrigin origin() const { return fOrigin; }
const GrPipeline& pipeline() const { return fPipeline; }
@ -101,16 +108,6 @@ public:
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:
@ -120,6 +117,7 @@ private:
const GrPrimitiveProcessor& fPrimProc;
const GrPipeline::FixedDynamicState* fFixedDynamicState;
const GrPipeline::DynamicStateArrays* fDynamicStateArrays;
GrProcessor::CustomFeatures fRequestedFeatures;
};
#endif

View File

@ -85,7 +85,7 @@ SkString GrGLSLFragmentShaderBuilder::ensureCoords2D(const GrShaderVar& coords)
}
const char* GrGLSLFragmentShaderBuilder::sampleOffsets() {
SkASSERT(CustomFeatures::kSampleLocations & fProgramBuilder->header().processorFeatures());
SkASSERT(CustomFeatures::kSampleLocations & fProgramBuilder->processorFeatures());
SkDEBUGCODE(fUsedProcessorFeaturesThisStage_DebugOnly |= CustomFeatures::kSampleLocations);
SkDEBUGCODE(fUsedProcessorFeaturesAllStages_DebugOnly |= CustomFeatures::kSampleLocations);
return "_sampleOffsets";
@ -118,7 +118,7 @@ void GrGLSLFragmentShaderBuilder::maskOffMultisampleCoverage(
void GrGLSLFragmentShaderBuilder::applyFnToMultisampleMask(
const char* fn, const char* grad, ScopeFlags scopeFlags) {
SkASSERT(CustomFeatures::kSampleLocations & fProgramBuilder->header().processorFeatures());
SkASSERT(CustomFeatures::kSampleLocations & fProgramBuilder->processorFeatures());
SkDEBUGCODE(fUsedProcessorFeaturesThisStage_DebugOnly |= CustomFeatures::kSampleLocations);
SkDEBUGCODE(fUsedProcessorFeaturesAllStages_DebugOnly |= CustomFeatures::kSampleLocations);
@ -283,18 +283,13 @@ const char* GrGLSLFragmentShaderBuilder::getSecondaryColorOutputName() const {
}
GrSurfaceOrigin GrGLSLFragmentShaderBuilder::getSurfaceOrigin() const {
SkASSERT(fProgramBuilder->header().hasSurfaceOriginKey());
return static_cast<GrSurfaceOrigin>(fProgramBuilder->header().fSurfaceOriginKey-1);
GR_STATIC_ASSERT(0 == kTopLeft_GrSurfaceOrigin);
GR_STATIC_ASSERT(1 == kBottomLeft_GrSurfaceOrigin);
return fProgramBuilder->origin();
}
void GrGLSLFragmentShaderBuilder::onFinalize() {
SkASSERT(fProgramBuilder->header().processorFeatures()
== fUsedProcessorFeaturesAllStages_DebugOnly);
SkASSERT(fProgramBuilder->processorFeatures() == fUsedProcessorFeaturesAllStages_DebugOnly);
if (CustomFeatures::kSampleLocations & fProgramBuilder->header().processorFeatures()) {
if (CustomFeatures::kSampleLocations & fProgramBuilder->processorFeatures()) {
const SkTArray<SkPoint>& sampleLocations = fProgramBuilder->getSampleLocations();
this->definitions().append("const float2 _sampleOffsets[] = float2[](");
for (int i = 0; i < sampleLocations.count(); ++i) {

View File

@ -42,10 +42,13 @@ public:
const GrPipeline& pipeline() const { return fProgramInfo.pipeline(); }
const GrPrimitiveProcessor& primitiveProcessor() const { return fProgramInfo.primProc(); }
const GrTextureProxy* const* primProcProxies() const { return fProgramInfo.primProcProxies(); }
GrProcessor::CustomFeatures processorFeatures() const {
return fProgramInfo.requestedFeatures();
}
// TODO: stop passing in the renderTarget for just the sampleLocations
int effectiveSampleCnt() const {
SkASSERT(GrProcessor::CustomFeatures::kSampleLocations & header().processorFeatures());
SkASSERT(GrProcessor::CustomFeatures::kSampleLocations & fProgramInfo.requestedFeatures());
return fRenderTarget->renderTargetPriv().getSampleLocations().count();
}
const SkTArray<SkPoint>& getSampleLocations() const {