[PATCH 9/9] d2d1: Partially implement ID2D1Bitmap1
Lucian Poston
lucian.poston at gmail.com
Tue Nov 21 02:41:13 CST 2017
https://bugs.winehq.org/show_bug.cgi?id=44052
Signed-off-by: Lucian Poston <lucian.poston at 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(
--
2.13.6
More information about the wine-devel
mailing list