diff options
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/include/GrConfig.h | 2 | ||||
-rw-r--r-- | gpu/include/GrDrawTarget.h | 2 | ||||
-rw-r--r-- | gpu/include/GrGLConfig.h | 33 | ||||
-rw-r--r-- | gpu/include/GrGLConfig_chrome.h | 7 | ||||
-rw-r--r-- | gpu/include/GrTypes.h | 2 | ||||
-rw-r--r-- | gpu/src/GrGLProgram.cpp | 65 | ||||
-rw-r--r-- | gpu/src/GrGLProgram.h | 24 | ||||
-rw-r--r-- | gpu/src/GrGpuGLShaders.cpp | 118 | ||||
-rw-r--r-- | gpu/src/GrGpuGLShaders.h | 3 | ||||
-rw-r--r-- | gpu/src/GrGpuGLShaders2.cpp | 258 | ||||
-rw-r--r-- | gpu/src/GrGpuGLShaders2.h | 33 |
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; }; |