Allan Tong : wined3d: Add code to cleanup device multistate_funcs.

Alexandre Julliard julliard at winehq.org
Sat Jan 10 11:16:44 CST 2009


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

Author: Allan Tong <actong88 at gmail.com>
Date:   Tue Jan  6 20:20:08 2009 -0500

wined3d: Add code to cleanup device multistate_funcs.

---

 dlls/wined3d/device.c          |    7 +++++++
 dlls/wined3d/directx.c         |   10 +++++++++-
 dlls/wined3d/state.c           |   33 ++++++++++++++++++++++++++-------
 dlls/wined3d/wined3d_private.h |    2 +-
 4 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index fb9dd6e..ed343dd 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -164,6 +164,13 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) {
     TRACE("(%p) : Releasing from %d\n", This, refCount + 1);
 
     if (!refCount) {
+        UINT i;
+
+        for (i = 0; i < sizeof(This->multistate_funcs)/sizeof(This->multistate_funcs[0]); ++i) {
+            HeapFree(GetProcessHeap(), 0, This->multistate_funcs[i]);
+            This->multistate_funcs[i] = NULL;
+        }
+
         /* TODO: Clean up all the surfaces and textures! */
         /* NOTE: You must release the parent if the object was created via a callback
         ** ***************************/
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 639b07e..b9a63ab 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -3631,6 +3631,7 @@ static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
     const struct fragment_pipeline *frag_pipeline = NULL;
     int i;
     struct fragment_caps ffp_caps;
+    HRESULT hr;
 
     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
      * number and create a device without a 3D adapter for 2D only operation.
@@ -3689,9 +3690,16 @@ static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
     frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &ffp_caps);
     object->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
     object->max_ffp_texture_stages = ffp_caps.MaxTextureBlendStages;
-    compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
+    hr = compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
                         ffp_vertexstate_template, frag_pipeline, misc_state_template);
 
+    if (FAILED(hr)) {
+        IWineD3D_Release(object->wineD3D);
+        HeapFree(GetProcessHeap(), 0, object);
+
+        return hr;
+    }
+
     object->blitter = select_blit_implementation(Adapter, DeviceType);
 
     /* set the state of the device to valid */
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index b054ee1..9d97283 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -5488,7 +5488,7 @@ static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock,
     stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context);
 }
 
-void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
+HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
         const WineD3D_GL_Info *gl_info, const struct StateEntryTemplate *vertex,
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
 {
@@ -5520,6 +5520,7 @@ void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_mul
         memset(set, 0, sizeof(set));
 
         for(i = 0; cur[i].state; i++) {
+            APPLYSTATEFUNC *funcs_array;
 
             /* Only use the first matching state with the available extension from one template.
              * e.g.
@@ -5552,17 +5553,24 @@ void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_mul
                     dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
                                                                    0,
                                                                    sizeof(**dev_multistate_funcs) * 2);
+                    if (!dev_multistate_funcs[cur[i].state]) {
+                        goto out_of_mem;
+                    }
+
                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
                     dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
                     break;
                 case 2:
                     StateTable[cur[i].state].apply = multistate_apply_3;
-                    HeapFree(GetProcessHeap(), 0, multistate_funcs[cur[i].state]);
-                    dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
-                                                                   0,
-                                                                   sizeof(**dev_multistate_funcs) * 3);
-                    dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
-                    dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
+                    funcs_array = HeapReAlloc(GetProcessHeap(),
+                                              0,
+                                              dev_multistate_funcs[cur[i].state],
+                                              sizeof(**dev_multistate_funcs) * 3);
+                    if (!funcs_array) {
+                        goto out_of_mem;
+                    }
+
+                    dev_multistate_funcs[cur[i].state] = funcs_array;
                     dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
                     break;
                 default:
@@ -5578,5 +5586,16 @@ void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_mul
             StateTable[cur[i].state].representative = cur[i].content.representative;
         }
     }
+
+    return WINED3D_OK;
+
+out_of_mem:
+    for (i = 0; i <= STATE_HIGHEST; ++i) {
+        HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
+    }
+
+    memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
+
+    return E_OUTOFMEMORY;
 }
 #undef GLINFO_LOCATION
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 43b1ae0..11b8680 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -760,7 +760,7 @@ extern const struct fragment_pipeline nvts_fragment_pipeline;
 extern const struct fragment_pipeline nvrc_fragment_pipeline;
 
 /* "Base" state table */
-void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
+HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
         const WineD3D_GL_Info *gl_info, const struct StateEntryTemplate *vertex,
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc);
 




More information about the wine-cvs mailing list