Index: src/gpu/gl/GrGLUniform.cpp |
diff --git a/src/gpu/gl/GrGLUniform.cpp b/src/gpu/gl/GrGLUniform.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..17cca2cbef473647ac3fadd63a1b03bff617aacf |
--- /dev/null |
+++ b/src/gpu/gl/GrGLUniform.cpp |
@@ -0,0 +1,236 @@ |
+/* |
+ * Copyright 2012 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "gl/GrGLShaderBuilder.h" |
+#include "gl/GrGLProgram.h" |
+#include "SkMatrix.h" |
+ |
+#define ASSERT_ARRAY_UPLOAD_IN_BOUNDS(OFFSET, COUNT) \ |
+ GrAssert(offset + arrayCount <= fArrayCount || \ |
+ (0 == offset && 1 == arrayCount && GrGLShaderVar::kNonArray == fArrayCount)) |
+ |
+void GrGLUniform::initLocations(const GrGLContext& context, GrGLuint programID, const char* name, uint32_t visibility) { |
+ GrGLint location; |
+ // TODO: Move the Xoom uniform array in both FS and VS bug workaround here. |
+ GR_GL_CALL_RET(context.interface(), location, GetUniformLocation(programID, name)); |
+ if (GrGLShaderBuilder::kVertex_ShaderType & visibility) { |
+ fVSLocation = location; |
+ } |
+ if (GrGLShaderBuilder::kFragment_ShaderType & visibility) { |
+ fFSLocation = location; |
+ } |
+} |
+ |
+void GrGLUniform::setSampler(const GrGLContext& context, GrGLint texUnit) const { |
+ GrAssert(fType == kSampler2D_GrSLType); |
+ GrAssert(GrGLShaderVar::kNonArray == fArrayCount); |
+ // FIXME: We still insert a single sampler uniform for every stage. If the shader does not |
+ // reference the sampler then the compiler may have optimized it out. Uncomment this assert |
+ // once stages insert their own samplers. |
+ // GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform1i(fFSLocation, texUnit)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform1i(fVSLocation, texUnit)); |
+ } |
+} |
+ |
+void GrGLUniform::set1f(const GrGLContext& context, GrGLfloat v0) const { |
+ GrAssert(fType == kFloat_GrSLType); |
+ GrAssert(GrGLShaderVar::kNonArray == fArrayCount); |
+ GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform1f(fFSLocation, v0)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform1f(fVSLocation, v0)); |
+ } |
+} |
+ |
+void GrGLUniform::set1fv(const GrGLContext& context, |
+ int offset, |
+ int arrayCount, |
+ const GrGLfloat v[]) const { |
+ GrAssert(fType == kFloat_GrSLType); |
+ GrAssert(arrayCount > 0); |
+ ASSERT_ARRAY_UPLOAD_IN_BOUNDS(offset, arrayCount); |
+ // This assert fires in some instances of the two-pt gradient for its VSParams. |
+ // Once the uniform is responsible for inserting the duplicate uniform |
+ // arrays in VS and FS driver bug workaround, this can be enabled. |
+ //GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform1fv(fFSLocation + offset, arrayCount, v)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform1fv(fVSLocation + offset, arrayCount, v)); |
+ } |
+} |
+ |
+void GrGLUniform::set2f(const GrGLContext& context, GrGLfloat v0, GrGLfloat v1) const { |
+ GrAssert(fType == kVec2f_GrSLType); |
+ GrAssert(GrGLShaderVar::kNonArray == fArrayCount); |
+ GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform2f(fFSLocation, v0, v1)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform2f(fVSLocation, v0, v1)); |
+ } |
+} |
+ |
+void GrGLUniform::set2fv(const GrGLContext& context, |
+ int offset, |
+ int arrayCount, |
+ const GrGLfloat v[]) const { |
+ GrAssert(fType == kVec2f_GrSLType); |
+ GrAssert(arrayCount > 0); |
+ ASSERT_ARRAY_UPLOAD_IN_BOUNDS(offset, arrayCount); |
+ GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform2fv(fFSLocation + offset, arrayCount, v)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform2fv(fVSLocation + offset, arrayCount, v)); |
+ } |
+} |
+ |
+void GrGLUniform::set3f(const GrGLContext& context, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) const { |
+ GrAssert(fType == kVec3f_GrSLType); |
+ GrAssert(GrGLShaderVar::kNonArray == fArrayCount); |
+ GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform3f(fFSLocation, v0, v1, v2)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform3f(fVSLocation, v0, v1, v2)); |
+ } |
+} |
+ |
+void GrGLUniform::set3fv(const GrGLContext& context, |
+ int offset, |
+ int arrayCount, |
+ const GrGLfloat v[]) const { |
+ GrAssert(fType == kVec3f_GrSLType); |
+ GrAssert(arrayCount > 0); |
+ ASSERT_ARRAY_UPLOAD_IN_BOUNDS(offset, arrayCount); |
+ GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform3fv(fFSLocation + offset, arrayCount, v)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform3fv(fVSLocation + offset, arrayCount, v)); |
+ } |
+} |
+ |
+void GrGLUniform::set4f(const GrGLContext& context, |
+ GrGLfloat v0, |
+ GrGLfloat v1, |
+ GrGLfloat v2, |
+ GrGLfloat v3) const { |
+ GrAssert(fType == kVec4f_GrSLType); |
+ GrAssert(GrGLShaderVar::kNonArray == fArrayCount); |
+ GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform4f(fFSLocation, v0, v1, v2, v3)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform4f(fVSLocation, v0, v1, v2, v3)); |
+ } |
+} |
+ |
+void GrGLUniform::set4fv(const GrGLContext& context, |
+ int offset, |
+ int arrayCount, |
+ const GrGLfloat v[]) const { |
+ GrAssert(fType == kVec4f_GrSLType); |
+ GrAssert(arrayCount > 0); |
+ GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform4fv(fFSLocation + offset, arrayCount, v)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), Uniform4fv(fVSLocation + offset, arrayCount, v)); |
+ } |
+} |
+ |
+void GrGLUniform::setMatrix3f(const GrGLContext& context, const GrGLfloat matrix[]) const { |
+ GrAssert(fType == kMat33f_GrSLType); |
+ GrAssert(GrGLShaderVar::kNonArray == fArrayCount); |
+ // TODO: Re-enable this assert once texture matrices aren't forced on all effects |
+ // GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), UniformMatrix3fv(fFSLocation, 1, false, matrix)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), UniformMatrix3fv(fVSLocation, 1, false, matrix)); |
+ } |
+} |
+ |
+void GrGLUniform::setMatrix4f(const GrGLContext& context, const GrGLfloat matrix[]) const { |
+ GrAssert(fType == kMat44f_GrSLType); |
+ GrAssert(GrGLShaderVar::kNonArray == fArrayCount); |
+ GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), UniformMatrix4fv(fFSLocation, 1, false, matrix)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), UniformMatrix4fv(fVSLocation, 1, false, matrix)); |
+ } |
+} |
+ |
+void GrGLUniform::setMatrix3fv(const GrGLContext& context, |
+ int offset, |
+ int arrayCount, |
+ const GrGLfloat matrices[]) const { |
+ GrAssert(fType == kMat33f_GrSLType); |
+ GrAssert(arrayCount > 0); |
+ ASSERT_ARRAY_UPLOAD_IN_BOUNDS(offset, arrayCount); |
+ GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), |
+ UniformMatrix3fv(fFSLocation + offset, arrayCount, false, matrices)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), |
+ UniformMatrix3fv(fVSLocation + offset, arrayCount, false, matrices)); |
+ } |
+} |
+ |
+void GrGLUniform::setMatrix4fv(const GrGLContext& context, |
+ int offset, |
+ int arrayCount, |
+ const GrGLfloat matrices[]) const { |
+ GrAssert(fType == kMat44f_GrSLType); |
+ GrAssert(arrayCount > 0); |
+ ASSERT_ARRAY_UPLOAD_IN_BOUNDS(offset, arrayCount); |
+ GrAssert(kUnusedUniform != fFSLocation || kUnusedUniform != fVSLocation); |
+ if (kUnusedUniform != fFSLocation) { |
+ GR_GL_CALL(context.interface(), |
+ UniformMatrix4fv(fFSLocation + offset, arrayCount, false, matrices)); |
+ } |
+ if (kUnusedUniform != fVSLocation && fVSLocation != fFSLocation) { |
+ GR_GL_CALL(context.interface(), |
+ UniformMatrix4fv(fVSLocation + offset, arrayCount, false, matrices)); |
+ } |
+} |
+ |
+void GrGLUniform::setSkMatrix(const GrGLContext& context, const SkMatrix& matrix) const { |
+// GR_STATIC_ASSERT(SK_SCALAR_IS_FLOAT); |
+ GrGLfloat mt[] = { |
+ matrix.get(SkMatrix::kMScaleX), |
+ matrix.get(SkMatrix::kMSkewY), |
+ matrix.get(SkMatrix::kMPersp0), |
+ matrix.get(SkMatrix::kMSkewX), |
+ matrix.get(SkMatrix::kMScaleY), |
+ matrix.get(SkMatrix::kMPersp1), |
+ matrix.get(SkMatrix::kMTransX), |
+ matrix.get(SkMatrix::kMTransY), |
+ matrix.get(SkMatrix::kMPersp2), |
+ }; |
+ this->setMatrix3f(context, mt); |
+} |