diff --git a/dlls/d2d1/d2d1.spec b/dlls/d2d1/d2d1.spec index fff6f1c9c81..0ebcd0af553 100644 --- a/dlls/d2d1/d2d1.spec +++ b/dlls/d2d1/d2d1.spec @@ -4,7 +4,7 @@ @ stdcall D2D1IsMatrixInvertible(ptr) @ stdcall D2D1InvertMatrix(ptr) @ stub D2D1ConvertColorSpace -@ stub D2D1CreateDevice +@ stdcall D2D1CreateDevice(ptr ptr ptr) @ stub D2D1CreateDeviceContext @ stub D2D1SinCos @ stub D2D1Tan diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 4eb7e33142d..4546d5c1e3a 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -27,6 +27,7 @@ #include #define COBJMACROS #include "d2d1_2.h" +#include "d3d11.h" #ifdef D2D1_INIT_GUID #include "initguid.h" #endif diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 80334d82d02..2f50836bbcd 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -681,6 +681,38 @@ BOOL WINAPI D2D1InvertMatrix(D2D1_MATRIX_3X2_F *matrix) return d2d_matrix_invert(matrix, &m); } +HRESULT WINAPI D2D1CreateDevice(IDXGIDevice *dxgi_device, + const D2D1_CREATION_PROPERTIES *properties, ID2D1Device **device) +{ + D2D1_CREATION_PROPERTIES default_properties = {0}; + D2D1_FACTORY_OPTIONS factory_options; + ID3D11Device *d3d_device; + ID2D1Factory1 *factory; + HRESULT hr; + + TRACE("dxgi_device %p, properties %p, device %p.\n", dxgi_device, properties, device); + + if (!properties) + { + if (SUCCEEDED(IDXGIDevice_QueryInterface(dxgi_device, &IID_ID3D11Device, (void **)&d3d_device))) + { + if (!(ID3D11Device_GetCreationFlags(d3d_device) & D3D11_CREATE_DEVICE_SINGLETHREADED)) + default_properties.threadingMode = D2D1_THREADING_MODE_MULTI_THREADED; + ID3D11Device_Release(d3d_device); + } + properties = &default_properties; + } + + factory_options.debugLevel = properties->debugLevel; + if (FAILED(hr = D2D1CreateFactory(properties->threadingMode, + &IID_ID2D1Factory1, &factory_options, (void **)&factory))) + return hr; + + hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, device); + ID2D1Factory1_Release(factory); + return hr; +} + static BOOL get_config_key_dword(HKEY default_key, HKEY application_key, const char *name, DWORD *value) { DWORD type, data, size; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 87c87324f3d..f52a34514e4 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -28,6 +28,9 @@ #include "wincodec.h" #include "wine/heap.h" +static HRESULT (WINAPI *pD2D1CreateDevice)(IDXGIDevice *dxgi_device, + const D2D1_CREATION_PROPERTIES *properties, ID2D1Device **device); + static BOOL use_mt = TRUE; static struct test_entry @@ -7911,6 +7914,7 @@ static void test_bezier_intersect(void) static void test_create_device(void) { + D2D1_CREATION_PROPERTIES properties = {0}; ID3D10Device1 *d3d_device; IDXGIDevice *dxgi_device; ID2D1Factory1 *factory; @@ -7943,6 +7947,19 @@ static void test_create_device(void) ID2D1Factory_Release(factory2); ID2D1Device_Release(device); + if (pD2D1CreateDevice) + { + hr = pD2D1CreateDevice(dxgi_device, NULL, &device); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ID2D1Device_Release(device); + + hr = pD2D1CreateDevice(dxgi_device, &properties, &device); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ID2D1Device_Release(device); + } + else + win_skip("D2D1CreateDevice() is unavailable.\n"); + IDXGIDevice_Release(dxgi_device); ID3D10Device1_Release(d3d_device); @@ -9416,6 +9433,8 @@ START_TEST(d2d1) unsigned int argc, i; char **argv; + pD2D1CreateDevice = (void *)GetProcAddress(GetModuleHandleA("d2d1.dll"), "D2D1CreateDevice"); + use_mt = !getenv("WINETEST_NO_MT_D3D"); argc = winetest_get_mainargs(&argv); diff --git a/include/d2d1_1.idl b/include/d2d1_1.idl index 4a644ffd4ca..ddb7669c24b 100644 --- a/include/d2d1_1.idl +++ b/include/d2d1_1.idl @@ -187,6 +187,20 @@ typedef enum D2D1_PROPERTY_TYPE D2D1_PROPERTY_TYPE_FORCE_DWORD = 0xffffffff, } D2D1_PROPERTY_TYPE; +typedef enum D2D1_THREADING_MODE +{ + D2D1_THREADING_MODE_SINGLE_THREADED = D2D1_FACTORY_TYPE_SINGLE_THREADED, + D2D1_THREADING_MODE_MULTI_THREADED = D2D1_FACTORY_TYPE_MULTI_THREADED, + D2D1_THREADING_MODE_FORCE_DWORD = 0xffffffff, +} D2D1_THREADING_MODE; + +typedef struct D2D1_CREATION_PROPERTIES +{ + D2D1_THREADING_MODE threadingMode; + D2D1_DEBUG_LEVEL debugLevel; + D2D1_DEVICE_CONTEXT_OPTIONS options; +} D2D1_CREATION_PROPERTIES; + typedef struct D2D1_STROKE_STYLE_PROPERTIES1 { D2D1_CAP_STYLE startCap; @@ -777,3 +791,6 @@ interface ID2D1Factory1 : ID2D1Factory [out] ID2D1Properties **props ); } + +[local] HRESULT __stdcall D2D1CreateDevice(IDXGIDevice *dxgi_device, + const D2D1_CREATION_PROPERTIES *creation_properties, ID2D1Device **device);