Prevent redundant uniform updates

TRAC #12154 Signed-off-by: Shannon Woods Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@255 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent ff42c639
...@@ -153,6 +153,8 @@ Context::Context(const egl::Config *config) ...@@ -153,6 +153,8 @@ Context::Context(const egl::Config *config)
mInvalidFramebufferOperation = false; mInvalidFramebufferOperation = false;
mHasBeenCurrent = false; mHasBeenCurrent = false;
markAllStateDirty();
} }
Context::~Context() Context::~Context()
...@@ -276,6 +278,11 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -276,6 +278,11 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
} }
} }
void Context::markAllStateDirty()
{
mAppliedProgram = 0;
}
void Context::setClearColor(float red, float green, float blue, float alpha) void Context::setClearColor(float red, float green, float blue, float alpha)
{ {
mState.colorClearValue.red = red; mState.colorClearValue.red = red;
...@@ -1781,6 +1788,12 @@ void Context::applyShaders() ...@@ -1781,6 +1788,12 @@ void Context::applyShaders()
device->SetVertexShader(vertexShader); device->SetVertexShader(vertexShader);
device->SetPixelShader(pixelShader); device->SetPixelShader(pixelShader);
if (programObject->getSerial() != mAppliedProgram)
{
programObject->dirtyAllUniforms();
mAppliedProgram = programObject->getSerial();
}
programObject->applyUniforms(); programObject->applyUniforms();
} }
......
...@@ -204,6 +204,8 @@ class Context ...@@ -204,6 +204,8 @@ class Context
void makeCurrent(egl::Display *display, egl::Surface *surface); void makeCurrent(egl::Display *display, egl::Surface *surface);
void markAllStateDirty();
// State manipulation // State manipulation
void setClearColor(float red, float green, float blue, float alpha); void setClearColor(float red, float green, float blue, float alpha);
...@@ -442,6 +444,8 @@ class Context ...@@ -442,6 +444,8 @@ class Context
bool mHasBeenCurrent; bool mHasBeenCurrent;
unsigned int mAppliedProgram;
const char *mPsProfile; const char *mPsProfile;
const char *mVsProfile; const char *mVsProfile;
}; };
......
...@@ -17,12 +17,14 @@ ...@@ -17,12 +17,14 @@
namespace gl namespace gl
{ {
unsigned int Program::mCurrentSerial = 1;
Uniform::Uniform(GLenum type, const std::string &name, unsigned int arraySize) : type(type), name(name), arraySize(arraySize) Uniform::Uniform(GLenum type, const std::string &name, unsigned int arraySize) : type(type), name(name), arraySize(arraySize)
{ {
int bytes = UniformTypeSize(type) * arraySize; int bytes = UniformTypeSize(type) * arraySize;
data = new unsigned char[bytes];
this->data = new unsigned char[bytes]; memset(data, 0, bytes);
memset(this->data, 0, bytes); dirty = true;
} }
Uniform::~Uniform() Uniform::~Uniform()
...@@ -53,6 +55,8 @@ Program::Program() ...@@ -53,6 +55,8 @@ Program::Program()
unlink(); unlink();
mDeleteStatus = false; mDeleteStatus = false;
mSerial = issueSerial();
} }
Program::~Program() Program::~Program()
...@@ -215,9 +219,11 @@ GLint Program::getUniformLocation(const char *name) ...@@ -215,9 +219,11 @@ GLint Program::getUniformLocation(const char *name)
subscript = atoi(subscrStr.c_str()); subscript = atoi(subscrStr.c_str());
} }
nameStr = decorate(nameStr);
for (unsigned int location = 0; location < mUniformIndex.size(); location++) for (unsigned int location = 0; location < mUniformIndex.size(); location++)
{ {
if (mUniformIndex[location].name == decorate(nameStr) && if (mUniformIndex[location].name == nameStr &&
mUniformIndex[location].element == subscript) mUniformIndex[location].element == subscript)
{ {
return location; return location;
...@@ -235,6 +241,7 @@ bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) ...@@ -235,6 +241,7 @@ bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type == GL_FLOAT) if (targetUniform->type == GL_FLOAT)
{ {
...@@ -291,6 +298,7 @@ bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) ...@@ -291,6 +298,7 @@ bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type == GL_FLOAT_VEC2) if (targetUniform->type == GL_FLOAT_VEC2)
{ {
...@@ -348,6 +356,7 @@ bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) ...@@ -348,6 +356,7 @@ bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type == GL_FLOAT_VEC3) if (targetUniform->type == GL_FLOAT_VEC3)
{ {
...@@ -404,6 +413,7 @@ bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) ...@@ -404,6 +413,7 @@ bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type == GL_FLOAT_VEC4) if (targetUniform->type == GL_FLOAT_VEC4)
{ {
...@@ -460,6 +470,7 @@ bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat * ...@@ -460,6 +470,7 @@ bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type != GL_FLOAT_MAT2) if (targetUniform->type != GL_FLOAT_MAT2)
{ {
...@@ -487,6 +498,7 @@ bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat * ...@@ -487,6 +498,7 @@ bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type != GL_FLOAT_MAT3) if (targetUniform->type != GL_FLOAT_MAT3)
{ {
...@@ -514,6 +526,7 @@ bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat * ...@@ -514,6 +526,7 @@ bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type != GL_FLOAT_MAT4) if (targetUniform->type != GL_FLOAT_MAT4)
{ {
...@@ -541,6 +554,7 @@ bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) ...@@ -541,6 +554,7 @@ bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type == GL_INT) if (targetUniform->type == GL_INT)
{ {
...@@ -597,6 +611,7 @@ bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) ...@@ -597,6 +611,7 @@ bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type == GL_INT_VEC2) if (targetUniform->type == GL_INT_VEC2)
{ {
...@@ -653,6 +668,7 @@ bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v) ...@@ -653,6 +668,7 @@ bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type == GL_INT_VEC3) if (targetUniform->type == GL_INT_VEC3)
{ {
...@@ -709,6 +725,7 @@ bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) ...@@ -709,6 +725,7 @@ bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
if (targetUniform->type == GL_INT_VEC4) if (targetUniform->type == GL_INT_VEC4)
{ {
...@@ -843,6 +860,14 @@ bool Program::getUniformiv(GLint location, GLint *params) ...@@ -843,6 +860,14 @@ bool Program::getUniformiv(GLint location, GLint *params)
return true; return true;
} }
void Program::dirtyAllUniforms()
{
for (unsigned int index = 0; index < mUniforms.size(); index++)
{
mUniforms[index]->dirty = true;
}
}
// Applies all the uniforms set for this program object to the Direct3D 9 device // Applies all the uniforms set for this program object to the Direct3D 9 device
void Program::applyUniforms() void Program::applyUniforms()
{ {
...@@ -855,31 +880,35 @@ void Program::applyUniforms() ...@@ -855,31 +880,35 @@ void Program::applyUniforms()
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
int arraySize = targetUniform->arraySize; if (targetUniform->dirty)
GLfloat *f = (GLfloat*)targetUniform->data;
GLint *i = (GLint*)targetUniform->data;
GLboolean *b = (GLboolean*)targetUniform->data;
switch (targetUniform->type)
{ {
case GL_BOOL: applyUniform1bv(location, arraySize, b); break; int arraySize = targetUniform->arraySize;
case GL_BOOL_VEC2: applyUniform2bv(location, arraySize, b); break; GLfloat *f = (GLfloat*)targetUniform->data;
case GL_BOOL_VEC3: applyUniform3bv(location, arraySize, b); break; GLint *i = (GLint*)targetUniform->data;
case GL_BOOL_VEC4: applyUniform4bv(location, arraySize, b); break; GLboolean *b = (GLboolean*)targetUniform->data;
case GL_FLOAT: applyUniform1fv(location, arraySize, f); break;
case GL_FLOAT_VEC2: applyUniform2fv(location, arraySize, f); break; switch (targetUniform->type)
case GL_FLOAT_VEC3: applyUniform3fv(location, arraySize, f); break; {
case GL_FLOAT_VEC4: applyUniform4fv(location, arraySize, f); break; case GL_BOOL: applyUniform1bv(location, arraySize, b); break;
case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, arraySize, f); break; case GL_BOOL_VEC2: applyUniform2bv(location, arraySize, b); break;
case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, arraySize, f); break; case GL_BOOL_VEC3: applyUniform3bv(location, arraySize, b); break;
case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, arraySize, f); break; case GL_BOOL_VEC4: applyUniform4bv(location, arraySize, b); break;
case GL_INT: applyUniform1iv(location, arraySize, i); break; case GL_FLOAT: applyUniform1fv(location, arraySize, f); break;
case GL_INT_VEC2: applyUniform2iv(location, arraySize, i); break; case GL_FLOAT_VEC2: applyUniform2fv(location, arraySize, f); break;
case GL_INT_VEC3: applyUniform3iv(location, arraySize, i); break; case GL_FLOAT_VEC3: applyUniform3fv(location, arraySize, f); break;
case GL_INT_VEC4: applyUniform4iv(location, arraySize, i); break; case GL_FLOAT_VEC4: applyUniform4fv(location, arraySize, f); break;
default: case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, arraySize, f); break;
UNIMPLEMENTED(); // FIXME case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, arraySize, f); break;
UNREACHABLE(); case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, arraySize, f); break;
case GL_INT: applyUniform1iv(location, arraySize, i); break;
case GL_INT_VEC2: applyUniform2iv(location, arraySize, i); break;
case GL_INT_VEC3: applyUniform3iv(location, arraySize, i); break;
case GL_INT_VEC4: applyUniform4iv(location, arraySize, i); break;
default:
UNREACHABLE();
}
targetUniform->dirty = false;
} }
} }
} }
...@@ -2004,6 +2033,16 @@ bool Program::isValidated() const ...@@ -2004,6 +2033,16 @@ bool Program::isValidated() const
return mValidated; return mValidated;
} }
unsigned int Program::getSerial() const
{
return mSerial;
}
unsigned int Program::issueSerial()
{
return mCurrentSerial++;
}
int Program::getInfoLogLength() const int Program::getInfoLogLength() const
{ {
if (!mInfoLog) if (!mInfoLog)
......
...@@ -33,7 +33,9 @@ struct Uniform ...@@ -33,7 +33,9 @@ struct Uniform
const GLenum type; const GLenum type;
const std::string name; const std::string name;
const unsigned int arraySize; const unsigned int arraySize;
unsigned char *data; unsigned char *data;
bool dirty;
}; };
// Struct used for correlating uniforms/elements of uniform arrays to handles // Struct used for correlating uniforms/elements of uniform arrays to handles
...@@ -83,6 +85,7 @@ class Program ...@@ -83,6 +85,7 @@ class Program
bool getUniformfv(GLint location, GLfloat *params); bool getUniformfv(GLint location, GLfloat *params);
bool getUniformiv(GLint location, GLint *params); bool getUniformiv(GLint location, GLint *params);
void dirtyAllUniforms();
void applyUniforms(); void applyUniforms();
void link(); void link();
...@@ -106,6 +109,8 @@ class Program ...@@ -106,6 +109,8 @@ class Program
bool validateSamplers() const; bool validateSamplers() const;
bool isValidated() const; bool isValidated() const;
unsigned int getSerial() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(Program); DISALLOW_COPY_AND_ASSIGN(Program);
...@@ -158,6 +163,8 @@ class Program ...@@ -158,6 +163,8 @@ class Program
static std::string decorate(const std::string &string); // Prepend an underscore static std::string decorate(const std::string &string); // Prepend an underscore
static std::string undecorate(const std::string &string); // Remove leading underscore static std::string undecorate(const std::string &string); // Remove leading underscore
static unsigned int issueSerial();
FragmentShader *mFragmentShader; FragmentShader *mFragmentShader;
VertexShader *mVertexShader; VertexShader *mVertexShader;
...@@ -191,6 +198,10 @@ class Program ...@@ -191,6 +198,10 @@ class Program
bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use
char *mInfoLog; char *mInfoLog;
bool mValidated; bool mValidated;
unsigned int mSerial;
static unsigned int mCurrentSerial;
}; };
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment