b=951799, cache uniforms in OGLShaderProgram, part 1; r=bjacob

This commit is contained in:
Vladimir Vukicevic 2014-01-29 17:53:37 -05:00
parent a18d495121
commit 0fec1fd861
2 changed files with 237 additions and 132 deletions

View File

@ -21,23 +21,44 @@ namespace layers {
typedef ProgramProfileOGL::Argument Argument;
// helper methods for GetProfileFor
void
AddUniforms(ProgramProfileOGL& aProfile)
{
static const char *sKnownUniformNames[] = {
"uLayerTransform",
"uMaskQuadTransform",
"uLayerQuadTransform",
"uMatrixProj",
"uTextureTransform",
"uRenderTargetOffset",
"uLayerOpacity",
"uTexture",
"uYTexture",
"uCbTexture",
"uCrTexture",
"uBlackTexture",
"uWhiteTexture",
"uMaskTexture",
"uRenderColor",
"uTexCoordMultiplier",
nullptr
};
for (int i = 0; sKnownUniformNames[i] != nullptr; ++i) {
aProfile.mUniforms[i].mNameString = sKnownUniformNames[i];
aProfile.mUniforms[i].mName = (KnownUniform::KnownUniformName) i;
}
}
void
AddCommonArgs(ProgramProfileOGL& aProfile)
{
aProfile.mUniforms.AppendElement(Argument("uLayerTransform"));
aProfile.mUniforms.AppendElement(Argument("uLayerQuadTransform"));
aProfile.mUniforms.AppendElement(Argument("uMatrixProj"));
aProfile.mHasMatrixProj = true;
aProfile.mUniforms.AppendElement(Argument("uRenderTargetOffset"));
aProfile.mAttributes.AppendElement(Argument("aVertexCoord"));
}
void
AddCommonTextureArgs(ProgramProfileOGL& aProfile)
{
aProfile.mUniforms.AppendElement(Argument("uLayerOpacity"));
aProfile.mUniforms.AppendElement(Argument("uTexture"));
aProfile.mUniforms.AppendElement(Argument("uTextureTransform"));
aProfile.mAttributes.AppendElement(Argument("aTexCoord"));
}
@ -48,6 +69,8 @@ ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
NS_ASSERTION(ProgramExists(aType, aMask), "Invalid program type.");
ProgramProfileOGL result;
AddUniforms(result);
switch (aType) {
case RGBALayerProgramType:
if (aMask == Mask3d) {
@ -162,7 +185,6 @@ ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
result.mFragmentShaderString = sSolidColorLayerFS;
}
AddCommonArgs(result);
result.mUniforms.AppendElement(Argument("uRenderColor"));
break;
case YCbCrLayerProgramType:
if (aMask == Mask2d) {
@ -173,11 +195,6 @@ ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
result.mFragmentShaderString = sYCbCrTextureLayerFS;
}
AddCommonArgs(result);
result.mUniforms.AppendElement(Argument("uLayerOpacity"));
result.mUniforms.AppendElement(Argument("uYTexture"));
result.mUniforms.AppendElement(Argument("uCbTexture"));
result.mUniforms.AppendElement(Argument("uCrTexture"));
result.mUniforms.AppendElement(Argument("uTextureTransform"));
result.mAttributes.AppendElement(Argument("aTexCoord"));
result.mTextureCount = 3;
break;
@ -190,10 +207,6 @@ ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
result.mFragmentShaderString = sComponentPass1FS;
}
AddCommonArgs(result);
result.mUniforms.AppendElement(Argument("uLayerOpacity"));
result.mUniforms.AppendElement(Argument("uBlackTexture"));
result.mUniforms.AppendElement(Argument("uWhiteTexture"));
result.mUniforms.AppendElement(Argument("uTextureTransform"));
result.mAttributes.AppendElement(Argument("aTexCoord"));
result.mTextureCount = 2;
break;
@ -206,10 +219,6 @@ ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
result.mFragmentShaderString = sComponentPass1RGBFS;
}
AddCommonArgs(result);
result.mUniforms.AppendElement(Argument("uLayerOpacity"));
result.mUniforms.AppendElement(Argument("uBlackTexture"));
result.mUniforms.AppendElement(Argument("uWhiteTexture"));
result.mUniforms.AppendElement(Argument("uTextureTransform"));
result.mAttributes.AppendElement(Argument("aTexCoord"));
result.mTextureCount = 2;
break;
@ -222,10 +231,6 @@ ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
result.mFragmentShaderString = sComponentPass2FS;
}
AddCommonArgs(result);
result.mUniforms.AppendElement(Argument("uLayerOpacity"));
result.mUniforms.AppendElement(Argument("uBlackTexture"));
result.mUniforms.AppendElement(Argument("uWhiteTexture"));
result.mUniforms.AppendElement(Argument("uTextureTransform"));
result.mAttributes.AppendElement(Argument("aTexCoord"));
result.mTextureCount = 2;
break;
@ -238,10 +243,6 @@ ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
result.mFragmentShaderString = sComponentPass2RGBFS;
}
AddCommonArgs(result);
result.mUniforms.AppendElement(Argument("uLayerOpacity"));
result.mUniforms.AppendElement(Argument("uBlackTexture"));
result.mUniforms.AppendElement(Argument("uWhiteTexture"));
result.mUniforms.AppendElement(Argument("uTextureTransform"));
result.mAttributes.AppendElement(Argument("aTexCoord"));
result.mTextureCount = 2;
break;
@ -249,8 +250,6 @@ ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
NS_ASSERTION(!aMask, "Program does not have masked variant.");
result.mVertexShaderString = sCopyVS;
result.mFragmentShaderString = sCopy2DFS;
result.mUniforms.AppendElement(Argument("uTexture"));
result.mUniforms.AppendElement(Argument("uTextureTransform"));
result.mAttributes.AppendElement(Argument("aVertexCoord"));
result.mAttributes.AppendElement(Argument("aTexCoord"));
result.mTextureCount = 1;
@ -259,8 +258,6 @@ ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
NS_ASSERTION(!aMask, "Program does not have masked variant.");
result.mVertexShaderString = sCopyVS;
result.mFragmentShaderString = sCopy2DRectFS;
result.mUniforms.AppendElement(Argument("uTexture"));
result.mUniforms.AppendElement(Argument("uTextureTransform"));
result.mAttributes.AppendElement(Argument("aVertexCoord"));
result.mAttributes.AppendElement(Argument("aTexCoord"));
result.mTextureCount = 1;
@ -270,8 +267,6 @@ ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
}
if (aMask > MaskNone) {
result.mUniforms.AppendElement(Argument("uMaskTexture"));
result.mUniforms.AppendElement(Argument("uMaskQuadTransform"));
result.mTextureCount += 1;
}
@ -287,7 +282,8 @@ ShaderProgramOGL::ShaderProgramOGL(GLContext* aGL, const ProgramProfileOGL& aPro
, mProgram(0)
, mProfile(aProfile)
, mProgramState(STATE_NEW)
{}
{
}
ShaderProgramOGL::~ShaderProgramOGL()
{
@ -316,10 +312,9 @@ ShaderProgramOGL::Initialize()
mProgramState = STATE_OK;
for (uint32_t i = 0; i < mProfile.mUniforms.Length(); ++i) {
for (uint32_t i = 0; i < KnownUniform::KnownUniformCount; ++i) {
mProfile.mUniforms[i].mLocation =
mGL->fGetUniformLocation(mProgram, mProfile.mUniforms[i].mName);
NS_ASSERTION(mProfile.mUniforms[i].mLocation >= 0, "Bad uniform location.");
mGL->fGetUniformLocation(mProgram, mProfile.mUniforms[i].mNameString);
}
for (uint32_t i = 0; i < mProfile.mAttributes.Length(); ++i) {
@ -328,10 +323,6 @@ ShaderProgramOGL::Initialize()
NS_ASSERTION(mProfile.mAttributes[i].mLocation >= 0, "Bad attribute location.");
}
// this is a one-off that's present in the 2DRect versions of some shaders.
mTexCoordMultiplierUniformLocation =
mGL->fGetUniformLocation(mProgram, "uTexCoordMultiplier");
return true;
}
@ -456,72 +447,90 @@ ShaderProgramOGL::Activate()
void
ShaderProgramOGL::SetUniform(GLint aLocation, float aFloatValue)
ShaderProgramOGL::SetUniform(KnownUniform::KnownUniformName aKnownUniform, float aFloatValue)
{
ASSERT_THIS_PROGRAM;
NS_ASSERTION(aLocation >= 0, "Invalid location");
NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
mGL->fUniform1f(aLocation, aFloatValue);
KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
if (ku.UpdateUniform(aFloatValue)) {
mGL->fUniform1f(ku.mLocation, aFloatValue);
}
}
void
ShaderProgramOGL::SetUniform(GLint aLocation, const gfxRGBA& aColor)
ShaderProgramOGL::SetUniform(KnownUniform::KnownUniformName aKnownUniform, const gfxRGBA& aColor)
{
ASSERT_THIS_PROGRAM;
NS_ASSERTION(aLocation >= 0, "Invalid location");
NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
mGL->fUniform4f(aLocation, float(aColor.r), float(aColor.g), float(aColor.b), float(aColor.a));
KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
if (ku.UpdateUniform(aColor.r, aColor.g, aColor.b, aColor.a)) {
mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v);
}
}
void
ShaderProgramOGL::SetUniform(GLint aLocation, int aLength, float *aFloatValues)
ShaderProgramOGL::SetUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, float *aFloatValues)
{
ASSERT_THIS_PROGRAM;
NS_ASSERTION(aLocation >= 0, "Invalid location");
NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
if (ku.UpdateUniform(aLength, aFloatValues)) {
if (aLength == 1) {
mGL->fUniform1fv(aLocation, 1, aFloatValues);
mGL->fUniform1fv(ku.mLocation, 1, ku.mValue.f16v);
} else if (aLength == 2) {
mGL->fUniform2fv(aLocation, 1, aFloatValues);
mGL->fUniform2fv(ku.mLocation, 1, ku.mValue.f16v);
} else if (aLength == 3) {
mGL->fUniform3fv(aLocation, 1, aFloatValues);
mGL->fUniform3fv(ku.mLocation, 1, ku.mValue.f16v);
} else if (aLength == 4) {
mGL->fUniform4fv(aLocation, 1, aFloatValues);
mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v);
} else {
NS_NOTREACHED("Bogus aLength param");
}
}
void
ShaderProgramOGL::SetUniform(GLint aLocation, GLint aIntValue)
{
ASSERT_THIS_PROGRAM;
NS_ASSERTION(aLocation >= 0, "Invalid location");
mGL->fUniform1i(aLocation, aIntValue);
}
void
ShaderProgramOGL::SetMatrixUniform(GLint aLocation, const gfx3DMatrix& aMatrix)
ShaderProgramOGL::SetUniform(KnownUniform::KnownUniformName aKnownUniform, GLint aIntValue)
{
SetMatrixUniform(aLocation, &aMatrix._11);
ASSERT_THIS_PROGRAM;
NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
if (ku.UpdateUniform(aIntValue)) {
mGL->fUniform1i(ku.mLocation, aIntValue);
}
}
void
ShaderProgramOGL::SetMatrixUniform(GLint aLocation, const float *aFloatValues)
ShaderProgramOGL::SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx3DMatrix& aMatrix)
{
ASSERT_THIS_PROGRAM;
NS_ASSERTION(aLocation >= 0, "Invalid location");
mGL->fUniformMatrix4fv(aLocation, 1, false, aFloatValues);
SetMatrixUniform(aKnownUniform, &aMatrix._11);
}
void
ShaderProgramOGL::SetUniform(GLint aLocation, const gfx::Color& aColor) {
ShaderProgramOGL::SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const float *aFloatValues)
{
ASSERT_THIS_PROGRAM;
NS_ASSERTION(aLocation >= 0, "Invalid location");
NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
mGL->fUniform4f(aLocation, float(aColor.r), float(aColor.g), float(aColor.b), float(aColor.a));
KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
if (ku.UpdateUniform(16, aFloatValues)) {
mGL->fUniformMatrix4fv(ku.mLocation, 1, false, ku.mValue.f16v);
}
}
void
ShaderProgramOGL::SetUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx::Color& aColor) {
ASSERT_THIS_PROGRAM;
NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
if (ku.UpdateUniform(aColor.r, aColor.g, aColor.b, aColor.a)) {
mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v);
}
}

