Reduce GrGLProgram::ProgramDesc from 88B to 24B.
http://codereview.appspot.com/4561058.
git-svn-id: http://skia.googlecode.com/svn/trunk@1480 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrGLProgram.cpp b/gpu/src/GrGLProgram.cpp
index af83801..ecb4753 100644
--- a/gpu/src/GrGLProgram.cpp
+++ b/gpu/src/GrGLProgram.cpp
@@ -86,14 +86,14 @@
}
static inline const char* all_ones_vec(int count) {
- static const char* ONESVEC[] = {"ERROR", "1.0", "vec2(1,1)",
+ static const char* ONESVEC[] = {"ERROR", "1.0", "vec2(1,1)",
"vec3(1,1,1)", "vec4(1,1,1,1)"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ONESVEC));
return ONESVEC[count];
}
static inline const char* all_zeros_vec(int count) {
- static const char* ZEROSVEC[] = {"ERROR", "0.0", "vec2(0,0)",
+ static const char* ZEROSVEC[] = {"ERROR", "0.0", "vec2(0,0)",
"vec3(0,0,0)", "vec4(0,0,0,0)"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ZEROSVEC));
return ZEROSVEC[count];
@@ -337,7 +337,9 @@
// The rest of transfer mode color filters have not been implemented
if (fProgramDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) {
GR_DEBUGCODE(bool success =)
- SkXfermode::ModeAsCoeff(fProgramDesc.fColorFilterXfermode, &uniformCoeff, &colorCoeff);
+ SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>
+ (fProgramDesc.fColorFilterXfermode),
+ &uniformCoeff, &colorCoeff);
GR_DEBUGASSERT(success);
} else {
colorCoeff = SkXfermode::kOne_Coeff;
@@ -423,7 +425,7 @@
if (needComputedColor) {
GrStringBuilder outColor;
for (int s = 0; s < fProgramDesc.fFirstCoverageStage; ++s) {
- if (fProgramDesc.fStages[s].fEnabled) {
+ if (fProgramDesc.fStages[s].isEnabled()) {
// create var to hold stage result
outColor = "color";
outColor.appendS32(s);
@@ -456,12 +458,12 @@
// if have all ones for the "dst" input to the color filter then we can make
// additional optimizations.
- if (needColorFilterUniform && !inColor.size() &&
+ if (needColorFilterUniform && !inColor.size() &&
(SkXfermode::kIDC_Coeff == uniformCoeff ||
SkXfermode::kIDA_Coeff == uniformCoeff)) {
uniformCoeff = SkXfermode::kZero_Coeff;
bool bogus;
- needBlendInputs(SkXfermode::kZero_Coeff, colorCoeff,
+ needBlendInputs(SkXfermode::kZero_Coeff, colorCoeff,
&needColorFilterUniform, &bogus);
}
if (needColorFilterUniform) {
@@ -470,16 +472,16 @@
}
bool wroteFragColorZero = false;
- if (SkXfermode::kZero_Coeff == uniformCoeff &&
+ if (SkXfermode::kZero_Coeff == uniformCoeff &&
SkXfermode::kZero_Coeff == colorCoeff) {
- segments.fFSCode.appendf("\t%s = %s;\n",
+ segments.fFSCode.appendf("\t%s = %s;\n",
fsColorOutput,
all_zeros_vec(4));
wroteFragColorZero = true;
} else if (SkXfermode::kDst_Mode != fProgramDesc.fColorFilterXfermode) {
segments.fFSCode.appendf("\tvec4 filteredColor;\n");
const char* color = inColor.size() ? inColor.c_str() : all_ones_vec(4);
- addColorFilter(&segments.fFSCode, "filteredColor", uniformCoeff,
+ addColorFilter(&segments.fFSCode, "filteredColor", uniformCoeff,
colorCoeff, color);
inColor = "filteredColor";
}
@@ -529,8 +531,7 @@
GrStringBuilder outCoverage;
const int& startStage = fProgramDesc.fFirstCoverageStage;
for (int s = startStage; s < GrDrawTarget::kNumStages; ++s) {
- if (fProgramDesc.fStages[s].fEnabled) {
-
+ if (fProgramDesc.fStages[s].isEnabled()) {
// create var to hold stage output
outCoverage = "coverage";
outCoverage.appendS32(s);
@@ -559,16 +560,16 @@
}
}
if (ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) {
- segments.fFSOutputs.appendf("out vec4 %s;\n",
+ segments.fFSOutputs.appendf("out vec4 %s;\n",
dual_source_output_name());
bool outputIsZero = false;
GrStringBuilder coeff;
- if (ProgramDesc::kCoverage_DualSrcOutput !=
+ if (ProgramDesc::kCoverage_DualSrcOutput !=
fProgramDesc.fDualSrcOutput && !wroteFragColorZero) {
if (!inColor.size()) {
outputIsZero = true;
} else {
- if (fProgramDesc.fDualSrcOutput ==
+ if (fProgramDesc.fDualSrcOutput ==
ProgramDesc::kCoverageISA_DualSrcOutput) {
coeff.printf("(1 - %s.a)", inColor.c_str());
} else {
@@ -577,7 +578,7 @@
}
}
if (outputIsZero) {
- segments.fFSCode.appendf("\t%s = %s;\n",
+ segments.fFSCode.appendf("\t%s = %s;\n",
dual_source_output_name(),
all_zeros_vec(4));
} else {
@@ -768,7 +769,7 @@
bool GrGLProgram::bindOutputsAttribsAndLinkProgram(
GrStringBuilder texCoordAttrNames[],
bool bindColorOut,
- bool bindDualSrcOut,
+ bool bindDualSrcOut,
CachedData* programData) const {
programData->fProgramID = GR_GL(CreateProgram());
if (!programData->fProgramID) {
@@ -780,7 +781,7 @@
GR_GL(AttachShader(progID, programData->fFShaderID));
if (bindColorOut) {
- GR_GL(BindFragDataLocationIndexed(programData->fProgramID,
+ GR_GL(BindFragDataLocationIndexed(programData->fProgramID,
0, 0, declared_color_output_name()));
}
if (bindDualSrcOut) {
@@ -849,18 +850,18 @@
GrAssert(kUnusedUniform != programData->fUniLocations.fViewMatrixUni);
}
if (kUseUniform == programData->fUniLocations.fColorUni) {
- programData->fUniLocations.fColorUni =
+ programData->fUniLocations.fColorUni =
GR_GL(GetUniformLocation(progID, COL_UNI_NAME));
GrAssert(kUnusedUniform != programData->fUniLocations.fColorUni);
}
if (kUseUniform == programData->fUniLocations.fColorFilterUni) {
- programData->fUniLocations.fColorFilterUni =
+ programData->fUniLocations.fColorFilterUni =
GR_GL(GetUniformLocation(progID, COL_FILTER_UNI_NAME));
GrAssert(kUnusedUniform != programData->fUniLocations.fColorFilterUni);
}
if (kUseUniform == programData->fUniLocations.fEdgesUni) {
- programData->fUniLocations.fEdgesUni =
+ programData->fUniLocations.fEdgesUni =
GR_GL(GetUniformLocation(progID, EDGES_UNI_NAME));
GrAssert(kUnusedUniform != programData->fUniLocations.fEdgesUni);
} else {
@@ -869,7 +870,7 @@
for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
StageUniLocations& locations = programData->fUniLocations.fStages[s];
- if (fProgramDesc.fStages[s].fEnabled) {
+ if (fProgramDesc.fStages[s].isEnabled()) {
if (kUseUniform == locations.fTextureMatrixUni) {
GrStringBuilder texMName;
tex_matrix_name(s, &texMName);
@@ -891,7 +892,7 @@
if (kUseUniform == locations.fNormalizedTexelSizeUni) {
GrStringBuilder texelSizeName;
normalized_texel_size_name(s, &texelSizeName);
- locations.fNormalizedTexelSizeUni =
+ locations.fNormalizedTexelSizeUni =
GR_GL(GetUniformLocation(progID, texelSizeName.c_str()));
GrAssert(kUnusedUniform != locations.fNormalizedTexelSizeUni);
}
@@ -989,7 +990,7 @@
segments->fFSUnis.appendf("uniform vec2 %s;\n", texelSizeName.c_str());
}
- segments->fVaryings.appendf("varying %s %s;\n",
+ segments->fVaryings.appendf("varying %s %s;\n",
float_vector_type(varyingDims), varyingName.c_str());
if (desc.fOptFlags & ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit) {
@@ -1011,9 +1012,9 @@
if (ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping == desc.fCoordMapping) {
- segments->fVSUnis.appendf("uniform %s float %s[6];\n",
+ segments->fVSUnis.appendf("uniform %s float %s[6];\n",
GrPrecision(), radial2ParamsName.c_str());
- segments->fFSUnis.appendf("uniform float %s[6];\n",
+ segments->fFSUnis.appendf("uniform float %s[6];\n",
radial2ParamsName.c_str());
locations->fRadial2Uni = kUseUniform;
@@ -1132,11 +1133,11 @@
modulate.printf(" * %s", fsInColor);
}
- if (desc.fOptFlags &
+ if (desc.fOptFlags &
ProgramDesc::StageDesc::kCustomTextureDomain_OptFlagBit) {
GrStringBuilder texDomainName;
tex_domain_name(stageNum, &texDomainName);
- segments->fFSUnis.appendf("uniform %s %s;\n",
+ segments->fFSUnis.appendf("uniform %s %s;\n",
float_vector_type(4),
texDomainName.c_str());
GrStringBuilder coordVar("clampCoord");
diff --git a/gpu/src/GrGLProgram.h b/gpu/src/GrGLProgram.h
index f6258ab..473bcb6 100644
--- a/gpu/src/GrGLProgram.h
+++ b/gpu/src/GrGLProgram.h
@@ -78,16 +78,18 @@
static int PositionAttributeIdx() { return 0; }
static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; }
static int ColorAttributeIdx() { return 1 + GrDrawTarget::kMaxTexCoords; }
- static int ViewMatrixAttributeIdx() {
- return 2 + GrDrawTarget::kMaxTexCoords;
+ static int ViewMatrixAttributeIdx() {
+ return 2 + GrDrawTarget::kMaxTexCoords;
}
- static int TextureMatrixAttributeIdx(int stage) {
- return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
+ static int TextureMatrixAttributeIdx(int stage) {
+ return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
}
private:
- //Parameters that affect code generation
+ // Parameters that affect code generation
+ // These structs should be kept compact; they are the input to an
+ // expensive hash key generator.
struct ProgramDesc {
ProgramDesc() {
// since we use this as part of a key we can't have any unitialized
@@ -95,16 +97,51 @@
memset(this, 0, sizeof(ProgramDesc));
}
- // stripped of bits that don't affect prog generation
- GrVertexLayout fVertexLayout;
+ struct StageDesc {
+ enum OptFlagBits {
+ kNoPerspective_OptFlagBit = 1 << 0,
+ kIdentityMatrix_OptFlagBit = 1 << 1,
+ kCustomTextureDomain_OptFlagBit = 1 << 2,
+ kIsEnabled_OptFlagBit = 1 << 7
+ };
+ enum Modulation {
+ kColor_Modulation,
+ kAlpha_Modulation
+ };
+ enum FetchMode {
+ kSingle_FetchMode,
+ k2x2_FetchMode
+ };
+ enum CoordMapping {
+ kIdentity_CoordMapping,
+ kRadialGradient_CoordMapping,
+ kSweepGradient_CoordMapping,
+ kRadial2Gradient_CoordMapping
+ };
- enum {
+ uint8_t fOptFlags;
+ uint8_t fModulation; // casts to enum Modulation
+ uint8_t fFetchMode; // casts to enum FetchMode
+ uint8_t fCoordMapping; // casts to enum CoordMapping
+
+ inline bool isEnabled() const {
+ return fOptFlags & kIsEnabled_OptFlagBit;
+ }
+ inline void setEnabled(bool newValue) {
+ if (newValue) {
+ fOptFlags |= kIsEnabled_OptFlagBit;
+ } else {
+ fOptFlags &= ~kIsEnabled_OptFlagBit;
+ }
+ }
+ };
+
+ enum ColorType {
kNone_ColorType = 0,
kAttribute_ColorType = 1,
kUniform_ColorType = 2,
- } fColorType;
-
- // Dual-src blending makes use of a secondary output color that can be
+ };
+ // Dual-src blending makes use of a secondary output color that can be
// used as a per-pixel blend coeffecient. This controls whether a
// secondary source is output and what value it holds.
enum DualSrcOutput {
@@ -113,41 +150,23 @@
kCoverageISA_DualSrcOutput,
kCoverageISC_DualSrcOutput,
kDualSrcOutputCnt
- } fDualSrcOutput;
+ };
- int fFirstCoverageStage;
- bool fEmitsPointSize;
- int fEdgeAANumEdges;
+ // stripped of bits that don't affect prog generation
+ GrVertexLayout fVertexLayout;
- SkXfermode::Mode fColorFilterXfermode;
+ StageDesc fStages[GrDrawTarget::kNumStages];
- struct StageDesc {
- enum OptFlagBits {
- kNoPerspective_OptFlagBit = 1 << 0,
- kIdentityMatrix_OptFlagBit = 1 << 1,
- kCustomTextureDomain_OptFlagBit = 1 << 2
- };
+ uint8_t fColorType; // casts to enum ColorType
+ uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
+ int8_t fFirstCoverageStage;
+ SkBool8 fEmitsPointSize;
- unsigned fOptFlags;
- bool fEnabled;
+ int8_t fEdgeAANumEdges;
+ uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
- enum Modulation {
- kColor_Modulation,
- kAlpha_Modulation
- } fModulation;
+ uint8_t fPadTo32bLengthMultiple [2];
- enum FetchMode {
- kSingle_FetchMode,
- k2x2_FetchMode
- } fFetchMode;
-
- enum CoordMapping {
- kIdentity_CoordMapping,
- kRadialGradient_CoordMapping,
- kSweepGradient_CoordMapping,
- kRadial2Gradient_CoordMapping
- } fCoordMapping;
- } fStages[GrDrawTarget::kNumStages];
} fProgramDesc;
const ProgramDesc& getDesc() { return fProgramDesc; }
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index 6d4b4b1..bd57291 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -196,11 +196,11 @@
pdesc.fEdgeAANumEdges = (random.nextF() * (getMaxEdges() + 1));
if (fDualSourceBlendingSupport) {
- pdesc.fDualSrcOutput =
+ pdesc.fDualSrcOutput =
(GrGLProgram::ProgramDesc::DualSrcOutput)
(int)(random.nextF() * GrGLProgram::ProgramDesc::kDualSrcOutputCnt);
} else {
- pdesc.fDualSrcOutput =
+ pdesc.fDualSrcOutput =
GrGLProgram::ProgramDesc::kNone_DualSrcOutput;
}
@@ -219,7 +219,6 @@
if (random.nextF() > .5f) {
pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit;
}
- pdesc.fStages[s].fEnabled = VertexUsesStage(s, pdesc.fVertexLayout);
idx = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_OPTS));
pdesc.fStages[s].fOptFlags = STAGE_OPTS[idx];
idx = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_MODULATES));
@@ -228,6 +227,7 @@
pdesc.fStages[s].fCoordMapping = STAGE_COORD_MAPPINGS[idx];
idx = (int)(random.nextF() * GR_ARRAY_COUNT(FETCH_MODES));
pdesc.fStages[s].fFetchMode = FETCH_MODES[idx];
+ pdesc.fStages[s].setEnabled(VertexUsesStage(s, pdesc.fVertexLayout));
}
GrGLProgram::CachedData cachedData;
program.genProgram(&cachedData);
@@ -730,20 +730,19 @@
for (int s = 0; s < kNumStages; ++s) {
GrGLProgram::ProgramDesc::StageDesc& stage = desc.fStages[s];
- stage.fEnabled = this->isStageEnabled(s);
+ stage.fOptFlags = 0;
+ stage.setEnabled(this->isStageEnabled(s));
- if (stage.fEnabled) {
+ if (stage.isEnabled()) {
lastEnabledStage = s;
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
GrAssert(NULL != texture);
// we matrix to invert when orientation is TopDown, so make sure
// we aren't in that case before flagging as identity.
if (TextureMatrixIsIdentity(texture, fCurrDrawState.fSamplerStates[s])) {
- stage.fOptFlags = GrGLProgram::ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit;
+ stage.fOptFlags |= GrGLProgram::ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit;
} else if (!getSamplerMatrix(s).hasPerspective()) {
- stage.fOptFlags = GrGLProgram::ProgramDesc::StageDesc::kNoPerspective_OptFlagBit;
- } else {
- stage.fOptFlags = 0;
+ stage.fOptFlags |= GrGLProgram::ProgramDesc::StageDesc::kNoPerspective_OptFlagBit;
}
switch (fCurrDrawState.fSamplerStates[s].getSampleMode()) {
case GrSamplerState::kNormal_SampleMode:
@@ -779,11 +778,11 @@
}
if (fCurrDrawState.fSamplerStates[s].hasTextureDomain()) {
- GrAssert(GrSamplerState::kClamp_WrapMode ==
- fCurrDrawState.fSamplerStates[s].getWrapX() &&
+ GrAssert(GrSamplerState::kClamp_WrapMode ==
+ fCurrDrawState.fSamplerStates[s].getWrapX() &&
GrSamplerState::kClamp_WrapMode ==
fCurrDrawState.fSamplerStates[s].getWrapY());
- stage.fOptFlags |=
+ stage.fOptFlags |=
GrGLProgram::ProgramDesc::StageDesc::
kCustomTextureDomain_OptFlagBit;
}
@@ -837,5 +836,3 @@
}
}
}
-
-