Only update a constant buffer when any of its uniforms are dirty.

TRAC #22327
Signed-off-by: Daniel Koch
Signed-off-by: Geoff Lang
Author: Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1768 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 3c46e7b..d01f38c 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -111,7 +111,7 @@
 
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
     virtual void applyShaders(gl::ProgramBinary *programBinary) = 0;
-    virtual void applyUniforms(gl::ProgramBinary *programBinary, const gl::UniformArray *uniformArray) = 0;
+    virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) = 0;
     virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
     virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) = 0;
     virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index 10f1165..4c72599 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -1043,7 +1043,7 @@
     }
 }
 
-void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, const gl::UniformArray *uniformArray)
+void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray)
 {
     ShaderExecutable11 *vertexExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable());
     ShaderExecutable11 *pixelExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getPixelExecutable());
@@ -1051,6 +1051,9 @@
     unsigned int totalRegisterCountVS = 0;
     unsigned int totalRegisterCountPS = 0;
 
+    bool vertexUniformsDirty = false;
+    bool pixelUniformsDirty = false;
+
     for (gl::UniformArray::const_iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++)
     {
         const gl::Uniform *uniform = *uniform_iterator;
@@ -1058,23 +1061,25 @@
         if (uniform->vsRegisterIndex >= 0)
         {
             totalRegisterCountVS += uniform->registerCount;
+            vertexUniformsDirty = vertexUniformsDirty || uniform->dirty;
         }
 
         if (uniform->psRegisterIndex >= 0)
         {
             totalRegisterCountPS += uniform->registerCount;
+            pixelUniformsDirty = pixelUniformsDirty || uniform->dirty;
         }
     }
 
     ID3D11Buffer *vertexConstantBuffer = vertexExecutable->getConstantBuffer(mDevice, totalRegisterCountVS);
     ID3D11Buffer *pixelConstantBuffer = pixelExecutable->getConstantBuffer(mDevice, totalRegisterCountPS);
 
-    void *mapVS = new float[4 * totalRegisterCountVS];
-    void *mapPS = new float[4 * totalRegisterCountPS];
+    void *mapVS = (totalRegisterCountVS > 0 && vertexUniformsDirty) ? new float[4 * totalRegisterCountVS] : NULL;
+    void *mapPS = (totalRegisterCountPS > 0 && pixelUniformsDirty) ? new float[4 * totalRegisterCountPS] : NULL;
 
-    for (gl::UniformArray::const_iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++)
+    for (gl::UniformArray::iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++)
     {
-        const gl::Uniform *uniform = *uniform_iterator;
+        gl::Uniform *uniform = *uniform_iterator;
 
         switch (uniform->type)
         {
@@ -1088,7 +1093,7 @@
           case GL_FLOAT_MAT2:
           case GL_FLOAT_MAT3:
           case GL_FLOAT_MAT4:
-            if (uniform->vsRegisterIndex >= 0)
+            if (uniform->vsRegisterIndex >= 0 && mapVS)
             {
                 GLfloat (*c)[4] = (GLfloat(*)[4])mapVS;
                 float (*f)[4] = (float(*)[4])uniform->data;
@@ -1101,7 +1106,7 @@
                     c[uniform->vsRegisterIndex + i][3] = f[i][3];
                 }
             }
-            if (uniform->psRegisterIndex >= 0)
+            if (uniform->psRegisterIndex >= 0 && mapPS)
             {
                 GLfloat (*c)[4] = (GLfloat(*)[4])mapPS;
                 float (*f)[4] = (float(*)[4])uniform->data;
@@ -1119,7 +1124,7 @@
           case GL_INT_VEC2:
           case GL_INT_VEC3:
           case GL_INT_VEC4:
-            if (uniform->vsRegisterIndex >= 0)
+            if (uniform->vsRegisterIndex >= 0 && mapVS)
             {
                 int (*c)[4] = (int(*)[4])mapVS;
                 GLint *x = (GLint*)uniform->data;
@@ -1133,7 +1138,7 @@
                     if (count >= 4) c[uniform->vsRegisterIndex + i][3] = x[i * count + 3];
                 }
             }
-            if (uniform->psRegisterIndex >= 0)
+            if (uniform->psRegisterIndex >= 0 && mapPS)
             {
                 int (*c)[4] = (int(*)[4])mapPS;
                 GLint *x = (GLint*)uniform->data;
@@ -1152,7 +1157,7 @@
           case GL_BOOL_VEC2:
           case GL_BOOL_VEC3:
           case GL_BOOL_VEC4:
-            if (uniform->vsRegisterIndex >= 0)
+            if (uniform->vsRegisterIndex >= 0 && mapVS)
             {
                 int (*c)[4] = (int(*)[4])mapVS;
                 GLboolean *b = (GLboolean*)uniform->data;
@@ -1166,7 +1171,7 @@
                     if (count >= 4) c[uniform->vsRegisterIndex + i][3] = b[i * count + 3];
                 }
             }
-            if (uniform->psRegisterIndex >= 0)
+            if (uniform->psRegisterIndex >= 0 && mapPS)
             {
                 int (*c)[4] = (int(*)[4])mapPS;
                 GLboolean *b = (GLboolean*)uniform->data;
@@ -1184,14 +1189,16 @@
           default:
             UNREACHABLE();
         }
+
+        uniform->dirty = false;
     }
 
-    if (vertexConstantBuffer)
+    if (vertexConstantBuffer && mapVS)
     {
         mDeviceContext->UpdateSubresource(vertexConstantBuffer, 0, NULL, mapVS, 0, 0);
     }
 
-    if (pixelConstantBuffer)
+    if (pixelConstantBuffer && mapPS)
     {
         mDeviceContext->UpdateSubresource(pixelConstantBuffer, 0, NULL, mapPS, 0, 0);
     }
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index 387a395..5bab122 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -67,7 +67,7 @@
     virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
     virtual void applyShaders(gl::ProgramBinary *programBinary);
-    virtual void applyUniforms(gl::ProgramBinary *programBinary, const gl::UniformArray *uniformArray);
+    virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
     virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
     virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
 
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index 429b6a1..460a391 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -1606,7 +1606,7 @@
     }
 }
 
-void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, const gl::UniformArray *uniformArray)
+void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray)
 {
     for (std::vector<gl::Uniform*>::const_iterator ub = uniformArray->begin(), ue = uniformArray->end(); ub != ue; ++ub)
     {
diff --git a/src/libGLESv2/renderer/Renderer9.h b/src/libGLESv2/renderer/Renderer9.h
index ae36b2b..55f98fc 100644
--- a/src/libGLESv2/renderer/Renderer9.h
+++ b/src/libGLESv2/renderer/Renderer9.h
@@ -90,7 +90,7 @@
 
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
     virtual void applyShaders(gl::ProgramBinary *programBinary);
-    virtual void applyUniforms(gl::ProgramBinary *programBinary, const gl::UniformArray *uniformArray);
+    virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
     virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
     virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
     virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);