aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-27 18:14:57 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-27 18:14:57 +0000
commit31ec7985f2b52a0cab4aa714a613b918cf663c08 (patch)
treead59af0996923cf29291351a003767204d70c653 /src/gpu
parent04b959abfc971804bb5b1ee177eb7c24c716ec13 (diff)
Move GrGLProgram::Desc out of GrGLProgram.
Review URL: https://codereview.chromium.org/12942014 git-svn-id: http://skia.googlecode.com/svn/trunk@8411 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrDrawState.h31
-rw-r--r--src/gpu/gl/GrGLProgram.cpp107
-rw-r--r--src/gpu/gl/GrGLProgram.h107
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h104
-rw-r--r--src/gpu/gl/GrGLVertexArray.h26
-rw-r--r--src/gpu/gl/GrGpuGL.h4
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp12
7 files changed, 194 insertions, 197 deletions
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index fed89dbefc..8b7a36e466 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -16,6 +16,7 @@
#include "GrStencil.h"
#include "GrTemplates.h"
#include "GrTexture.h"
+#include "GrTypesPriv.h"
#include "effects/GrSimpleTextureEffect.h"
#include "SkMatrix.h"
@@ -24,36 +25,6 @@
class GrPaint;
/**
- * Types used to describe format of vertices in arrays
- */
-enum GrVertexAttribType {
- kFloat_GrVertexAttribType = 0,
- kVec2f_GrVertexAttribType,
- kVec3f_GrVertexAttribType,
- kVec4f_GrVertexAttribType,
- kVec4ub_GrVertexAttribType, // vector of 4 unsigned bytes, e.g. colors
-
- kLast_GrVertexAttribType = kVec4ub_GrVertexAttribType
-};
-static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
-
-struct GrVertexAttrib {
- inline void set(GrVertexAttribType type, size_t offset) {
- fType = type; fOffset = offset;
- }
- bool operator==(const GrVertexAttrib& other) const {
- return fType == other.fType && fOffset == other.fOffset;
- };
- bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
-
- GrVertexAttribType fType;
- size_t fOffset;
-};
-
-template <int N>
-class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
-
-/**
* Type used to describe how attributes bind to program usage
*/
typedef int GrAttribBindings;
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 5f567912f6..5c5dabfd70 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -36,21 +36,13 @@ inline const char* declared_color_output_name() { return "fsColorOut"; }
inline const char* dual_source_output_name() { return "dualSourceOut"; }
}
-const GrGLProgram::AttribLayout GrGLProgram::kAttribLayouts[kGrVertexAttribTypeCount] = {
- {1, GR_GL_FLOAT, false}, // kFloat_GrVertexAttribType
- {2, GR_GL_FLOAT, false}, // kVec2f_GrVertexAttribType
- {3, GR_GL_FLOAT, false}, // kVec3f_GrVertexAttribType
- {4, GR_GL_FLOAT, false}, // kVec4f_GrVertexAttribType
- {4, GR_GL_UNSIGNED_BYTE, true}, // kVec4ub_GrVertexAttribType
-};
-
-void GrGLProgram::BuildDesc(const GrDrawState& drawState,
+void GrGLProgramDesc::Build(const GrDrawState& drawState,
bool isPoints,
GrDrawState::BlendOptFlags blendOpts,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff,
const GrGpuGL* gpu,
- Desc* desc) {
+ GrGLProgramDesc* desc) {
// This should already have been caught
GrAssert(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts));
@@ -94,25 +86,25 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) ||
(!requiresAttributeColors && 0xffffffff == drawState.getColor());
if (colorIsTransBlack) {
- desc->fColorInput = Desc::kTransBlack_ColorInput;
+ desc->fColorInput = kTransBlack_ColorInput;
} else if (colorIsSolidWhite) {
- desc->fColorInput = Desc::kSolidWhite_ColorInput;
+ desc->fColorInput = kSolidWhite_ColorInput;
} else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeColors) {
- desc->fColorInput = Desc::kUniform_ColorInput;
+ desc->fColorInput = kUniform_ColorInput;
} else {
- desc->fColorInput = Desc::kAttribute_ColorInput;
+ desc->fColorInput = kAttribute_ColorInput;
}
bool covIsSolidWhite = !requiresAttributeCoverage && 0xffffffff == drawState.getCoverage();
if (skipCoverage) {
- desc->fCoverageInput = Desc::kTransBlack_ColorInput;
+ desc->fCoverageInput = kTransBlack_ColorInput;
} else if (covIsSolidWhite) {
- desc->fCoverageInput = Desc::kSolidWhite_ColorInput;
+ desc->fCoverageInput = kSolidWhite_ColorInput;
} else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresAttributeCoverage) {
- desc->fCoverageInput = Desc::kUniform_ColorInput;
+ desc->fCoverageInput = kUniform_ColorInput;
} else {
- desc->fCoverageInput = Desc::kAttribute_ColorInput;
+ desc->fCoverageInput = kAttribute_ColorInput;
}
int lastEnabledStage = -1;
@@ -133,7 +125,7 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
}
}
- desc->fDualSrcOutput = Desc::kNone_DualSrcOutput;
+ desc->fDualSrcOutput = kNone_DualSrcOutput;
// Currently the experimental GS will only work with triangle prims (and it doesn't do anything
// other than pass through values from the VS to the FS anyway).
@@ -181,15 +173,15 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
GrDrawState::kCoverageAsAlpha_BlendOptFlag))) {
if (kZero_GrBlendCoeff == dstCoeff) {
// write the coverage value to second color
- desc->fDualSrcOutput = Desc::kCoverage_DualSrcOutput;
+ desc->fDualSrcOutput = kCoverage_DualSrcOutput;
desc->fFirstCoverageStage = firstCoverageStage;
} else if (kSA_GrBlendCoeff == dstCoeff) {
// SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
- desc->fDualSrcOutput = Desc::kCoverageISA_DualSrcOutput;
+ desc->fDualSrcOutput = kCoverageISA_DualSrcOutput;
desc->fFirstCoverageStage = firstCoverageStage;
} else if (kSC_GrBlendCoeff == dstCoeff) {
// SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
- desc->fDualSrcOutput = Desc::kCoverageISC_DualSrcOutput;
+ desc->fDualSrcOutput = kCoverageISC_DualSrcOutput;
desc->fFirstCoverageStage = firstCoverageStage;
}
}
@@ -211,27 +203,28 @@ void GrGLProgram::BuildDesc(const GrDrawState& drawState,
}
#if GR_DEBUG
- // verify valid vertex attribute state
+ // Verify valid vertex attribute state. These assertions should probably be done somewhere
+ // higher up the callstack
const GrVertexAttrib* vertexAttribs = drawState.getVertexAttribs();
GrAssert(desc->fPositionAttributeIndex < GrDrawState::kVertexAttribCnt);
- GrAssert(kAttribLayouts[vertexAttribs[desc->fPositionAttributeIndex].fType].fCount == 2);
+ GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fPositionAttributeIndex].fType).fCount == 2);
if (requiresAttributeColors) {
GrAssert(desc->fColorAttributeIndex < GrDrawState::kVertexAttribCnt);
- GrAssert(kAttribLayouts[vertexAttribs[desc->fColorAttributeIndex].fType].fCount == 4);
+ GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fColorAttributeIndex].fType).fCount == 4);
}
if (requiresAttributeCoverage) {
GrAssert(desc->fCoverageAttributeIndex < GrDrawState::kVertexAttribCnt);
- GrAssert(kAttribLayouts[vertexAttribs[desc->fCoverageAttributeIndex].fType].fCount == 4);
+ GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fCoverageAttributeIndex].fType).fCount == 4);
}
if (desc->fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) {
GrAssert(desc->fLocalCoordsAttributeIndex < GrDrawState::kVertexAttribCnt);
- GrAssert(kAttribLayouts[vertexAttribs[desc->fLocalCoordsAttributeIndex].fType].fCount == 2);
+ GrAssert(GrGLAttribTypeToLayout(vertexAttribs[desc->fLocalCoordsAttributeIndex].fType).fCount == 2);
}
#endif
}
GrGLProgram* GrGLProgram::Create(const GrGLContext& gl,
- const Desc& desc,
+ const GrGLProgramDesc& desc,
const GrEffectStage* stages[]) {
GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages));
if (!program->succeeded()) {
@@ -242,7 +235,7 @@ GrGLProgram* GrGLProgram::Create(const GrGLContext& gl,
}
GrGLProgram::GrGLProgram(const GrGLContext& gl,
- const Desc& desc,
+ const GrGLProgramDesc& desc,
const GrEffectStage* stages[])
: fContext(gl)
, fUniformManager(gl) {
@@ -291,13 +284,13 @@ void GrGLProgram::abandon() {
void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
GrBlendCoeff* dstCoeff) const {
switch (fDesc.fDualSrcOutput) {
- case Desc::kNone_DualSrcOutput:
+ case GrGLProgramDesc::kNone_DualSrcOutput:
break;
// the prog will write a coverage value to the secondary
// output and the dst is blended by one minus that value.
- case Desc::kCoverage_DualSrcOutput:
- case Desc::kCoverageISA_DualSrcOutput:
- case Desc::kCoverageISC_DualSrcOutput:
+ case GrGLProgramDesc::kCoverage_DualSrcOutput:
+ case GrGLProgramDesc::kCoverageISA_DualSrcOutput:
+ case GrGLProgramDesc::kCoverageISC_DualSrcOutput:
*dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
break;
default:
@@ -413,24 +406,24 @@ void add_color_filter(GrGLShaderBuilder* builder,
void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) {
switch (fDesc.fColorInput) {
- case GrGLProgram::Desc::kAttribute_ColorInput: {
+ case GrGLProgramDesc::kAttribute_ColorInput: {
builder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME);
const char *vsName, *fsName;
builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName);
builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
*inColor = fsName;
} break;
- case GrGLProgram::Desc::kUniform_ColorInput: {
+ case GrGLProgramDesc::kUniform_ColorInput: {
const char* name;
fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kVec4f_GrSLType, "Color", &name);
*inColor = name;
break;
}
- case GrGLProgram::Desc::kTransBlack_ColorInput:
+ case GrGLProgramDesc::kTransBlack_ColorInput:
GrAssert(!"needComputedColor should be false.");
break;
- case GrGLProgram::Desc::kSolidWhite_ColorInput:
+ case GrGLProgramDesc::kSolidWhite_ColorInput:
break;
default:
GrCrash("Unknown color type.");
@@ -497,7 +490,7 @@ const char* GrGLProgram::adjustInColor(const SkString& inColor) const {
if (inColor.size()) {
return inColor.c_str();
} else {
- if (Desc::kSolidWhite_ColorInput == fDesc.fColorInput) {
+ if (GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.fColorInput) {
return GrGLSLOnesVecf(4);
} else {
return GrGLSLZerosVecf(4);
@@ -636,7 +629,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
// no need to do the color filter if coverage is 0. The output color is scaled by the coverage.
// All the dual source outputs are scaled by the coverage as well.
- if (Desc::kTransBlack_ColorInput == fDesc.fCoverageInput) {
+ if (GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fCoverageInput) {
colorCoeff = SkXfermode::kZero_Coeff;
uniformCoeff = SkXfermode::kZero_Coeff;
}
@@ -644,7 +637,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
// If we know the final color is going to be all zeros then we can
// simplify the color filter coefficients. needComputedColor will then
// come out false below.
- if (Desc::kTransBlack_ColorInput == fDesc.fColorInput) {
+ if (GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fColorInput) {
colorCoeff = SkXfermode::kZero_Coeff;
if (SkXfermode::kDC_Coeff == uniformCoeff ||
SkXfermode::kDA_Coeff == uniformCoeff) {
@@ -724,7 +717,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
// if have all ones or zeros for the "dst" input to the color filter then we
// may be able to make additional optimizations.
if (needColorFilterUniform && needComputedColor && !inColor.size()) {
- GrAssert(Desc::kSolidWhite_ColorInput == fDesc.fColorInput);
+ GrAssert(GrGLProgramDesc::kSolidWhite_ColorInput == fDesc.fColorInput);
bool uniformCoeffIsZero = SkXfermode::kIDC_Coeff == uniformCoeff ||
SkXfermode::kIDA_Coeff == uniformCoeff;
if (uniformCoeffIsZero) {
@@ -758,20 +751,20 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
// compute the partial coverage (coverage stages and edge aa)
SkString inCoverage;
- bool coverageIsZero = Desc::kTransBlack_ColorInput == fDesc.fCoverageInput;
+ bool coverageIsZero = GrGLProgramDesc::kTransBlack_ColorInput == fDesc.fCoverageInput;
// we don't need to compute coverage at all if we know the final shader
// output will be zero and we don't have a dual src blend output.
- if (!wroteFragColorZero || Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
+ if (!wroteFragColorZero || GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
if (!coverageIsZero) {
switch (fDesc.fCoverageInput) {
- case Desc::kSolidWhite_ColorInput:
+ case GrGLProgramDesc::kSolidWhite_ColorInput:
// empty string implies solid white
break;
- case Desc::kAttribute_ColorInput:
+ case GrGLProgramDesc::kAttribute_ColorInput:
gen_attribute_coverage(&builder, &inCoverage);
break;
- case Desc::kUniform_ColorInput:
+ case GrGLProgramDesc::kUniform_ColorInput:
this->genUniformCoverage(&builder, &inCoverage);
break;
default:
@@ -807,18 +800,18 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) {
}
}
- if (Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
+ if (GrGLProgramDesc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
builder.fFSOutputs.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kOut_TypeModifier,
dual_source_output_name());
bool outputIsZero = coverageIsZero;
SkString coeff;
if (!outputIsZero &&
- Desc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput && !wroteFragColorZero) {
+ GrGLProgramDesc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput && !wroteFragColorZero) {
if (!inColor.size()) {
outputIsZero = true;
} else {
- if (Desc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput) {
+ if (GrGLProgramDesc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput) {
coeff.printf("(1 - %s.a)", inColor.c_str());
} else {
coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str());
@@ -1009,7 +1002,7 @@ void GrGLProgram::setColor(const GrDrawState& drawState,
SharedGLState* sharedState) {
if (!(drawState.getAttribBindings() & GrDrawState::kColor_AttribBindingsBit)) {
switch (fDesc.fColorInput) {
- case GrGLProgram::Desc::kAttribute_ColorInput:
+ case GrGLProgramDesc::kAttribute_ColorInput:
if (sharedState->fConstAttribColor != color) {
// OpenGL ES only supports the float varieties of glVertexAttrib
GrGLfloat c[4];
@@ -1018,7 +1011,7 @@ void GrGLProgram::setColor(const GrDrawState& drawState,
sharedState->fConstAttribColor = color;
}
break;
- case GrGLProgram::Desc::kUniform_ColorInput:
+ case GrGLProgramDesc::kUniform_ColorInput:
if (fColor != color) {
// OpenGL ES doesn't support unsigned byte varieties of glUniform
GrGLfloat c[4];
@@ -1029,8 +1022,8 @@ void GrGLProgram::setColor(const GrDrawState& drawState,
fColor = color;
}
break;
- case GrGLProgram::Desc::kSolidWhite_ColorInput:
- case GrGLProgram::Desc::kTransBlack_ColorInput:
+ case GrGLProgramDesc::kSolidWhite_ColorInput:
+ case GrGLProgramDesc::kTransBlack_ColorInput:
break;
default:
GrCrash("Unknown color type.");
@@ -1043,7 +1036,7 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState,
SharedGLState* sharedState) {
if (!(drawState.getAttribBindings() & GrDrawState::kCoverage_AttribBindingsBit)) {
switch (fDesc.fCoverageInput) {
- case Desc::kAttribute_ColorInput:
+ case GrGLProgramDesc::kAttribute_ColorInput:
if (sharedState->fConstAttribCoverage != coverage) {
// OpenGL ES only supports the float varieties of glVertexAttrib
GrGLfloat c[4];
@@ -1052,7 +1045,7 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState,
sharedState->fConstAttribCoverage = coverage;
}
break;
- case Desc::kUniform_ColorInput:
+ case GrGLProgramDesc::kUniform_ColorInput:
if (fCoverage != coverage) {
// OpenGL ES doesn't support unsigned byte varieties of glUniform
GrGLfloat c[4];
@@ -1063,8 +1056,8 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState,
fCoverage = coverage;
}
break;
- case Desc::kSolidWhite_ColorInput:
- case Desc::kTransBlack_ColorInput:
+ case GrGLProgramDesc::kSolidWhite_ColorInput:
+ case GrGLProgramDesc::kTransBlack_ColorInput:
break;
default:
GrCrash("Unknown coverage type.");
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 2dea59efd8..df46e9b58d 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -10,8 +10,8 @@
#define GrGLProgram_DEFINED
#include "GrDrawState.h"
-#include "GrGLEffect.h"
#include "GrGLContext.h"
+#include "GrGLProgramDesc.h"
#include "GrGLSL.h"
#include "GrGLTexture.h"
#include "GrGLUniformManager.h"
@@ -24,10 +24,6 @@ class GrGLEffect;
class GrGLShaderBuilder;
class SkMWCRandom;
-// optionally compile the experimental GS code. Set to GR_DEBUG
-// so that debug build bots will execute the code.
-#define GR_GL_EXPERIMENTAL_GS GR_DEBUG
-
/**
* This class manages a GPU program and records per-program information.
* We can specify the attribute locations so that they are constant
@@ -41,22 +37,8 @@ class GrGLProgram : public GrRefCnt {
public:
SK_DECLARE_INST_COUNT(GrGLProgram)
- class Desc;
-
- /**
- * Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the
- * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs.
- */
- static void BuildDesc(const GrDrawState&,
- bool isPoints,
- GrDrawState::BlendOptFlags,
- GrBlendCoeff srcCoeff,
- GrBlendCoeff dstCoeff,
- const GrGpuGL* gpu,
- Desc* outDesc);
-
static GrGLProgram* Create(const GrGLContext& gl,
- const Desc& desc,
+ const GrGLProgramDesc& desc,
const GrEffectStage* stages[]);
virtual ~GrGLProgram();
@@ -71,7 +53,7 @@ public:
*/
void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
- const Desc& getDesc() { return fDesc; }
+ const GrGLProgramDesc& getDesc() { return fDesc; }
/**
* Gets the GL program ID for this program.
@@ -123,88 +105,9 @@ public:
*/
void setData(GrGpuGL*, GrColor color, GrColor coverage, SharedGLState*);
- // Parameters that affect code generation
- // This structs should be kept compact; it is input to an expensive hash key generator.
- class Desc {
- public:
- Desc() {
- // since we use this as part of a key we can't have any uninitialized
- // padding
- memset(this, 0, sizeof(Desc));
- }
-
- // returns this as a uint32_t array to be used as a key in the program cache
- const uint32_t* asKey() const {
- return reinterpret_cast<const uint32_t*>(this);
- }
-
- // For unit testing.
- void setRandom(SkMWCRandom*,
- const GrGpuGL* gpu,
- const GrEffectStage stages[GrDrawState::kNumStages]);
-
- private:
- // Specifies where the initial color comes from before the stages are applied.
- enum ColorInput {
- kSolidWhite_ColorInput,
- kTransBlack_ColorInput,
- kAttribute_ColorInput,
- kUniform_ColorInput,
-
- kColorInputCnt
- };
- // Dual-src blending makes use of a secondary output color that can be
- // used as a per-pixel blend coefficient. This controls whether a
- // secondary source is output and what value it holds.
- enum DualSrcOutput {
- kNone_DualSrcOutput,
- kCoverage_DualSrcOutput,
- kCoverageISA_DualSrcOutput,
- kCoverageISC_DualSrcOutput,
-
- kDualSrcOutputCnt
- };
-
- // should the FS discard if the coverage is zero (to avoid stencil manipulation)
- bool fDiscardIfZeroCoverage;
-
- // stripped of bits that don't affect program generation
- GrAttribBindings fAttribBindings;
-
- /** Non-zero if this stage has an effect */
- GrGLEffect::EffectKey fEffectKeys[GrDrawState::kNumStages];
-
- // To enable experimental geometry shader code (not for use in
- // production)
-#if GR_GL_EXPERIMENTAL_GS
- bool fExperimentalGS;
-#endif
- uint8_t fColorInput; // casts to enum ColorInput
- uint8_t fCoverageInput; // casts to enum ColorInput
- uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
- int8_t fFirstCoverageStage;
- SkBool8 fEmitsPointSize;
- uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
-
- int8_t fPositionAttributeIndex;
- int8_t fColorAttributeIndex;
- int8_t fCoverageAttributeIndex;
- int8_t fLocalCoordsAttributeIndex;
-
- friend class GrGLProgram;
- };
-
- // Layout information for OpenGL vertex attributes
- struct AttribLayout {
- GrGLint fCount;
- GrGLenum fType;
- GrGLboolean fNormalized;
- };
- static const AttribLayout kAttribLayouts[kGrVertexAttribTypeCount];
-
private:
GrGLProgram(const GrGLContext& gl,
- const Desc& desc,
+ const GrGLProgramDesc& desc,
const GrEffectStage* stages[]);
bool succeeded() const { return 0 != fProgramID; }
@@ -281,7 +184,7 @@ private:
GrGLEffect* fEffects[GrDrawState::kNumStages];
- Desc fDesc;
+ GrGLProgramDesc fDesc;
const GrGLContext& fContext;
GrGLUniformManager fUniformManager;
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
new file mode 100644
index 0000000000..2835259868
--- /dev/null
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLProgramDesc_DEFINED
+#define GrGLProgramDesc_DEFINED
+
+#include "GrGLEffect.h"
+
+class GrGpuGL;
+
+// optionally compile the experimental GS code. Set to GR_DEBUG so that debug build bots will
+// execute the code.
+#define GR_GL_EXPERIMENTAL_GS GR_DEBUG
+
+
+/** This class describes a program to generate. It also serves as a program cache key. The only
+ thing GL-specific about this is the generation of GrGLEffect::EffectKeys. With some refactoring
+ it could be made backend-neutral. */
+class GrGLProgramDesc {
+public:
+ GrGLProgramDesc() {
+ // since we use this as part of a key we can't have any uninitialized padding
+ memset(this, 0, sizeof(GrGLProgramDesc));
+ }
+
+ // Returns this as a uint32_t array to be used as a key in the program cache
+ const uint32_t* asKey() const {
+ return reinterpret_cast<const uint32_t*>(this);
+ }
+
+ // For unit testing.
+ void setRandom(SkMWCRandom*,
+ const GrGpuGL* gpu,
+ const GrEffectStage stages[GrDrawState::kNumStages]);
+
+ /**
+ * Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the
+ * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs.
+ */
+ static void Build(const GrDrawState&,
+ bool isPoints,
+ GrDrawState::BlendOptFlags,
+ GrBlendCoeff srcCoeff,
+ GrBlendCoeff dstCoeff,
+ const GrGpuGL* gpu,
+ GrGLProgramDesc* outDesc);
+
+private:
+ // Specifies where the initial color comes from before the stages are applied.
+ enum ColorInput {
+ kSolidWhite_ColorInput,
+ kTransBlack_ColorInput,
+ kAttribute_ColorInput,
+ kUniform_ColorInput,
+
+ kColorInputCnt
+ };
+ // Dual-src blending makes use of a secondary output color that can be
+ // used as a per-pixel blend coefficient. This controls whether a
+ // secondary source is output and what value it holds.
+ enum DualSrcOutput {
+ kNone_DualSrcOutput,
+ kCoverage_DualSrcOutput,
+ kCoverageISA_DualSrcOutput,
+ kCoverageISC_DualSrcOutput,
+
+ kDualSrcOutputCnt
+ };
+
+ // should the FS discard if the coverage is zero (to avoid stencil manipulation)
+ bool fDiscardIfZeroCoverage;
+
+ // stripped of bits that don't affect program generation
+ GrAttribBindings fAttribBindings;
+
+ /** Non-zero if this stage has an effect */
+ GrGLEffect::EffectKey fEffectKeys[GrDrawState::kNumStages];
+
+ // To enable experimental geometry shader code (not for use in
+ // production)
+#if GR_GL_EXPERIMENTAL_GS
+ bool fExperimentalGS;
+#endif
+ uint8_t fColorInput; // casts to enum ColorInput
+ uint8_t fCoverageInput; // casts to enum ColorInput
+ uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
+ int8_t fFirstCoverageStage;
+ SkBool8 fEmitsPointSize;
+ uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
+
+ int8_t fPositionAttributeIndex;
+ int8_t fColorAttributeIndex;
+ int8_t fCoverageAttributeIndex;
+ int8_t fLocalCoordsAttributeIndex;
+
+ // GrGLProgram reads the private fields to generate code.
+ friend class GrGLProgram;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLVertexArray.h b/src/gpu/gl/GrGLVertexArray.h
index 5693f4a5e0..2d1ff2950d 100644
--- a/src/gpu/gl/GrGLVertexArray.h
+++ b/src/gpu/gl/GrGLVertexArray.h
@@ -9,6 +9,8 @@
#define GrGLVertexArray_DEFINED
#include "GrResource.h"
+#include "GrTypesPriv.h"
+#include "gl/GrGLDefines.h"
#include "gl/GrGLFunctions.h"
#include "SkTArray.h"
@@ -17,6 +19,30 @@ class GrGLVertexBuffer;
class GrGLIndexBuffer;
class GrGpuGL;
+struct GrGLAttribLayout {
+ GrGLint fCount;
+ GrGLenum fType;
+ GrGLboolean fNormalized;
+};
+
+static inline const GrGLAttribLayout& GrGLAttribTypeToLayout(GrVertexAttribType type) {
+ GrAssert(type >= 0 && type < kGrVertexAttribTypeCount);
+ static const GrGLAttribLayout kLayouts[kGrVertexAttribTypeCount] = {
+ {1, GR_GL_FLOAT, false}, // kFloat_GrVertexAttribType
+ {2, GR_GL_FLOAT, false}, // kVec2f_GrVertexAttribType
+ {3, GR_GL_FLOAT, false}, // kVec3f_GrVertexAttribType
+ {4, GR_GL_FLOAT, false}, // kVec4f_GrVertexAttribType
+ {4, GR_GL_UNSIGNED_BYTE, true}, // kVec4ub_GrVertexAttribType
+ };
+ GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
+ GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
+ GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
+ GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
+ GR_STATIC_ASSERT(4 == kVec4ub_GrVertexAttribType);
+ GR_STATIC_ASSERT(SK_ARRAY_COUNT(kLayouts) == kGrVertexAttribTypeCount);
+ return kLayouts[type];
+}
+
/**
* This sets and tracks the vertex attribute array state. It is used internally by GrGLVertexArray
* (below) but is separate because it is also used to track the state of vertex array object 0.
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 423d87fe16..c95b40ad46 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -163,10 +163,10 @@ private:
~ProgramCache();
void abandon();
- GrGLProgram* getProgram(const GrGLProgram::Desc& desc, const GrEffectStage* stages[]);
+ GrGLProgram* getProgram(const GrGLProgramDesc& desc, const GrEffectStage* stages[]);
private:
enum {
- kKeySize = sizeof(GrGLProgram::Desc),
+ kKeySize = sizeof(GrGLProgramDesc),
// We may actually have kMaxEntries+1 shaders in the GL context because we create a new
// shader before evicting from the cache.
kMaxEntries = 32
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index a07ad02501..8f527f878d 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -48,7 +48,7 @@ void GrGpuGL::ProgramCache::abandon() {
fCount = 0;
}
-GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgram::Desc& desc,
+GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc,
const GrEffectStage* stages[]) {
Entry newEntry;
newEntry.fKey.setKeyData(desc.asKey());
@@ -180,8 +180,8 @@ bool GrGpuGL::flushGraphicsState(DrawType type) {
for (int i = 0; i < GrDrawState::kNumStages; ++i) {
stages[i] = drawState.isStageEnabled(i) ? &drawState.getStage(i) : NULL;
}
- GrGLProgram::Desc desc;
- GrGLProgram::BuildDesc(this->getDrawState(),
+ GrGLProgramDesc desc;
+ GrGLProgramDesc::Build(this->getDrawState(),
kDrawPoints_DrawType == type,
blendOpts,
srcCoeff,
@@ -302,9 +302,9 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
attribState->set(this,
vertexAttribIndex,
vbuf,
- GrGLProgram::kAttribLayouts[attribType].fCount,
- GrGLProgram::kAttribLayouts[attribType].fType,
- GrGLProgram::kAttribLayouts[attribType].fNormalized,
+ GrGLAttribTypeToLayout(attribType).fCount,
+ GrGLAttribTypeToLayout(attribType).fType,
+ GrGLAttribTypeToLayout(attribType).fNormalized,
stride,
reinterpret_cast<GrGLvoid*>(
vertexOffsetInBytes + vertexAttrib->fOffset));