Note that IDCompositionDevice2 is not inherited from IDCompositionDevice.
From: Zhiyi Zhang zzhang@codeweavers.com
--- configure.ac | 1 + dlls/dcomp/tests/Makefile.in | 5 ++ dlls/dcomp/tests/dcomp.c | 152 +++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 dlls/dcomp/tests/Makefile.in create mode 100644 dlls/dcomp/tests/dcomp.c
diff --git a/configure.ac b/configure.ac index 84fadd08853..a514d658775 100644 --- a/configure.ac +++ b/configure.ac @@ -2513,6 +2513,7 @@ WINE_CONFIG_MAKEFILE(dlls/dbghelp) WINE_CONFIG_MAKEFILE(dlls/dbghelp/tests) WINE_CONFIG_MAKEFILE(dlls/dciman32) WINE_CONFIG_MAKEFILE(dlls/dcomp) +WINE_CONFIG_MAKEFILE(dlls/dcomp/tests) WINE_CONFIG_MAKEFILE(dlls/ddeml.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/ddraw) WINE_CONFIG_MAKEFILE(dlls/ddraw/tests) diff --git a/dlls/dcomp/tests/Makefile.in b/dlls/dcomp/tests/Makefile.in new file mode 100644 index 00000000000..f1ad3efeb4d --- /dev/null +++ b/dlls/dcomp/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = dcomp.dll +IMPORTS = d3d10_1 + +C_SRCS = \ + dcomp.c diff --git a/dlls/dcomp/tests/dcomp.c b/dlls/dcomp/tests/dcomp.c new file mode 100644 index 00000000000..688991e180f --- /dev/null +++ b/dlls/dcomp/tests/dcomp.c @@ -0,0 +1,152 @@ +/* + * Unit test for DirectComposition + * + * Copyright 2023 Zhiyi Zhang for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS +#include "initguid.h" +#include <d3d10_1.h> +#include "dcomp.h" +#include "wine/test.h" + +static HRESULT (WINAPI *pDCompositionCreateDevice)(IDXGIDevice *dxgi_device, REFIID iid, void **device); + +static IDXGIDevice *create_device(unsigned int flags) +{ + IDXGIDevice *dxgi_device; + ID3D10Device1 *device; + HRESULT hr; + + hr = D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D10_FEATURE_LEVEL_10_0, + D3D10_1_SDK_VERSION, &device); + if (SUCCEEDED(hr)) + goto success; + if (SUCCEEDED(D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_WARP, NULL, flags, + D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device))) + goto success; + if (SUCCEEDED(D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_REFERENCE, NULL, flags, + D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device))) + goto success; + + return NULL; + +success: + hr = ID3D10Device1_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device); + ok(SUCCEEDED(hr), "Created device does not implement IDXGIDevice.\n"); + ID3D10Device1_Release(device); + return dxgi_device; +} + +static void test_DCompositionCreateDevice(void) +{ + IDCompositionDevice2 *dcomp_device2; + IDCompositionDevice *dcomp_device; + IDXGIDevice *dxgi_device; + ULONG refcount; + HRESULT hr; + + /* D3D device created without BGRA support */ + if (!(dxgi_device = create_device(0))) + { + skip("Failed to create device.\n"); + return; + } + + hr = pDCompositionCreateDevice(dxgi_device, &IID_IDCompositionDevice, (void **)&dcomp_device); + todo_wine + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount); + } + refcount = IDXGIDevice_Release(dxgi_device); + ok(!refcount, "Device has %lu references left.\n", refcount); + + /* D3D device created with BGRA support */ + if (!(dxgi_device = create_device(D3D10_CREATE_DEVICE_BGRA_SUPPORT))) + { + skip("Failed to create device.\n"); + return; + } + + hr = pDCompositionCreateDevice(dxgi_device, &IID_IDCompositionDevice, (void **)&dcomp_device); + todo_wine + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + /* Device created from DCompositionCreateDevice() doesn't support IDCompositionDevice2 */ + hr = IDCompositionDevice_QueryInterface(dcomp_device, &IID_IDCompositionDevice2, + (void **)&dcomp_device2); + ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount); + } + + /* Parameter checks */ + hr = pDCompositionCreateDevice(NULL, &IID_IDCompositionDevice, (void **)&dcomp_device); + todo_wine + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount); + } + + /* Crash on Windows */ + if (0) + { + hr = pDCompositionCreateDevice(dxgi_device, NULL, (void **)&dcomp_device); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + } + + hr = pDCompositionCreateDevice(dxgi_device, &IID_IDCompositionDevice2, (void **)&dcomp_device); + todo_wine + ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + + hr = pDCompositionCreateDevice(dxgi_device, &IID_IDCompositionDevice, NULL); + todo_wine + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + + refcount = IDXGIDevice_Release(dxgi_device); + ok(!refcount, "Device has %lu references left.\n", refcount); +} + +START_TEST(dcomp) +{ + HMODULE module; + + module = LoadLibraryW(L"dcomp.dll"); + if (!module) + { + win_skip("dcomp.dll not found.\n"); + return; + } + + pDCompositionCreateDevice = (void *)GetProcAddress(module, "DCompositionCreateDevice"); + if (!pDCompositionCreateDevice) + { + win_skip("DCompositionCreateDevice() is unavailable.\n"); + FreeLibrary(module); + return; + } + + test_DCompositionCreateDevice(); + + FreeLibrary(module); +}
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/dcomp/dcomp_private.h | 34 +++++ dlls/dcomp/device.c | 280 ++++++++++++++++++++++++++++++++++++- dlls/dcomp/tests/dcomp.c | 35 ++--- 3 files changed, 323 insertions(+), 26 deletions(-) create mode 100644 dlls/dcomp/dcomp_private.h
diff --git a/dlls/dcomp/dcomp_private.h b/dlls/dcomp/dcomp_private.h new file mode 100644 index 00000000000..a9ae8896e8f --- /dev/null +++ b/dlls/dcomp/dcomp_private.h @@ -0,0 +1,34 @@ +/* + * Copyright 2023 Zhiyi Zhang for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#ifndef __WINE_DCOMP_PRIVATE_H +#define __WINE_DCOMP_PRIVATE_H + +#include "dcomp.h" + +struct composition_device +{ + IDCompositionDevice IDCompositionDevice_iface; + LONG ref; +}; + +static inline struct composition_device *impl_from_IDCompositionDevice(IDCompositionDevice *iface) +{ + return CONTAINING_RECORD(iface, struct composition_device, IDCompositionDevice_iface); +} + +#endif /* __WINE_DCOMP_PRIVATE_H */ diff --git a/dlls/dcomp/device.c b/dlls/dcomp/device.c index 2d0600ce50a..29fd569acbe 100644 --- a/dlls/dcomp/device.c +++ b/dlls/dcomp/device.c @@ -1,5 +1,6 @@ /* * Copyright 2020 Nikolay Sivov for CodeWeavers + * Copyright 2023 Zhiyi Zhang for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,22 +17,297 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include <stdarg.h> +#include <stdlib.h>
+#define COBJMACROS #include "windef.h" #include "winbase.h" +#include "initguid.h" #include "objidl.h" +#include "dcomp_private.h" #include "dxgi.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dcomp);
-HRESULT WINAPI DCompositionCreateDevice(IDXGIDevice *dxgi_device, REFIID iid, void **device) +static HRESULT STDMETHODCALLTYPE device_QueryInterface(IDCompositionDevice *iface, + REFIID iid, void **out) +{ + struct composition_device *device = impl_from_IDCompositionDevice(iface); + + TRACE("iface %p, iid %s, out %p\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IDCompositionDevice)) + { + IUnknown_AddRef(&device->IDCompositionDevice_iface); + *out = &device->IDCompositionDevice_iface; + return S_OK; + } + + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE device_AddRef(IDCompositionDevice *iface) +{ + struct composition_device *device = impl_from_IDCompositionDevice(iface); + ULONG ref = InterlockedIncrement(&device->ref); + + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static ULONG STDMETHODCALLTYPE device_Release(IDCompositionDevice *iface) +{ + struct composition_device *device = impl_from_IDCompositionDevice(iface); + ULONG ref = InterlockedDecrement(&device->ref); + + TRACE("iface %p, ref %lu.\n", iface, ref); + + if (!ref) + free(device); + + return ref; +} + +static HRESULT STDMETHODCALLTYPE device_Commit(IDCompositionDevice *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_WaitForCommitCompletion(IDCompositionDevice *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_GetFrameStatistics(IDCompositionDevice *iface, + DCOMPOSITION_FRAME_STATISTICS *statistics) +{ + FIXME("iface %p, statistics %p stub!\n", iface, statistics); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateTargetForHwnd(IDCompositionDevice *iface, + HWND hwnd, BOOL topmost, IDCompositionTarget **target) +{ + FIXME("iface %p, hwnd %p, topmost %d, target %p stub!\n", iface, hwnd, topmost, target); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateVisual(IDCompositionDevice *iface, + IDCompositionVisual **visual) +{ + FIXME("iface %p, visual %p stub!\n", iface, visual); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateSurface(IDCompositionDevice *iface, + UINT width, UINT height, DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, + IDCompositionSurface **surface) +{ + FIXME("iface %p, width %u, height %u, format %#x, alpha_mode %#x, surface %p stub!\n", iface, + width, height, pixel_format, alpha_mode, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateVirtualSurface(IDCompositionDevice *iface, + UINT width, UINT height, DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, + IDCompositionVirtualSurface **surface) +{ + FIXME("iface %p, width %u, height %u, format %#x, alpha_mode %#x, surface %p stub!\n", iface, + width, height, pixel_format, alpha_mode, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateSurfaceFromHandle(IDCompositionDevice *iface, + HANDLE handle, IUnknown **surface) +{ + FIXME("iface %p, handle %p, surface %p stub!\n", iface, handle, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateSurfaceFromHwnd(IDCompositionDevice *iface, + HWND hwnd, IUnknown **surface) +{ + FIXME("iface %p, hwnd %p, surface %p stub!\n", iface, hwnd, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateTranslateTransform(IDCompositionDevice *iface, + IDCompositionTranslateTransform **transform) +{ + FIXME("iface %p, transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateScaleTransform(IDCompositionDevice *iface, + IDCompositionScaleTransform **transform) +{ + FIXME("iface %p, transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateRotateTransform(IDCompositionDevice *iface, + IDCompositionRotateTransform **transform) { - FIXME("%p, %s, %p.\n", dxgi_device, debugstr_guid(iid), device); + FIXME("iface %p, transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateSkewTransform(IDCompositionDevice *iface, + IDCompositionSkewTransform **transform) +{ + FIXME("iface %p, transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateMatrixTransform(IDCompositionDevice *iface, + IDCompositionMatrixTransform **transform) +{ + FIXME("iface %p, transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateTransformGroup(IDCompositionDevice *iface, + IDCompositionTransform **transforms, UINT elements, + IDCompositionTransform **transform_group) +{ + FIXME("iface %p, transforms %p, elements %u, transform_group %p stub!\n", iface, transforms, + elements, transform_group); + return E_NOTIMPL; +}
+static HRESULT STDMETHODCALLTYPE device_CreateTranslateTransform3D(IDCompositionDevice *iface, + IDCompositionTranslateTransform3D **transform_3d) +{ + FIXME("iface %p, translate_transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateScaleTransform3D(IDCompositionDevice *iface, + IDCompositionScaleTransform3D **transform_3d) +{ + FIXME("iface %p, transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateRotateTransform3D(IDCompositionDevice *iface, + IDCompositionRotateTransform3D **transform_3d) +{ + FIXME("iface %p, transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateMatrixTransform3D(IDCompositionDevice *iface, + IDCompositionMatrixTransform3D **transform_3d) +{ + FIXME("iface %p, transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateTransform3DGroup(IDCompositionDevice *iface, + IDCompositionTransform3D **transforms_3d, UINT elements, + IDCompositionTransform3D **transform_3d_group) +{ + FIXME("iface %p, transforms_3d %p, elements %u, transform_3d_group %p stub!\n", iface, + transforms_3d, elements, transform_3d_group); return E_NOTIMPL; }
+static HRESULT STDMETHODCALLTYPE device_CreateEffectGroup(IDCompositionDevice *iface, + IDCompositionEffectGroup **effect_group) +{ + FIXME("iface %p, effect_group %p stub!\n", iface, effect_group); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateRectangleClip(IDCompositionDevice *iface, + IDCompositionRectangleClip **clip) +{ + FIXME("iface %p, clip %p stub!\n", iface, clip); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CreateAnimation(IDCompositionDevice *iface, + IDCompositionAnimation **animation) +{ + FIXME("iface %p, animation %p stub!\n", iface, animation); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device_CheckDeviceState(IDCompositionDevice *iface, + BOOL *valid) +{ + FIXME("iface %p, valid %p stub!\n", iface, valid); + return E_NOTIMPL; +} + +static const struct IDCompositionDeviceVtbl device_vtbl = +{ + /* IUnknown methods */ + device_QueryInterface, + device_AddRef, + device_Release, + /* IDCompositionDevice methods */ + device_Commit, + device_WaitForCommitCompletion, + device_GetFrameStatistics, + device_CreateTargetForHwnd, + device_CreateVisual, + device_CreateSurface, + device_CreateVirtualSurface, + device_CreateSurfaceFromHandle, + device_CreateSurfaceFromHwnd, + device_CreateTranslateTransform, + device_CreateScaleTransform, + device_CreateRotateTransform, + device_CreateSkewTransform, + device_CreateMatrixTransform, + device_CreateTransformGroup, + device_CreateTranslateTransform3D, + device_CreateScaleTransform3D, + device_CreateRotateTransform3D, + device_CreateMatrixTransform3D, + device_CreateTransform3DGroup, + device_CreateEffectGroup, + device_CreateRectangleClip, + device_CreateAnimation, + device_CheckDeviceState, +}; + +static HRESULT create_device(REFIID iid, void **out) +{ + struct composition_device *device; + HRESULT hr; + + if (!out) + return E_INVALIDARG; + + device = calloc(1, sizeof(*device)); + if (!device) + return E_OUTOFMEMORY; + + device->IDCompositionDevice_iface.lpVtbl = &device_vtbl; + device->ref = 1; + hr = IDCompositionDevice_QueryInterface(&device->IDCompositionDevice_iface, iid, out); + IDCompositionDevice_Release(&device->IDCompositionDevice_iface); + return hr; +} + +HRESULT WINAPI DCompositionCreateDevice(IDXGIDevice *dxgi_device, REFIID iid, void **device) +{ + TRACE("%p, %s, %p\n", dxgi_device, debugstr_guid(iid), device); + + if (!IsEqualIID(iid, &IID_IDCompositionDevice)) + return E_NOINTERFACE; + + return create_device(iid, device); +} + HRESULT WINAPI DCompositionCreateDevice2(IUnknown *rendering_device, REFIID iid, void **device) { FIXME("%p, %s, %p.\n", rendering_device, debugstr_guid(iid), device); diff --git a/dlls/dcomp/tests/dcomp.c b/dlls/dcomp/tests/dcomp.c index 688991e180f..27432e9903c 100644 --- a/dlls/dcomp/tests/dcomp.c +++ b/dlls/dcomp/tests/dcomp.c @@ -68,13 +68,9 @@ static void test_DCompositionCreateDevice(void) }
hr = pDCompositionCreateDevice(dxgi_device, &IID_IDCompositionDevice, (void **)&dcomp_device); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { - refcount = IDCompositionDevice_Release(dcomp_device); - ok(!refcount, "Device has %lu references left.\n", refcount); - } + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount); refcount = IDXGIDevice_Release(dxgi_device); ok(!refcount, "Device has %lu references left.\n", refcount);
@@ -86,27 +82,20 @@ static void test_DCompositionCreateDevice(void) }
hr = pDCompositionCreateDevice(dxgi_device, &IID_IDCompositionDevice, (void **)&dcomp_device); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { - /* Device created from DCompositionCreateDevice() doesn't support IDCompositionDevice2 */ - hr = IDCompositionDevice_QueryInterface(dcomp_device, &IID_IDCompositionDevice2, - (void **)&dcomp_device2); - ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); - refcount = IDCompositionDevice_Release(dcomp_device); - ok(!refcount, "Device has %lu references left.\n", refcount); - } + + /* Device created from DCompositionCreateDevice() doesn't support IDCompositionDevice2 */ + hr = IDCompositionDevice_QueryInterface(dcomp_device, &IID_IDCompositionDevice2, + (void **)&dcomp_device2); + ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount);
/* Parameter checks */ hr = pDCompositionCreateDevice(NULL, &IID_IDCompositionDevice, (void **)&dcomp_device); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { - refcount = IDCompositionDevice_Release(dcomp_device); - ok(!refcount, "Device has %lu references left.\n", refcount); - } + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount);
/* Crash on Windows */ if (0) @@ -116,11 +105,9 @@ static void test_DCompositionCreateDevice(void) }
hr = pDCompositionCreateDevice(dxgi_device, &IID_IDCompositionDevice2, (void **)&dcomp_device); - todo_wine ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr);
hr = pDCompositionCreateDevice(dxgi_device, &IID_IDCompositionDevice, NULL); - todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
refcount = IDXGIDevice_Release(dxgi_device);
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/dcomp/tests/dcomp.c | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+)
diff --git a/dlls/dcomp/tests/dcomp.c b/dlls/dcomp/tests/dcomp.c index 27432e9903c..8878cfa0dfd 100644 --- a/dlls/dcomp/tests/dcomp.c +++ b/dlls/dcomp/tests/dcomp.c @@ -25,6 +25,7 @@ #include "wine/test.h"
static HRESULT (WINAPI *pDCompositionCreateDevice)(IDXGIDevice *dxgi_device, REFIID iid, void **device); +static HRESULT (WINAPI *pDCompositionCreateDevice2)(IUnknown *rendering_device, REFIID iid, void **device);
static IDXGIDevice *create_device(unsigned int flags) { @@ -114,6 +115,112 @@ static void test_DCompositionCreateDevice(void) ok(!refcount, "Device has %lu references left.\n", refcount); }
+static void test_DCompositionCreateDevice2(void) +{ + IDCompositionDesktopDevice *desktop_device; + IDCompositionDevice2 *dcomp_device2; + IDCompositionDevice *dcomp_device; + IDXGIDevice *dxgi_device; + ULONG refcount; + HRESULT hr; + + /* D3D device created without BGRA support */ + if (!(dxgi_device = create_device(0))) + { + skip("Failed to create device.\n"); + return; + } + + hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDevice, + (void **)&dcomp_device); + todo_wine + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount); + } + refcount = IDXGIDevice_Release(dxgi_device); + ok(!refcount, "Device has %lu references left.\n", refcount); + + /* D3D device created with BGRA support */ + if (!(dxgi_device = create_device(D3D10_CREATE_DEVICE_BGRA_SUPPORT))) + { + skip("Failed to create device.\n"); + return; + } + + hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDevice, + (void **)&dcomp_device); + todo_wine + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + hr = IDCompositionDevice_QueryInterface(dcomp_device, &IID_IDCompositionDevice2, + (void **)&dcomp_device2); + todo_wine + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + refcount = IDCompositionDevice2_Release(dcomp_device2); + ok(refcount == 1, "Got unexpected refcount %lu.\n", refcount); + } + + hr = IDCompositionDevice_QueryInterface(dcomp_device, &IID_IDCompositionDesktopDevice, + (void **)&desktop_device); + todo_wine + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + refcount = IDCompositionDesktopDevice_Release(desktop_device); + ok(refcount == 1, "Got unexpected refcount %lu.\n", refcount); + } + + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount); + } + + /* Parameter checks */ + hr = pDCompositionCreateDevice2(NULL, &IID_IDCompositionDevice, (void **)&dcomp_device); + todo_wine + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount); + } + + /* Crash on Windows */ + if (0) + { + hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, NULL, (void **)&dcomp_device); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + } + + /* IDCompositionDevice2 needs to be queried from the device instance */ + hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDevice2, + (void **)&dcomp_device2); + todo_wine + ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr); + + hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDesktopDevice, + (void **)&desktop_device); + todo_wine + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + refcount = IDCompositionDesktopDevice_Release(desktop_device); + ok(!refcount, "Device has %lu references left.\n", refcount); + } + + hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDevice, NULL); + todo_wine + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + + refcount = IDXGIDevice_Release(dxgi_device); + ok(!refcount, "Device has %lu references left.\n", refcount); +} + START_TEST(dcomp) { HMODULE module; @@ -126,6 +233,8 @@ START_TEST(dcomp) }
pDCompositionCreateDevice = (void *)GetProcAddress(module, "DCompositionCreateDevice"); + pDCompositionCreateDevice2 = (void *)GetProcAddress(module, "DCompositionCreateDevice2"); + if (!pDCompositionCreateDevice) { win_skip("DCompositionCreateDevice() is unavailable.\n"); @@ -134,6 +243,7 @@ START_TEST(dcomp) }
test_DCompositionCreateDevice(); + test_DCompositionCreateDevice2();
FreeLibrary(module); }
From: Zhiyi Zhang zzhang@codeweavers.com
Note that IDCompositionDevice2 is not inherited from IDCompositionDevice. --- dlls/dcomp/dcomp_private.h | 7 ++ dlls/dcomp/device.c | 231 ++++++++++++++++++++++++++++++++++++- dlls/dcomp/tests/dcomp.c | 54 +++------ 3 files changed, 252 insertions(+), 40 deletions(-)
diff --git a/dlls/dcomp/dcomp_private.h b/dlls/dcomp/dcomp_private.h index a9ae8896e8f..99912ab9156 100644 --- a/dlls/dcomp/dcomp_private.h +++ b/dlls/dcomp/dcomp_private.h @@ -23,6 +23,8 @@ struct composition_device { IDCompositionDevice IDCompositionDevice_iface; + IDCompositionDevice2 IDCompositionDevice2_iface; + int version; LONG ref; };
@@ -31,4 +33,9 @@ static inline struct composition_device *impl_from_IDCompositionDevice(IDComposi return CONTAINING_RECORD(iface, struct composition_device, IDCompositionDevice_iface); }
+static inline struct composition_device *impl_from_IDCompositionDevice2(IDCompositionDevice2 *iface) +{ + return CONTAINING_RECORD(iface, struct composition_device, IDCompositionDevice2_iface); +} + #endif /* __WINE_DCOMP_PRIVATE_H */ diff --git a/dlls/dcomp/device.c b/dlls/dcomp/device.c index 29fd569acbe..519e5b065bf 100644 --- a/dlls/dcomp/device.c +++ b/dlls/dcomp/device.c @@ -44,6 +44,12 @@ static HRESULT STDMETHODCALLTYPE device_QueryInterface(IDCompositionDevice *ifac *out = &device->IDCompositionDevice_iface; return S_OK; } + else if (device->version >= 2 && IsEqualGUID(iid, &IID_IDCompositionDevice2)) + { + IUnknown_AddRef(&device->IDCompositionDevice2_iface); + *out = &device->IDCompositionDevice2_iface; + return S_OK; + }
FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); *out = NULL; @@ -279,7 +285,219 @@ static const struct IDCompositionDeviceVtbl device_vtbl = device_CheckDeviceState, };
-static HRESULT create_device(REFIID iid, void **out) +static HRESULT STDMETHODCALLTYPE device2_QueryInterface(IDCompositionDevice2 *iface, + REFIID iid, void **out) +{ + struct composition_device *device = impl_from_IDCompositionDevice2(iface); + + TRACE("iface %p.\n", iface); + + return IDCompositionDevice_QueryInterface(&device->IDCompositionDevice_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE device2_AddRef(IDCompositionDevice2 *iface) +{ + struct composition_device *device = impl_from_IDCompositionDevice2(iface); + + TRACE("iface %p.\n", iface); + + return IDCompositionDevice_AddRef(&device->IDCompositionDevice_iface); +} + +static ULONG STDMETHODCALLTYPE device2_Release(IDCompositionDevice2 *iface) +{ + struct composition_device *device = impl_from_IDCompositionDevice2(iface); + + TRACE("iface %p.\n", iface); + + return IDCompositionDevice_Release(&device->IDCompositionDevice_iface); +} + +static HRESULT STDMETHODCALLTYPE device2_Commit(IDCompositionDevice2 *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_WaitForCommitCompletion(IDCompositionDevice2 *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_GetFrameStatistics(IDCompositionDevice2 *iface, + DCOMPOSITION_FRAME_STATISTICS *statistics) +{ + FIXME("iface %p, statistics %p stub!\n", iface, statistics); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateVisual(IDCompositionDevice2 *iface, + IDCompositionVisual2 **visual) +{ + FIXME("iface %p, visual %p stub!\n", iface, visual); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateSurfaceFactory(IDCompositionDevice2 *iface, + IUnknown *rendering_device, IDCompositionSurfaceFactory **surface_factory) +{ + FIXME("iface %p, rendering_device %p, surface_factory %p stub!\n", iface, rendering_device, + surface_factory); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateSurface(IDCompositionDevice2 *iface, + UINT width, UINT height, DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, + IDCompositionSurface **surface) +{ + FIXME("iface %p, width %u, height %u, format %#x, alpha_mode %#x, surface %p stub!\n", iface, + width, height, pixel_format, alpha_mode, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateVirtualSurface(IDCompositionDevice2 *iface, + UINT width, UINT height, DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, + IDCompositionVirtualSurface **surface) +{ + FIXME("iface %p, width %u, height %u, format %#x, alpha_mode %#x, surface %p stub!\n", iface, + width, height, pixel_format, alpha_mode, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateTranslateTransform(IDCompositionDevice2 *iface, + IDCompositionTranslateTransform **transform) +{ + FIXME("iface %p, transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateScaleTransform(IDCompositionDevice2 *iface, + IDCompositionScaleTransform **transform) +{ + FIXME("iface %p, transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateRotateTransform(IDCompositionDevice2 *iface, + IDCompositionRotateTransform **transform) +{ + FIXME("iface %p, transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateSkewTransform(IDCompositionDevice2 *iface, + IDCompositionSkewTransform **transform) +{ + FIXME("iface %p, transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateMatrixTransform(IDCompositionDevice2 *iface, + IDCompositionMatrixTransform **transform) +{ + FIXME("iface %p, transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateTransformGroup(IDCompositionDevice2 *iface, + IDCompositionTransform **transforms, UINT elements, + IDCompositionTransform **transform_group) +{ + FIXME("iface %p, transforms %p, elements %u, transform_group %p stub!\n", iface, transforms, + elements, transform_group); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateTranslateTransform3D(IDCompositionDevice2 *iface, + IDCompositionTranslateTransform3D **transform_3d) +{ + FIXME("iface %p, translate_transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateScaleTransform3D(IDCompositionDevice2 *iface, + IDCompositionScaleTransform3D **transform_3d) +{ + FIXME("iface %p, transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateRotateTransform3D(IDCompositionDevice2 *iface, + IDCompositionRotateTransform3D **transform_3d) +{ + FIXME("iface %p, transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateMatrixTransform3D(IDCompositionDevice2 *iface, + IDCompositionMatrixTransform3D **transform_3d) +{ + FIXME("iface %p, transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateTransform3DGroup(IDCompositionDevice2 *iface, + IDCompositionTransform3D **transforms_3d, UINT elements, + IDCompositionTransform3D **transform_3d_group) +{ + FIXME("iface %p, transforms_3d %p, elements %u, transform_3d_group %p stub!\n", iface, + transforms_3d, elements, transform_3d_group); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateEffectGroup(IDCompositionDevice2 *iface, + IDCompositionEffectGroup **effect_group) +{ + FIXME("iface %p, effect_group %p stub!\n", iface, effect_group); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateRectangleClip(IDCompositionDevice2 *iface, + IDCompositionRectangleClip **clip) +{ + FIXME("iface %p, clip %p stub!\n", iface, clip); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE device2_CreateAnimation(IDCompositionDevice2 *iface, + IDCompositionAnimation **animation) +{ + FIXME("iface %p, animation %p stub!\n", iface, animation); + return E_NOTIMPL; +} + +static const struct IDCompositionDevice2Vtbl device2_vtbl = +{ + /* IUnknown methods */ + device2_QueryInterface, + device2_AddRef, + device2_Release, + /* IDCompositionDevice2 methods */ + device2_Commit, + device2_WaitForCommitCompletion, + device2_GetFrameStatistics, + device2_CreateVisual, + device2_CreateSurfaceFactory, + device2_CreateSurface, + device2_CreateVirtualSurface, + device2_CreateTranslateTransform, + device2_CreateScaleTransform, + device2_CreateRotateTransform, + device2_CreateSkewTransform, + device2_CreateMatrixTransform, + device2_CreateTransformGroup, + device2_CreateTranslateTransform3D, + device2_CreateScaleTransform3D, + device2_CreateRotateTransform3D, + device2_CreateMatrixTransform3D, + device2_CreateTransform3DGroup, + device2_CreateEffectGroup, + device2_CreateRectangleClip, + device2_CreateAnimation, +}; + +static HRESULT create_device(int version, REFIID iid, void **out) { struct composition_device *device; HRESULT hr; @@ -292,6 +510,8 @@ static HRESULT create_device(REFIID iid, void **out) return E_OUTOFMEMORY;
device->IDCompositionDevice_iface.lpVtbl = &device_vtbl; + device->IDCompositionDevice2_iface.lpVtbl = &device2_vtbl; + device->version = version; device->ref = 1; hr = IDCompositionDevice_QueryInterface(&device->IDCompositionDevice_iface, iid, out); IDCompositionDevice_Release(&device->IDCompositionDevice_iface); @@ -305,12 +525,15 @@ HRESULT WINAPI DCompositionCreateDevice(IDXGIDevice *dxgi_device, REFIID iid, vo if (!IsEqualIID(iid, &IID_IDCompositionDevice)) return E_NOINTERFACE;
- return create_device(iid, device); + return create_device(1, iid, device); }
HRESULT WINAPI DCompositionCreateDevice2(IUnknown *rendering_device, REFIID iid, void **device) { - FIXME("%p, %s, %p.\n", rendering_device, debugstr_guid(iid), device); + FIXME("%p, %s, %p semi-stub!\n", rendering_device, debugstr_guid(iid), device);
- return E_NOTIMPL; + if (!IsEqualIID(iid, &IID_IDCompositionDevice)) + return E_NOINTERFACE; + + return create_device(2, iid, device); } diff --git a/dlls/dcomp/tests/dcomp.c b/dlls/dcomp/tests/dcomp.c index 8878cfa0dfd..6b731bf7e98 100644 --- a/dlls/dcomp/tests/dcomp.c +++ b/dlls/dcomp/tests/dcomp.c @@ -133,13 +133,9 @@ static void test_DCompositionCreateDevice2(void)
hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDevice, (void **)&dcomp_device); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { - refcount = IDCompositionDevice_Release(dcomp_device); - ok(!refcount, "Device has %lu references left.\n", refcount); - } + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount); refcount = IDXGIDevice_Release(dxgi_device); ok(!refcount, "Device has %lu references left.\n", refcount);
@@ -152,43 +148,31 @@ static void test_DCompositionCreateDevice2(void)
hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDevice, (void **)&dcomp_device); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDCompositionDevice_QueryInterface(dcomp_device, &IID_IDCompositionDevice2, + (void **)&dcomp_device2); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + refcount = IDCompositionDevice2_Release(dcomp_device2); + ok(refcount == 1, "Got unexpected refcount %lu.\n", refcount); + + hr = IDCompositionDevice_QueryInterface(dcomp_device, &IID_IDCompositionDesktopDevice, + (void **)&desktop_device); todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { - hr = IDCompositionDevice_QueryInterface(dcomp_device, &IID_IDCompositionDevice2, - (void **)&dcomp_device2); - todo_wine - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { - refcount = IDCompositionDevice2_Release(dcomp_device2); - ok(refcount == 1, "Got unexpected refcount %lu.\n", refcount); - } - - hr = IDCompositionDevice_QueryInterface(dcomp_device, &IID_IDCompositionDesktopDevice, - (void **)&desktop_device); - todo_wine - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { - refcount = IDCompositionDesktopDevice_Release(desktop_device); - ok(refcount == 1, "Got unexpected refcount %lu.\n", refcount); - } - - refcount = IDCompositionDevice_Release(dcomp_device); - ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDCompositionDesktopDevice_Release(desktop_device); + ok(refcount == 1, "Got unexpected refcount %lu.\n", refcount); }
+ refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount); + /* Parameter checks */ hr = pDCompositionCreateDevice2(NULL, &IID_IDCompositionDevice, (void **)&dcomp_device); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { - refcount = IDCompositionDevice_Release(dcomp_device); - ok(!refcount, "Device has %lu references left.\n", refcount); - } + refcount = IDCompositionDevice_Release(dcomp_device); + ok(!refcount, "Device has %lu references left.\n", refcount);
/* Crash on Windows */ if (0) @@ -200,7 +184,6 @@ static void test_DCompositionCreateDevice2(void) /* IDCompositionDevice2 needs to be queried from the device instance */ hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDevice2, (void **)&dcomp_device2); - todo_wine ok(hr == E_NOINTERFACE, "Got unexpected hr %#lx.\n", hr);
hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDesktopDevice, @@ -214,7 +197,6 @@ static void test_DCompositionCreateDevice2(void) }
hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDevice, NULL); - todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
refcount = IDXGIDevice_Release(dxgi_device);
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/dcomp/dcomp_private.h | 6 +- dlls/dcomp/device.c | 147 ++++++++++++++++++++++--------------- dlls/dcomp/tests/dcomp.c | 16 +--- 3 files changed, 94 insertions(+), 75 deletions(-)
diff --git a/dlls/dcomp/dcomp_private.h b/dlls/dcomp/dcomp_private.h index 99912ab9156..98e79ad3827 100644 --- a/dlls/dcomp/dcomp_private.h +++ b/dlls/dcomp/dcomp_private.h @@ -23,7 +23,7 @@ struct composition_device { IDCompositionDevice IDCompositionDevice_iface; - IDCompositionDevice2 IDCompositionDevice2_iface; + IDCompositionDesktopDevice IDCompositionDesktopDevice_iface; int version; LONG ref; }; @@ -33,9 +33,9 @@ static inline struct composition_device *impl_from_IDCompositionDevice(IDComposi return CONTAINING_RECORD(iface, struct composition_device, IDCompositionDevice_iface); }
-static inline struct composition_device *impl_from_IDCompositionDevice2(IDCompositionDevice2 *iface) +static inline struct composition_device *impl_from_IDCompositionDesktopDevice(IDCompositionDesktopDevice *iface) { - return CONTAINING_RECORD(iface, struct composition_device, IDCompositionDevice2_iface); + return CONTAINING_RECORD(iface, struct composition_device, IDCompositionDesktopDevice_iface); }
#endif /* __WINE_DCOMP_PRIVATE_H */ diff --git a/dlls/dcomp/device.c b/dlls/dcomp/device.c index 519e5b065bf..c64719c836d 100644 --- a/dlls/dcomp/device.c +++ b/dlls/dcomp/device.c @@ -44,10 +44,12 @@ static HRESULT STDMETHODCALLTYPE device_QueryInterface(IDCompositionDevice *ifac *out = &device->IDCompositionDevice_iface; return S_OK; } - else if (device->version >= 2 && IsEqualGUID(iid, &IID_IDCompositionDevice2)) + else if (device->version >= 2 + && (IsEqualGUID(iid, &IID_IDCompositionDevice2) + || IsEqualGUID(iid, &IID_IDCompositionDesktopDevice))) { - IUnknown_AddRef(&device->IDCompositionDevice2_iface); - *out = &device->IDCompositionDevice2_iface; + IUnknown_AddRef(&device->IDCompositionDesktopDevice_iface); + *out = &device->IDCompositionDesktopDevice_iface; return S_OK; }
@@ -285,61 +287,61 @@ static const struct IDCompositionDeviceVtbl device_vtbl = device_CheckDeviceState, };
-static HRESULT STDMETHODCALLTYPE device2_QueryInterface(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_QueryInterface(IDCompositionDesktopDevice *iface, REFIID iid, void **out) { - struct composition_device *device = impl_from_IDCompositionDevice2(iface); + struct composition_device *device = impl_from_IDCompositionDesktopDevice(iface);
TRACE("iface %p.\n", iface);
return IDCompositionDevice_QueryInterface(&device->IDCompositionDevice_iface, iid, out); }
-static ULONG STDMETHODCALLTYPE device2_AddRef(IDCompositionDevice2 *iface) +static ULONG STDMETHODCALLTYPE desktop_device_AddRef(IDCompositionDesktopDevice *iface) { - struct composition_device *device = impl_from_IDCompositionDevice2(iface); + struct composition_device *device = impl_from_IDCompositionDesktopDevice(iface);
TRACE("iface %p.\n", iface);
return IDCompositionDevice_AddRef(&device->IDCompositionDevice_iface); }
-static ULONG STDMETHODCALLTYPE device2_Release(IDCompositionDevice2 *iface) +static ULONG STDMETHODCALLTYPE desktop_device_Release(IDCompositionDesktopDevice *iface) { - struct composition_device *device = impl_from_IDCompositionDevice2(iface); + struct composition_device *device = impl_from_IDCompositionDesktopDevice(iface);
TRACE("iface %p.\n", iface);
return IDCompositionDevice_Release(&device->IDCompositionDevice_iface); }
-static HRESULT STDMETHODCALLTYPE device2_Commit(IDCompositionDevice2 *iface) +static HRESULT STDMETHODCALLTYPE desktop_device_Commit(IDCompositionDesktopDevice *iface) { FIXME("iface %p stub!\n", iface); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_WaitForCommitCompletion(IDCompositionDevice2 *iface) +static HRESULT STDMETHODCALLTYPE desktop_device_WaitForCommitCompletion(IDCompositionDesktopDevice *iface) { FIXME("iface %p stub!\n", iface); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_GetFrameStatistics(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_GetFrameStatistics(IDCompositionDesktopDevice *iface, DCOMPOSITION_FRAME_STATISTICS *statistics) { FIXME("iface %p, statistics %p stub!\n", iface, statistics); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateVisual(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateVisual(IDCompositionDesktopDevice *iface, IDCompositionVisual2 **visual) { FIXME("iface %p, visual %p stub!\n", iface, visual); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateSurfaceFactory(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateSurfaceFactory(IDCompositionDesktopDevice *iface, IUnknown *rendering_device, IDCompositionSurfaceFactory **surface_factory) { FIXME("iface %p, rendering_device %p, surface_factory %p stub!\n", iface, rendering_device, @@ -347,7 +349,7 @@ static HRESULT STDMETHODCALLTYPE device2_CreateSurfaceFactory(IDCompositionDevic return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateSurface(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateSurface(IDCompositionDesktopDevice *iface, UINT width, UINT height, DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionSurface **surface) { @@ -356,7 +358,7 @@ static HRESULT STDMETHODCALLTYPE device2_CreateSurface(IDCompositionDevice2 *ifa return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateVirtualSurface(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateVirtualSurface(IDCompositionDesktopDevice *iface, UINT width, UINT height, DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionVirtualSurface **surface) { @@ -365,79 +367,78 @@ static HRESULT STDMETHODCALLTYPE device2_CreateVirtualSurface(IDCompositionDevic return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateTranslateTransform(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateTranslateTransform(IDCompositionDesktopDevice *iface, IDCompositionTranslateTransform **transform) { FIXME("iface %p, transform %p stub!\n", iface, transform); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateScaleTransform(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateScaleTransform(IDCompositionDesktopDevice *iface, IDCompositionScaleTransform **transform) { FIXME("iface %p, transform %p stub!\n", iface, transform); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateRotateTransform(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateRotateTransform(IDCompositionDesktopDevice *iface, IDCompositionRotateTransform **transform) { FIXME("iface %p, transform %p stub!\n", iface, transform); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateSkewTransform(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateSkewTransform(IDCompositionDesktopDevice *iface, IDCompositionSkewTransform **transform) { FIXME("iface %p, transform %p stub!\n", iface, transform); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateMatrixTransform(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateMatrixTransform(IDCompositionDesktopDevice *iface, IDCompositionMatrixTransform **transform) { FIXME("iface %p, transform %p stub!\n", iface, transform); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateTransformGroup(IDCompositionDevice2 *iface, - IDCompositionTransform **transforms, UINT elements, - IDCompositionTransform **transform_group) +static HRESULT STDMETHODCALLTYPE desktop_device_CreateTransformGroup(IDCompositionDesktopDevice *iface, + IDCompositionTransform **transforms, UINT elements, IDCompositionTransform **transform_group) { FIXME("iface %p, transforms %p, elements %u, transform_group %p stub!\n", iface, transforms, elements, transform_group); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateTranslateTransform3D(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateTranslateTransform3D(IDCompositionDesktopDevice *iface, IDCompositionTranslateTransform3D **transform_3d) { FIXME("iface %p, translate_transform_3d %p stub!\n", iface, transform_3d); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateScaleTransform3D(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateScaleTransform3D(IDCompositionDesktopDevice *iface, IDCompositionScaleTransform3D **transform_3d) { FIXME("iface %p, transform_3d %p stub!\n", iface, transform_3d); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateRotateTransform3D(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateRotateTransform3D(IDCompositionDesktopDevice *iface, IDCompositionRotateTransform3D **transform_3d) { FIXME("iface %p, transform_3d %p stub!\n", iface, transform_3d); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateMatrixTransform3D(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateMatrixTransform3D(IDCompositionDesktopDevice *iface, IDCompositionMatrixTransform3D **transform_3d) { FIXME("iface %p, transform_3d %p stub!\n", iface, transform_3d); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateTransform3DGroup(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateTransform3DGroup(IDCompositionDesktopDevice *iface, IDCompositionTransform3D **transforms_3d, UINT elements, IDCompositionTransform3D **transform_3d_group) { @@ -446,55 +447,80 @@ static HRESULT STDMETHODCALLTYPE device2_CreateTransform3DGroup(IDCompositionDev return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateEffectGroup(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateEffectGroup(IDCompositionDesktopDevice *iface, IDCompositionEffectGroup **effect_group) { FIXME("iface %p, effect_group %p stub!\n", iface, effect_group); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateRectangleClip(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateRectangleClip(IDCompositionDesktopDevice *iface, IDCompositionRectangleClip **clip) { FIXME("iface %p, clip %p stub!\n", iface, clip); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE device2_CreateAnimation(IDCompositionDevice2 *iface, +static HRESULT STDMETHODCALLTYPE desktop_device_CreateAnimation(IDCompositionDesktopDevice *iface, IDCompositionAnimation **animation) { FIXME("iface %p, animation %p stub!\n", iface, animation); return E_NOTIMPL; }
-static const struct IDCompositionDevice2Vtbl device2_vtbl = +static HRESULT STDMETHODCALLTYPE desktop_device_CreateTargetForHwnd(IDCompositionDesktopDevice *iface, + HWND hwnd, BOOL topmost, IDCompositionTarget **target) +{ + FIXME("iface %p, hwnd %p, topmost %d, target %p stub!\n", iface, hwnd, topmost, target); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE desktop_device_CreateSurfaceFromHandle(IDCompositionDesktopDevice *iface, + HANDLE handle, IUnknown **surface) +{ + FIXME("iface %p, handle %p, surface %p stub!\n", iface, handle, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE desktop_device_CreateSurfaceFromHwnd(IDCompositionDesktopDevice *iface, + HWND hwnd, IUnknown **surface) +{ + FIXME("iface %p, hwnd %p, surface %p stub!\n", iface, hwnd, surface); + return E_NOTIMPL; +} + +static const struct IDCompositionDesktopDeviceVtbl desktop_device_vtbl = { /* IUnknown methods */ - device2_QueryInterface, - device2_AddRef, - device2_Release, + desktop_device_QueryInterface, + desktop_device_AddRef, + desktop_device_Release, /* IDCompositionDevice2 methods */ - device2_Commit, - device2_WaitForCommitCompletion, - device2_GetFrameStatistics, - device2_CreateVisual, - device2_CreateSurfaceFactory, - device2_CreateSurface, - device2_CreateVirtualSurface, - device2_CreateTranslateTransform, - device2_CreateScaleTransform, - device2_CreateRotateTransform, - device2_CreateSkewTransform, - device2_CreateMatrixTransform, - device2_CreateTransformGroup, - device2_CreateTranslateTransform3D, - device2_CreateScaleTransform3D, - device2_CreateRotateTransform3D, - device2_CreateMatrixTransform3D, - device2_CreateTransform3DGroup, - device2_CreateEffectGroup, - device2_CreateRectangleClip, - device2_CreateAnimation, + desktop_device_Commit, + desktop_device_WaitForCommitCompletion, + desktop_device_GetFrameStatistics, + desktop_device_CreateVisual, + desktop_device_CreateSurfaceFactory, + desktop_device_CreateSurface, + desktop_device_CreateVirtualSurface, + desktop_device_CreateTranslateTransform, + desktop_device_CreateScaleTransform, + desktop_device_CreateRotateTransform, + desktop_device_CreateSkewTransform, + desktop_device_CreateMatrixTransform, + desktop_device_CreateTransformGroup, + desktop_device_CreateTranslateTransform3D, + desktop_device_CreateScaleTransform3D, + desktop_device_CreateRotateTransform3D, + desktop_device_CreateMatrixTransform3D, + desktop_device_CreateTransform3DGroup, + desktop_device_CreateEffectGroup, + desktop_device_CreateRectangleClip, + desktop_device_CreateAnimation, + /* IDCompositionDesktopDevice methods */ + desktop_device_CreateTargetForHwnd, + desktop_device_CreateSurfaceFromHandle, + desktop_device_CreateSurfaceFromHwnd, };
static HRESULT create_device(int version, REFIID iid, void **out) @@ -510,7 +536,7 @@ static HRESULT create_device(int version, REFIID iid, void **out) return E_OUTOFMEMORY;
device->IDCompositionDevice_iface.lpVtbl = &device_vtbl; - device->IDCompositionDevice2_iface.lpVtbl = &device2_vtbl; + device->IDCompositionDesktopDevice_iface.lpVtbl = &desktop_device_vtbl; device->version = version; device->ref = 1; hr = IDCompositionDevice_QueryInterface(&device->IDCompositionDevice_iface, iid, out); @@ -530,9 +556,10 @@ HRESULT WINAPI DCompositionCreateDevice(IDXGIDevice *dxgi_device, REFIID iid, vo
HRESULT WINAPI DCompositionCreateDevice2(IUnknown *rendering_device, REFIID iid, void **device) { - FIXME("%p, %s, %p semi-stub!\n", rendering_device, debugstr_guid(iid), device); + TRACE("%p, %s, %p\n", rendering_device, debugstr_guid(iid), device);
- if (!IsEqualIID(iid, &IID_IDCompositionDevice)) + if (!IsEqualIID(iid, &IID_IDCompositionDevice) + && !IsEqualIID(iid, &IID_IDCompositionDesktopDevice)) return E_NOINTERFACE;
return create_device(2, iid, device); diff --git a/dlls/dcomp/tests/dcomp.c b/dlls/dcomp/tests/dcomp.c index 6b731bf7e98..cb14528e303 100644 --- a/dlls/dcomp/tests/dcomp.c +++ b/dlls/dcomp/tests/dcomp.c @@ -157,13 +157,9 @@ static void test_DCompositionCreateDevice2(void)
hr = IDCompositionDevice_QueryInterface(dcomp_device, &IID_IDCompositionDesktopDevice, (void **)&desktop_device); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { - refcount = IDCompositionDesktopDevice_Release(desktop_device); - ok(refcount == 1, "Got unexpected refcount %lu.\n", refcount); - } + refcount = IDCompositionDesktopDevice_Release(desktop_device); + ok(refcount == 1, "Got unexpected refcount %lu.\n", refcount);
refcount = IDCompositionDevice_Release(dcomp_device); ok(!refcount, "Device has %lu references left.\n", refcount); @@ -188,13 +184,9 @@ static void test_DCompositionCreateDevice2(void)
hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDesktopDevice, (void **)&desktop_device); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { - refcount = IDCompositionDesktopDevice_Release(desktop_device); - ok(!refcount, "Device has %lu references left.\n", refcount); - } + refcount = IDCompositionDesktopDevice_Release(desktop_device); + ok(!refcount, "Device has %lu references left.\n", refcount);
hr = pDCompositionCreateDevice2((IUnknown *)dxgi_device, &IID_IDCompositionDevice, NULL); ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
Won't this patchset regress a lot (starting from many CEF versions) by making DCompositionCreateDevice / DCompositionCreateDevice2 succeed now without actual implementation? I think now many CEF flavours call that but fallback to other ways of rendering when that fails.
If that is the case, maybe it is best to get the dxgi.CreateSwapchainForComposition implementation first which I guess is potentially most problematic for basic dcomp support?
On Tue Feb 21 04:48:55 2023 +0000, Paul Gofman wrote:
Won't this patchset regress a lot (starting from many CEF versions) by making DCompositionCreateDevice / DCompositionCreateDevice2 succeed now without actual implementation? I think now many CEF flavours call that but fallback to other ways of rendering when that fails. If that is the case, maybe it is best to get the dxgi.CreateSwapchainForComposition implementation first which I guess is potentially most problematic for basic dcomp support?
I don't think so.
For CEF versions that are affected by the Windows version bump, they will black screen until all the used DirectComposition APIs are implemented. See https://github.com/google/angle/commit/49ae88bad9c6a1c9a52728755c632b3a39438.... First, libANGLE tries DCompositionCreateDevice, and then CreateTargetForHwnd(), CreateVisual, and CreateSwapChainForComposition(). If any of these functions fail, NativeWindow::createSwapChain() fails. So DCompositionCreateDevice() succeeding now should not make a difference for CEF versions that are affected.
But then, there is no harm in upstreaming IDXGIFactory2::CreateSwapChainForComposition() first. I can get it in first.