From: Santino Mazza <smazza@codeweavers.com> --- dlls/d2d1/d2d1_private.h | 1 + dlls/d2d1/device.c | 3 +++ dlls/d2d1/sprite_batch.c | 29 +++++++++++++++++++++++------ dlls/d2d1/tests/d2d1.c | 4 ++-- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 2609bfdeff2..a095aaef66c 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -470,6 +470,7 @@ struct d2d_sprite_batch { UINT32 sprites_allocated; D2D1_RECT_F *destination_rectangles; D2D1_RECT_U *source_rectangles; + D2D1_MATRIX_3X2_F *transform_matrixes; }; HRESULT d2d_create_sprite_batch(struct d2d_device_context *ctx, ID2D1SpriteBatch **iface); diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index ac25a044526..5ad1b32421a 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -3072,9 +3072,12 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawSpriteBatch(ID2D1DeviceCont for (int i = start_index; i < start_index + sprite_count; ++i) { convert_rect_u_to_rect_f(&sprite_batch_impl->source_rectangles[i], &source_rect); + ID2D1DeviceContext6_SetTransform(iface, &sprite_batch_impl->transform_matrixes[i]); ID2D1DeviceContext6_DrawBitmap(iface, bitmap, &sprite_batch_impl->destination_rectangles[i], 1.0f, (D2D1_INTERPOLATION_MODE)interpolation_mode, is_rect_f_empty(&source_rect) ? NULL : &source_rect, 0); } + + ID2D1DeviceContext6_SetTransform(iface, &identity); } static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSvgGlyphStyle(ID2D1DeviceContext6 *iface, diff --git a/dlls/d2d1/sprite_batch.c b/dlls/d2d1/sprite_batch.c index eb4fb4e27b0..edc43b43585 100644 --- a/dlls/d2d1/sprite_batch.c +++ b/dlls/d2d1/sprite_batch.c @@ -66,6 +66,7 @@ static ULONG STDMETHODCALLTYPE d2d_sprite_batch_Release(ID2D1SpriteBatch *iface) ID2D1Factory_Release(batch->factory); free(batch->destination_rectangles); free(batch->source_rectangles); + free(batch->transform_matrixes); free(batch); } @@ -82,6 +83,16 @@ static void STDMETHODCALLTYPE d2d_sprite_batch_GetFactory(ID2D1SpriteBatch *ifac ID2D1Factory_AddRef(*factory); } +static void set_matrix_identity(D2D1_MATRIX_3X2_F *matrix) +{ + matrix->_11 = 1.0f; + matrix->_12 = 0.0f; + matrix->_21 = 0.0f; + matrix->_22 = 1.0f; + matrix->_31 = 0.0f; + matrix->_32 = 0.0f; +} + static HRESULT STDMETHODCALLTYPE d2d_sprite_batch_AddSprites(ID2D1SpriteBatch *iface, UINT32 sprite_count, const D2D1_RECT_F *destination_rectangles, const D2D1_RECT_U *source_rectangles, const D2D1_COLOR_F *colors, const D2D1_MATRIX_3X2_F *transforms, UINT32 destination_rectangles_stride, UINT32 source_rectangles_stride, @@ -97,14 +108,12 @@ static HRESULT STDMETHODCALLTYPE d2d_sprite_batch_AddSprites(ID2D1SpriteBatch *i if (colors) FIXME("Color mask not implemented\n"); - if (transforms) - FIXME("Transform matrixes not implemented.\n"); - if (batch->sprites_allocated <= batch->sprite_count + sprite_count) { batch->sprites_allocated = max(batch->sprites_allocated + sprite_count, batch->sprites_allocated * 2); batch->destination_rectangles = realloc(batch->destination_rectangles, sizeof(D2D1_RECT_F) * batch->sprites_allocated); batch->source_rectangles = realloc(batch->source_rectangles, batch->sprites_allocated * sizeof(D2D1_RECT_U)); + batch->transform_matrixes = realloc(batch->transform_matrixes, batch->sprites_allocated * sizeof(D2D1_MATRIX_3X2_F)); } for (int i = 0; i < sprite_count; ++i) @@ -114,6 +123,11 @@ static HRESULT STDMETHODCALLTYPE d2d_sprite_batch_AddSprites(ID2D1SpriteBatch *i batch->source_rectangles[i + batch->sprite_count] = *(D2D1_RECT_U *)(((UCHAR*)source_rectangles) + i * source_rectangles_stride); else batch->source_rectangles[i + batch->sprite_count] = (D2D1_RECT_U){0}; + + if (transforms) + batch->transform_matrixes[i + batch->sprite_count] = *(D2D1_MATRIX_3X2_F *)(((UCHAR*)transforms) + i * transforms_stride); + else + set_matrix_identity(&batch->transform_matrixes[i + batch->sprite_count]); } batch->sprite_count += sprite_count; @@ -139,15 +153,14 @@ static HRESULT STDMETHODCALLTYPE d2d_sprite_batch_SetSprites(ID2D1SpriteBatch *i if (colors) FIXME("Color mask not implemented\n"); - if (transforms) - FIXME("Transform matrixes not implemented\n"); - for (int i = start_index; i < start_index + sprite_count; ++i) { if (destination_rectangles) batch->destination_rectangles[i] = *(D2D1_RECT_F *)(((UCHAR*)destination_rectangles) + i * destination_rectangles_stride); if (source_rectangles) batch->source_rectangles[i] = *(D2D1_RECT_U *)(((UCHAR*)source_rectangles) + i * source_rectangles_stride); + if (transforms) + batch->transform_matrixes[i] = *(D2D1_MATRIX_3X2_F *)(((UCHAR*)transforms) + i * transforms_stride); } return S_OK; @@ -172,6 +185,9 @@ static HRESULT STDMETHODCALLTYPE d2d_sprite_batch_GetSprites(ID2D1SpriteBatch *i if (source_rectangles) memcpy(source_rectangles, &batch->source_rectangles[start_index], sizeof(D2D1_RECT_U) * sprite_count); + if (transforms) + memcpy(transforms, &batch->transform_matrixes[start_index], sizeof(D2D1_MATRIX_3X2_F) * sprite_count); + return S_OK; } @@ -213,6 +229,7 @@ HRESULT d2d_create_sprite_batch(struct d2d_device_context *ctx, ID2D1SpriteBatch sprite_batch->sprites_allocated = 1; sprite_batch->destination_rectangles = calloc(sprite_batch->sprites_allocated, sizeof(D2D1_RECT_F)); sprite_batch->source_rectangles = calloc(sprite_batch->sprites_allocated, sizeof(D2D1_RECT_U)); + sprite_batch->transform_matrixes = calloc(sprite_batch->sprites_allocated, sizeof(D2D1_MATRIX_3X2_F)); ID2D1Factory_AddRef(ctx->factory); sprite_batch->factory = ctx->factory; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index b93d3666ba0..b51f3ca437f 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -18288,7 +18288,7 @@ static void test_sprite_batches(BOOL d3d11) { hr = ID2D1DeviceContext3_EndDraw(device, 0, 0); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); check = compare_surface(&ctx, "30bf2de6f4f10ae8ebfc61261ad0d0a4abfed094"); - todo_wine ok(check, "Surface does not match.\n"); + ok(check, "Surface does not match.\n"); ID2D1SpriteBatch_Clear(sprite_batch); @@ -18320,7 +18320,7 @@ static void test_sprite_batches(BOOL d3d11) { hr = ID2D1DeviceContext3_EndDraw(device, 0, 0); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); check = compare_surface(&ctx, "72d4c7723073eabc2d7d1939b6f41040546b21f7"); - todo_wine ok(check, "Surface does not match.\n"); + todo_wine ok(check, "Surface does not match.\n"); // FIXME: Anti Aliasing issue? If instead of skewing I just translate or scale the surface matches. ID2D1DeviceContext3_SetAntialiasMode(device, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11249