wined3d: Add code to cleanup device multistate_funcs.

oldstable
Allan Tong 2009-01-06 20:20:08 -05:00 committed by Alexandre Julliard
parent 538cf8b847
commit 29dd286d79
4 changed files with 43 additions and 9 deletions

View File

@ -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
** ***************************/

View File

@ -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 */

View File

@ -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

View File

@ -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);