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