| 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);
|
| +}
|
|
|