Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/bitmap.c | 69 ++++++++++++++++++++++++---------------- dlls/d2d1/d2d1_private.h | 12 +++++-- dlls/d2d1/device.c | 9 ++---- dlls/d2d1/tests/d2d1.c | 63 ++++++++++++++++++++---------------- 4 files changed, 90 insertions(+), 63 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index 8b5b6aa0a9..f7db91b652 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -70,6 +70,8 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap1 *iface) if (!refcount) { ID3D10ShaderResourceView_Release(bitmap->view); + if (bitmap->surface) + IDXGISurface_Release(bitmap->surface); ID2D1Factory_Release(bitmap->factory); heap_free(bitmap); } @@ -188,9 +190,15 @@ static D2D1_BITMAP_OPTIONS STDMETHODCALLTYPE d2d_bitmap_GetOptions(ID2D1Bitmap1
static HRESULT STDMETHODCALLTYPE d2d_bitmap_GetSurface(ID2D1Bitmap1 *iface, IDXGISurface **surface) { - FIXME("iface %p, surface %p stub!\n", iface, surface); + struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface);
- return E_NOTIMPL; + TRACE("iface %p, surface %p.\n", iface, surface); + + *surface = bitmap->surface; + if (*surface) + IDXGISurface_AddRef(*surface); + + return *surface ? S_OK : D2DERR_INVALID_CALL; }
static HRESULT STDMETHODCALLTYPE d2d_bitmap_Map(ID2D1Bitmap1 *iface, D2D1_MAP_OPTIONS options, @@ -264,7 +272,7 @@ static BOOL format_supported(const D2D1_PIXEL_FORMAT *format) }
static void d2d_bitmap_init(struct d2d_bitmap *bitmap, ID2D1Factory *factory, - ID3D10ShaderResourceView *view, D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES1 *desc) + ID3D10ShaderResourceView *view, IDXGISurface *surface, D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES1 *desc) { bitmap->ID2D1Bitmap1_iface.lpVtbl = &d2d_bitmap_vtbl; bitmap->refcount = 1; @@ -275,6 +283,9 @@ static void d2d_bitmap_init(struct d2d_bitmap *bitmap, ID2D1Factory *factory, bitmap->dpi_x = desc->dpiX; bitmap->dpi_y = desc->dpiY; bitmap->options = desc->bitmapOptions; + bitmap->surface = surface; + if (bitmap->surface) + IDXGISurface_AddRef(bitmap->surface);
if (bitmap->dpi_x == 0.0f && bitmap->dpi_y == 0.0f) { @@ -283,13 +294,14 @@ static void d2d_bitmap_init(struct d2d_bitmap *bitmap, ID2D1Factory *factory, } }
-HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE_U size, const void *src_data, +HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) { D3D10_SUBRESOURCE_DATA resource_data; D3D10_TEXTURE2D_DESC texture_desc; ID3D10ShaderResourceView *view; ID3D10Texture2D *texture; + IDXGISurface *surface; HRESULT hr;
if (!format_supported(&desc->pixelFormat)) @@ -314,37 +326,46 @@ HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE resource_data.pSysMem = src_data; resource_data.SysMemPitch = pitch;
- if (FAILED(hr = ID3D10Device_CreateTexture2D(device, &texture_desc, + if (FAILED(hr = ID3D10Device_CreateTexture2D(context->device, &texture_desc, src_data ? &resource_data : NULL, &texture))) { ERR("Failed to create texture, hr %#x.\n", hr); return hr; }
- hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture, NULL, &view); + if (FAILED(hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface))) + { + WARN("Failed to get surface interface, hr %#x.\n", hr); + ID3D10Texture2D_Release(texture); + return hr; + } + + hr = ID3D10Device_CreateShaderResourceView(context->device, (ID3D10Resource *)texture, NULL, &view); ID3D10Texture2D_Release(texture); if (FAILED(hr)) { ERR("Failed to create view, hr %#x.\n", hr); + IDXGISurface_Release(surface); return hr; }
if ((*bitmap = heap_alloc_zero(sizeof(**bitmap)))) { - d2d_bitmap_init(*bitmap, factory, view, size, desc); + d2d_bitmap_init(*bitmap, context->factory, view, d2d_device_context_is_dxgi_target(context) ? surface : NULL, + size, desc); TRACE("Created bitmap %p.\n", *bitmap); }
ID3D10ShaderResourceView_Release(view); + IDXGISurface_Release(surface);
return *bitmap ? S_OK : E_OUTOFMEMORY; }
-HRESULT d2d_bitmap_create_shared(ID2D1DeviceContext *context, ID3D10Device *target_device, - REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) +HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, void *data, + const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) { D2D1_BITMAP_PROPERTIES1 d; - ID2D1Factory *factory;
if (IsEqualGUID(iid, &IID_ID2D1Bitmap)) { @@ -352,8 +373,7 @@ HRESULT d2d_bitmap_create_shared(ID2D1DeviceContext *context, ID3D10Device *targ ID3D10Device *device; HRESULT hr = S_OK;
- ID2D1DeviceContext_GetFactory(context, &factory); - if (src_impl->factory != factory) + if (src_impl->factory != context->factory) { hr = D2DERR_WRONG_FACTORY; goto failed; @@ -361,7 +381,7 @@ HRESULT d2d_bitmap_create_shared(ID2D1DeviceContext *context, ID3D10Device *targ
ID3D10ShaderResourceView_GetDevice(src_impl->view, &device); ID3D10Device_Release(device); - if (device != target_device) + if (device != context->device) { hr = D2DERR_UNSUPPORTED_OPERATION; goto failed; @@ -391,11 +411,10 @@ HRESULT d2d_bitmap_create_shared(ID2D1DeviceContext *context, ID3D10Device *targ goto failed; }
- d2d_bitmap_init(*bitmap, factory, src_impl->view, src_impl->pixel_size, desc); + d2d_bitmap_init(*bitmap, context->factory, src_impl->view, NULL, src_impl->pixel_size, desc); TRACE("Created bitmap %p.\n", *bitmap);
failed: - ID2D1Factory_Release(factory); return hr; }
@@ -417,13 +436,13 @@ HRESULT d2d_bitmap_create_shared(ID2D1DeviceContext *context, ID3D10Device *targ
ID3D10Resource_GetDevice(resource, &device); ID3D10Device_Release(device); - if (device != target_device) + if (device != context->device) { ID3D10Resource_Release(resource); return D2DERR_UNSUPPORTED_OPERATION; }
- hr = ID3D10Device_CreateShaderResourceView(target_device, resource, NULL, &view); + hr = ID3D10Device_CreateShaderResourceView(context->device, resource, NULL, &view); ID3D10Resource_Release(resource); if (FAILED(hr)) { @@ -455,22 +474,18 @@ HRESULT d2d_bitmap_create_shared(ID2D1DeviceContext *context, ID3D10Device *targ
if (d.dpiX == 0.0f || d.dpiY == 0.0f) { - float dpi_x, dpi_y; - - ID2D1DeviceContext_GetDpi(context, &dpi_x, &dpi_y); if (d.dpiX == 0.0f) - d.dpiX = dpi_x; + d.dpiX = context->desc.dpiX; if (d.dpiY == 0.0f) - d.dpiY = dpi_y; + d.dpiY = context->desc.dpiY; }
pixel_size.width = surface_desc.Width; pixel_size.height = surface_desc.Height;
- ID2D1DeviceContext_GetFactory(context, &factory); - d2d_bitmap_init(*bitmap, factory, view, pixel_size, &d); + d2d_bitmap_init(*bitmap, context->factory, view, d2d_device_context_is_dxgi_target(context) ? surface : NULL, + pixel_size, &d); ID3D10ShaderResourceView_Release(view); - ID2D1Factory_Release(factory); TRACE("Created bitmap %p.\n", *bitmap);
return S_OK; @@ -481,7 +496,7 @@ HRESULT d2d_bitmap_create_shared(ID2D1DeviceContext *context, ID3D10Device *targ return E_INVALIDARG; }
-HRESULT d2d_bitmap_create_from_wic_bitmap(ID2D1Factory *factory, ID3D10Device *device, IWICBitmapSource *bitmap_source, +HRESULT d2d_bitmap_create_from_wic_bitmap(struct d2d_device_context *context, IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) { const D2D1_PIXEL_FORMAT *d2d_format; @@ -581,7 +596,7 @@ HRESULT d2d_bitmap_create_from_wic_bitmap(ID2D1Factory *factory, ID3D10Device *d return hr; }
- hr = d2d_bitmap_create(factory, device, size, data, pitch, &bitmap_desc, bitmap); + hr = d2d_bitmap_create(context, size, data, pitch, &bitmap_desc, bitmap);
heap_free(data);
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 5f83f8fde2..510b61b219 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -160,6 +160,11 @@ HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surfac void **render_target) DECLSPEC_HIDDEN; HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN;
+static inline BOOL d2d_device_context_is_dxgi_target(const struct d2d_device_context *context) +{ + return !context->ops; +} + struct d2d_wic_render_target { IUnknown IUnknown_iface; @@ -339,6 +344,7 @@ struct d2d_bitmap
ID2D1Factory *factory; ID3D10ShaderResourceView *view; + IDXGISurface *surface; D2D1_SIZE_U pixel_size; D2D1_PIXEL_FORMAT format; float dpi_x; @@ -346,11 +352,11 @@ struct d2d_bitmap D2D1_BITMAP_OPTIONS options; };
-HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE_U size, const void *src_data, +HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; -HRESULT d2d_bitmap_create_shared(ID2D1DeviceContext *context, ID3D10Device *device, REFIID iid, void *data, +HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; -HRESULT d2d_bitmap_create_from_wic_bitmap(ID2D1Factory *factory, ID3D10Device *device, IWICBitmapSource *bitmap_source, +HRESULT d2d_bitmap_create_from_wic_bitmap(struct d2d_device_context *context, IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; struct d2d_bitmap *unsafe_impl_from_ID2D1Bitmap(ID2D1Bitmap *iface) DECLSPEC_HIDDEN;
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 649fcc4311..041cb33c90 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -343,8 +343,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmap(ID2D1DeviceCont bitmap_desc.colorContext = NULL; }
- if (SUCCEEDED(hr = d2d_bitmap_create(context->factory, context->device, - size, src_data, pitch, desc ? &bitmap_desc : NULL, &object))) + if (SUCCEEDED(hr = d2d_bitmap_create(context, size, src_data, pitch, desc ? &bitmap_desc : NULL, &object))) *bitmap = (ID2D1Bitmap *)&object->ID2D1Bitmap1_iface;
return hr; @@ -368,8 +367,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromWicBitmap(ID bitmap_desc.colorContext = NULL; }
- if (SUCCEEDED(hr = d2d_bitmap_create_from_wic_bitmap(context->factory, context->device, - bitmap_source, desc ? &bitmap_desc : NULL, &object))) + if (SUCCEEDED(hr = d2d_bitmap_create_from_wic_bitmap(context, bitmap_source, desc ? &bitmap_desc : NULL, &object))) *bitmap = (ID2D1Bitmap *)&object->ID2D1Bitmap1_iface;
return hr; @@ -393,8 +391,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSharedBitmap(ID2D1Devi bitmap_desc.colorContext = NULL; }
- if (SUCCEEDED(hr = d2d_bitmap_create_shared(iface, context->device, - iid, data, desc ? &bitmap_desc : NULL, &object))) + if (SUCCEEDED(hr = d2d_bitmap_create_shared(context, iid, data, desc ? &bitmap_desc : NULL, &object))) *bitmap = (ID2D1Bitmap *)&object->ID2D1Bitmap1_iface;
return hr; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 467d61314d..379edc1ff0 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -774,29 +774,30 @@ static ID2D1RenderTarget *create_render_target(IDXGISurface *surface) }
#define check_bitmap_surface(b, s, o) check_bitmap_surface_(__LINE__, b, s, o) -static void check_bitmap_surface_(unsigned int line, ID2D1Bitmap1 *bitmap, BOOL has_surface, DWORD expected_options) +static void check_bitmap_surface_(unsigned int line, ID2D1Bitmap *bitmap, BOOL has_surface, DWORD expected_options) { D2D1_BITMAP_OPTIONS options; IDXGISurface *surface; + ID2D1Bitmap1 *bitmap1; HRESULT hr;
- options = ID2D1Bitmap1_GetOptions(bitmap); + hr = ID2D1Bitmap_QueryInterface(bitmap, &IID_ID2D1Bitmap1, (void **)&bitmap1); + ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get ID2D1Bitmap1 interface, hr %#x.\n", hr); + + options = ID2D1Bitmap1_GetOptions(bitmap1); ok_(__FILE__, line)(options == expected_options, "Unexpected bitmap options %#x, expected %#x.\n", options, expected_options);
surface = (void *)0xdeadbeef; - hr = ID2D1Bitmap1_GetSurface(bitmap, &surface); + hr = ID2D1Bitmap1_GetSurface(bitmap1, &surface); if (has_surface) { D3D10_TEXTURE2D_DESC desc; ID3D10Texture2D *texture;
- todo_wine ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get bitmap surface, hr %#x.\n", hr); ok_(__FILE__, line)(!!surface, "Expected surface instance.\n");
- if (SUCCEEDED(hr)) - { /* Correlate with resource configuration. */ hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Texture2D, (void **)&texture); ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get texture pointer, hr %#x.\n", hr); @@ -813,14 +814,13 @@ static void check_bitmap_surface_(unsigned int line, ID2D1Bitmap1 *bitmap, BOOL
IDXGISurface_Release(surface); } - } else { - todo_wine { ok_(__FILE__, line)(hr == D2DERR_INVALID_CALL, "Unexpected hr %#x.\n", hr); ok_(__FILE__, line)(!surface, "Unexpected surface instance.\n"); } - } + + ID2D1Bitmap1_Release(bitmap1); }
static inline struct geometry_sink *impl_from_ID2D1SimplifiedGeometrySink(ID2D1SimplifiedGeometrySink *iface) @@ -4162,18 +4162,12 @@ static void test_shared_bitmap(void)
if (SUCCEEDED(hr)) { - ID2D1Bitmap1 *bitmap3; - size = ID2D1Bitmap_GetPixelSize(bitmap2); hr = IDXGISurface_GetDesc(surface2, &surface_desc); ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr); ok(size.width == surface_desc.Width && size.height == surface_desc.Height, "Got wrong bitmap size.\n");
- hr = ID2D1Bitmap_QueryInterface(bitmap2, &IID_ID2D1Bitmap1, (void **)&bitmap3); - ok(SUCCEEDED(hr), "Failed to get ID2D1Bitmap1 pointer, hr %#x.\n", hr); - - check_bitmap_surface(bitmap3, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW); - ID2D1Bitmap1_Release(bitmap3); + check_bitmap_surface(bitmap2, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
ID2D1Bitmap_Release(bitmap2);
@@ -6592,8 +6586,9 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B { D2D1_BITMAP_PROPERTIES bitmap_desc; ID2D1RenderTarget *compatible_rt; + IWICImagingFactory *wic_factory; ID2D1DeviceContext *context; - ID2D1Bitmap1 *bitmap1; + IWICBitmap *wic_bitmap; ID2D1Bitmap *bitmap; D2D1_SIZE_U size; HRESULT hr; @@ -6603,6 +6598,7 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B 0x7f7f0000, };
+ /* Raw data bitmap. */ set_size_u(&size, 1, 1); bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; @@ -6611,14 +6607,31 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap); ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
- hr = ID2D1Bitmap_QueryInterface(bitmap, &IID_ID2D1Bitmap1, (void **)&bitmap1); - ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get ID2D1Bitmap1 interface, hr %#x.\n", hr); + check_bitmap_surface_(line, bitmap, has_surface, options);
- check_bitmap_surface_(line, bitmap1, has_surface, options); + ID2D1Bitmap_Release(bitmap); + + /* WIC bitmap. */ + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, + &IID_IWICImagingFactory, (void **)&wic_factory); + ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr); + + hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16, + &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap); + ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create WIC bitmap, hr %#x.\n", hr); + IWICImagingFactory_Release(wic_factory); + + hr = ID2D1RenderTarget_CreateBitmapFromWicBitmap(rt, (IWICBitmapSource *)wic_bitmap, NULL, &bitmap); + ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap from WIC source, hr %#x.\n", hr); + + check_bitmap_surface_(line, bitmap, has_surface, options);
- ID2D1Bitmap1_Release(bitmap1); ID2D1Bitmap_Release(bitmap);
+ CoUninitialize(); + if (FAILED(ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&context))) { /* Compatible target follows its parent. */ @@ -6629,13 +6642,9 @@ static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, B hr = ID2D1RenderTarget_CreateBitmap(compatible_rt, size, bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap); ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
- hr = ID2D1Bitmap_QueryInterface(bitmap, &IID_ID2D1Bitmap1, (void **)&bitmap1); - ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get ID2D1Bitmap1 interface, hr %#x.\n", hr); - - check_bitmap_surface_(line, bitmap1, has_surface, options); + check_bitmap_surface_(line, bitmap, has_surface, options); ID2D1RenderTarget_Release(compatible_rt);
- ID2D1Bitmap1_Release(bitmap1); ID2D1Bitmap_Release(bitmap); } else @@ -6707,7 +6716,7 @@ if (SUCCEEDED(hr)) hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, surface, NULL, &bitmap); ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
- check_bitmap_surface(bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW); + check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW); check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE);
ID2D1DeviceContext_Release(device_context);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 8 ++--- dlls/d2d1/factory.c | 26 +++++++++++--- dlls/d2d1/state_block.c | 75 ++++++++++++++++++++++++++-------------- dlls/d2d1/tests/d2d1.c | 69 ++++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 34 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 510b61b219..3fed59fa72 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -146,7 +146,7 @@ struct d2d_device_context ID3D10BlendState *bs;
struct d2d_error_state error; - D2D1_DRAWING_STATE_DESCRIPTION drawing_state; + D2D1_DRAWING_STATE_DESCRIPTION1 drawing_state; IDWriteRenderingParams *text_rendering_params; IDWriteRenderingParams *default_text_rendering_params;
@@ -362,16 +362,16 @@ struct d2d_bitmap *unsafe_impl_from_ID2D1Bitmap(ID2D1Bitmap *iface) DECLSPEC_HID
struct d2d_state_block { - ID2D1DrawingStateBlock ID2D1DrawingStateBlock_iface; + ID2D1DrawingStateBlock1 ID2D1DrawingStateBlock1_iface; LONG refcount;
ID2D1Factory *factory; - D2D1_DRAWING_STATE_DESCRIPTION drawing_state; + D2D1_DRAWING_STATE_DESCRIPTION1 drawing_state; IDWriteRenderingParams *text_rendering_params; };
void d2d_state_block_init(struct d2d_state_block *state_block, ID2D1Factory *factory, - const D2D1_DRAWING_STATE_DESCRIPTION *desc, IDWriteRenderingParams *text_rendering_params) DECLSPEC_HIDDEN; + const D2D1_DRAWING_STATE_DESCRIPTION1 *desc, IDWriteRenderingParams *text_rendering_params) DECLSPEC_HIDDEN; struct d2d_state_block *unsafe_impl_from_ID2D1DrawingStateBlock(ID2D1DrawingStateBlock *iface) DECLSPEC_HIDDEN;
enum d2d_geometry_state diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 1a28663e89..5ce21f6f15 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -245,6 +245,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock(ID2D1Factor const D2D1_DRAWING_STATE_DESCRIPTION *desc, IDWriteRenderingParams *text_rendering_params, ID2D1DrawingStateBlock **state_block) { + D2D1_DRAWING_STATE_DESCRIPTION1 state_desc; struct d2d_state_block *object;
TRACE("iface %p, desc %p, text_rendering_params %p, state_block %p.\n", @@ -253,10 +254,17 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock(ID2D1Factor if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY;
- d2d_state_block_init(object, (ID2D1Factory *)iface, desc, text_rendering_params); + if (desc) + { + memcpy(&state_desc, desc, sizeof(*desc)); + state_desc.primitiveBlend = D2D1_PRIMITIVE_BLEND_SOURCE_OVER; + state_desc.unitMode = D2D1_UNIT_MODE_DIPS; + } + + d2d_state_block_init(object, (ID2D1Factory *)iface, desc ? &state_desc : NULL, text_rendering_params);
TRACE("Created state block %p.\n", object); - *state_block = &object->ID2D1DrawingStateBlock_iface; + *state_block = (ID2D1DrawingStateBlock *)&object->ID2D1DrawingStateBlock1_iface;
return S_OK; } @@ -411,10 +419,20 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock1(ID2D1Facto const D2D1_DRAWING_STATE_DESCRIPTION1 *desc, IDWriteRenderingParams *text_rendering_params, ID2D1DrawingStateBlock1 **state_block) { - FIXME("iface %p, desc %p, text_rendering_params %p, state_block %p stub!\n", + struct d2d_state_block *object; + + TRACE("iface %p, desc %p, text_rendering_params %p, state_block %p.\n", iface, desc, text_rendering_params, state_block);
- return E_NOTIMPL; + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + d2d_state_block_init(object, (ID2D1Factory *)iface, desc, text_rendering_params); + + TRACE("Created state block %p.\n", object); + *state_block = &object->ID2D1DrawingStateBlock1_iface; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGdiMetafile(ID2D1Factory1 *iface, diff --git a/dlls/d2d1/state_block.c b/dlls/d2d1/state_block.c index 3a3cb2e460..b15384e116 100644 --- a/dlls/d2d1/state_block.c +++ b/dlls/d2d1/state_block.c @@ -23,20 +23,21 @@
WINE_DEFAULT_DEBUG_CHANNEL(d2d);
-static inline struct d2d_state_block *impl_from_ID2D1DrawingStateBlock(ID2D1DrawingStateBlock *iface) +static inline struct d2d_state_block *impl_from_ID2D1DrawingStateBlock1(ID2D1DrawingStateBlock1 *iface) { - return CONTAINING_RECORD(iface, struct d2d_state_block, ID2D1DrawingStateBlock_iface); + return CONTAINING_RECORD(iface, struct d2d_state_block, ID2D1DrawingStateBlock1_iface); }
-static HRESULT STDMETHODCALLTYPE d2d_state_block_QueryInterface(ID2D1DrawingStateBlock *iface, REFIID iid, void **out) +static HRESULT STDMETHODCALLTYPE d2d_state_block_QueryInterface(ID2D1DrawingStateBlock1 *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
- if (IsEqualGUID(iid, &IID_ID2D1DrawingStateBlock) + if (IsEqualGUID(iid, &IID_ID2D1DrawingStateBlock1) + || IsEqualGUID(iid, &IID_ID2D1DrawingStateBlock) || IsEqualGUID(iid, &IID_ID2D1Resource) || IsEqualGUID(iid, &IID_IUnknown)) { - ID2D1DrawingStateBlock_AddRef(iface); + ID2D1DrawingStateBlock1_AddRef(iface); *out = iface; return S_OK; } @@ -47,9 +48,9 @@ static HRESULT STDMETHODCALLTYPE d2d_state_block_QueryInterface(ID2D1DrawingStat return E_NOINTERFACE; }
-static ULONG STDMETHODCALLTYPE d2d_state_block_AddRef(ID2D1DrawingStateBlock *iface) +static ULONG STDMETHODCALLTYPE d2d_state_block_AddRef(ID2D1DrawingStateBlock1 *iface) { - struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock(iface); + struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface); ULONG refcount = InterlockedIncrement(&state_block->refcount);
TRACE("%p increasing refcount to %u.\n", iface, refcount); @@ -57,9 +58,9 @@ static ULONG STDMETHODCALLTYPE d2d_state_block_AddRef(ID2D1DrawingStateBlock *if return refcount; }
-static ULONG STDMETHODCALLTYPE d2d_state_block_Release(ID2D1DrawingStateBlock *iface) +static ULONG STDMETHODCALLTYPE d2d_state_block_Release(ID2D1DrawingStateBlock1 *iface) { - struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock(iface); + struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface); ULONG refcount = InterlockedDecrement(&state_block->refcount);
TRACE("%p decreasing refcount to %u.\n", iface, refcount); @@ -75,39 +76,39 @@ static ULONG STDMETHODCALLTYPE d2d_state_block_Release(ID2D1DrawingStateBlock *i return refcount; }
-static void STDMETHODCALLTYPE d2d_state_block_GetFactory(ID2D1DrawingStateBlock *iface, ID2D1Factory **factory) +static void STDMETHODCALLTYPE d2d_state_block_GetFactory(ID2D1DrawingStateBlock1 *iface, ID2D1Factory **factory) { - struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock(iface); + struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface);
TRACE("iface %p, factory %p.\n", iface, factory);
ID2D1Factory_AddRef(*factory = state_block->factory); }
-static void STDMETHODCALLTYPE d2d_state_block_GetDescription(ID2D1DrawingStateBlock *iface, +static void STDMETHODCALLTYPE d2d_state_block_GetDescription(ID2D1DrawingStateBlock1 *iface, D2D1_DRAWING_STATE_DESCRIPTION *desc) { - struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock(iface); + struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface);
TRACE("iface %p, desc %p.\n", iface, desc);
- *desc = state_block->drawing_state; + memcpy(desc, &state_block->drawing_state, sizeof(*desc)); }
-static void STDMETHODCALLTYPE d2d_state_block_SetDescription(ID2D1DrawingStateBlock *iface, +static void STDMETHODCALLTYPE d2d_state_block_SetDescription(ID2D1DrawingStateBlock1 *iface, const D2D1_DRAWING_STATE_DESCRIPTION *desc) { - struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock(iface); + struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface);
TRACE("iface %p, desc %p.\n", iface, desc);
- state_block->drawing_state = *desc; + memcpy(&state_block->drawing_state, desc, sizeof(*desc)); }
-static void STDMETHODCALLTYPE d2d_state_block_SetTextRenderingParams(ID2D1DrawingStateBlock *iface, +static void STDMETHODCALLTYPE d2d_state_block_SetTextRenderingParams(ID2D1DrawingStateBlock1 *iface, IDWriteRenderingParams *text_rendering_params) { - struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock(iface); + struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface);
TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params);
@@ -118,10 +119,10 @@ static void STDMETHODCALLTYPE d2d_state_block_SetTextRenderingParams(ID2D1Drawin state_block->text_rendering_params = text_rendering_params; }
-static void STDMETHODCALLTYPE d2d_state_block_GetTextRenderingParams(ID2D1DrawingStateBlock *iface, +static void STDMETHODCALLTYPE d2d_state_block_GetTextRenderingParams(ID2D1DrawingStateBlock1 *iface, IDWriteRenderingParams **text_rendering_params) { - struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock(iface); + struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface);
TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params);
@@ -129,7 +130,27 @@ static void STDMETHODCALLTYPE d2d_state_block_GetTextRenderingParams(ID2D1Drawin IDWriteRenderingParams_AddRef(*text_rendering_params); }
-static const struct ID2D1DrawingStateBlockVtbl d2d_state_block_vtbl = +static void STDMETHODCALLTYPE d2d_state_block_GetDescription1(ID2D1DrawingStateBlock1 *iface, + D2D1_DRAWING_STATE_DESCRIPTION1 *desc) +{ + struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + *desc = state_block->drawing_state; +} + +static void STDMETHODCALLTYPE d2d_state_block_SetDescription1(ID2D1DrawingStateBlock1 *iface, + const D2D1_DRAWING_STATE_DESCRIPTION1 *desc) +{ + struct d2d_state_block *state_block = impl_from_ID2D1DrawingStateBlock1(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + state_block->drawing_state = *desc; +} + +static const struct ID2D1DrawingStateBlock1Vtbl d2d_state_block_vtbl = { d2d_state_block_QueryInterface, d2d_state_block_AddRef, @@ -139,10 +160,12 @@ static const struct ID2D1DrawingStateBlockVtbl d2d_state_block_vtbl = d2d_state_block_SetDescription, d2d_state_block_SetTextRenderingParams, d2d_state_block_GetTextRenderingParams, + d2d_state_block_GetDescription1, + d2d_state_block_SetDescription1, };
void d2d_state_block_init(struct d2d_state_block *state_block, ID2D1Factory *factory, - const D2D1_DRAWING_STATE_DESCRIPTION *desc, IDWriteRenderingParams *text_rendering_params) + const D2D1_DRAWING_STATE_DESCRIPTION1 *desc, IDWriteRenderingParams *text_rendering_params) { static const D2D1_MATRIX_3X2_F identity = { @@ -151,7 +174,7 @@ void d2d_state_block_init(struct d2d_state_block *state_block, ID2D1Factory *fac 0.0f, 0.0f, };
- state_block->ID2D1DrawingStateBlock_iface.lpVtbl = &d2d_state_block_vtbl; + state_block->ID2D1DrawingStateBlock1_iface.lpVtbl = &d2d_state_block_vtbl; state_block->refcount = 1; ID2D1Factory_AddRef(state_block->factory = factory); if (desc) @@ -166,6 +189,6 @@ struct d2d_state_block *unsafe_impl_from_ID2D1DrawingStateBlock(ID2D1DrawingStat { if (!iface) return NULL; - assert(iface->lpVtbl == &d2d_state_block_vtbl); - return CONTAINING_RECORD(iface, struct d2d_state_block, ID2D1DrawingStateBlock_iface); + assert(iface->lpVtbl == (ID2D1DrawingStateBlockVtbl *)&d2d_state_block_vtbl); + return CONTAINING_RECORD(iface, struct d2d_state_block, ID2D1DrawingStateBlock1_iface); } diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 379edc1ff0..39b3092008 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -1277,6 +1277,7 @@ static void test_state_block(void) ID2D1DrawingStateBlock *state_block; IDWriteFactory *dwrite_factory; IDXGISwapChain *swapchain; + ID2D1Factory1 *factory1; ID2D1RenderTarget *rt; ID3D10Device1 *device; IDXGISurface *surface; @@ -1463,6 +1464,74 @@ static void test_state_block(void) text_rendering_params2, text_rendering_params1); IDWriteRenderingParams_Release(text_rendering_params2);
+ if (SUCCEEDED(ID2D1Factory_QueryInterface(factory, &IID_ID2D1Factory1, (void **)&factory1))) + { + D2D1_DRAWING_STATE_DESCRIPTION1 drawing_state1; + ID2D1DrawingStateBlock1 *state_block1; + + hr = ID2D1DrawingStateBlock_QueryInterface(state_block, &IID_ID2D1DrawingStateBlock1, (void **)&state_block1); + ok(SUCCEEDED(hr), "Failed to get ID2D1DrawingStateBlock1 interface, hr %#x.\n", hr); + + ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1); + ok(drawing_state1.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED, + "Got unexpected antialias mode %#x.\n", drawing_state1.antialiasMode); + ok(drawing_state1.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, + "Got unexpected text antialias mode %#x.\n", drawing_state1.textAntialiasMode); + ok(drawing_state1.tag1 == 3 && drawing_state1.tag2 == 4, "Got unexpected tags %s:%s.\n", + wine_dbgstr_longlong(drawing_state1.tag1), wine_dbgstr_longlong(drawing_state1.tag2)); + ok(!memcmp(&drawing_state1.transform, &transform1, sizeof(drawing_state1.transform)), + "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", + drawing_state1.transform._11, drawing_state1.transform._12, drawing_state1.transform._21, + drawing_state1.transform._22, drawing_state1.transform._31, drawing_state1.transform._32); + ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_SOURCE_OVER, + "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend); + ok(drawing_state1.unitMode == D2D1_UNIT_MODE_DIPS, "Got unexpected unit mode %#x.\n", drawing_state1.unitMode); + ID2D1DrawingStateBlock1_GetTextRenderingParams(state_block1, &text_rendering_params2); + ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n", + text_rendering_params2, text_rendering_params1); + IDWriteRenderingParams_Release(text_rendering_params2); + + drawing_state1.primitiveBlend = D2D1_PRIMITIVE_BLEND_COPY; + drawing_state1.unitMode = D2D1_UNIT_MODE_PIXELS; + ID2D1DrawingStateBlock1_SetDescription(state_block1, &drawing_state1); + ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1); + ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_COPY, + "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend); + ok(drawing_state1.unitMode == D2D1_UNIT_MODE_PIXELS, + "Got unexpected unit mode %#x.\n", drawing_state1.unitMode); + + ID2D1DrawingStateBlock_SetDescription(state_block, &drawing_state); + ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1); + ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_COPY, + "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend); + ok(drawing_state1.unitMode == D2D1_UNIT_MODE_PIXELS, + "Got unexpected unit mode %#x.\n", drawing_state1.unitMode); + + ID2D1DrawingStateBlock1_Release(state_block1); + + hr = ID2D1Factory1_CreateDrawingStateBlock(factory1, NULL, NULL, &state_block1); + ok(SUCCEEDED(hr), "Failed to create drawing state block, hr %#x\n", hr); + ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1); + ok(drawing_state1.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, + "Got unexpected antialias mode %#x.\n", drawing_state1.antialiasMode); + ok(drawing_state1.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, + "Got unexpected text antialias mode %#x.\n", drawing_state1.textAntialiasMode); + ok(drawing_state1.tag1 == 0 && drawing_state1.tag2 == 0, "Got unexpected tags %s:%s.\n", + wine_dbgstr_longlong(drawing_state1.tag1), wine_dbgstr_longlong(drawing_state1.tag2)); + ok(!memcmp(&drawing_state1.transform, &identity, sizeof(drawing_state1.transform)), + "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", + drawing_state1.transform._11, drawing_state1.transform._12, drawing_state1.transform._21, + drawing_state1.transform._22, drawing_state1.transform._31, drawing_state1.transform._32); + ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_SOURCE_OVER, + "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend); + ok(drawing_state1.unitMode == D2D1_UNIT_MODE_DIPS, "Got unexpected unit mode %#x.\n", drawing_state1.unitMode); + ID2D1DrawingStateBlock1_GetTextRenderingParams(state_block1, &text_rendering_params2); + ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2); + ID2D1DrawingStateBlock1_Release(state_block1); + + ID2D1Factory1_Release(factory1); + } + ID2D1DrawingStateBlock_Release(state_block);
refcount = IDWriteRenderingParams_Release(text_rendering_params1);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
On 14 September 2018 at 10:20, Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d2d1/bitmap.c | 69 ++++++++++++++++++++++++---------------- dlls/d2d1/d2d1_private.h | 12 +++++-- dlls/d2d1/device.c | 9 ++---- dlls/d2d1/tests/d2d1.c | 63 ++++++++++++++++++++---------------- 4 files changed, 90 insertions(+), 63 deletions(-)
This seems a little more complicated than it really needs to be. In d2d_bitmap_GetSurface(), can't you just do something like the following?
ID3D10ShaderResourceView_GetResource(bitmap->view, &resource); ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface, &surface);
On 09/14/2018 06:15 PM, Henri Verbeet wrote:
On 14 September 2018 at 10:20, Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d2d1/bitmap.c | 69 ++++++++++++++++++++++++---------------- dlls/d2d1/d2d1_private.h | 12 +++++-- dlls/d2d1/device.c | 9 ++---- dlls/d2d1/tests/d2d1.c | 63 ++++++++++++++++++++---------------- 4 files changed, 90 insertions(+), 63 deletions(-)
This seems a little more complicated than it really needs to be. In d2d_bitmap_GetSurface(), can't you just do something like the following?
ID3D10ShaderResourceView_GetResource(bitmap->view, &resource); ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface, &surface);
Yes, that would be an alternative to separate surface pointer in bitmap structure. The problem is that this method is not supposed to always work. According to tests it only works for bitmaps created from DXGI target/device context. I can use some flag instead to indicate that if you think it's better.
On 14 September 2018 at 20:13, Nikolay Sivov nsivov@codeweavers.com wrote:
On 09/14/2018 06:15 PM, Henri Verbeet wrote:
This seems a little more complicated than it really needs to be. In d2d_bitmap_GetSurface(), can't you just do something like the following?
ID3D10ShaderResourceView_GetResource(bitmap->view, &resource); ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface, &surface);
Yes, that would be an alternative to separate surface pointer in bitmap structure. The problem is that this method is not supposed to always work. According to tests it only works for bitmaps created from DXGI target/device context. I can use some flag instead to indicate that if you think it's better.
Sure, you can just flag it on bitmap creation. It's perhaps unfortunate that D2D1_BITMAP_OPTIONS doesn't have a flag for that.
I'm not necessarily opposed to storing the surface in struct d2d_bitmap though, but in that case I think you should retrieve it from the SRV in d2d_bitmap_init() as well, instead of doing that in its callers.
On 09/14/2018 07:02 PM, Henri Verbeet wrote:
On 14 September 2018 at 20:13, Nikolay Sivov nsivov@codeweavers.com wrote:
On 09/14/2018 06:15 PM, Henri Verbeet wrote:
This seems a little more complicated than it really needs to be. In d2d_bitmap_GetSurface(), can't you just do something like the following?
ID3D10ShaderResourceView_GetResource(bitmap->view, &resource); ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface, &surface);
Yes, that would be an alternative to separate surface pointer in bitmap structure. The problem is that this method is not supposed to always work. According to tests it only works for bitmaps created from DXGI target/device context. I can use some flag instead to indicate that if you think it's better.
Sure, you can just flag it on bitmap creation. It's perhaps unfortunate that D2D1_BITMAP_OPTIONS doesn't have a flag for that.
Yes, I don't think you can tell from options if it will work.
I'm not necessarily opposed to storing the surface in struct d2d_bitmap though, but in that case I think you should retrieve it from the SRV in d2d_bitmap_init() as well, instead of doing that in its callers.
Right, I'll keep this field then, thanks for the suggestion.