[PATCH] d2d1: Implement D2D1CreateDevice().
Henri Verbeet
hverbeet at codeweavers.com
Wed Jun 17 11:14:29 CDT 2020
From: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
This supersedes patch 187157. Minor style changes.
dlls/d2d1/d2d1.spec | 2 +-
dlls/d2d1/d2d1_private.h | 1 +
dlls/d2d1/factory.c | 32 ++++++++++++++++++++++++++++++++
dlls/d2d1/tests/d2d1.c | 19 +++++++++++++++++++
include/d2d1_1.idl | 17 +++++++++++++++++
5 files changed, 70 insertions(+), 1 deletion(-)
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 <math.h>
#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);
--
2.20.1
More information about the wine-devel
mailing list