2017-04-20 13:26 GMT+02:00 Paul Gofman gofmanp@gmail.com:
Signed-off-by: Paul Gofman gofmanp@gmail.com
dlls/d3dx9_36/d3dx9_private.h | 11 ++- dlls/d3dx9_36/effect.c | 197 +++++++++++++++++++++++++++++++++++++++++- dlls/d3dx9_36/tests/effect.c | 17 ++-- 3 files changed, 211 insertions(+), 14 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index da4564d..d6d4280 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -215,15 +215,22 @@ struct d3dx_parameter struct d3dx_parameter *annotations; struct d3dx_parameter *members;
struct d3dx_parameter *referenced_param; struct d3dx_param_eval *param_eval;
struct d3dx_parameter *top_level_param;
- union
- {
struct d3dx_parameter *referenced_param;
struct d3dx_parameter *shared_param;
- };
- LONG shared_refcount;
};
I think you mentioned this before but it shouldn't be necessary to store the whole parameter structure in the pool. I guess it could be improved after the fact but it shouldn't be too complicated to do it right away. Probably it could just be shared_param_list[] from patch 8/8 and shared_refcount (which at that point won't need to be in struct d3dx_parameter anymore), in addition to data. You could access the other parameter fields through shared_param_list[0].
+static void d3dx_pool_sync_shared_parameter(struct ID3DXEffectPoolImpl *pool, struct d3dx_parameter *param) +{
- unsigned int i, free_entry_index;
- LONG new_refcount;
- if (!(param->flags & PARAMETER_FLAG_SHARED) || !pool
|| is_param_type_sampler(param->type))
return;
- free_entry_index = pool->parameter_count;
- for (i = 0; i < pool->parameter_count; ++i)
- {
if (!pool->parameters[i]->shared_refcount)
free_entry_index = i;
else if (is_same_parameter(param, pool->parameters[i]))
break;
- }
- if (i == pool->parameter_count)
- {
i = free_entry_index;
if (i >= pool->table_size)
{
struct d3dx_parameter ** new_alloc;
No whitespace after "**", please.
else
{
new_size = pool->table_size * 2;
new_alloc = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pool->parameters,
sizeof(*pool->parameters) * new_size);
if (!new_alloc)
{
ERR("Out of memory.\n");
return;
}
}
pool->parameters = new_alloc;
pool->table_size = new_size;
}
pool->parameters[i] = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(*pool->parameters[i]));
copy_parameter_structure(param, pool->parameters[i], NULL, FALSE);
param_set_data_pointer(pool->parameters[i], (unsigned char *)param->data, FALSE, FALSE);
if (i == pool->parameter_count)
pool->parameter_count++;
- }
I don't think this works. HeapReAlloc might move the memory block and that would break the preexisting effects using the pool (and also the previous parameters of the new effect). HEAP_REALLOC_IN_PLACE_ONLY would avoid that but it also makes it easier for the reallocation to fail.
I see two ways to fix this: - refresh all the parameters of the effects that are in the pool when you have to reallocate (shared_param_list[] might help here) - allocate the memory in chunks, keeping an array (or list) of chunks which you allocate (but never resize) as needed