Nikolay Sivov : d2d1: Support shared bitmaps created from dxgi surface.
Alexandre Julliard
julliard at winehq.org
Tue Oct 11 15:21:09 CDT 2016
Module: wine
Branch: master
Commit: 31b162b37d9b9338b168270fc37ed83cd23ffa85
URL: http://source.winehq.org/git/wine.git/?a=commit;h=31b162b37d9b9338b168270fc37ed83cd23ffa85
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Oct 10 17:12:39 2016 +0300
d2d1: Support shared bitmaps created from dxgi surface.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/d2d1/bitmap.c | 97 ++++++++++++++++++++++++++++++++++++++++++++---
dlls/d2d1/d2d1_private.h | 2 +-
dlls/d2d1/render_target.c | 2 +-
dlls/d2d1/tests/d2d1.c | 44 +++++++++++++++++++++
4 files changed, 137 insertions(+), 8 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c
index b2f2ad7..43904bb 100644
--- a/dlls/d2d1/bitmap.c
+++ b/dlls/d2d1/bitmap.c
@@ -296,22 +296,32 @@ HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE
return *bitmap ? S_OK : E_OUTOFMEMORY;
}
-HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *target_device,
+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;
+ ID2D1Factory *factory;
+
if (IsEqualGUID(iid, &IID_ID2D1Bitmap))
{
struct d2d_bitmap *src_impl = unsafe_impl_from_ID2D1Bitmap(data);
- D2D1_BITMAP_PROPERTIES d;
ID3D10Device *device;
+ HRESULT hr = S_OK;
+ ID2D1RenderTarget_GetFactory(render_target, &factory);
if (src_impl->factory != factory)
- return D2DERR_WRONG_FACTORY;
+ {
+ hr = D2DERR_WRONG_FACTORY;
+ goto failed;
+ }
ID3D10ShaderResourceView_GetDevice(src_impl->view, &device);
ID3D10Device_Release(device);
if (device != target_device)
- return D2DERR_UNSUPPORTED_OPERATION;
+ {
+ hr = D2DERR_UNSUPPORTED_OPERATION;
+ goto failed;
+ }
if (!desc)
{
@@ -325,15 +335,90 @@ HRESULT d2d_bitmap_create_shared(ID2D1Factory *factory, ID3D10Device *target_dev
{
WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n",
desc->pixelFormat.format, desc->pixelFormat.alphaMode);
- return D2DERR_UNSUPPORTED_PIXEL_FORMAT;
+ hr = D2DERR_UNSUPPORTED_PIXEL_FORMAT;
+ goto failed;
}
if (!(*bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**bitmap))))
- return E_OUTOFMEMORY;
+ {
+ hr = E_OUTOFMEMORY;
+ goto failed;
+ }
d2d_bitmap_init(*bitmap, factory, src_impl->view, src_impl->pixel_size, desc);
TRACE("Created bitmap %p.\n", *bitmap);
+ failed:
+ ID2D1Factory_Release(factory);
+ return hr;
+ }
+
+ if (IsEqualGUID(iid, &IID_IDXGISurface) || IsEqualGUID(iid, &IID_IDXGISurface1))
+ {
+ ID3D10ShaderResourceView *view;
+ DXGI_SURFACE_DESC surface_desc;
+ IDXGISurface *surface = data;
+ ID3D10Resource *resource;
+ D2D1_SIZE_U pixel_size;
+ ID3D10Device *device;
+ HRESULT hr;
+
+ if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
+ {
+ WARN("Failed to get d3d resource from dxgi surface.\n");
+ return E_FAIL;
+ }
+
+ ID3D10Resource_GetDevice(resource, &device);
+ ID3D10Device_Release(device);
+ if (device != target_device)
+ {
+ ID3D10Resource_Release(resource);
+ return D2DERR_UNSUPPORTED_OPERATION;
+ }
+
+ hr = ID3D10Device_CreateShaderResourceView(target_device, resource, NULL, &view);
+ 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;
+ }
+
+ d = *desc;
+ if (d.dpiX == 0.0f || d.dpiY == 0.0f)
+ {
+ float dpi_x, dpi_y;
+
+ ID2D1RenderTarget_GetDpi(render_target, &dpi_x, &dpi_y);
+ if (d.dpiX == 0.0f)
+ d.dpiX = dpi_x;
+ if (d.dpiY == 0.0f)
+ d.dpiY = dpi_y;
+ }
+
+ if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
+ {
+ WARN("Failed to get surface desc, hr %#x.\n", hr);
+ ID3D10ShaderResourceView_Release(view);
+ return hr;
+ }
+
+ pixel_size.width = surface_desc.Width;
+ pixel_size.height = surface_desc.Height;
+
+ ID2D1RenderTarget_GetFactory(render_target, &factory);
+ d2d_bitmap_init(*bitmap, factory, view, pixel_size, &d);
+ ID3D10ShaderResourceView_Release(view);
+ ID2D1Factory_Release(factory);
+ TRACE("Created bitmap %p.\n", *bitmap);
+
return S_OK;
}
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index 6cee5ef..c5c3a03 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -236,7 +236,7 @@ struct d2d_bitmap
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_shared(ID2D1Factory *factory, ID3D10Device *device, REFIID iid, void *data,
+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,
const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN;
diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c
index e9a971e..78000af 100644
--- a/dlls/d2d1/render_target.c
+++ b/dlls/d2d1/render_target.c
@@ -341,7 +341,7 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSharedBitmap(ID2D1R
TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n",
iface, debugstr_guid(iid), data, desc, bitmap);
- if (SUCCEEDED(hr = d2d_bitmap_create_shared(render_target->factory, render_target->device, iid, data, desc, &object)))
+ if (SUCCEEDED(hr = d2d_bitmap_create_shared(iface, render_target->device, iid, data, desc, &object)))
*bitmap = &object->ID2D1Bitmap_iface;
return hr;
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index ba4be0c..38012ca 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -2046,8 +2046,10 @@ static void test_shared_bitmap(void)
ID3D10Device1 *device1, *device2;
IWICImagingFactory *wic_factory;
ID2D1Bitmap *bitmap1, *bitmap2;
+ DXGI_SURFACE_DESC surface_desc;
ID2D1RenderTarget *rt1, *rt2;
D2D1_SIZE_U size = {4, 4};
+ IDXGISurface1 *surface3;
HWND window1, window2;
HRESULT hr;
@@ -2171,6 +2173,48 @@ static void test_shared_bitmap(void)
ID2D1Bitmap_Release(bitmap2);
ID2D1RenderTarget_Release(rt2);
+ /* Shared DXGI surface. */
+ desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
+ desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
+ desc.dpiX = 0.0f;
+ desc.dpiY = 0.0f;
+ desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
+ desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
+
+ hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2);
+ ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
+
+ bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
+ bitmap_desc.dpiX = 0.0f;
+ bitmap_desc.dpiY = 0.0f;
+
+ hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2);
+ ok(SUCCEEDED(hr) || broken(hr == E_INVALIDARG) /* vista */, "Failed to create bitmap, hr %#x.\n", hr);
+
+ if (SUCCEEDED(hr))
+ {
+ 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");
+
+ ID2D1Bitmap_Release(bitmap2);
+
+ /* IDXGISurface1 is supported too. */
+ if (IDXGISurface_QueryInterface(surface2, &IID_IDXGISurface1, (void **)&surface3) == S_OK)
+ {
+ hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface1, surface3, &bitmap_desc, &bitmap2);
+ ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
+
+ ID2D1Bitmap_Release(bitmap2);
+ IDXGISurface1_Release(surface3);
+ }
+ }
+
+ ID2D1RenderTarget_Release(rt2);
+
ID2D1Bitmap_Release(bitmap1);
ID2D1RenderTarget_Release(rt1);
ID2D1Factory_Release(factory2);
More information about the wine-cvs
mailing list