aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-04-19 21:15:09 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-04-19 21:15:09 +0000
commit4be283f3a82895530d1b70372cd48ddb1c663fd8 (patch)
tree6b439eed9d51302125f5448683b6984b7f113f0a /gpu
parentc733996e84cbac28492e133e00c573740a8708c4 (diff)
Adds a build flag for GL to never use vertex attributes that don't have per-vertex values.
Also promotes the ATTRIBUTE_MATRIX flag that was local to cpp files to the public config file. Review URL: http://codereview.appspot.com/4434057/ git-svn-id: http://skia.googlecode.com/svn/trunk@1155 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu')
-rw-r--r--gpu/include/GrConfig.h2
-rw-r--r--gpu/include/GrDrawTarget.h2
-rw-r--r--gpu/include/GrGLConfig.h33
-rw-r--r--gpu/include/GrGLConfig_chrome.h7
-rw-r--r--gpu/include/GrTypes.h2
-rw-r--r--gpu/src/GrGLProgram.cpp65
-rw-r--r--gpu/src/GrGLProgram.h24
-rw-r--r--gpu/src/GrGpuGLShaders.cpp118
-rw-r--r--gpu/src/GrGpuGLShaders.h3
-rw-r--r--gpu/src/GrGpuGLShaders2.cpp258
-rw-r--r--gpu/src/GrGpuGLShaders2.h33
11 files changed, 353 insertions, 194 deletions
diff --git a/gpu/include/GrConfig.h b/gpu/include/GrConfig.h
index 6f519b5dc4..8b8b28043f 100644
--- a/gpu/include/GrConfig.h
+++ b/gpu/include/GrConfig.h
@@ -120,6 +120,8 @@ typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
#else
/*
* Include stdint.h with defines that trigger declaration of C99 limit/const
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h
index 349cafd14f..038e776c5b 100644
--- a/gpu/include/GrDrawTarget.h
+++ b/gpu/include/GrDrawTarget.h
@@ -498,7 +498,7 @@ public:
kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
};
// make sure we haven't exceeded the number of bits in GrVertexLayout.
- GR_STATIC_ASSERT(kHighVertexLayoutBit < (1 << 8*sizeof(GrVertexLayout)));
+ GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
/**
* There are three paths for specifying geometry (vertices and optionally
diff --git a/gpu/include/GrGLConfig.h b/gpu/include/GrGLConfig.h
index 0502332cb4..18cc049010 100644
--- a/gpu/include/GrGLConfig.h
+++ b/gpu/include/GrGLConfig.h
@@ -53,23 +53,46 @@
*
* GR_GL_CHECK_ERROR_START: controls the initial value of gCheckErrorGL
* when GR_GL_CHECK_ERROR is 1. Defaults to 1.
+ *
+ * GR_GL_NO_CONSTANT_ATTRIBUTES: if this evaluates to true then the GL backend
+ * will use uniforms instead of attributes in all cases when there is not
+ * per-vertex data. This is important when the underlying GL implementation
+ * doesn't actually support immediate style attribute values (e.g. when
+ * the GL stream is converted to DX as in ANGLE on Chrome). Defaults to 0.
+ *
+ * GR_GL_ATTRIBUTE_MATRICES: If changing uniforms is very expensive it may be
+ * faster to use vertex attributes for matrices (set via glVertexAttrib3fv).
+ * Setting this build flag enables this behavior. GR_GL_NO_CONSTANT_ATTRIBUTES
+ * must not be set since this uses constant attributes for the matrices.
+ * Defaults to 0.
*/
-
#if !defined(GR_GL_LOG_CALLS)
- #define GR_GL_LOG_CALLS 0
+ #define GR_GL_LOG_CALLS 0
#endif
#if !defined(GR_GL_LOG_CALLS_START)
- #define GR_GL_LOG_CALLS_START 0
+ #define GR_GL_LOG_CALLS_START 0
#endif
#if !defined(GR_GL_CHECK_ERROR)
- #define GR_GL_CHECK_ERROR GR_DEBUG
+ #define GR_GL_CHECK_ERROR GR_DEBUG
#endif
#if !defined(GR_GL_CHECK_ERROR_START)
- #define GR_GL_CHECK_ERROR_START 1
+ #define GR_GL_CHECK_ERROR_START 1
+#endif
+
+#if !defined(GR_GL_NO_CONSTANT_ATTRIBUTES)
+ #define GR_GL_NO_CONSTANT_ATTRIBUTES 0
+#endif
+
+#if !defined(GR_GL_ATTRIBUTE_MATRICES)
+ #define GR_GL_ATTRIBUTE_MATRICES 0
+#endif
+
+#if(GR_GL_NO_CONSTANT_ATTRIBUTES) && (GR_GL_ATTRIBUTE_MATRICES)
+ #error "Cannot combine GR_GL_NO_CONSTANT_ATTRIBUTES and GR_GL_ATTRIBUTE_MATRICES"
#endif
////////////////////////////////////////////////////////////////////////////////
diff --git a/gpu/include/GrGLConfig_chrome.h b/gpu/include/GrGLConfig_chrome.h
index 08f7547084..738e80186b 100644
--- a/gpu/include/GrGLConfig_chrome.h
+++ b/gpu/include/GrGLConfig_chrome.h
@@ -2,9 +2,12 @@
#define GrGLConfig_chrome_DEFINED
// chrome always assumes BGRA
-#define GR_GL_32BPP_COLOR_FORMAT GR_GL_BGRA
+#define GR_GL_32BPP_COLOR_FORMAT GR_GL_BGRA
// glGetError() forces a sync with gpu process on chrome
-#define GR_GL_CHECK_ERROR_START 0
+#define GR_GL_CHECK_ERROR_START 0
+
+// ANGLE creates a temp VB for vertex attributes not specified per-vertex.
+#define GR_GL_NO_CONSTANT_ATTRIBUTES GR_WIN32_BUILD
#endif
diff --git a/gpu/include/GrTypes.h b/gpu/include/GrTypes.h
index fb62333414..9d1c5e3bcb 100644
--- a/gpu/include/GrTypes.h
+++ b/gpu/include/GrTypes.h
@@ -202,7 +202,7 @@ private:
* Type used to describe format of vertices in arrays
* Values are defined in GrDrawTarget
*/
-typedef uint16_t GrVertexLayout;
+typedef int GrVertexLayout;
/**
* Geometric primitives used for drawing.
diff --git a/gpu/src/GrGLProgram.cpp b/gpu/src/GrGLProgram.cpp
index 5dd09f018a..0365470387 100644
--- a/gpu/src/GrGLProgram.cpp
+++ b/gpu/src/GrGLProgram.cpp
@@ -42,7 +42,7 @@ const char* GrShaderPrecision() {
} // namespace
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
#define VIEW_MATRIX_NAME "aViewM"
#else
#define VIEW_MATRIX_NAME "uViewM"
@@ -50,6 +50,7 @@ const char* GrShaderPrecision() {
#define POS_ATTR_NAME "aPosition"
#define COL_ATTR_NAME "aColor"
+#define COL_UNI_NAME "uColor"
// for variable names etc
typedef GrSStringBuilder<16> GrTokenString;
@@ -84,7 +85,7 @@ static inline const char* vector_all_coords(int count) {
}
static void tex_matrix_name(int stage, GrStringBuilder* s) {
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
*s = "aTexM";
#else
*s = "uTexM";
@@ -179,33 +180,40 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
memset(&programData->fUniLocations, 0, sizeof(UniLocations));
- bool haveColor = !(ProgramDesc::kVertexColorAllOnes_OptFlagBit &
- fProgramDesc.fOptFlags);
-
-#if ATTRIBUTE_MATRIX
- segments.fVSAttrs = "attribute mat3 " VIEW_MATRIX_NAME ";\n";
+#if GR_GL_ATTRIBUTE_MATRICES
+ segments.fVSAttrs += "attribute mat3 " VIEW_MATRIX_NAME ";\n";
#else
- segments.fVSUnis = "uniform mat3 " VIEW_MATRIX_NAME ";\n";
- segments.fVSAttrs = "";
+ segments.fVSUnis += "uniform mat3 " VIEW_MATRIX_NAME ";\n";
#endif
segments.fVSAttrs += "attribute vec2 " POS_ATTR_NAME ";\n";
- if (haveColor) {
- segments.fVSAttrs += "attribute vec4 " COL_ATTR_NAME ";\n";
- segments.fVaryings = "varying vec4 vColor;\n";
- } else {
- segments.fVaryings = "";
- }
segments.fVSCode = "void main() {\n"
"\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3(" POS_ATTR_NAME ", 1);\n"
"\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n";
- if (haveColor) {
+
+ // incoming color to current stage being processed.
+ GrTokenString inColor;
+
+ switch (fProgramDesc.fColorType) {
+ case ProgramDesc::kAttribute_ColorType:
+ segments.fVSAttrs += "attribute vec4 " COL_ATTR_NAME ";\n";
+ segments.fVaryings += "varying vec4 vColor;\n";
segments.fVSCode += "\tvColor = " COL_ATTR_NAME ";\n";
+ inColor = "vColor";
+ break;
+ case ProgramDesc::kUniform_ColorType:
+ segments.fFSUnis += "uniform vec4 " COL_UNI_NAME ";\n";
+ inColor = COL_UNI_NAME;
+ break;
+ case ProgramDesc::kNone_ColorType:
+ inColor = "";
+ break;
}
- if (!(fProgramDesc.fOptFlags & ProgramDesc::kNotPoints_OptFlagBit)) {
+ if (fProgramDesc.fEmitsPointSize){
segments.fVSCode += "\tgl_PointSize = 1.0;\n";
}
+
segments.fFSCode = "void main() {\n";
// add texture coordinates that are used to the list of vertex attr decls
@@ -240,8 +248,6 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
}
}
- GrTokenString inColor = "vColor";
-
// if we have active stages string them together, feeding the output color
// of each to the next and generating code for each stage.
if (numActiveStages) {
@@ -261,19 +267,18 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
genStageCode(s,
fProgramDesc.fStages[s],
- haveColor ? inColor.cstr() : NULL,
+ inColor.length() ? inColor.cstr() : NULL,
outColor.cstr(),
stageInCoords[s],
&segments,
&programData->fUniLocations.fStages[s]);
++currActiveStage;
inColor = outColor;
- haveColor = true;
}
}
} else {
segments.fFSCode += "\tgl_FragColor = ";
- if (haveColor) {
+ if (inColor.length()) {
segments.fFSCode += inColor;
} else {
segments.fFSCode += "vec4(1,1,1,1)";
@@ -372,7 +377,7 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
}
}
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
// set unis to a bogus value so that checks against -1 before
// flushing will pass.
GR_GL(BindAttribLocation(progID,
@@ -418,15 +423,23 @@ void GrGLProgram::genProgram(GrGLProgram::CachedData* programData,
}
// Get uniform locations
-#if !ATTRIBUTE_MATRIX
+#if !GR_GL_ATTRIBUTE_MATRICES
programData->fUniLocations.fViewMatrixUni =
GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME));
GrAssert(-1 != programData->fUniLocations.fViewMatrixUni);
#endif
+ if (ProgramDesc::kUniform_ColorType == fProgramDesc.fColorType) {
+ programData->fUniLocations.fColorUni =
+ GR_GL(GetUniformLocation(progID, COL_UNI_NAME));
+ GrAssert(-1 != programData->fUniLocations.fColorUni);
+ } else {
+ programData->fUniLocations.fColorUni = -1;
+ }
+
for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
StageUniLocations& locations = programData->fUniLocations.fStages[s];
if (fProgramDesc.fStages[s].fEnabled) {
-#if !ATTRIBUTE_MATRIX
+#if !GR_GL_ATTRIBUTE_MATRICES
if (locations.fTextureMatrixUni) {
GrTokenString texMName;
tex_matrix_name(s, &texMName);
@@ -548,7 +561,7 @@ void GrGLProgram::genStageCode(int stageNum,
if (desc.fOptFlags & ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit) {
varyingDims = coordDims;
} else {
- #if ATTRIBUTE_MATRIX
+ #if GR_GL_ATTRIBUTE_MATRICES
segments->fVSAttrs += "attribute mat3 ";
segments->fVSAttrs += texMName;
segments->fVSAttrs += ";\n";
diff --git a/gpu/src/GrGLProgram.h b/gpu/src/GrGLProgram.h
index 1a15953e74..bc740384df 100644
--- a/gpu/src/GrGLProgram.h
+++ b/gpu/src/GrGLProgram.h
@@ -84,16 +84,22 @@ private:
//Parameters that affect code generation
struct ProgramDesc {
+ ProgramDesc() {
+ // since we use this as part of a key we can't have any unitialized
+ // padding
+ memset(this, 0, sizeof(ProgramDesc));
+ }
+
+ // stripped of bits that don't affect prog generation
GrVertexLayout fVertexLayout;
enum {
- kNotPoints_OptFlagBit = 0x1,
- kVertexColorAllOnes_OptFlagBit = 0x2,
- };
- // we're assuming optflags and layout pack into 32 bits
- // VS 2010 seems to require short rather than just unsigned
- // for this to pack
- unsigned short fOptFlags : 16;
+ kNone_ColorType = 0,
+ kAttribute_ColorType = 1,
+ kUniform_ColorType = 2,
+ } fColorType;
+
+ bool fEmitsPointSize;
struct StageDesc {
enum OptFlagBits {
@@ -118,6 +124,8 @@ private:
} fStages[GrDrawTarget::kNumStages];
} fProgramDesc;
+ const ProgramDesc& getDesc() { return fProgramDesc; }
+
public:
struct StageUniLocations {
GrGLint fTextureMatrixUni;
@@ -127,6 +135,7 @@ public:
struct UniLocations {
GrGLint fViewMatrixUni;
+ GrGLint fColorUni;
StageUniLocations fStages[GrDrawTarget::kNumStages];
};
@@ -177,6 +186,7 @@ public:
// these reflect the current values of uniforms
// (GL uniform values travel with program)
+ GrColor fColor;
GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index b34fc33bef..c16e9e05fc 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -23,15 +23,14 @@
#include "GrNoncopyable.h"
#include "GrStringBuilder.h"
-#define ATTRIBUTE_MATRIX 0
#define PRINT_SHADERS 0
#define SKIP_CACHE_CHECK true
#define GR_UINT32_MAX static_cast<uint32_t>(-1)
-#if ATTRIBUTE_MATRIX
-#define VIEWMAT_ATTR_LOCATION (3 + GrDrawTarget::kMaxTexCoords)
-#define TEXMAT_ATTR_LOCATION(X) (6 + GrDrawTarget::kMaxTexCoords + 3 * (X))
-#define BOGUS_MATRIX_UNI_LOCATION 1000
+#if GR_GL_ATTRIBUTE_MATRICES
+ #define VIEWMAT_ATTR_LOCATION (3 + GrDrawTarget::kMaxTexCoords)
+ #define TEXMAT_ATTR_LOCATION(X) (6 + GrDrawTarget::kMaxTexCoords + 3 * (X))
+ #define BOGUS_MATRIX_UNI_LOCATION 1000
#endif
#include "GrTHashCache.h"
@@ -157,7 +156,7 @@ GrGpuGLShaders::~GrGpuGLShaders() {
}
const GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) {
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
return fHWDrawState.fSamplerStates[stage].getMatrix();
#else
GrAssert(fProgramData);
@@ -166,7 +165,7 @@ const GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) {
}
void GrGpuGLShaders::recordHWSamplerMatrix(int stage, const GrMatrix& matrix) {
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
fHWDrawState.fSamplerStates[stage].setMatrix(matrix);
#else
GrAssert(fProgramData);
@@ -209,7 +208,7 @@ void GrGpuGLShaders::flushViewMatrix() {
m[GrMatrix::kTransY],
m[GrMatrix::kPersp2]
};
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+0, mt+0));
GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+1, mt+3));
GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+2, mt+6));
@@ -241,7 +240,7 @@ void GrGpuGLShaders::flushTextureMatrix(int stage) {
m[GrMatrix::kTransY],
m[GrMatrix::kPersp2]
};
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+0, mt+0));
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+1, mt+3));
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6));
@@ -273,6 +272,51 @@ void GrGpuGLShaders::flushRadial2(int stage) {
unis));
}
+void GrGpuGLShaders::flushColor() {
+ const GrGLProgram::ProgramDesc& desc = fCurrentProgram.getDesc();
+ if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
+ // color will be specified per-vertex as an attribute
+ // invalidate the const vertex attrib color
+ fHWDrawState.fColor = GrColor_ILLEGAL;
+ } else {
+ switch (desc.fColorType) {
+ case GrGLProgram::ProgramDesc::kAttribute_ColorType:
+ if (fHWDrawState.fColor != fCurrDrawState.fColor) {
+ // OpenGL ES only supports the float varities of glVertexAttrib
+ float c[] = {
+ GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackA(fCurrDrawState.fColor) / 255.f
+ };
+ GR_GL(VertexAttrib4fv(COL_ATTR_LOCATION, c));
+ fHWDrawState.fColor = fCurrDrawState.fColor;
+ }
+ break;
+ case GrGLProgram::ProgramDesc::kUniform_ColorType:
+ if (fProgramData->fColor != fCurrDrawState.fColor) {
+ // OpenGL ES only supports the float varities of glVertexAttrib
+ float c[] = {
+ GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackA(fCurrDrawState.fColor) / 255.f
+ };
+ GrAssert(-1 != fProgramData->fUniLocations.fColorUni);
+ GR_GL(Uniform4fv(fProgramData->fUniLocations.fColorUni, 1, c));
+ fProgramData->fColor = fCurrDrawState.fColor;
+ }
+ break;
+ case GrGLProgram::ProgramDesc::kNone_ColorType:
+ GrAssert(0xffffffff == fCurrDrawState.fColor);
+ break;
+ default:
+ GrCrash("Unknown color type.");
+ }
+ }
+}
+
+
bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
if (!flushGLStateCommon(type)) {
return false;
@@ -281,7 +325,7 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
if (fDirtyFlags.fRenderTargetChanged) {
// our coords are in pixel space and the GL matrices map to NDC
// so if the viewport changed, our matrix is now wrong.
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix();
#else
// we assume all shader matrices may be wrong after viewport changes
@@ -289,23 +333,6 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
#endif
}
- if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
- // invalidate the immediate mode color
- fHWDrawState.fColor = GrColor_ILLEGAL;
- } else {
- if (fHWDrawState.fColor != fCurrDrawState.fColor) {
- // OpenGL ES only supports the float varities of glVertexAttrib
- float c[] = {
- GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
- GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
- GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
- GrColorUnpackA(fCurrDrawState.fColor) / 255.f
- };
- GR_GL(VertexAttrib4fv(COL_ATTR_LOCATION, c));
- fHWDrawState.fColor = fCurrDrawState.fColor;
- }
- }
-
buildProgram(type);
fProgramData = fProgramCache->getProgramData(fCurrentProgram, this);
@@ -318,7 +345,9 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
return false;
}
-#if ATTRIBUTE_MATRIX
+ flushColor();
+
+#if GR_GL_ATTRIBUTE_MATRICES
GrMatrix& currViewMatrix = fHWDrawState.fViewMatrix;
#else
GrMatrix& currViewMatrix = fProgramData->fViewMatrix;
@@ -456,22 +485,35 @@ void GrGpuGLShaders::setupGeometry(int* startVertex,
}
void GrGpuGLShaders::buildProgram(GrPrimitiveType type) {
+ GrGLProgram::ProgramDesc& desc = fCurrentProgram.fProgramDesc;
+
// Must initialize all fields or cache will have false negatives!
- fCurrentProgram.fProgramDesc.fVertexLayout = fGeometrySrc.fVertexLayout;
+ desc.fVertexLayout = fGeometrySrc.fVertexLayout;
+
+ desc.fEmitsPointSize = kPoints_PrimitiveType == type;
+
+ bool requiresAttributeColors = desc.fVertexLayout & kColor_VertexLayoutBit;
+ // fColorType records how colors are specified for the program. Strip
+ // the bit from the layout to avoid false negatives when searching for an
+ // existing program in the cache.
+ desc.fVertexLayout &= ~(kColor_VertexLayoutBit);
- fCurrentProgram.fProgramDesc.fOptFlags = 0;
- if (kPoints_PrimitiveType != type) {
- fCurrentProgram.fProgramDesc.fOptFlags |= GrGLProgram::ProgramDesc::kNotPoints_OptFlagBit;
- }
#if GR_AGGRESSIVE_SHADER_OPTS
- if (!(fCurrentProgram.fProgramDesc.fVertexLayout & kColor_VertexLayoutBit) &&
- (0xffffffff == fCurrDrawState.fColor)) {
- fCurrentProgram.fProgramDesc.fOptFlags |= GrGLProgram::ProgramDesc::kVertexColorAllOnes_OptFlagBit;
- }
+ if (!requiresAttributeColors && (0xffffffff == fCurrDrawState.fColor)) {
+ desc.fColorType = ProgramDesc::kNone_ColorType;
+ } else
+#endif
+#if GR_GL_NO_CONSTANT_ATTRIBUTES
+ if (!requiresAttributeColors) {
+ desc.fColorType = GrGLProgram::ProgramDesc::kUniform_ColorType;
+ } else
#endif
+ {
+ desc.fColorType = GrGLProgram::ProgramDesc::kAttribute_ColorType;
+ }
for (int s = 0; s < kNumStages; ++s) {
- GrGLProgram::ProgramDesc::StageDesc& stage = fCurrentProgram.fProgramDesc.fStages[s];
+ GrGLProgram::ProgramDesc::StageDesc& stage = desc.fStages[s];
stage.fEnabled = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
diff --git a/gpu/src/GrGpuGLShaders.h b/gpu/src/GrGpuGLShaders.h
index ee29533d56..92aab6ce44 100644
--- a/gpu/src/GrGpuGLShaders.h
+++ b/gpu/src/GrGpuGLShaders.h
@@ -51,6 +51,9 @@ private:
// sets the texture matrix uniform for currently bound program
void flushTextureMatrix(int stage);
+ // sets the color specified by GrDrawTarget::setColor()
+ void flushColor();
+
// sets the MVP matrix uniform for currently bound program
void flushViewMatrix();
diff --git a/gpu/src/GrGpuGLShaders2.cpp b/gpu/src/GrGpuGLShaders2.cpp
index 4deecd4279..94b941fc09 100644
--- a/gpu/src/GrGpuGLShaders2.cpp
+++ b/gpu/src/GrGpuGLShaders2.cpp
@@ -22,20 +22,17 @@
#include "GrMemory.h"
#include "GrStringBuilder.h"
-
-#define ATTRIBUTE_MATRIX 0
-
#define PRINT_SHADERS 0
-#define SKIP_CACHE_CHECK true
+#define SKIP_CACHE_CHECK true
#define POS_ATTR_LOCATION 0
#define TEX_ATTR_LOCATION(X) (1 + X)
#define COL_ATTR_LOCATION (2 + GrDrawTarget::kMaxTexCoords)
-#if ATTRIBUTE_MATRIX
-#define VIEWMAT_ATTR_LOCATION (3 + GrDrawTarget::kMaxTexCoords)
-#define TEXMAT_ATTR_LOCATION(X) (6 + GrDrawTarget::kMaxTexCoords + 3 * (X))
-#define BOGUS_MATRIX_UNI_LOCATION 1000
+#if GR_GL_ATTRIBUTE_MATRICES
+ #define VIEWMAT_ATTR_LOCATION (3 + GrDrawTarget::kMaxTexCoords)
+ #define TEXMAT_ATTR_LOCATION(X) (6 + GrDrawTarget::kMaxTexCoords + 3 * (X))
+ #define BOGUS_MATRIX_UNI_LOCATION 1000
#endif
#define GR_UINT32_MAX static_cast<uint32_t>(-1)
@@ -68,6 +65,7 @@ struct GrGpuGLShaders2::StageUniLocations {
struct GrGpuGLShaders2::UniLocations {
GrGLint fViewMatrixUni;
+ GrGLint fColorUni;
StageUniLocations fStages[kNumStages];
};
@@ -90,6 +88,7 @@ struct GrGpuGLShaders2::Program {
// these reflect the current values of uniforms
// (GL uniform values travel with program)
GrMatrix fViewMatrix;
+ GrColor fColor;
GrMatrix fTextureMatrices[kNumStages];
GrScalar fRadial2CenterX1[kNumStages];
GrScalar fRadial2Radius0[kNumStages];
@@ -122,24 +121,23 @@ struct GrGpuGLShaders2::StageDesc {
// must be tightly packed
struct GrGpuGLShaders2::ProgramDesc {
- GrVertexLayout fVertexLayout;
- GR_STATIC_ASSERT(2 == sizeof(GrVertexLayout)); // pack with next field
+ ProgramDesc() {
+ // since we use this as a key we can't have any unitialized padding
+ memset(this, 0, sizeof(ProgramDesc));
+ }
+ GrVertexLayout fVertexLayout; // stripped of bits that don't affect
+ // program generation.
enum {
- kNotPoints_OptFlagBit = 0x1,
- kVertexColorAllOnes_OptFlagBit = 0x2,
- };
- // we're assuming optflags and layout pack into 32 bits
- // VS 2010 seems to require short rather than just unsigned
- // for this to pack
- unsigned short fOptFlags : 16;
+ kNone_ColorType = 0,
+ kAttribute_ColorType = 1,
+ kUniform_ColorType = 2,
+ } fColorType;
+ bool fEmitsPointSize;
StageDesc fStages[kNumStages];
bool operator == (const ProgramDesc& desc) const {
- // keep 4-byte aligned and tightly packed
- GR_STATIC_ASSERT(4 == sizeof(StageDesc));
- GR_STATIC_ASSERT(2 + 2 + 4 * kNumStages == sizeof(ProgramDesc));
return 0 == memcmp(this, &desc, sizeof(ProgramDesc));
}
};
@@ -239,21 +237,29 @@ public:
GrGpuGLShaders2::ProgramCache::HashKey::HashKey() {
}
-static uint32_t ror(uint32_t x) {
+static inline uint32_t ror(uint32_t x) {
return (x >> 8) | (x << 24);
}
-static uint32_t rol(uint32_t x) {
+static inline uint32_t rol(uint32_t x) {
return (x << 8) | (x >> 24);
}
+static inline uint32_t roh(uint32_t x) {
+ return (x << 16) | (x >> 16);
+}
+
+static inline uint32_t swapouter(uint32_t x) {
+ return (x & 0x00ff00) | (x << 24) | (x >> 24);
+}
+
GrGpuGLShaders2::ProgramCache::HashKey::HashKey(const ProgramDesc& desc) {
fDesc = desc;
// if you change the size of the desc, need to update the hash function
- GR_STATIC_ASSERT(12 == sizeof(ProgramDesc));
+ GR_STATIC_ASSERT(20 == sizeof(ProgramDesc));
uint32_t* d = GrTCast<uint32_t*>(&fDesc);
- fHash = d[0] ^ ror(d[1]) ^ rol(d[2]);
+ fHash = d[0] ^ ror(d[1]) ^ rol(d[2]) ^ roh(d[3]) ^ swapouter(d[4]);
}
bool GrGpuGLShaders2::ProgramCache::HashKey::EQ(const Entry& entry,
@@ -289,7 +295,7 @@ struct GrGpuGLShaders2::ShaderCodeSegments {
// for variable names etc
typedef GrSStringBuilder<16> GrTokenString;
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
#define VIEW_MATRIX_NAME "aViewM"
#else
#define VIEW_MATRIX_NAME "uViewM"
@@ -297,6 +303,7 @@ typedef GrSStringBuilder<16> GrTokenString;
#define POS_ATTR_NAME "aPosition"
#define COL_ATTR_NAME "aColor"
+#define COL_UNI_NAME "uColor"
static inline void tex_attr_name(int coordIdx, GrStringBuilder* s) {
*s = "aTexCoord";
@@ -328,7 +335,7 @@ static inline const char* vector_all_coords(int count) {
}
static void tex_matrix_name(int stage, GrStringBuilder* s) {
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
*s = "aTexM";
#else
*s = "uTexM";
@@ -359,12 +366,7 @@ static void radial2_varying_name(int stage, GrStringBuilder* s) {
#include "GrRandom.h"
void GrGpuGLShaders2::ProgramUnitTest() {
- static const int PROG_OPTS[] = {
- 0,
- ProgramDesc::kNotPoints_OptFlagBit,
- ProgramDesc::kVertexColorAllOnes_OptFlagBit,
- ProgramDesc::kNotPoints_OptFlagBit | ProgramDesc::kVertexColorAllOnes_OptFlagBit
- };
+
static const int STAGE_OPTS[] = {
0,
StageDesc::kNoPerspective_OptFlagBit,
@@ -391,6 +393,15 @@ void GrGpuGLShaders2::ProgramUnitTest() {
for (int t = 0; t < NUM_TESTS; ++t) {
pdesc.fVertexLayout = 0;
+ pdesc.fEmitsPointSize = random.nextF() > .5f;
+ float colorType = random.nextF();
+ if (colorType < 1.f / 3.f) {
+ pdesc.fColorType = ProgramDesc::kAttribute_ColorType;
+ } else if (colorType < 2.f / 3.f) {
+ pdesc.fColorType = ProgramDesc::kUniform_ColorType;
+ } else {
+ pdesc.fColorType = ProgramDesc::kNone_ColorType;
+ }
for (int s = 0; s < kNumStages; ++s) {
// enable the stage?
if (random.nextF() > .5f) {
@@ -408,9 +419,8 @@ void GrGpuGLShaders2::ProgramUnitTest() {
}
}
- int x = (int)(random.nextF() * GR_ARRAY_COUNT(PROG_OPTS));
- pdesc.fOptFlags = PROG_OPTS[x];
for (int s = 0; s < kNumStages; ++s) {
+ int x;
pdesc.fStages[s].fEnabled = VertexUsesStage(s, pdesc.fVertexLayout);
x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_OPTS));
pdesc.fStages[s].fOptFlags = STAGE_OPTS[x];
@@ -452,7 +462,7 @@ void GrGpuGLShaders2::GenStageCode(int stageNum,
if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
varyingDims = coordDims;
} else {
- #if ATTRIBUTE_MATRIX
+ #if GR_GL_ATTRIBUTE_MATRICES
segments->fVSAttrs += "attribute mat3 ";
segments->fVSAttrs += texMName;
segments->fVSAttrs += ";\n";
@@ -691,34 +701,40 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
memset(&program->fUniLocations, 0, sizeof(UniLocations));
- bool haveColor = !(ProgramDesc::kVertexColorAllOnes_OptFlagBit &
- desc.fOptFlags);
-
-#if ATTRIBUTE_MATRIX
- segments.fVSAttrs = "attribute mat3 " VIEW_MATRIX_NAME ";\n";
+#if GR_GL_ATTRIBUTE_MATRICES
+ segments.fVSAttrs += "attribute mat3 " VIEW_MATRIX_NAME ";\n";
#else
- segments.fVSUnis = "uniform mat3 " VIEW_MATRIX_NAME ";\n";
- segments.fVSAttrs = "";
+ segments.fVSUnis += "uniform mat3 " VIEW_MATRIX_NAME ";\n";
#endif
segments.fVSAttrs += "attribute vec2 " POS_ATTR_NAME ";\n";
- if (haveColor) {
- segments.fVSAttrs += "attribute vec4 " COL_ATTR_NAME ";\n";
- segments.fVaryings = "varying vec4 vColor;\n";
- } else {
- segments.fVaryings = "";
- }
- segments.fVSCode = "void main() {\n"
- "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3(" POS_ATTR_NAME ", 1);\n"
- "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n";
- if (haveColor) {
+ segments.fVSCode += "void main() {\n"
+ "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3(" POS_ATTR_NAME ", 1);\n"
+ "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n";
+
+ // incoming color to current stage being processed.
+ GrTokenString inColor;
+
+ switch (desc.fColorType) {
+ case ProgramDesc::kAttribute_ColorType:
+ segments.fVSAttrs += "attribute vec4 " COL_ATTR_NAME ";\n";
+ segments.fVaryings += "varying vec4 vColor;\n";
segments.fVSCode += "\tvColor = " COL_ATTR_NAME ";\n";
+ inColor = "vColor";
+ break;
+ case ProgramDesc::kUniform_ColorType:
+ segments.fFSUnis += "uniform vec4 " COL_UNI_NAME ";\n";
+ inColor = COL_UNI_NAME;
+ break;
+ case ProgramDesc::kNone_ColorType:
+ inColor = "";
+ break;
}
- if (!(desc.fOptFlags & ProgramDesc::kNotPoints_OptFlagBit)){
+ if (desc.fEmitsPointSize){
segments.fVSCode += "\tgl_PointSize = 1.0;\n";
}
- segments.fFSCode = "void main() {\n";
+ segments.fFSCode += "void main() {\n";
// add texture coordinates that are used to the list of vertex attr decls
GrTokenString texCoordAttrs[kMaxTexCoords];
@@ -752,8 +768,6 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
}
}
- GrTokenString inColor = "vColor";
-
// if we have active stages string them together, feeding the output color
// of each to the next and generating code for each stage.
if (numActiveStages) {
@@ -772,19 +786,18 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
}
GenStageCode(s,
desc.fStages[s],
- haveColor ? inColor.cstr() : NULL,
+ inColor.length() ? inColor.cstr() : NULL,
outColor.cstr(),
stageInCoords[s],
&segments,
&program->fUniLocations.fStages[s]);
++currActiveStage;
inColor = outColor;
- haveColor = true;
}
}
} else {
segments.fFSCode += "\tgl_FragColor = ";
- if (haveColor) {
+ if (inColor.length()) {
segments.fFSCode += inColor;
} else {
segments.fFSCode += "vec4(1,1,1,1)";
@@ -883,7 +896,7 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
}
}
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
// set unis to a bogus value so that checks against -1 before
// flushing will pass.
GR_GL(BindAttribLocation(progID,
@@ -929,15 +942,23 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
}
// Get uniform locations
-#if !ATTRIBUTE_MATRIX
+#if !GR_GL_ATTRIBUTE_MATRICES
program->fUniLocations.fViewMatrixUni =
GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME));
GrAssert(-1 != program->fUniLocations.fViewMatrixUni);
#endif
+ if (ProgramDesc::kUniform_ColorType == desc.fColorType) {
+ program->fUniLocations.fColorUni =
+ GR_GL(GetUniformLocation(progID, COL_UNI_NAME));
+ GrAssert(-1 != program->fUniLocations.fColorUni);
+ } else {
+ program->fUniLocations.fColorUni = -1;
+ }
+
for (int s = 0; s < kNumStages; ++s) {
StageUniLocations& locations = program->fUniLocations.fStages[s];
if (desc.fStages[s].fEnabled) {
-#if !ATTRIBUTE_MATRIX
+#if !GR_GL_ATTRIBUTE_MATRICES
if (locations.fTextureMatrixUni) {
GrTokenString texMName;
tex_matrix_name(s, &texMName);
@@ -988,6 +1009,7 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
program->fTextureMatrices[s] = GrMatrix::InvalidMatrix();
program->fRadial2CenterX1[s] = GR_ScalarMax;
program->fRadial2Radius0[s] = -GR_ScalarMax;
+ program->fColor = GrColor_ILLEGAL;
}
program->fViewMatrix = GrMatrix::InvalidMatrix();
}
@@ -997,16 +1019,27 @@ void GrGpuGLShaders2::getProgramDesc(GrPrimitiveType primType, ProgramDesc* desc
// Must initialize all fields or cache will have false negatives!
desc->fVertexLayout = fGeometrySrc.fVertexLayout;
- desc->fOptFlags = 0;
- if (kPoints_PrimitiveType != primType) {
- desc->fOptFlags |= ProgramDesc::kNotPoints_OptFlagBit;
- }
+ desc->fEmitsPointSize = kPoints_PrimitiveType == primType;
+
+ bool requiresAttributeColors = desc->fVertexLayout & kColor_VertexLayoutBit;
+ // fColorType records how colors are specified for the program. Strip
+ // the bit from the layout to avoid false negatives when searching for an
+ // existing program in the cache.
+ desc->fVertexLayout &= ~(kColor_VertexLayoutBit);
+
#if GR_AGGRESSIVE_SHADER_OPTS
- if (!(desc->fVertexLayout & kColor_VertexLayoutBit) &&
- (0xffffffff == fCurrDrawState.fColor)) {
- desc->fOptFlags |= ProgramDesc::kVertexColorAllOnes_OptFlagBit;
- }
+ if (!requiresAttributeColors && (0xffffffff == fCurrDrawState.fColor)) {
+ desc->fColorType = ProgramDesc::kNone_ColorType;
+ } else
#endif
+#if GR_GL_NO_CONSTANT_ATTRIBUTES
+ if (!requiresAttributeColors) {
+ desc->fColorType = ProgramDesc::kUniform_ColorType;
+ } else
+#endif
+ {
+ desc->fColorType = ProgramDesc::kAttribute_ColorType;
+ }
for (int s = 0; s < kNumStages; ++s) {
StageDesc& stage = desc->fStages[s];
@@ -1114,7 +1147,7 @@ GrGpuGLShaders2::~GrGpuGLShaders2() {
}
const GrMatrix& GrGpuGLShaders2::getHWSamplerMatrix(int stage) {
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
return fHWDrawState.fSamplerStates[stage].getMatrix();
#else
return fProgram->fTextureMatrices[stage];
@@ -1122,7 +1155,7 @@ const GrMatrix& GrGpuGLShaders2::getHWSamplerMatrix(int stage) {
}
void GrGpuGLShaders2::recordHWSamplerMatrix(int stage, const GrMatrix& matrix){
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
fHWDrawState.fSamplerStates[stage].setMatrix(matrix);
#else
fProgram->fTextureMatrices[stage] = matrix;
@@ -1165,7 +1198,7 @@ void GrGpuGLShaders2::flushViewMatrix() {
m[GrMatrix::kTransY],
m[GrMatrix::kPersp2]
};
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+0, mt+0));
GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+1, mt+3));
GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+2, mt+6));
@@ -1197,7 +1230,7 @@ void GrGpuGLShaders2::flushTextureMatrix(int stage) {
m[GrMatrix::kTransY],
m[GrMatrix::kPersp2]
};
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+0, mt+0));
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+1, mt+3));
GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6));
@@ -1229,10 +1262,9 @@ void GrGpuGLShaders2::flushRadial2(int stage) {
unis));
}
-void GrGpuGLShaders2::flushProgram(GrPrimitiveType type) {
- ProgramDesc desc;
- getProgramDesc(type, &desc);
- fProgram = fProgramCache->getProgram(desc);
+void GrGpuGLShaders2::flushProgram(GrPrimitiveType type, ProgramDesc* desc) {
+ getProgramDesc(type, desc);
+ fProgram = fProgramCache->getProgram(*desc);
if (fHWProgramID != fProgram->fProgramID) {
GR_GL(UseProgram(fProgram->fProgramID));
@@ -1243,6 +1275,49 @@ void GrGpuGLShaders2::flushProgram(GrPrimitiveType type) {
}
}
+void GrGpuGLShaders2::flushColor(const ProgramDesc& desc) {
+ if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
+ // color will be specified per-vertex as an attribute
+ // invalidate the const vertex attrib color
+ fHWDrawState.fColor = GrColor_ILLEGAL;
+ } else {
+ switch (desc.fColorType) {
+ case ProgramDesc::kAttribute_ColorType:
+ if (fHWDrawState.fColor != fCurrDrawState.fColor) {
+ // OpenGL ES only supports the float varities of glVertexAttrib
+ float c[] = {
+ GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackA(fCurrDrawState.fColor) / 255.f
+ };
+ GR_GL(VertexAttrib4fv(COL_ATTR_LOCATION, c));
+ fHWDrawState.fColor = fCurrDrawState.fColor;
+ }
+ break;
+ case ProgramDesc::kUniform_ColorType:
+ if (fProgram->fColor != fCurrDrawState.fColor) {
+ // OpenGL ES only supports the float varities of glVertexAttrib
+ float c[] = {
+ GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
+ GrColorUnpackA(fCurrDrawState.fColor) / 255.f
+ };
+ GrAssert(-1 != fProgram->fUniLocations.fColorUni);
+ GR_GL(Uniform4fv(fProgram->fUniLocations.fColorUni, 1, c));
+ fProgram->fColor = fCurrDrawState.fColor;
+ }
+ break;
+ case ProgramDesc::kNone_ColorType:
+ GrAssert(0xffffffff == fCurrDrawState.fColor);
+ break;
+ default:
+ GrCrash("Unknown color type.");
+ }
+ }
+}
+
bool GrGpuGLShaders2::flushGraphicsState(GrPrimitiveType type) {
if (!flushGLStateCommon(type)) {
@@ -1252,7 +1327,7 @@ bool GrGpuGLShaders2::flushGraphicsState(GrPrimitiveType type) {
if (fDirtyFlags.fRenderTargetChanged) {
// our coords are in pixel space and the GL matrices map to NDC
// so if the viewport changed, our matrix is now wrong.
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix();
#else
// we assume all shader matrices may be wrong after viewport changes
@@ -1260,29 +1335,12 @@ bool GrGpuGLShaders2::flushGraphicsState(GrPrimitiveType type) {
#endif
}
- flushProgram(type);
+ ProgramDesc desc;
+ flushProgram(type, &desc);
- if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
- // invalidate the immediate mode color
- fHWDrawState.fColor = GrColor_ILLEGAL;
- } else {
- if (fHWDrawState.fColor != fCurrDrawState.fColor &&
- (!GR_AGGRESSIVE_SHADER_OPTS || 0xffffffff != fCurrDrawState.fColor)) {
- // avoid pushing the color attrib if the shader will optimize it out
-
- // OpenGL ES only supports the float varities of glVertexAttrib
- float c[] = {
- GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
- GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
- GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
- GrColorUnpackA(fCurrDrawState.fColor) / 255.f
- };
- GR_GL(VertexAttrib4fv(COL_ATTR_LOCATION, c));
- fHWDrawState.fColor = fCurrDrawState.fColor;
- }
- }
+ flushColor(desc);
-#if ATTRIBUTE_MATRIX
+#if GR_GL_ATTRIBUTE_MATRICES
GrMatrix& currViewMatrix = fHWDrawState.fViewMatrix;
#else
GrMatrix& currViewMatrix = fProgram->fViewMatrix;
diff --git a/gpu/src/GrGpuGLShaders2.h b/gpu/src/GrGpuGLShaders2.h
index b9a019b79b..205f9afedd 100644
--- a/gpu/src/GrGpuGLShaders2.h
+++ b/gpu/src/GrGpuGLShaders2.h
@@ -36,6 +36,19 @@ protected:
private:
+ struct Program;
+
+ struct StageDesc;
+ struct ProgramDesc;
+
+ struct UniLocations;
+ struct StageUniLocations;
+
+ struct ShaderCodeSegments;
+
+ class ProgramCache;
+
+ // GrGpu override
virtual void resetContext();
// Helpers to make code more readable
@@ -51,20 +64,12 @@ private:
// flushes the parameters to two point radial gradient
void flushRadial2(int stage);
- // called at flush time to setup the appropriate program
- void flushProgram(GrPrimitiveType type);
+ // called at flush time to setup the appropriate program, also returns
+ // the program description.
+ void flushProgram(GrPrimitiveType type, ProgramDesc* desc);
- struct Program;
-
- struct StageDesc;
- struct ProgramDesc;
-
- struct UniLocations;
- struct StageUniLocations;
-
- struct ShaderCodeSegments;
-
- class ProgramCache;
+ // called at flush time to handle the color specified by setColor()
+ void flushColor(const ProgramDesc& desc);
// gets a description of needed shader
void getProgramDesc(GrPrimitiveType primType, ProgramDesc* desc);
@@ -93,7 +98,7 @@ private:
ProgramCache* fProgramCache;
Program* fProgram;
- GrGLuint fHWProgramID;
+ GrGLuint fHWProgramID;
typedef GrGpuGL INHERITED;
};