d2d1: Support shared bitmaps created from dxgi surface.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a85f11c2e6
commit
31b162b37d
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue