Calculate stage stats in GrOptDrawState
BUG=skia: R=bsalomon@google.com Author: egdaniel@google.com Review URL: https://codereview.chromium.org/545693004
This commit is contained in:
parent
f96ba02513
commit
a7dc0a83f0
@ -44,6 +44,7 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
||||
this->copyEffectiveColorStages(drawState);
|
||||
this->copyEffectiveCoverageStages(drawState);
|
||||
this->adjustFromBlendOpts();
|
||||
this->getStageStats();
|
||||
};
|
||||
|
||||
void GrOptDrawState::adjustFromBlendOpts() {
|
||||
@ -179,6 +180,41 @@ void GrOptDrawState::copyEffectiveCoverageStages(const GrDrawState& ds) {
|
||||
}
|
||||
}
|
||||
|
||||
static void get_stage_stats(const GrEffectStage& stage, bool* readsDst, bool* readsFragPosition) {
|
||||
if (stage.getEffect()->willReadDstColor()) {
|
||||
*readsDst = true;
|
||||
}
|
||||
if (stage.getEffect()->willReadFragmentPosition()) {
|
||||
*readsFragPosition = true;
|
||||
}
|
||||
}
|
||||
void GrOptDrawState::getStageStats() {
|
||||
// We will need a local coord attrib if there is one currently set on the optState and we are
|
||||
// actually generating some effect code
|
||||
fRequiresLocalCoordAttrib = this->hasLocalCoordAttribute() && this->numTotalStages() > 0;
|
||||
|
||||
// if 1 == fVACount then that VA must be position, otherwise it contains some attribute which
|
||||
// will require a vertexShader
|
||||
fRequiresVertexShader = fVACount > 1;
|
||||
|
||||
fReadsDst = false;
|
||||
fReadsFragPosition = false;
|
||||
|
||||
for (int s = 0; s < this->numColorStages(); ++s) {
|
||||
const GrEffectStage& stage = this->getColorStage(s);
|
||||
get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
|
||||
}
|
||||
for (int s = 0; s < this->numCoverageStages(); ++s) {
|
||||
const GrEffectStage& stage = this->getCoverageStage(s);
|
||||
get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
|
||||
}
|
||||
if (this->hasGeometryProcessor()) {
|
||||
const GrEffectStage& stage = *this->getGeometryProcessor();
|
||||
get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
|
||||
SkASSERT(fRequiresVertexShader);
|
||||
}
|
||||
}
|
||||
|
||||
bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
|
||||
return this->isEqual(that);
|
||||
}
|
||||
|
@ -23,6 +23,11 @@ public:
|
||||
bool inputColorIsUsed() const { return fInputColorIsUsed; }
|
||||
bool inputCoverageIsUsed() const { return fInputCoverageIsUsed; }
|
||||
|
||||
bool readsDst() const { return fReadsDst; }
|
||||
bool readsFragPosition() const { return fReadsFragPosition; }
|
||||
bool requiresVertexShader() const { return fRequiresVertexShader; }
|
||||
bool requiresLocalCoordAttrib() const { return fRequiresLocalCoordAttrib; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Constructs and optimized drawState out of a GrRODrawState.
|
||||
@ -61,11 +66,23 @@ private:
|
||||
*/
|
||||
void adjustFromBlendOpts();
|
||||
|
||||
/**
|
||||
* Loop over the effect stages to determine various info like what data they will read and what
|
||||
* shaders they require.
|
||||
*/
|
||||
void getStageStats();
|
||||
|
||||
// These flags are needed to protect the code from creating an unused uniform color/coverage
|
||||
// which will cause shader compiler errors.
|
||||
bool fInputColorIsUsed;
|
||||
bool fInputCoverageIsUsed;
|
||||
|
||||
// These flags give aggregated info on the effect stages that are used when building programs.
|
||||
bool fReadsDst;
|
||||
bool fReadsFragPosition;
|
||||
bool fRequiresVertexShader;
|
||||
bool fRequiresLocalCoordAttrib;
|
||||
|
||||
SkAutoSTArray<4, GrVertexAttrib> fOptVA;
|
||||
|
||||
BlendOptFlags fBlendOptFlags;
|
||||
|
@ -14,25 +14,11 @@
|
||||
|
||||
#include "SkChecksum.h"
|
||||
|
||||
bool GrGLProgramDesc::GetEffectKeyAndUpdateStats(const GrEffectStage& stage,
|
||||
const GrGLCaps& caps,
|
||||
bool useExplicitLocalCoords,
|
||||
GrEffectKeyBuilder* b,
|
||||
uint16_t* effectKeySize,
|
||||
bool* setTrueIfReadsDst,
|
||||
bool* setTrueIfReadsPos,
|
||||
bool* setTrueIfRequiresVertexShader) {
|
||||
bool GrGLProgramDesc::GetEffectKey(const GrEffectStage& stage, const GrGLCaps& caps,
|
||||
bool useExplicitLocalCoords, GrEffectKeyBuilder* b,
|
||||
uint16_t* effectKeySize) {
|
||||
const GrBackendEffectFactory& factory = stage.getEffect()->getFactory();
|
||||
const GrEffect& effect = *stage.getEffect();
|
||||
if (effect.willReadDstColor()) {
|
||||
*setTrueIfReadsDst = true;
|
||||
}
|
||||
if (effect.willReadFragmentPosition()) {
|
||||
*setTrueIfReadsPos = true;
|
||||
}
|
||||
if (effect.requiresVertexShader()) {
|
||||
*setTrueIfRequiresVertexShader = true;
|
||||
}
|
||||
factory.getGLEffectKey(effect, caps, b);
|
||||
size_t size = b->size();
|
||||
if (size > SK_MaxU16) {
|
||||
@ -72,15 +58,7 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
|
||||
|
||||
bool requiresColorAttrib = optState.hasColorVertexAttribute();
|
||||
bool requiresCoverageAttrib = optState.hasCoverageVertexAttribute();
|
||||
// we only need the local coords if we're actually going to generate effect code
|
||||
bool requiresLocalCoordAttrib = optState.numTotalStages() > 0 &&
|
||||
optState.hasLocalCoordAttribute();
|
||||
|
||||
bool readsDst = false;
|
||||
bool readFragPosition = false;
|
||||
|
||||
// Provide option for shader programs without vertex shader only when drawing paths.
|
||||
bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType);
|
||||
bool requiresLocalCoordAttrib = optState.requiresLocalCoordAttrib();
|
||||
|
||||
int numStages = optState.numTotalStages();
|
||||
|
||||
@ -105,18 +83,14 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
|
||||
GrEffectKeyBuilder b(&desc->fKey);
|
||||
uint16_t effectKeySize;
|
||||
uint32_t effectOffset = desc->fKey.count();
|
||||
effectKeySuccess |= GetEffectKeyAndUpdateStats(
|
||||
*optState.getGeometryProcessor(), gpu->glCaps(),
|
||||
requiresLocalCoordAttrib, &b,
|
||||
&effectKeySize, &readsDst,
|
||||
&readFragPosition, &requiresVertexShader);
|
||||
effectKeySuccess |= GetEffectKey(*optState.getGeometryProcessor(), gpu->glCaps(),
|
||||
requiresLocalCoordAttrib, &b, &effectKeySize);
|
||||
effectKeySuccess |= (effectOffset <= SK_MaxU16);
|
||||
|
||||
offsetAndSize[0] = SkToU16(effectOffset);
|
||||
offsetAndSize[1] = effectKeySize;
|
||||
++offsetAndSizeIndex;
|
||||
*geometryProcessor = optState.getGeometryProcessor();
|
||||
SkASSERT(requiresVertexShader);
|
||||
header->fHasGeometryProcessor = true;
|
||||
}
|
||||
|
||||
@ -125,21 +99,16 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
|
||||
reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
|
||||
offsetAndSizeIndex * 2 * sizeof(uint16_t));
|
||||
|
||||
bool effectRequiresVertexShader = false;
|
||||
GrEffectKeyBuilder b(&desc->fKey);
|
||||
uint16_t effectKeySize;
|
||||
uint32_t effectOffset = desc->fKey.count();
|
||||
effectKeySuccess |= GetEffectKeyAndUpdateStats(
|
||||
optState.getColorStage(s), gpu->glCaps(),
|
||||
requiresLocalCoordAttrib, &b,
|
||||
&effectKeySize, &readsDst,
|
||||
&readFragPosition, &effectRequiresVertexShader);
|
||||
effectKeySuccess |= GetEffectKey(optState.getColorStage(s), gpu->glCaps(),
|
||||
requiresLocalCoordAttrib, &b, &effectKeySize);
|
||||
effectKeySuccess |= (effectOffset <= SK_MaxU16);
|
||||
|
||||
offsetAndSize[0] = SkToU16(effectOffset);
|
||||
offsetAndSize[1] = effectKeySize;
|
||||
++offsetAndSizeIndex;
|
||||
SkASSERT(!effectRequiresVertexShader);
|
||||
}
|
||||
|
||||
for (int s = 0; s < optState.numCoverageStages(); ++s) {
|
||||
@ -147,21 +116,16 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
|
||||
reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
|
||||
offsetAndSizeIndex * 2 * sizeof(uint16_t));
|
||||
|
||||
bool effectRequiresVertexShader = false;
|
||||
GrEffectKeyBuilder b(&desc->fKey);
|
||||
uint16_t effectKeySize;
|
||||
uint32_t effectOffset = desc->fKey.count();
|
||||
effectKeySuccess |= GetEffectKeyAndUpdateStats(
|
||||
optState.getCoverageStage(s), gpu->glCaps(),
|
||||
requiresLocalCoordAttrib, &b,
|
||||
&effectKeySize, &readsDst,
|
||||
&readFragPosition, &effectRequiresVertexShader);
|
||||
effectKeySuccess |= GetEffectKey(optState.getCoverageStage(s), gpu->glCaps(),
|
||||
requiresLocalCoordAttrib, &b, &effectKeySize);
|
||||
effectKeySuccess |= (effectOffset <= SK_MaxU16);
|
||||
|
||||
offsetAndSize[0] = SkToU16(effectOffset);
|
||||
offsetAndSize[1] = effectKeySize;
|
||||
++offsetAndSizeIndex;
|
||||
SkASSERT(!effectRequiresVertexShader);
|
||||
}
|
||||
|
||||
if (!effectKeySuccess) {
|
||||
@ -172,7 +136,12 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
|
||||
// Because header is a pointer into the dynamic array, we can't push any new data into the key
|
||||
// below here.
|
||||
|
||||
header->fRequiresVertexShader = requiresVertexShader || requiresLocalCoordAttrib;
|
||||
// We will only require a vertex shader if we have more than just the position VA attrib.
|
||||
// If we have a geom processor we must us a vertex shader and we should not have a geometry
|
||||
// processor if we are doing path rendering.
|
||||
SkASSERT(!GrGpu::IsPathRenderingDrawType(drawType) || !optState.requiresVertexShader());
|
||||
header->fRequiresVertexShader = optState.requiresVertexShader() ||
|
||||
!GrGpu::IsPathRenderingDrawType(drawType);
|
||||
header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType;
|
||||
|
||||
// Currently the experimental GS will only work with triangle prims (and it doesn't do anything
|
||||
@ -206,7 +175,7 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
|
||||
header->fRequiresVertexShader = true;
|
||||
}
|
||||
|
||||
if (readsDst) {
|
||||
if (optState.readsDst()) {
|
||||
SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport());
|
||||
const GrTexture* dstCopyTexture = NULL;
|
||||
if (dstCopy) {
|
||||
@ -219,7 +188,7 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
|
||||
header->fDstReadKey = 0;
|
||||
}
|
||||
|
||||
if (readFragPosition) {
|
||||
if (optState.readsFragPosition()) {
|
||||
header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition(
|
||||
optState.getRenderTarget(), gpu->glCaps());
|
||||
} else {
|
||||
@ -277,7 +246,7 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
|
||||
header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput;
|
||||
separateCoverageFromColor = true;
|
||||
}
|
||||
} else if (readsDst &&
|
||||
} else if (optState.readsDst() &&
|
||||
kOne_GrBlendCoeff == srcCoeff &&
|
||||
kZero_GrBlendCoeff == dstCoeff) {
|
||||
header->fCoverageOutput = kCombineWithDst_CoverageOutput;
|
||||
|
@ -201,14 +201,9 @@ private:
|
||||
KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); }
|
||||
|
||||
// Shared code between setRandom() and Build().
|
||||
static bool GetEffectKeyAndUpdateStats(const GrEffectStage& stage,
|
||||
const GrGLCaps& caps,
|
||||
bool useExplicitLocalCoords,
|
||||
GrEffectKeyBuilder* b,
|
||||
uint16_t* effectKeySize,
|
||||
bool* setTrueIfReadsDst,
|
||||
bool* setTrueIfReadsPos,
|
||||
bool* setTrueIfRequiresVertexShader);
|
||||
static bool GetEffectKey(const GrEffectStage& stage, const GrGLCaps& caps,
|
||||
bool useExplicitLocalCoords, GrEffectKeyBuilder* b,
|
||||
uint16_t* effectKeySize);
|
||||
|
||||
void finalize();
|
||||
|
||||
|
@ -21,6 +21,19 @@
|
||||
#include "SkRandom.h"
|
||||
#include "Test.h"
|
||||
|
||||
static void get_stage_stats(const GrEffectStage stage, bool* readsDst,
|
||||
bool* readsFragPosition, bool* requiresVertexShader) {
|
||||
if (stage.getEffect()->willReadDstColor()) {
|
||||
*readsDst = true;
|
||||
}
|
||||
if (stage.getEffect()->willReadFragmentPosition()) {
|
||||
*readsFragPosition = true;
|
||||
}
|
||||
if (stage.getEffect()->requiresVertexShader()) {
|
||||
*requiresVertexShader = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool GrGLProgramDesc::setRandom(SkRandom* random,
|
||||
const GrGpuGL* gpu,
|
||||
const GrRenderTarget* dstRenderTarget,
|
||||
@ -57,11 +70,11 @@ bool GrGLProgramDesc::setRandom(SkRandom* random,
|
||||
}
|
||||
GrEffectKeyBuilder b(&fKey);
|
||||
uint16_t effectKeySize;
|
||||
if (!GetEffectKeyAndUpdateStats(*stage, gpu->glCaps(), useLocalCoords, &b,
|
||||
&effectKeySize, &dstRead, &fragPos, &vertexShader)) {
|
||||
if (!GetEffectKey(*stage, gpu->glCaps(), useLocalCoords, &b, &effectKeySize)) {
|
||||
fKey.reset();
|
||||
return false;
|
||||
}
|
||||
get_stage_stats(*stage, &dstRead, &fragPos, &vertexShader);
|
||||
offsetAndSize[0] = effectKeyOffset;
|
||||
offsetAndSize[1] = effectKeySize;
|
||||
offset++;
|
||||
@ -79,11 +92,11 @@ bool GrGLProgramDesc::setRandom(SkRandom* random,
|
||||
}
|
||||
GrEffectKeyBuilder b(&fKey);
|
||||
uint16_t effectKeySize;
|
||||
if (!GetEffectKeyAndUpdateStats(*stage, gpu->glCaps(), useLocalCoords, &b,
|
||||
&effectKeySize, &dstRead, &fragPos, &vertexShader)) {
|
||||
if (!GetEffectKey(*stages[s], gpu->glCaps(), useLocalCoords, &b, &effectKeySize)) {
|
||||
fKey.reset();
|
||||
return false;
|
||||
}
|
||||
get_stage_stats(*stage, &dstRead, &fragPos, &vertexShader);
|
||||
offsetAndSize[0] = effectKeyOffset;
|
||||
offsetAndSize[1] = effectKeySize;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user