Found this after seeing test crashes caused by writing to adjacent stack memory, corrupting it. Happened with "size + 1" tests.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
From: Nikolay Sivov nsivov@codeweavers.com
Found this after seeing test crashes caused by writing to adjacent stack memory, corrupting it. Happened with "size + 1" tests.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/effect.c | 2 + dlls/d2d1/tests/d2d1.c | 86 +++++++++++++++++++++++++++++++----------- 2 files changed, 67 insertions(+), 21 deletions(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 42d2c589edc..6738bc43a1d 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1252,6 +1252,8 @@ static HRESULT d2d_effect_property_get_value(const struct d2d_effect_properties struct d2d_effect *effect = properties->effect; UINT32 actual_size;
+ memset(value, 0, size); + if (type != D2D1_PROPERTY_TYPE_UNKNOWN && prop->type != type) return E_INVALIDARG; if (prop->type != D2D1_PROPERTY_TYPE_STRING && prop->size != size) return E_INVALIDARG;
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index ad7d5163f1f..15a9eeb00ab 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -20,6 +20,7 @@ #include <limits.h> #include <math.h> #include <float.h> +#include <stdint.h> #include "d3dcompiler.h" #include "d2d1_3.h" #include "d2d1effectauthor.h" @@ -11707,6 +11708,19 @@ static void test_effect_context(BOOL d3d11) release_test_context(&ctx); }
+#define check_zero_buffer(a, b) check_zero_buffer_(a, b, __LINE__) +static void check_zero_buffer_(const void *buffer, size_t size, unsigned int line) +{ + const uint32_t *ptr = buffer; + const uint8_t *ptr2 = buffer; + size_t i; + + for (i = 0; i < size / sizeof(*ptr); ++i) + ok_(__FILE__, line)(!ptr[i], "Expected zero value %#x.\n", ptr[i]); + for (i = 0; i < size % sizeof(*ptr); ++i) + ok_(__FILE__, line)(!ptr2[size - i - 1], "Expected zero value %#x.\n", ptr2[i]); +} + static void test_effect_properties(BOOL d3d11) { UINT32 i, min_inputs, max_inputs, integer, index, size; @@ -11720,6 +11734,7 @@ static void test_effect_properties(BOOL d3d11) ID2D1Effect *effect; UINT32 count, data; WCHAR buffer[128]; + BYTE value[128]; float mat[20]; INT32 val; CLSID clsid; @@ -12077,55 +12092,84 @@ static void test_effect_properties(BOOL d3d11) index = ID2D1Effect_GetPropertyIndex(effect, L"Integer"); ok(index == 1, "Got unexpected index %u.\n", index);
- effect_context = (ID2D1EffectContext *)0xdeadbeef; - hr = ID2D1Effect_GetValueByName(effect, - L"Context", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) - 1); + /* On type mismatch output buffer is zeroed. */ + memset(value, 0xcc, sizeof(value)); + hr = ID2D1Effect_GetValueByName(effect, L"Context", D2D1_PROPERTY_TYPE_UINT32, value, sizeof(void *)); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); - hr = ID2D1Effect_GetValueByName(effect, - L"Context", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) + 1); + check_zero_buffer(value, sizeof(void *)); + + /* On size mismatch output buffer is zeroed. */ + memset(value, 0xcc, sizeof(value)); + hr = ID2D1Effect_GetValueByName(effect, L"Context", D2D1_PROPERTY_TYPE_IUNKNOWN, value, sizeof(void *) - 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + check_zero_buffer(value, sizeof(void *) - 1); + + memset(value, 0xcc, sizeof(value)); + hr = ID2D1Effect_GetValueByName(effect, L"Context", D2D1_PROPERTY_TYPE_IUNKNOWN, value, sizeof(void *) + 1); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + check_zero_buffer(value, sizeof(void *) + 1); + + effect_context = NULL; hr = ID2D1Effect_GetValueByName(effect, L"Context", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(effect_context != NULL && effect_context != (ID2D1EffectContext *)0xdeadbeef, - "Got unexpected effect context %p.\n", effect_context); + ok(!!effect_context, "Got unexpected effect context %p.\n", effect_context);
- effect_context = (ID2D1EffectContext *)0xdeadbeef; - hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) - 1); + memset(value, 0xcc, sizeof(value)); + hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, value, sizeof(void *) - 1); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); - hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) + 1); + check_zero_buffer(value, sizeof(void *) - 1); + + memset(value, 0xcc, sizeof(value)); + hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, value, sizeof(void *) + 1); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + check_zero_buffer(value, sizeof(void *) + 1); + + effect_context = NULL; hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(effect_context != NULL && effect_context != (ID2D1EffectContext *)0xdeadbeef, - "Got unexpected effect context %p.\n", effect_context); + ok(!!effect_context, "Got unexpected effect context %p.\n", effect_context);
hr = ID2D1Effect_SetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
- integer = 0xdeadbeef; - hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) - 1); + memset(value, 0xcc, sizeof(value)); + hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, value, 3); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); - hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) + 1); + check_zero_buffer(value, 3); + + memset(value, 0xcc, sizeof(value)); + hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, value, 5); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + check_zero_buffer(value, 5); + + integer = 0; hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(integer == 10, "Got unexpected integer %u.", integer);
- integer = 0xdeadbeef; - hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) - 1); + memset(value, 0xcc, sizeof(value)); + hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, value, 3); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); - hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) + 1); + check_zero_buffer(value, 3); + + memset(value, 0xcc, sizeof(value)); + hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, value, 5); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + check_zero_buffer(value, 5); + + integer = 0; hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(integer == 10, "Got unexpected integer %u.", integer);
- integer = 20; - hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) - 1); + memset(value, 0, sizeof(value)); + hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, value, 3); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) + 1); + hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, value, 5); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + integer = 20; hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); integer = 0xdeadbeef;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 57 ++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 24 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 15a9eeb00ab..7eaeddda341 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -11726,20 +11726,26 @@ static void test_effect_properties(BOOL d3d11) UINT32 i, min_inputs, max_inputs, integer, index, size; ID2D1EffectContext *effect_context; D2D1_BUFFER_PRECISION precision; - float vec2[2], vec3[3], vec4[4]; ID2D1Properties *subproperties; D2D1_PROPERTY_TYPE prop_type; struct d2d1_test_context ctx; + D2D_MATRIX_3X2_F mat3x2; + D2D_MATRIX_4X3_F mat4x3; + D2D_MATRIX_4X4_F mat4x4; + D2D_MATRIX_5X4_F mat5x4; ID2D1Factory1 *factory; ID2D1Effect *effect; UINT32 count, data; + D2D_VECTOR_2F vec2; + D2D_VECTOR_3F vec3; + D2D_VECTOR_4F vec4; WCHAR buffer[128]; BYTE value[128]; - float mat[20]; - INT32 val; CLSID clsid; BOOL cached; HRESULT hr; + float *ptr; + INT32 val;
static const WCHAR *effect_author = L"The Wine Project"; static const WCHAR *effect_category = L"Test"; @@ -11890,9 +11896,10 @@ static void test_effect_properties(BOOL d3d11) ok(!wcscmp(buffer, L"Vec2Prop"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); prop_type = ID2D1Effect_GetType(effect, index); ok(prop_type == D2D1_PROPERTY_TYPE_VECTOR2, "Unexpected type %u.\n", prop_type); - hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_VECTOR2, (BYTE *)vec2, sizeof(vec2)); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_VECTOR2, (BYTE *)&vec2, sizeof(vec2)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(vec2[0] == 3.0f && vec2[1] == 4.0f, "Unexpected vector (%.8e,%.8e).\n", vec2[0], vec2[1]); + ok(vec2.x == 3.0f, "Unexpected value %.8e.\n", vec2.x); + ok(vec2.y == 4.0f, "Unexpected value %.8e.\n", vec2.y);
/* Vector3 property. */ index = ID2D1Effect_GetPropertyIndex(effect, L"Vec3Prop"); @@ -11901,10 +11908,11 @@ static void test_effect_properties(BOOL d3d11) ok(!wcscmp(buffer, L"Vec3Prop"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); prop_type = ID2D1Effect_GetType(effect, index); ok(prop_type == D2D1_PROPERTY_TYPE_VECTOR3, "Unexpected type %u.\n", prop_type); - hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_VECTOR3, (BYTE *)vec3, sizeof(vec3)); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_VECTOR3, (BYTE *)&vec3, sizeof(vec3)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(vec3[0] == 5.0f && vec3[1] == 6.0f && vec3[2] == 7.0f, "Unexpected vector (%.8e,%.8e,%.8e).\n", - vec3[0], vec3[1], vec3[2]); + ok(vec3.x == 5.0f, "Unexpected value %.8e.\n", vec3.x); + ok(vec3.y == 6.0f, "Unexpected value %.8e.\n", vec3.y); + ok(vec3.z == 7.0f, "Unexpected value %.8e.\n", vec3.z);
/* Vector4 property. */ index = ID2D1Effect_GetPropertyIndex(effect, L"Vec4Prop"); @@ -11913,10 +11921,12 @@ static void test_effect_properties(BOOL d3d11) ok(!wcscmp(buffer, L"Vec4Prop"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); prop_type = ID2D1Effect_GetType(effect, index); ok(prop_type == D2D1_PROPERTY_TYPE_VECTOR4, "Unexpected type %u.\n", prop_type); - hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_VECTOR4, (BYTE *)vec4, sizeof(vec4)); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_VECTOR4, (BYTE *)&vec4, sizeof(vec4)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(vec4[0] == 8.0f && vec4[1] == 9.0f && vec4[2] == 10.0f && vec4[3] == 11.0f, - "Unexpected vector (%.8e,%.8e,%.8e,%.8e).\n", vec4[0], vec4[1], vec4[2], vec4[3]); + ok(vec4.x == 8.0f, "Unexpected value %.8e.\n", vec4.x); + ok(vec4.y == 9.0f, "Unexpected value %.8e.\n", vec4.y); + ok(vec4.z == 10.0f, "Unexpected value %.8e.\n", vec4.z); + ok(vec4.w == 11.0f, "Unexpected value %.8e.\n", vec4.w);
/* Matrix3x2 property. */ index = ID2D1Effect_GetPropertyIndex(effect, L"Mat3x2Prop"); @@ -11925,11 +11935,10 @@ static void test_effect_properties(BOOL d3d11) ok(!wcscmp(buffer, L"Mat3x2Prop"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); prop_type = ID2D1Effect_GetType(effect, index); ok(prop_type == D2D1_PROPERTY_TYPE_MATRIX_3X2, "Unexpected type %u.\n", prop_type); - hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_MATRIX_3X2, (BYTE *)mat, 6 * sizeof(float)); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_MATRIX_3X2, (BYTE *)&mat3x2, sizeof(mat3x2)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - ok(mat[0] == 1.0f && mat[1] == 2.0f && mat[2] == 3.0f && mat[3] == 4.0f && mat[4] == 5.0f && mat[5] == 6.0f, - "Unexpected matrix (%.8e,%.8e,%.8e,%.8e,%.8e,%.8e).\n", - mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); + for (i = 0, ptr = (float *)&mat3x2; i < sizeof(mat3x2) / sizeof(*ptr); ++i, ++ptr) + ok(*ptr == 1.0f + i, "Unexpected value %.8e.\n", *ptr);
/* Matrix4x3 property. */ index = ID2D1Effect_GetPropertyIndex(effect, L"Mat4x3Prop"); @@ -11938,10 +11947,10 @@ static void test_effect_properties(BOOL d3d11) ok(!wcscmp(buffer, L"Mat4x3Prop"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); prop_type = ID2D1Effect_GetType(effect, index); ok(prop_type == D2D1_PROPERTY_TYPE_MATRIX_4X3, "Unexpected type %u.\n", prop_type); - hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_MATRIX_4X3, (BYTE *)mat, 12 * sizeof(float)); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_MATRIX_4X3, (BYTE *)&mat4x3, sizeof(mat4x3)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - for (i = 0; i < 12; ++i) - ok(mat[i] == 1.0f + i, "Unexpected matrix element %u.\n", i); + for (i = 0, ptr = (float *)&mat4x3; i < sizeof(mat4x3) / sizeof(*ptr); ++i, ++ptr) + ok(*ptr == 1.0f + i, "Unexpected value %.8e.\n", *ptr);
/* Matrix4x4 property. */ index = ID2D1Effect_GetPropertyIndex(effect, L"Mat4x4Prop"); @@ -11950,10 +11959,10 @@ static void test_effect_properties(BOOL d3d11) ok(!wcscmp(buffer, L"Mat4x4Prop"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); prop_type = ID2D1Effect_GetType(effect, index); ok(prop_type == D2D1_PROPERTY_TYPE_MATRIX_4X4, "Unexpected type %u.\n", prop_type); - hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_MATRIX_4X4, (BYTE *)mat, 16 * sizeof(float)); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_MATRIX_4X4, (BYTE *)&mat4x4, sizeof(mat4x4)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - for (i = 0; i < 16; ++i) - ok(mat[i] == 1.0f + i, "Unexpected matrix element %u.\n", i); + for (i = 0, ptr = (float *)&mat4x4; i < sizeof(mat4x4) / sizeof(*ptr); ++i, ++ptr) + ok(*ptr == 1.0f + i, "Unexpected value %.8e.\n", *ptr);
/* Matrix5x4 property. */ index = ID2D1Effect_GetPropertyIndex(effect, L"Mat5x4Prop"); @@ -11962,10 +11971,10 @@ static void test_effect_properties(BOOL d3d11) ok(!wcscmp(buffer, L"Mat5x4Prop"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); prop_type = ID2D1Effect_GetType(effect, index); ok(prop_type == D2D1_PROPERTY_TYPE_MATRIX_5X4, "Unexpected type %u.\n", prop_type); - hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_MATRIX_5X4, (BYTE *)mat, 20 * sizeof(float)); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_MATRIX_5X4, (BYTE *)&mat5x4, sizeof(mat5x4)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - for (i = 0; i < 20; ++i) - ok(mat[i] == 1.0f + i, "Unexpected matrix element %u.\n", i); + for (i = 0, ptr = (float *)&mat5x4; i < sizeof(mat5x4) / sizeof(*ptr); ++i, ++ptr) + ok(*ptr == 1.0f + i, "Unexpected value %.8e.\n", *ptr);
ID2D1Effect_Release(effect);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 15 +++ dlls/d2d1/effect.c | 222 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 237 insertions(+)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 6b6d51d4b3c..f5f484e0778 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -728,10 +728,25 @@ struct d2d_transform UINT32 input_count; };
+enum d2d_render_info_mask +{ + D2D_RENDER_INFO_PIXEL_SHADER = 0x1, +}; + +struct d2d_render_info +{ + ID2D1DrawInfo ID2D1DrawInfo_iface; + LONG refcount; + + unsigned int mask; + GUID pixel_shader; +}; + struct d2d_transform_node { struct list entry; ID2D1TransformNode *object; + struct d2d_render_info *render_info; };
struct d2d_transform_node_connection diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 6738bc43a1d..a6738823e6f 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -561,6 +561,9 @@ static void d2d_transform_graph_delete_node(struct d2d_transform_graph *graph, if (graph->output == node) graph->output = NULL;
+ if (node->render_info) + ID2D1DrawInfo_Release(&node->render_info->ID2D1DrawInfo_iface); + free(node); }
@@ -2265,6 +2268,218 @@ static void d2d_effect_init_properties_vtbls(struct d2d_effect *effect) } }
+static struct d2d_render_info *impl_from_ID2D1DrawInfo(ID2D1DrawInfo *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_render_info, ID2D1DrawInfo_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_QueryInterface(ID2D1DrawInfo *iface, REFIID iid, + void **obj) +{ + TRACE("iface %p, iid %s, obj %p.\n", iface, debugstr_guid(iid), obj); + + if (IsEqualGUID(iid, &IID_ID2D1DrawInfo) + || IsEqualGUID(iid, &IID_ID2D1RenderInfo) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *obj = iface; + ID2D1DrawInfo_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); + + *obj = NULL; + + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_draw_info_AddRef(ID2D1DrawInfo *iface) +{ + struct d2d_render_info *render_info = impl_from_ID2D1DrawInfo(iface); + ULONG refcount = InterlockedIncrement(&render_info->refcount); + + TRACE("iface %p refcount %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d2d_draw_info_Release(ID2D1DrawInfo *iface) +{ + struct d2d_render_info *render_info = impl_from_ID2D1DrawInfo(iface); + ULONG refcount = InterlockedDecrement(&render_info->refcount); + + TRACE("iface %p refcount %lu.\n", iface, refcount); + + if (!refcount) + free(render_info); + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetInputDescription(ID2D1DrawInfo *iface, + UINT32 index, D2D1_INPUT_DESCRIPTION description) +{ + FIXME("iface %p, index %u stub.\n", iface, index); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetOutputBuffer(ID2D1DrawInfo *iface, + D2D1_BUFFER_PRECISION precision, D2D1_CHANNEL_DEPTH depth) +{ + FIXME("iface %p, precision %u, depth %u stub.\n", iface, precision, depth); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d2d_draw_info_SetCached(ID2D1DrawInfo *iface, BOOL is_cached) +{ + FIXME("iface %p, is_cached %d stub.\n", iface, is_cached); +} + +static void STDMETHODCALLTYPE d2d_draw_info_SetInstructionCountHint(ID2D1DrawInfo *iface, + UINT32 count) +{ + FIXME("iface %p, count %u stub.\n", iface, count); +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetPixelShaderConstantBuffer(ID2D1DrawInfo *iface, + const BYTE *buffer, UINT32 size) +{ + FIXME("iface %p, buffer %p, size %u stub.\n", iface, buffer, size); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetResourceTexture(ID2D1DrawInfo *iface, + UINT32 index, ID2D1ResourceTexture *texture) +{ + FIXME("iface %p, index %u, texture %p stub.\n", iface, index, texture); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetVertexShaderConstantBuffer(ID2D1DrawInfo *iface, + const BYTE *buffer, UINT32 size) +{ + FIXME("iface %p, buffer %p, size %u stub.\n", iface, buffer, size); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetPixelShader(ID2D1DrawInfo *iface, + REFGUID id, D2D1_PIXEL_OPTIONS options) +{ + struct d2d_render_info *render_info = impl_from_ID2D1DrawInfo(iface); + + TRACE("iface %p, id %s, options %u.\n", iface, debugstr_guid(id), options); + + render_info->mask |= D2D_RENDER_INFO_PIXEL_SHADER; + render_info->pixel_shader = *id; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d2d_draw_info_SetVertexProcessing(ID2D1DrawInfo *iface, + ID2D1VertexBuffer *buffer, D2D1_VERTEX_OPTIONS options, + const D2D1_BLEND_DESCRIPTION *description, const D2D1_VERTEX_RANGE *range, + const GUID *shader) +{ + FIXME("iface %p, buffer %p, options %#x, description %p, range %p, shader %s stub.\n", + iface, buffer, options, description, range, debugstr_guid(shader)); + + return E_NOTIMPL; +} + +static const ID2D1DrawInfoVtbl d2d_draw_info_vtbl = +{ + d2d_draw_info_QueryInterface, + d2d_draw_info_AddRef, + d2d_draw_info_Release, + d2d_draw_info_SetInputDescription, + d2d_draw_info_SetOutputBuffer, + d2d_draw_info_SetCached, + d2d_draw_info_SetInstructionCountHint, + d2d_draw_info_SetPixelShaderConstantBuffer, + d2d_draw_info_SetResourceTexture, + d2d_draw_info_SetVertexShaderConstantBuffer, + d2d_draw_info_SetPixelShader, + d2d_draw_info_SetVertexProcessing, +}; + +static HRESULT d2d_effect_render_info_create(struct d2d_render_info **obj) +{ + struct d2d_render_info *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID2D1DrawInfo_iface.lpVtbl = &d2d_draw_info_vtbl; + object->refcount = 1; + + *obj = object; + + return S_OK; +} + +static bool d2d_transform_node_needs_render_info(const struct d2d_transform_node *node) +{ + static const GUID *iids[] = + { + &IID_ID2D1SourceTransform, + &IID_ID2D1ComputeTransform, + &IID_ID2D1DrawTransform, + }; + unsigned int i; + IUnknown *obj; + + for (i = 0; i < ARRAY_SIZE(iids); ++i) + { + if (SUCCEEDED(ID2D1TransformNode_QueryInterface(node->object, iids[i], (void **)&obj))) + { + IUnknown_Release(obj); + return true; + } + } + + return false; +} + +static HRESULT d2d_effect_transform_graph_initialize_nodes(struct d2d_transform_graph *graph) +{ + ID2D1DrawTransform *draw_transform; + struct d2d_transform_node *node; + HRESULT hr; + + LIST_FOR_EACH_ENTRY(node, &graph->nodes, struct d2d_transform_node, entry) + { + if (d2d_transform_node_needs_render_info(node)) + { + if (FAILED(hr = d2d_effect_render_info_create(&node->render_info))) + return hr; + } + + if (SUCCEEDED(ID2D1TransformNode_QueryInterface(node->object, &IID_ID2D1DrawTransform, + (void **)&draw_transform))) + { + hr = ID2D1DrawTransform_SetDrawInfo(draw_transform, &node->render_info->ID2D1DrawInfo_iface); + ID2D1DrawTransform_Release(draw_transform); + if (FAILED(hr)) + { + WARN("Failed to set draw info, hr %#lx.\n", hr); + return hr; + } + } + else + { + FIXME("Unsupported node %p.\n", node); + return E_NOTIMPL; + } + } + + return S_OK; +} + HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effect_id, ID2D1Effect **effect) { @@ -2330,6 +2545,13 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec return hr; }
+ if (FAILED(hr = d2d_effect_transform_graph_initialize_nodes(object->graph))) + { + WARN("Failed to initialize graph nodes, hr %#lx.\n", hr); + ID2D1Effect_Release(&object->ID2D1Effect_iface); + return hr; + } + *effect = &object->ID2D1Effect_iface;
TRACE("Created effect %p.\n", *effect);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=144845
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/d2d1/tests/d2d1.c:11726 Task: Patch failed to apply
=== debian11 (build log) ===
error: patch failed: dlls/d2d1/tests/d2d1.c:11726 Task: Patch failed to apply
=== debian11b (build log) ===
error: patch failed: dlls/d2d1/tests/d2d1.c:11726 Task: Patch failed to apply