[PATCH] d2d1: Implement D2D1CreateDevice().

Nikolay Sivov nsivov at codeweavers.com
Tue Jun 16 07:05:43 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d2d1/d2d1.spec      |  2 +-
 dlls/d2d1/d2d1_private.h |  1 +
 dlls/d2d1/factory.c      | 37 +++++++++++++++++++++++++++++++++++++
 dlls/d2d1/tests/d2d1.c   | 19 +++++++++++++++++++
 include/d2d1_1.idl       | 17 +++++++++++++++++
 5 files changed, 75 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..84461e43229 100644
--- a/dlls/d2d1/factory.c
+++ b/dlls/d2d1/factory.c
@@ -681,6 +681,43 @@ 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;
+    ID3D10Device *d3d10_device;
+    ID3D11Device *d3d11_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_ID3D10Device, (void **)&d3d10_device)))
+        {
+            if (!(ID3D10Device_GetCreationFlags(d3d10_device) & D3D10_CREATE_DEVICE_SINGLETHREADED))
+                default_properties.threadingMode = D2D1_THREADING_MODE_MULTI_THREADED;
+            ID3D10Device_Release(d3d10_device);
+        }
+        else if (SUCCEEDED(IDXGIDevice_QueryInterface(dxgi_device, &IID_ID3D11Device, (void **)&d3d11_device)))
+        {
+            if (!(ID3D11Device_GetCreationFlags(d3d11_device) & D3D11_CREATE_DEVICE_SINGLETHREADED))
+                default_properties.threadingMode = D2D1_THREADING_MODE_MULTI_THREADED;
+            ID3D11Device_Release(d3d11_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..b99f11d4ecf 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(SUCCEEDED(hr), "Failed to create d2d device, hr %#x.\n", hr);
+        ID2D1Device_Release(device);
+
+        hr = pD2D1CreateDevice(dxgi_device, &properties, &device);
+        ok(SUCCEEDED(hr), "Failed to create d2d device, 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..493224569e7 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.27.0




More information about the wine-devel mailing list