From 29dd286d79fceff109e408503d8b221290362f12 Mon Sep 17 00:00:00 2001 From: Allan Tong Date: Tue, 6 Jan 2009 20:20:08 -0500 Subject: [PATCH] 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 fb9dd6e6d9d..ed343dda6e6 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 639b07ec35c..b9a63ab3527 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 b054ee14ab7..9d972839bac 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 43b1ae0c09c..11b868054ee 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); -- 2.11.4.GIT