Stefan Dösinger : wined3d: Don' t single-allocate new gl shaders.

Alexandre Julliard julliard at winehq.org
Tue Jan 20 08:27:49 CST 2009


Module: wine
Branch: master
Commit: 3c3272dc413d6ffb78c4a91ae7c2e69de6521c17
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3c3272dc413d6ffb78c4a91ae7c2e69de6521c17

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Mon Jan 19 18:39:36 2009 +0100

wined3d: Don't single-allocate new gl shaders.

---

 dlls/wined3d/arb_program_shader.c |    1 +
 dlls/wined3d/glsl_shader.c        |    1 +
 dlls/wined3d/pixelshader.c        |   31 +++++++++++++++++++------------
 dlls/wined3d/wined3d_private.h    |    2 +-
 4 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 7ff3cd4..c5f7718 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -1857,6 +1857,7 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) {
         HeapFree(GetProcessHeap(), 0, This->gl_shaders);
         This->gl_shaders = NULL;
         This->num_gl_shaders = 0;
+        This->shader_array_size = 0;
     } else {
         IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
 
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index d1e1bae..4024269 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -3652,6 +3652,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
         HeapFree(GetProcessHeap(), 0, ps->gl_shaders);
         ps->gl_shaders = NULL;
         ps->num_gl_shaders = 0;
+        ps->shader_array_size = 0;
     } else {
         TRACE("Deleting shader object %u\n", vs->prgId);
         ENTER_GL();
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 9f96c59..9dcf37f 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -520,10 +520,12 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
 GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args)
 {
     UINT i;
-    struct ps_compiled_shader *old_array;
+    DWORD new_size;
+    struct ps_compiled_shader *new_array;
 
     /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
-     * so a linear search is more performant than a hashmap
+     * so a linear search is more performant than a hashmap or a binary search
+     * (cache coherency etc)
      */
     for(i = 0; i < shader->num_gl_shaders; i++) {
         if(memcmp(&shader->gl_shaders[i].args, args, sizeof(*args)) == 0) {
@@ -532,17 +534,22 @@ GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_
     }
 
     TRACE("No matching GL shader found, compiling a new shader\n");
-    old_array = shader->gl_shaders;
-    if(old_array) {
-        shader->gl_shaders = HeapReAlloc(GetProcessHeap(), 0, old_array,
-                                         (shader->num_gl_shaders + 1) * sizeof(*shader->gl_shaders));
-    } else {
-        shader->gl_shaders = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders));
-    }
+    if(shader->shader_array_size == shader->num_gl_shaders) {
+        if(shader->gl_shaders) {
+            new_size = shader->shader_array_size + max(1, shader->shader_array_size / 2);
+            new_array = HeapReAlloc(GetProcessHeap(), 0, shader->gl_shaders,
+                                    new_size * sizeof(*shader->gl_shaders));
+        } else {
+            new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders));
+            new_size = 1;
+        }
 
-    if(!shader->gl_shaders) {
-        ERR("Out of memory\n");
-        return 0;
+        if(!new_array) {
+            ERR("Out of memory\n");
+            return 0;
+        }
+        shader->gl_shaders = new_array;
+        shader->shader_array_size = new_size;
     }
 
     shader->gl_shaders[shader->num_gl_shaders].args = *args;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 80f6c72..f7f724b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2382,7 +2382,7 @@ typedef struct IWineD3DPixelShaderImpl {
 
     /* The GL shader */
     struct ps_compiled_shader   *gl_shaders;
-    UINT                        num_gl_shaders;
+    UINT                        num_gl_shaders, shader_array_size;
 
     /* Some information about the shader behavior */
     struct stb_const_desc       bumpenvmatconst[MAX_TEXTURES];




More information about the wine-cvs mailing list