https://bugs.winehq.org/show_bug.cgi?id=44052
Signed-off-by: Lucian Poston lucian.poston@gmail.com --- dlls/d2d1/bitmap.c | 132 ++++++++++++++++++++++++++++++++++++++++----- dlls/d2d1/d2d1_private.h | 6 +++ dlls/d2d1/device_context.c | 51 +++++++++++++++++- 3 files changed, 173 insertions(+), 16 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index 54202a6b13..576645f05e 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -29,6 +29,30 @@ static inline struct d2d_bitmap *impl_from_ID2D1Bitmap(ID2D1Bitmap1 *iface) return CONTAINING_RECORD(iface, struct d2d_bitmap, ID2D1Bitmap_iface); }
+static D2D1_BITMAP_PROPERTIES1 bitmap_properties_to_properties1( + const D2D1_BITMAP_PROPERTIES *desc) +{ + D2D1_BITMAP_PROPERTIES1 d; + d.bitmapOptions = D2D1_BITMAP_OPTIONS_NONE; + d.colorContext = NULL; + if (desc == NULL) + { + d.pixelFormat.format = DXGI_FORMAT_UNKNOWN; + d.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN; + d.dpiX = 96.0f; + d.dpiY = 96.0f; + } + else + { + d.pixelFormat.format = desc->pixelFormat.format; + d.pixelFormat.alphaMode = desc->pixelFormat.alphaMode; + d.dpiX = desc->dpiX; + d.dpiY = desc->dpiY; + } + + return d; +} + static HRESULT STDMETHODCALLTYPE d2d_bitmap_QueryInterface(ID2D1Bitmap1 *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); @@ -69,6 +93,10 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap1 *iface)
if (!refcount) { + if (bitmap->color_context) + ID2D1ColorContext_Release(bitmap->color_context); + if (bitmap->surface) + IDXGISurface_Release(bitmap->surface); ID3D10ShaderResourceView_Release(bitmap->view); ID2D1Factory_Release(bitmap->factory); HeapFree(GetProcessHeap(), 0, bitmap); @@ -193,8 +221,19 @@ static HRESULT WINAPI d2d_bitmap1_GetSurface( IDXGISurface **dxgiSurface) { struct d2d_bitmap *This = impl_from_ID2D1Bitmap(iface); - FIXME("%p stub!\n", This); - return E_NOTIMPL; + + TRACE("This %p, dxgiSurface %p.\n", This, dxgiSurface); + if (dxgiSurface == NULL) + return E_POINTER; + + if (This->surface) + { + IDXGISurface_AddRef(This->surface); + } + + *dxgiSurface = This->surface; + + return S_OK; }
static HRESULT WINAPI d2d_bitmap1_Map( @@ -271,7 +310,8 @@ 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_PROPERTIES *desc) + ID3D10ShaderResourceView *view, D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES1 *desc, + IDXGISurface *surface) { bitmap->ID2D1Bitmap_iface.lpVtbl = &d2d_bitmap_vtbl; bitmap->refcount = 1; @@ -281,6 +321,12 @@ static void d2d_bitmap_init(struct d2d_bitmap *bitmap, ID2D1Factory *factory, bitmap->format = desc->pixelFormat; bitmap->dpi_x = desc->dpiX; bitmap->dpi_y = desc->dpiY; + bitmap->options = desc->bitmapOptions; + if (surface) + IDXGISurface_AddRef(bitmap->surface = surface); + + if (desc->colorContext) + FIXME("Ignoring ID2D1ColorContext");
if (bitmap->dpi_x == 0.0f && bitmap->dpi_y == 0.0f) { @@ -292,16 +338,18 @@ 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, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) { + D2D1_BITMAP_PROPERTIES1 d = bitmap_properties_to_properties1(desc); D3D10_SUBRESOURCE_DATA resource_data; D3D10_TEXTURE2D_DESC texture_desc; ID3D10ShaderResourceView *view; ID3D10Texture2D *texture; + IDXGISurface *surface; HRESULT hr;
- if (!format_supported(&desc->pixelFormat)) + if (!format_supported(&d.pixelFormat)) { WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n", - desc->pixelFormat.format, desc->pixelFormat.alphaMode); + d.pixelFormat.format, d.pixelFormat.alphaMode); return D2DERR_UNSUPPORTED_PIXEL_FORMAT; }
@@ -309,7 +357,7 @@ HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE texture_desc.Height = size.height; texture_desc.MipLevels = 1; texture_desc.ArraySize = 1; - texture_desc.Format = desc->pixelFormat.format; + texture_desc.Format = d.pixelFormat.format; texture_desc.SampleDesc.Count = 1; texture_desc.SampleDesc.Quality = 0; texture_desc.Usage = D3D10_USAGE_DEFAULT; @@ -327,29 +375,87 @@ HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE return hr; }
+ if (FAILED(hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface))) + { + surface = NULL; + WARN("Texture2D had no underlying DXGISurface"); + } + hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture, NULL, &view); ID3D10Texture2D_Release(texture); if (FAILED(hr)) { + if (surface) IDXGISurface_Release(surface); ERR("Failed to create view, hr %#x.\n", hr); return hr; }
if ((*bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**bitmap)))) { - d2d_bitmap_init(*bitmap, factory, view, size, desc); + d2d_bitmap_init(*bitmap, factory, view, size, &d, surface); TRACE("Created bitmap %p.\n", *bitmap); }
ID3D10ShaderResourceView_Release(view); + if (surface) IDXGISurface_Release(surface);
return *bitmap ? S_OK : E_OUTOFMEMORY; }
+HRESULT d2d_bitmap_create_from_dxgi(ID2D1Factory *factory, IDXGISurface *surface, + D2D1_SIZE_U size, const void *src_data, UINT32 pitch, + const D2D1_BITMAP_PROPERTIES1 *desc, struct d2d_bitmap **bitmap) +{ + ID3D10ShaderResourceView *view; + DXGI_SURFACE_DESC surface_desc; + ID3D10Resource *resource; + D2D1_SIZE_U pixel_size; + ID3D10Device *device; + HRESULT hr; + + if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc))) + { + WARN("Failed to get surface desc, hr %#x.\n", hr); + return hr; + } + + pixel_size.width = surface_desc.Width; + pixel_size.height = surface_desc.Height; + + if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, + (void **)&resource))) + { + WARN("Failed to get d3d10 resource from dxgi surface.\n"); + return E_FAIL; + } + + ID3D10Resource_GetDevice(resource, &device); + hr = ID3D10Device_CreateShaderResourceView(device, resource, NULL, &view); + ID3D10Device_Release(device); + ID3D10Resource_Release(resource); + if (FAILED(hr)) + { + WARN("Failed to create shader resource view, hr %#x.\n", hr); + return hr; + } + + if (!(*bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**bitmap)))) + { + ID3D10ShaderResourceView_Release(view); + return E_OUTOFMEMORY; + } + + d2d_bitmap_init(*bitmap, factory, view, pixel_size, desc, surface); + ID3D10ShaderResourceView_Release(view); + TRACE("Created bitmap %p.\n", *bitmap); + + return S_OK; +} + HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device *target_device, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) { - D2D1_BITMAP_PROPERTIES d; + D2D1_BITMAP_PROPERTIES1 d = bitmap_properties_to_properties1(desc); ID2D1Factory *factory;
if (IsEqualGUID(iid, &IID_ID2D1Bitmap)) @@ -378,13 +484,12 @@ HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device d.pixelFormat = src_impl->format; d.dpiX = src_impl->dpi_x; d.dpiY = src_impl->dpi_y; - desc = &d; }
- if (!format_supported(&desc->pixelFormat)) + if (!format_supported(&d.pixelFormat)) { WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n", - desc->pixelFormat.format, desc->pixelFormat.alphaMode); + d.pixelFormat.format, d.pixelFormat.alphaMode); hr = D2DERR_UNSUPPORTED_PIXEL_FORMAT; goto failed; } @@ -395,7 +500,7 @@ HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device goto failed; }
- d2d_bitmap_init(*bitmap, factory, src_impl->view, src_impl->pixel_size, desc); + d2d_bitmap_init(*bitmap, factory, src_impl->view, src_impl->pixel_size, &d, src_impl->surface); TRACE("Created bitmap %p.\n", *bitmap);
failed: @@ -441,7 +546,6 @@ HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device return E_OUTOFMEMORY; }
- d = *desc; if (d.dpiX == 0.0f || d.dpiY == 0.0f) { float dpi_x, dpi_y; @@ -464,7 +568,7 @@ HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device pixel_size.height = surface_desc.Height;
ID2D1RenderTarget_GetFactory(render_target, &factory); - d2d_bitmap_init(*bitmap, factory, view, pixel_size, &d); + d2d_bitmap_init(*bitmap, factory, view, pixel_size, &d, surface); ID3D10ShaderResourceView_Release(view); ID2D1Factory_Release(factory); TRACE("Created bitmap %p.\n", *bitmap); diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 90ccc66a7d..c42b94886a 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -333,10 +333,16 @@ struct d2d_bitmap D2D1_PIXEL_FORMAT format; float dpi_x; float dpi_y; + D2D1_BITMAP_OPTIONS options; + ID2D1ColorContext *color_context; + IDXGISurface *surface; };
HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; +HRESULT d2d_bitmap_create_from_dxgi(ID2D1Factory *factory, IDXGISurface *surface, + 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(ID2D1RenderTarget *render_target, ID3D10Device *device, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; HRESULT d2d_bitmap_create_from_wic_bitmap(ID2D1Factory *factory, ID3D10Device *device, IWICBitmapSource *bitmap_source, diff --git a/dlls/d2d1/device_context.c b/dlls/d2d1/device_context.c index ef0fb88cba..b8b814935b 100644 --- a/dlls/d2d1/device_context.c +++ b/dlls/d2d1/device_context.c @@ -718,8 +718,55 @@ static HRESULT WINAPI d2d_device_context_CreateBitmapFromDxgiSurface( ID2D1Bitmap1 **bitmap) { struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); - FIXME("%p stub!\n", This); - return E_NOTIMPL; + struct d2d_bitmap *bitmap_impl; + DXGI_MAPPED_RECT locked_rect; + D2D1_BITMAP_PROPERTIES1 bitmap_desc; + HRESULT hr; + DXGI_SURFACE_DESC dxgi_surface_desc; + D2D1_SIZE_U size; + ID2D1Factory *factory; + + TRACE("This %p, surface %p, bitmapProperties %p, bitmap %p.\n", + This, surface, bitmapProperties, bitmap); + if (surface == NULL || bitmap == NULL) + return E_POINTER; + + if (FAILED(hr = IDXGISurface_GetDesc(surface, &dxgi_surface_desc))) + { + WARN("Failed to get surface description, hr %#x.\n", hr); + return hr; + } + + size.width = dxgi_surface_desc.Width; + size.height = dxgi_surface_desc.Height; + + if (bitmapProperties == NULL) + { + bitmap_desc.pixelFormat.format = dxgi_surface_desc.Format; + bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + bitmap_desc.dpiX = 96.0f; + bitmap_desc.dpiY = 96.0f; + bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_NONE; + bitmap_desc.colorContext = NULL; + } + else + { + bitmap_desc = *bitmapProperties; + } + + ID2D1Device_GetFactory(This->device, &factory); + hr = d2d_bitmap_create_from_dxgi(factory, surface, size, locked_rect.pBits, + locked_rect.Pitch, &bitmap_desc, &bitmap_impl); + ID2D1Factory_Release(factory); + if (FAILED(hr)) + { + WARN("Failed to create bitmap, hr %#x.\n", hr); + return hr; + } + + *bitmap = &bitmap_impl->ID2D1Bitmap_iface; + + return S_OK; }
static HRESULT WINAPI d2d_device_context_CreateEffect(