View File

@ -50,6 +50,115 @@ enum ShaderProgramType {
NumProgramTypes
};
class KnownUniform {
public:
enum KnownUniformName {
NotAKnownUniform = -1,
LayerTransform = 0,
MaskQuadTransform,
LayerQuadTransform,
MatrixProj,
TextureTransform,
RenderTargetOffset,
LayerOpacity,
Texture,
YTexture,
CbTexture,
CrTexture,
BlackTexture,
WhiteTexture,
MaskTexture,
RenderColor,
TexCoordMultiplier,
KnownUniformCount
};
KnownUniform()
{
mName = NotAKnownUniform;
mNameString = nullptr;
mLocation = -1;
memset(&mValue, 0, sizeof(mValue));
}
bool UpdateUniform(int32_t i1) {
if (mLocation == -1) return false;
if (mValue.i1 != i1) {
mValue.i1 = i1;
return true;
}
return false;
}
bool UpdateUniform(float f1) {
if (mLocation == -1) return false;
if (mValue.f1 != f1) {
mValue.f1 = f1;
return true;
}
return false;
}
bool UpdateUniform(float f1, float f2) {
if (mLocation == -1) return false;
if (mValue.f16v[0] != f1 ||
mValue.f16v[1] != f2)
{
mValue.f16v[0] = f1;
mValue.f16v[1] = f2;
return true;
}
return false;
}
bool UpdateUniform(float f1, float f2, float f3, float f4) {
if (mLocation == -1) return false;
if (mValue.f16v[0] != f1 ||
mValue.f16v[1] != f2 ||
mValue.f16v[2] != f3 ||
mValue.f16v[3] != f4)
{
mValue.f16v[0] = f1;
mValue.f16v[1] = f2;
mValue.f16v[2] = f3;
mValue.f16v[3] = f4;
return true;
}
return false;
}
bool UpdateUniform(int cnt, const float *fp) {
if (mLocation == -1) return false;
switch (cnt) {
case 1:
case 2:
case 3:
case 4:
case 16:
if (memcmp(mValue.f16v, fp, sizeof(float) * cnt) != 0) {
memcpy(mValue.f16v, fp, sizeof(float) * cnt);
return true;
}
return false;
}
NS_NOTREACHED("cnt must be 1 2 3 4 or 16");
return false;
}
KnownUniformName mName;
const char *mNameString;
int32_t mLocation;
union {
int i1;
float f1;
float f16v[16];
} mValue;
};
static inline ShaderProgramType
ShaderProgramFromSurfaceFormat(gfx::SurfaceFormat aFormat)
{
@ -149,17 +258,6 @@ struct ProgramProfileOGL
* respectively. Returns -1 if the named uniform/attribute does not
* have a location for the shaders represented by this profile.
*/
GLint LookupUniformLocation(const char* aName)
{
for (uint32_t i = 0; i < mUniforms.Length(); ++i) {
if (strcmp(mUniforms[i].mName, aName) == 0) {
return mUniforms[i].mLocation;
}
}
return -1;
}
GLint LookupAttributeLocation(const char* aName)
{
for (uint32_t i = 0; i < mAttributes.Length(); ++i) {
@ -184,7 +282,7 @@ struct ProgramProfileOGL
const char *mVertexShaderString;
const char *mFragmentShaderString;
nsTArray<Argument> mUniforms;
KnownUniform mUniforms[KnownUniform::KnownUniformCount];
nsTArray<Argument> mAttributes;
uint32_t mTextureCount;
bool mHasMatrixProj;
@ -247,7 +345,7 @@ public:
}
GLint GetTexCoordMultiplierUniformLocation() {
return mTexCoordMultiplierUniformLocation;
return mProfile.mUniforms[KnownUniform::TexCoordMultiplier].mLocation;
}
/**
@ -256,11 +354,11 @@ public:
* an assertion.
*/
void SetLayerTransform(const gfx::Matrix4x4& aMatrix) {
SetMatrixUniform(mProfile.LookupUniformLocation("uLayerTransform"), aMatrix);
SetMatrixUniform(KnownUniform::LayerTransform, aMatrix);
}
void SetMaskLayerTransform(const gfx::Matrix4x4& aMatrix) {
SetMatrixUniform(mProfile.LookupUniformLocation("uMaskQuadTransform"), aMatrix);
SetMatrixUniform(KnownUniform::MaskQuadTransform, aMatrix);
}
void SetLayerQuadRect(const nsIntRect& aRect) {
@ -269,7 +367,7 @@ public:
m._22 = float(aRect.height);
m._41 = float(aRect.x);
m._42 = float(aRect.y);
SetMatrixUniform(mProfile.LookupUniformLocation("uLayerQuadTransform"), m);
SetMatrixUniform(KnownUniform::LayerQuadTransform, m);
}
void SetLayerQuadRect(const gfx::Rect& aRect) {
@ -278,7 +376,7 @@ public:
m._22 = aRect.height;
m._41 = aRect.x;
m._42 = aRect.y;
SetMatrixUniform(mProfile.LookupUniformLocation("uLayerQuadTransform"), m);
SetMatrixUniform(KnownUniform::LayerQuadTransform, m);
}
// activates this program and sets its projection matrix, if the program uses one
@ -291,73 +389,73 @@ public:
}
void SetProjectionMatrix(const gfx::Matrix4x4& aMatrix) {
SetMatrixUniform(mProfile.LookupUniformLocation("uMatrixProj"), aMatrix);
SetMatrixUniform(KnownUniform::MatrixProj, aMatrix);
mIsProjectionMatrixStale = false;
}
// sets this program's texture transform, if it uses one
void SetTextureTransform(const gfx::Matrix4x4& aMatrix) {
SetMatrixUniform(mProfile.LookupUniformLocation("uTextureTransform"), aMatrix);
SetMatrixUniform(KnownUniform::TextureTransform, aMatrix);
}
void SetRenderOffset(const nsIntPoint& aOffset) {
float vals[4] = { float(aOffset.x), float(aOffset.y), 0.0f, 0.0f };
SetUniform(mProfile.LookupUniformLocation("uRenderTargetOffset"), 4, vals);
SetUniform(KnownUniform::RenderTargetOffset, 4, vals);
}
void SetRenderOffset(float aX, float aY) {
float vals[4] = { aX, aY, 0.0f, 0.0f };
SetUniform(mProfile.LookupUniformLocation("uRenderTargetOffset"), 4, vals);
SetUniform(KnownUniform::RenderTargetOffset, 4, vals);
}
void SetLayerOpacity(float aOpacity) {
SetUniform(mProfile.LookupUniformLocation("uLayerOpacity"), aOpacity);
SetUniform(KnownUniform::LayerOpacity, aOpacity);
}
void SetTextureUnit(GLint aUnit) {
SetUniform(mProfile.LookupUniformLocation("uTexture"), aUnit);
SetUniform(KnownUniform::Texture, aUnit);
}
void SetYTextureUnit(GLint aUnit) {
SetUniform(mProfile.LookupUniformLocation("uYTexture"), aUnit);
SetUniform(KnownUniform::YTexture, aUnit);
}
void SetCbTextureUnit(GLint aUnit) {
SetUniform(mProfile.LookupUniformLocation("uCbTexture"), aUnit);
SetUniform(KnownUniform::CbTexture, aUnit);
}
void SetCrTextureUnit(GLint aUnit) {
SetUniform(mProfile.LookupUniformLocation("uCrTexture"), aUnit);
SetUniform(KnownUniform::CrTexture, aUnit);
}
void SetYCbCrTextureUnits(GLint aYUnit, GLint aCbUnit, GLint aCrUnit) {
SetUniform(mProfile.LookupUniformLocation("uYTexture"), aYUnit);
SetUniform(mProfile.LookupUniformLocation("uCbTexture"), aCbUnit);
SetUniform(mProfile.LookupUniformLocation("uCrTexture"), aCrUnit);
SetUniform(KnownUniform::YTexture, aYUnit);
SetUniform(KnownUniform::CbTexture, aCbUnit);
SetUniform(KnownUniform::CrTexture, aCrUnit);
}
void SetBlackTextureUnit(GLint aUnit) {
SetUniform(mProfile.LookupUniformLocation("uBlackTexture"), aUnit);
SetUniform(KnownUniform::BlackTexture, aUnit);
}
void SetWhiteTextureUnit(GLint aUnit) {
SetUniform(mProfile.LookupUniformLocation("uWhiteTexture"), aUnit);
SetUniform(KnownUniform::WhiteTexture, aUnit);
}
void SetMaskTextureUnit(GLint aUnit) {
SetUniform(mProfile.LookupUniformLocation("uMaskTexture"), aUnit);
SetUniform(KnownUniform::MaskTexture, aUnit);
}
void SetRenderColor(const gfxRGBA& aColor) {
SetUniform(mProfile.LookupUniformLocation("uRenderColor"), aColor);
SetUniform(KnownUniform::RenderColor, aColor);
}
void SetRenderColor(const gfx::Color& aColor) {
SetUniform(mProfile.LookupUniformLocation("uRenderColor"), aColor);
SetUniform(KnownUniform::RenderColor, aColor);
}
void SetTexCoordMultiplier(float aWidth, float aHeight) {
float f[] = {aWidth, aHeight};
SetUniform(mTexCoordMultiplierUniformLocation, 2, f);
SetUniform(KnownUniform::TexCoordMultiplier, 2, f);
}
// the names of attributes
@ -379,18 +477,16 @@ protected:
STATE_ERROR
} mProgramState;
GLint mTexCoordMultiplierUniformLocation;
void SetUniform(KnownUniform::KnownUniformName aKnownUniform, float aFloatValue);
void SetUniform(KnownUniform::KnownUniformName aKnownUniform, const gfxRGBA& aColor);
void SetUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, float *aFloatValues);
void SetUniform(KnownUniform::KnownUniformName aKnownUniform, GLint aIntValue);
void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx3DMatrix& aMatrix);
void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const float *aFloatValues);
void SetUniform(GLint aLocation, float aFloatValue);
void SetUniform(GLint aLocation, const gfxRGBA& aColor);
void SetUniform(GLint aLocation, int aLength, float *aFloatValues);
void SetUniform(GLint aLocation, GLint aIntValue);
void SetMatrixUniform(GLint aLocation, const gfx3DMatrix& aMatrix);
void SetMatrixUniform(GLint aLocation, const float *aFloatValues);
void SetUniform(GLint aLocation, const gfx::Color& aColor);
void SetMatrixUniform(GLint aLocation, const gfx::Matrix4x4& aMatrix) {
SetMatrixUniform(aLocation, &aMatrix._11);
void SetUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx::Color& aColor);
void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx::Matrix4x4& aMatrix) {
SetMatrixUniform(aKnownUniform, &aMatrix._11);
}
};