[PATCH 0/3] MR9839: dcomp: Create stub implementations for DirectComposition
These stub implementations enable Dorico to successfully boot. They don't implement any real rendering or linkings to rendering contexts, they just create various interfaces with methods returning E_NOTIMPL. Notably, the `CompositionDevice` family has some interesting inheritance relations: * `IDCompositionDevice` inherits from `IUnknown` * `IDCompositionDevice2` also inherits from `IUnknown`, rather than `IDCompositionDevice` * `IDCompositionDesktopDevice` and `IDCompositionDevice3` both inherit from `IDCompositionDevice2`, rather than one inheriting from the other This means that a implementation of these needs to provide separate interfaces for at least `IDCompositionDevice` , `IDCompositionDesktopDevice` and `IDCompositionDevice3` . This MR also provides an 'implementation' for `IDCompositionDevice2` . The three commits here are: * Implement bare minimum of the `DCompositionCreateDevice` and `DCompositionCreateDevice2` to get Dorico to boot, ie. return the appropriate interfaces from those functions, which do nothing expect for some additional allocation functions, such as `IDCompositionDevice:CreateTargetForHwnd` . * Implement rest of `DCompositionCreateDevice`, `DCompositionCreateDevice2` and `DCompositionCreateDevice3`, and use shared 1implementations' for all of the related interfaces * Return fake S_OK responses from `IDCompositionDevice:Commit`, `IDCompositionTarget:SetRoot` and `IDCompositionVisual:SetContent` -- Dorico has one tool window where the software actually checks the response codes from all of these, and if any of these return E_NOTIMPL the entire software crashes. These prevent the crash, but the window in question will be rendered completely white. This is my first contribution for Wine, if there's some weird code it's most likely because of me, and not Microsoft. I don't have a bug for Dorico because the installer seems to require half of the internet through winetricks, but I believe this Cubase bug is caused by the same code: https://bugs.winehq.org/show_bug.cgi?id=57680 -- which I couldn't verify because the installers for Cubase currently don't seem work under Wine. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9839
From: Jaakko Hannikainen <jgke@jgke.fi> These stub implementations enable Dorico to successfully boot. They don't implement any real rendering or linkings to rendering contexts, they just create various interfaces with methods returning E_NOTIMPL. --- configure | 1 + configure.ac | 1 + dlls/dcomp/Makefile.in | 10 +- dlls/dcomp/composition_desktop_device.c | 322 +++++++++++++++++++++++ dlls/dcomp/composition_device.c | 330 ++++++++++++++++++++++++ dlls/dcomp/dcomp_private.h | 73 ++++++ dlls/dcomp/{device.c => main.c} | 29 ++- dlls/dcomp/surface.c | 183 +++++++++++++ dlls/dcomp/surface_factory.c | 136 ++++++++++ dlls/dcomp/target.c | 129 +++++++++ dlls/dcomp/tests/Makefile.in | 5 + dlls/dcomp/tests/dcomp.c | 166 ++++++++++++ dlls/dcomp/visual2.c | 277 ++++++++++++++++++++ 13 files changed, 1657 insertions(+), 5 deletions(-) create mode 100644 dlls/dcomp/composition_desktop_device.c create mode 100644 dlls/dcomp/composition_device.c create mode 100644 dlls/dcomp/dcomp_private.h rename dlls/dcomp/{device.c => main.c} (62%) create mode 100644 dlls/dcomp/surface.c create mode 100644 dlls/dcomp/surface_factory.c create mode 100644 dlls/dcomp/target.c create mode 100644 dlls/dcomp/tests/Makefile.in create mode 100644 dlls/dcomp/tests/dcomp.c create mode 100644 dlls/dcomp/visual2.c diff --git a/configure b/configure index 667b8f215bc..1fff3fc42f3 100755 --- a/configure +++ b/configure @@ -22508,6 +22508,7 @@ wine_fn_config_makefile dlls/dbghelp enable_dbghelp wine_fn_config_makefile dlls/dbghelp/tests enable_tests wine_fn_config_makefile dlls/dciman32 enable_dciman32 wine_fn_config_makefile dlls/dcomp enable_dcomp +wine_fn_config_makefile dlls/dcomp/tests enable_tests wine_fn_config_makefile dlls/ddeml.dll16 enable_win16 wine_fn_config_makefile dlls/ddraw enable_ddraw wine_fn_config_makefile dlls/ddraw/tests enable_tests diff --git a/configure.ac b/configure.ac index 1d3165dff84..1e10930dfa8 100644 --- a/configure.ac +++ b/configure.ac @@ -2650,6 +2650,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) WINE_CONFIG_MAKEFILE(dlls/ddraw) WINE_CONFIG_MAKEFILE(dlls/ddraw/tests) diff --git a/dlls/dcomp/Makefile.in b/dlls/dcomp/Makefile.in index d48b901a4fb..1664d40aec9 100644 --- a/dlls/dcomp/Makefile.in +++ b/dlls/dcomp/Makefile.in @@ -1,7 +1,15 @@ MODULE = dcomp.dll EXTRADLLFLAGS = -Wb,--prefer-native +IMPORTLIB = dcomp +IMPORTS = dxgi uuid ole32 user32 SOURCES = \ - device.c \ + main.c \ + composition_device.c \ + composition_desktop_device.c \ + surface_factory.c \ + surface.c \ + target.c \ + visual2.c \ version.rc diff --git a/dlls/dcomp/composition_desktop_device.c b/dlls/dcomp/composition_desktop_device.c new file mode 100644 index 00000000000..7cd5a159d68 --- /dev/null +++ b/dlls/dcomp/composition_desktop_device.c @@ -0,0 +1,322 @@ +/* + * Copyright 2025 Jaakko Hannikainen + * + * 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 <stdarg.h> +#include <stdlib.h> + +#include "windef.h" +#include "winbase.h" +#include "objidl.h" +#include "dxgi.h" +#include "wine/debug.h" +#include "dcomp.h" +#include "dcomp_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dcomp); + +static inline struct composition_desktop_device *impl_from_IDCompositionDesktopDevice(IDCompositionDesktopDevice *iface) +{ + return CONTAINING_RECORD(iface, struct composition_desktop_device, IDCompositionDesktopDevice_iface); +} + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_desktop_device_QueryInterface( + IDCompositionDesktopDevice *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IDCompositionDesktopDevice)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE composition_desktop_device_AddRef(IDCompositionDesktopDevice *iface) +{ + struct composition_desktop_device *factory = impl_from_IDCompositionDesktopDevice(iface); + ULONG refcount = InterlockedIncrement(&factory->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE composition_desktop_device_Release(IDCompositionDesktopDevice *iface) +{ + struct composition_desktop_device *device = impl_from_IDCompositionDesktopDevice(iface); + ULONG refcount = InterlockedDecrement(&device->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + { + free(device); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_Commit(IDCompositionDesktopDevice *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_WaitForCommitCompletion(IDCompositionDesktopDevice *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_GetFrameStatistics( + IDCompositionDesktopDevice *iface, DCOMPOSITION_FRAME_STATISTICS *statistics) +{ + FIXME("iface %p statistics %p stub!\n", iface, statistics); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateVisual( + IDCompositionDesktopDevice *iface, IDCompositionVisual2 **visual) +{ + return create_composition_visual(visual); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSurfaceFactory( + IDCompositionDesktopDevice *iface, + IUnknown *rendering_device, + IDCompositionSurfaceFactory **surface_factory) +{ + return create_composition_surface_factory(surface_factory); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSurface( + IDCompositionDesktopDevice *iface, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionSurface **surface) +{ + FIXME("iface %p width %u height %u pixel_format %#x alpha_mode %#x surface %p stub!\n", + iface, width, height, pixel_format, alpha_mode, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateVirtualSurface( + IDCompositionDesktopDevice *iface, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionVirtualSurface **surface) +{ + FIXME("iface %p width %u height %u pixel_format %#x alpha_mode %#x surface %p stub!\n", + iface, width, height, pixel_format, alpha_mode, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTranslateTransform( + IDCompositionDesktopDevice *iface, IDCompositionTranslateTransform **transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateScaleTransform( + IDCompositionDesktopDevice *iface, IDCompositionScaleTransform **transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateRotateTransform( + IDCompositionDesktopDevice *iface, IDCompositionRotateTransform **transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSkewTransform( + IDCompositionDesktopDevice *iface, IDCompositionSkewTransform **transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateMatrixTransform( + IDCompositionDesktopDevice *iface, IDCompositionMatrixTransform **transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTransformGroup( + IDCompositionDesktopDevice *iface, IDCompositionTransform **transforms, + UINT elements, IDCompositionTransform **transform_group) +{ + FIXME("iface %p transforms %p elemens %u transform_group %p stub!\n", + iface, transforms, elements, transform_group); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTranslateTransform3D( + IDCompositionDesktopDevice *iface, IDCompositionTranslateTransform3D **transform_3d) +{ + FIXME("iface %p transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_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 composition_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 composition_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 composition_desktop_device_CreateTransform3DGroup( + IDCompositionDesktopDevice *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 composition_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 composition_desktop_device_CreateRectangleClip( + IDCompositionDesktopDevice *iface, IDCompositionRectangleClip **clip) +{ + FIXME("iface %p clip %p stub!\n", iface, clip); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateAnimation( + IDCompositionDesktopDevice *iface, IDCompositionAnimation **animation) +{ + FIXME("iface %p animation %p stub!\n", iface, animation); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTargetForHwnd( + IDCompositionDesktopDevice *iface, HWND hwnd, BOOL topmost, IDCompositionTarget **target) +{ + return create_composition_target(hwnd, topmost, target); +} + +static HRESULT STDMETHODCALLTYPE composition_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 composition_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 composition_desktop_device_vtbl = +{ + composition_desktop_device_QueryInterface, + composition_desktop_device_AddRef, + composition_desktop_device_Release, + + /* IDCompositionDevice2 methods */ + composition_desktop_device_Commit, + composition_desktop_device_WaitForCommitCompletion, + composition_desktop_device_GetFrameStatistics, + composition_desktop_device_CreateVisual, + composition_desktop_device_CreateSurfaceFactory, + composition_desktop_device_CreateSurface, + composition_desktop_device_CreateVirtualSurface, + composition_desktop_device_CreateTranslateTransform, + composition_desktop_device_CreateScaleTransform, + composition_desktop_device_CreateRotateTransform, + composition_desktop_device_CreateSkewTransform, + composition_desktop_device_CreateMatrixTransform, + composition_desktop_device_CreateTransformGroup, + composition_desktop_device_CreateTranslateTransform3D, + composition_desktop_device_CreateScaleTransform3D, + composition_desktop_device_CreateRotateTransform3D, + composition_desktop_device_CreateMatrixTransform3D, + composition_desktop_device_CreateTransform3DGroup, + composition_desktop_device_CreateEffectGroup, + composition_desktop_device_CreateRectangleClip, + composition_desktop_device_CreateAnimation, + + /* IDCompositionDesktopDevice methods */ + composition_desktop_device_CreateTargetForHwnd, + composition_desktop_device_CreateSurfaceFromHandle, + composition_desktop_device_CreateSurfaceFromHwnd, +}; + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_init( + IUnknown *rendering_device, struct composition_desktop_device *device) +{ + device->IDCompositionDesktopDevice_iface.lpVtbl = &composition_desktop_device_vtbl; + device->refcount = 1; + return S_OK; +} + +HRESULT create_composition_desktop_device(IUnknown *rendering_device, void **device) +{ + struct composition_desktop_device *composition_device; + HRESULT hr; + + if(!(composition_device = calloc(1, sizeof(*composition_device)))) + { + ERR("Failed to allocate composition_device memory.\n"); + return E_OUTOFMEMORY; + } + + hr = composition_desktop_device_init(rendering_device, composition_device); + if (FAILED(hr)) + { + WARN("Failed to initialize composition_device, hr %#lx.\n", hr); + free(composition_device); + *device = NULL; + return hr; + } + + TRACE("Created composition_device %p.\n", composition_device); + *device = &composition_device->IDCompositionDesktopDevice_iface; + + return S_OK; +} diff --git a/dlls/dcomp/composition_device.c b/dlls/dcomp/composition_device.c new file mode 100644 index 00000000000..0087bba5608 --- /dev/null +++ b/dlls/dcomp/composition_device.c @@ -0,0 +1,330 @@ +/* + * Copyright 2025 Jaakko Hannikainen + * + * 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 <stdarg.h> +#include <stdlib.h> + +#include "windef.h" +#include "winbase.h" +#include "objidl.h" +#include "dxgi.h" +#include "wine/debug.h" +#include "dcomp.h" +#include "dcomp_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dcomp); + +static inline struct composition_device *impl_from_IDCompositionDevice(IDCompositionDevice *iface) +{ + return CONTAINING_RECORD(iface, struct composition_device, IDCompositionDevice_iface); +} + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_device_QueryInterface( + IDCompositionDevice *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IDCompositionDevice)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE composition_device_AddRef(IDCompositionDevice *iface) +{ + struct composition_device *factory = impl_from_IDCompositionDevice(iface); + ULONG refcount = InterlockedIncrement(&factory->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE composition_device_Release(IDCompositionDevice *iface) +{ + struct composition_device *composition_device = impl_from_IDCompositionDevice(iface); + ULONG refcount = InterlockedDecrement(&composition_device->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + { + free(composition_device); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE composition_device_Commit(IDCompositionDevice *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_WaitForCommitCompletion(IDCompositionDevice *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_GetFrameStatistics( + IDCompositionDevice *iface, DCOMPOSITION_FRAME_STATISTICS *statistics) +{ + FIXME("iface %p statistics %p stub!\n", iface, statistics); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTargetForHwnd( + IDCompositionDevice *iface, HWND hwnd, BOOL topmost, IDCompositionTarget **target) +{ + return create_composition_target(hwnd, topmost, target); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateVisual( + IDCompositionDevice *iface, IDCompositionVisual **visual) +{ + FIXME("iface %p visual %p stub!\n", iface, visual); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_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 pixel_format %#x alpha_mode %#x surface %p stub!\n", + iface, width, height, pixel_format, alpha_mode, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_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 pixel_format %#x alpha_mode %#x surface %p stub!\n", + iface, width, height, pixel_format, alpha_mode, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_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 composition_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 composition_device_CreateTranslateTransform( + IDCompositionDevice *iface, IDCompositionTranslateTransform **transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateScaleTransform( + IDCompositionDevice *iface, IDCompositionScaleTransform **transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateRotateTransform( + IDCompositionDevice *iface, IDCompositionRotateTransform **transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSkewTransform( + IDCompositionDevice *iface, IDCompositionSkewTransform **transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateMatrixTransform( + IDCompositionDevice *iface, IDCompositionMatrixTransform **transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_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 composition_device_CreateTranslateTransform3D( + IDCompositionDevice *iface, IDCompositionTranslateTransform3D **transform_3d) +{ + FIXME("iface %p transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateScaleTransform3D( + IDCompositionDevice *iface, IDCompositionScaleTransform3D **transform_3d) +{ + FIXME("iface %p transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateRotateTransform3D( + IDCompositionDevice *iface, IDCompositionRotateTransform3D **transform_3d) +{ + FIXME("iface %p transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateMatrixTransform3D( + IDCompositionDevice *iface, IDCompositionMatrixTransform3D **transform_3d) +{ + FIXME("iface %p transform_3d %p stub!\n", iface, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_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 composition_device_CreateEffectGroup( + IDCompositionDevice *iface, IDCompositionEffectGroup **effect_group) +{ + FIXME("iface %p effect_group %p stub!\n", iface, effect_group); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateRectangleClip( + IDCompositionDevice *iface, IDCompositionRectangleClip **clip) +{ + FIXME("iface %p clip %p stub!\n", iface, clip); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateAnimation( + IDCompositionDevice *iface, IDCompositionAnimation **animation) +{ + FIXME("iface %p animation %p stub!\n", iface, animation); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CheckDeviceState( + IDCompositionDevice *iface, BOOL *valid) +{ + FIXME("iface %p valid %p stub!\n", iface, valid); + return E_NOTIMPL; +} + +static const struct IDCompositionDeviceVtbl composition_device_vtbl = +{ + composition_device_QueryInterface, + composition_device_AddRef, + composition_device_Release, + composition_device_Commit, + composition_device_WaitForCommitCompletion, + composition_device_GetFrameStatistics, + composition_device_CreateTargetForHwnd, + composition_device_CreateVisual, + composition_device_CreateSurface, + composition_device_CreateVirtualSurface, + composition_device_CreateSurfaceFromHandle, + composition_device_CreateSurfaceFromHwnd, + composition_device_CreateTranslateTransform, + composition_device_CreateScaleTransform, + composition_device_CreateRotateTransform, + composition_device_CreateSkewTransform, + composition_device_CreateMatrixTransform, + composition_device_CreateTransformGroup, + composition_device_CreateTranslateTransform3D, + composition_device_CreateScaleTransform3D, + composition_device_CreateRotateTransform3D, + composition_device_CreateMatrixTransform3D, + composition_device_CreateTransform3DGroup, + composition_device_CreateEffectGroup, + composition_device_CreateRectangleClip, + composition_device_CreateAnimation, + composition_device_CheckDeviceState, +}; + +static HRESULT STDMETHODCALLTYPE composition_device_init( + IDXGIDevice *dxgi_device, struct composition_device *composition_device) +{ + composition_device->IDCompositionDevice_iface.lpVtbl = &composition_device_vtbl; + composition_device->refcount = 1; + return S_OK; +} + +HRESULT create_composition_device(IDXGIDevice *dxgi_device, void **device) +{ + struct composition_device *composition_device; + HRESULT hr; + + if(!(composition_device = calloc(1, sizeof(*composition_device)))) + { + ERR("Failed to allocate device memory.\n"); + return E_OUTOFMEMORY; + } + + hr = composition_device_init(dxgi_device, composition_device); + if (FAILED(hr)) + { + WARN("Failed to initialize device, hr %#lx.\n", hr); + free(composition_device); + *device = NULL; + return hr; + } + + TRACE("Created device %p.\n", composition_device); + *device = &composition_device->IDCompositionDevice_iface; + + return S_OK; +} diff --git a/dlls/dcomp/dcomp_private.h b/dlls/dcomp/dcomp_private.h new file mode 100644 index 00000000000..330a8ce2468 --- /dev/null +++ b/dlls/dcomp/dcomp_private.h @@ -0,0 +1,73 @@ +/* + * Copyright 2025 Jaakko Hannikainen + * + * 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" + +/* IDCompositionDevice */ +struct composition_device +{ + IDCompositionDevice IDCompositionDevice_iface; + LONG refcount; +}; + +/* IDCompositionDesktopDevice */ +struct composition_desktop_device +{ + IDCompositionDesktopDevice IDCompositionDesktopDevice_iface; + LONG refcount; +}; + +/* IDCompositionTarget */ +struct composition_target +{ + IDCompositionTarget IDCompositionTarget_iface; + LONG refcount; +}; + +/* IDCompositionVisual */ +struct composition_visual +{ + IDCompositionVisual2 IDCompositionVisual2_iface; + LONG refcount; +}; + +/* IDCompositionSurfaceFactory */ +struct composition_surface_factory +{ + IDCompositionSurfaceFactory IDCompositionSurfaceFactory_iface; + LONG refcount; +}; + +/* IDCompositionVirtualSurface */ +struct composition_virtual_surface +{ + IDCompositionVirtualSurface IDCompositionVirtualSurface_iface; + LONG refcount; +}; + +HRESULT create_composition_device(IDXGIDevice *dxgi_device, void **device); +HRESULT create_composition_desktop_device(IUnknown *rendering_device, void **device); +HRESULT create_composition_target(HWND hwnd, BOOL topmost, IDCompositionTarget **target); +HRESULT create_composition_visual(IDCompositionVisual2 **visual); +HRESULT create_composition_surface_factory(IDCompositionSurfaceFactory **surface_factory); +HRESULT create_composition_virtual_surface(IDCompositionVirtualSurface **virtual_surface); + +#endif /* __WINE_DCOMP_PRIVATE_H */ diff --git a/dlls/dcomp/device.c b/dlls/dcomp/main.c similarity index 62% rename from dlls/dcomp/device.c rename to dlls/dcomp/main.c index 2744d758e91..780b20d37f0 100644 --- a/dlls/dcomp/device.c +++ b/dlls/dcomp/main.c @@ -1,5 +1,6 @@ /* * Copyright 2020 Nikolay Sivov for CodeWeavers + * Copyright 2025 Jaakko Hannikainen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,21 +23,41 @@ #include "objidl.h" #include "dxgi.h" #include "wine/debug.h" +#include "initguid.h" +#include "dcomp.h" +#include "dcomp_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dcomp); HRESULT WINAPI DCompositionCreateDevice(IDXGIDevice *dxgi_device, REFIID iid, void **device) { - FIXME("%p, %s, %p.\n", dxgi_device, debugstr_guid(iid), device); + if(IsEqualGUID(iid, &IID_IDCompositionDevice)) + { + return create_composition_device(dxgi_device, device); + } - return E_NOTIMPL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *device = NULL; + + return E_NOINTERFACE; } HRESULT WINAPI DCompositionCreateDevice2(IUnknown *rendering_device, REFIID iid, void **device) { - FIXME("%p, %s, %p.\n", rendering_device, debugstr_guid(iid), device); + if(IsEqualGUID(iid, &IID_IDCompositionDevice)) + { + FIXME("%p, %s, %p.\n", rendering_device, debugstr_guid(iid), device); + return E_NOTIMPL; + } + if(IsEqualGUID(iid, &IID_IDCompositionDesktopDevice)) + { + return create_composition_desktop_device(rendering_device, device); + } - return E_NOTIMPL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *device = NULL; + + return E_NOINTERFACE; } HRESULT WINAPI DCompositionCreateDevice3(IUnknown *rendering_device, REFIID iid, void **device) diff --git a/dlls/dcomp/surface.c b/dlls/dcomp/surface.c new file mode 100644 index 00000000000..38648a9f920 --- /dev/null +++ b/dlls/dcomp/surface.c @@ -0,0 +1,183 @@ +/* + * Copyright 2025 Jaakko Hannikainen + * + * 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 <stdarg.h> +#include <stdlib.h> + +#include "windef.h" +#include "winbase.h" +#include "objidl.h" +#include "dxgi.h" +#include "wine/debug.h" +#include "dcomp.h" +#include "dcomp_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dcomp); + +static inline struct composition_virtual_surface *impl_from_IDCompositionVirtualSurface(IDCompositionVirtualSurface *iface) +{ + return CONTAINING_RECORD(iface, struct composition_virtual_surface, IDCompositionVirtualSurface_iface); +} + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_virtual_surface_QueryInterface( + IDCompositionVirtualSurface *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IDCompositionVisual)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE composition_virtual_surface_AddRef(IDCompositionVirtualSurface *iface) +{ + struct composition_virtual_surface *factory = impl_from_IDCompositionVirtualSurface(iface); + ULONG refcount = InterlockedIncrement(&factory->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE composition_virtual_surface_Release(IDCompositionVirtualSurface *iface) +{ + struct composition_virtual_surface *composition_virtual_surface = impl_from_IDCompositionVirtualSurface(iface); + ULONG refcount = InterlockedDecrement(&composition_virtual_surface->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + { + free(composition_virtual_surface); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE composition_virtual_surface_BeginDraw( + IDCompositionVirtualSurface *iface, const RECT *rect, + REFIID iid, void **object, POINT *offset) +{ + FIXME("iface %p rect %p iid %s object %p offset %p stub!\n", + iface, rect, debugstr_guid(iid), object, offset); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_virtual_surface_EndDraw(IDCompositionVirtualSurface *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_virtual_surface_SuspendDraw(IDCompositionVirtualSurface *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_virtual_surface_ResumeDraw(IDCompositionVirtualSurface *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_virtual_surface_Scroll( + IDCompositionVirtualSurface *iface, const RECT *scroll, const RECT *clip, + int offset_x, int offset_y) +{ + FIXME("iface %p scroll %p clip %p offset_x %d offset_y %d stub!\n", + iface, scroll, clip, offset_x, offset_y); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_virtual_surface_Resize( + IDCompositionVirtualSurface *iface, UINT width, UINT height) +{ + FIXME("iface %p width %u height %u stub!\n", iface, width, height); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_virtual_surface_Trim( + IDCompositionVirtualSurface *iface, const RECT *rectangles, UINT count) +{ + FIXME("iface %p rectangles %p count %u stub!\n", iface, rectangles, count); + return E_NOTIMPL; +} + + +static const struct IDCompositionVirtualSurfaceVtbl composition_virtual_surface_vtbl = +{ + composition_virtual_surface_QueryInterface, + composition_virtual_surface_AddRef, + composition_virtual_surface_Release, + + /* IDCompositionSurface methods */ + composition_virtual_surface_BeginDraw, + composition_virtual_surface_EndDraw, + composition_virtual_surface_SuspendDraw, + composition_virtual_surface_ResumeDraw, + composition_virtual_surface_Scroll, + + /* IDCompositionVirtualSurface methods */ + composition_virtual_surface_Resize, + composition_virtual_surface_Trim, +}; + +static HRESULT STDMETHODCALLTYPE composition_virtual_surface_init( + struct composition_virtual_surface *composition_virtual_surface) +{ + composition_virtual_surface->IDCompositionVirtualSurface_iface.lpVtbl = &composition_virtual_surface_vtbl; + composition_virtual_surface->refcount = 1; + return S_OK; +} + +HRESULT create_composition_virtual_surface(IDCompositionVirtualSurface **virtual_surface) +{ + struct composition_virtual_surface *composition_virtual_surface; + HRESULT hr; + + if(!(composition_virtual_surface = calloc(1, sizeof(*composition_virtual_surface)))) + { + ERR("Failed to allocate composition virtual_surface memory.\n"); + return E_OUTOFMEMORY; + } + + hr = composition_virtual_surface_init(composition_virtual_surface); + if (FAILED(hr)) + { + WARN("Failed to initialize composition virtual_surface, hr %#lx.\n", hr); + free(composition_virtual_surface); + *virtual_surface = NULL; + return hr; + } + + TRACE("Created composition virtual_surface %p.\n", composition_virtual_surface); + *virtual_surface = &composition_virtual_surface->IDCompositionVirtualSurface_iface; + + return S_OK; +} diff --git a/dlls/dcomp/surface_factory.c b/dlls/dcomp/surface_factory.c new file mode 100644 index 00000000000..273c8801f3b --- /dev/null +++ b/dlls/dcomp/surface_factory.c @@ -0,0 +1,136 @@ +/* + * Copyright 2025 Jaakko Hannikainen + * + * 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 <stdarg.h> +#include <stdlib.h> + +#include "windef.h" +#include "winbase.h" +#include "objidl.h" +#include "dxgi.h" +#include "wine/debug.h" +#include "dcomp.h" +#include "dcomp_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dcomp); + +static inline struct composition_surface_factory *impl_from_IDCompositionSurfaceFactory(IDCompositionSurfaceFactory *iface) +{ + return CONTAINING_RECORD(iface, struct composition_surface_factory, IDCompositionSurfaceFactory_iface); +} + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_surface_factory_QueryInterface( + IDCompositionSurfaceFactory *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IDCompositionVisual)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE composition_surface_factory_AddRef(IDCompositionSurfaceFactory *iface) +{ + struct composition_surface_factory *factory = impl_from_IDCompositionSurfaceFactory(iface); + ULONG refcount = InterlockedIncrement(&factory->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE composition_surface_factory_Release(IDCompositionSurfaceFactory *iface) +{ + struct composition_surface_factory *composition_surface_factory = impl_from_IDCompositionSurfaceFactory(iface); + ULONG refcount = InterlockedDecrement(&composition_surface_factory->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + { + free(composition_surface_factory); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE composition_surface_factory_CreateSurface( + IDCompositionSurfaceFactory *iface, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionSurface **surface) +{ + return create_composition_virtual_surface((IDCompositionVirtualSurface **)surface); +} +static HRESULT STDMETHODCALLTYPE composition_surface_factory_CreateVirtualSurface( + IDCompositionSurfaceFactory *iface, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionVirtualSurface **surface) +{ + return create_composition_virtual_surface(surface); +} + +static const struct IDCompositionSurfaceFactoryVtbl composition_surface_factory_vtbl = +{ + composition_surface_factory_QueryInterface, + composition_surface_factory_AddRef, + composition_surface_factory_Release, + composition_surface_factory_CreateSurface, + composition_surface_factory_CreateVirtualSurface, +}; + +static HRESULT STDMETHODCALLTYPE composition_surface_factory_init( + struct composition_surface_factory *composition_surface_factory) +{ + composition_surface_factory->IDCompositionSurfaceFactory_iface.lpVtbl = &composition_surface_factory_vtbl; + composition_surface_factory->refcount = 1; + return S_OK; +} + +HRESULT create_composition_surface_factory(IDCompositionSurfaceFactory **surface_factory) +{ + struct composition_surface_factory *composition_surface_factory; + HRESULT hr; + + if(!(composition_surface_factory = calloc(1, sizeof(*composition_surface_factory)))) + { + ERR("Failed to allocate composition surface_factory memory.\n"); + return E_OUTOFMEMORY; + } + + hr = composition_surface_factory_init(composition_surface_factory); + if (FAILED(hr)) + { + WARN("Failed to initialize composition surface_factory, hr %#lx.\n", hr); + free(composition_surface_factory); + *surface_factory = NULL; + return hr; + } + + TRACE("Created composition surface_factory %p.\n", composition_surface_factory); + *surface_factory = &composition_surface_factory->IDCompositionSurfaceFactory_iface; + + return S_OK; +} diff --git a/dlls/dcomp/target.c b/dlls/dcomp/target.c new file mode 100644 index 00000000000..eaa91165161 --- /dev/null +++ b/dlls/dcomp/target.c @@ -0,0 +1,129 @@ +/* + * Copyright 2025 Jaakko Hannikainen + * + * 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 <stdarg.h> +#include <stdlib.h> + +#include "windef.h" +#include "winbase.h" +#include "objidl.h" +#include "dxgi.h" +#include "wine/debug.h" +#include "dcomp.h" +#include "dcomp_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dcomp); + +static inline struct composition_target *impl_from_IDCompositionTarget(IDCompositionTarget *iface) +{ + return CONTAINING_RECORD(iface, struct composition_target, IDCompositionTarget_iface); +} + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_target_QueryInterface( + IDCompositionTarget *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IDCompositionTarget)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE composition_target_AddRef(IDCompositionTarget *iface) +{ + struct composition_target *factory = impl_from_IDCompositionTarget(iface); + ULONG refcount = InterlockedIncrement(&factory->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE composition_target_Release(IDCompositionTarget *iface) +{ + struct composition_target *composition_target = impl_from_IDCompositionTarget(iface); + ULONG refcount = InterlockedDecrement(&composition_target->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + { + free(composition_target); + } + + return refcount; +} + + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_target_SetRoot( + IDCompositionTarget *iface, IDCompositionVisual *visual) +{ + FIXME("iface %p, visual %p stub!\n", iface, visual); + return E_NOTIMPL; +} + +static const struct IDCompositionTargetVtbl composition_target_vtbl = +{ + composition_target_QueryInterface, + composition_target_AddRef, + composition_target_Release, + composition_target_SetRoot +}; + +static HRESULT STDMETHODCALLTYPE composition_target_init(struct composition_target *composition_target) +{ + composition_target->IDCompositionTarget_iface.lpVtbl = &composition_target_vtbl; + composition_target->refcount = 1; + return S_OK; +} + +HRESULT create_composition_target(HWND hwnd, BOOL topmost, IDCompositionTarget **target) +{ + struct composition_target *composition_target; + HRESULT hr; + + if(!(composition_target = calloc(1, sizeof(*composition_target)))) + { + ERR("Failed to allocate composition target memory.\n"); + return E_OUTOFMEMORY; + } + + hr = composition_target_init(composition_target); + if (FAILED(hr)) + { + WARN("Failed to initialize composition target, hr %#lx.\n", hr); + free(composition_target); + *target = NULL; + return hr; + } + + TRACE("Created composition target %p.\n", composition_target); + *target = &composition_target->IDCompositionTarget_iface; + + return S_OK; +} diff --git a/dlls/dcomp/tests/Makefile.in b/dlls/dcomp/tests/Makefile.in new file mode 100644 index 00000000000..115cb7e025d --- /dev/null +++ b/dlls/dcomp/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = dcomp.dll +IMPORTS = d3d11 dcomp ole32 user32 + +SOURCES = \ + dcomp.c diff --git a/dlls/dcomp/tests/dcomp.c b/dlls/dcomp/tests/dcomp.c new file mode 100644 index 00000000000..a3659592409 --- /dev/null +++ b/dlls/dcomp/tests/dcomp.c @@ -0,0 +1,166 @@ +/* + * Copyright 2025 Jaakko Hannikainen + * + * 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 <stdarg.h> + +#include "windef.h" +#include "initguid.h" +#include "d3d11_4.h" +#include "dcomp.h" +#include "wine/test.h" + +static ID3D11Device *create_d3d11_device(void) +{ + static const D3D_FEATURE_LEVEL default_feature_level[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + }; + const D3D_FEATURE_LEVEL *feature_level; + unsigned int feature_level_count; + ID3D11Device *device; + + feature_level = default_feature_level; + feature_level_count = ARRAY_SIZE(default_feature_level); + + if (SUCCEEDED(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, + feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL))) + return device; + if (SUCCEEDED(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0, + feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL))) + return device; + if (SUCCEEDED(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0, + feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL))) + return device; + + return NULL; +} + +static HRESULT create_window_and_device(HWND *hwnd, ID3D11Device **d3d11_device, IDXGIDevice **dxgi_device) +{ + HRESULT hr; + + WNDCLASSEXW wcx = + { + .cbSize = sizeof(WNDCLASSEXW), + .hInstance = GetModuleHandleW(NULL), + .lpszClassName = L"device_monitor", + .lpfnWndProc = DefWindowProcW, + }; + + RegisterClassExW(&wcx); + + *hwnd = CreateWindowW(wcx.lpszClassName, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); + + hr = *hwnd ? S_OK : E_FAIL; + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ShowWindow(*hwnd, SW_SHOWNORMAL); + UpdateWindow(*hwnd); + + *d3d11_device = create_d3d11_device(); + ok(*d3d11_device != NULL, "Failed to create D3D11 device\n"); + + hr = ID3D11Device_QueryInterface(*d3d11_device, &IID_IDXGIDevice, (void **)dxgi_device); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + return hr; +} + +static void test_CreateInstance2_DesktopDevice(void) +{ + HRESULT hr; + ID3D11Device *d3d11_device; + HWND hwnd; + IDXGIDevice *dxgi_device = NULL; + IDCompositionDesktopDevice *dcomp_device; + + hr = create_window_and_device(&hwnd, &d3d11_device, &dxgi_device); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = DCompositionCreateDevice2((IUnknown *)dxgi_device, + &IID_IDCompositionDesktopDevice, + (void **)&dcomp_device); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IDCompositionDesktopDevice_Release(dcomp_device); + + IDXGIDevice_Release(dxgi_device); +} + +static void test_create_surface_and_target(void) +{ + HRESULT hr; + ID3D11Device *d3d11_device; + HWND hwnd; + IDXGIDevice *dxgi_device = NULL; + IDCompositionDesktopDevice *dcomp_device; + IDCompositionSurfaceFactory *surface_factory; + IDCompositionSurface *surface; + IDCompositionVirtualSurface *virtual_surface; + IDCompositionTarget *target; + + hr = create_window_and_device(&hwnd, &d3d11_device, &dxgi_device); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = DCompositionCreateDevice2((IUnknown *)dxgi_device, + &IID_IDCompositionDesktopDevice, + (void **)&dcomp_device); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDCompositionDesktopDevice_CreateSurfaceFactory( + dcomp_device, (IUnknown *)dxgi_device, &surface_factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDCompositionSurfaceFactory_CreateSurface( + surface_factory, 100, 100, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_ALPHA_MODE_PREMULTIPLIED, &surface); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IDCompositionSurface_Release(surface); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDCompositionSurfaceFactory_CreateVirtualSurface( + surface_factory, 100, 100, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_ALPHA_MODE_PREMULTIPLIED, &virtual_surface); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IDCompositionVirtualSurface_Release(virtual_surface); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDCompositionDesktopDevice_CreateTargetForHwnd(dcomp_device, hwnd, FALSE, &target); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IDCompositionTarget_Release(target); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IDCompositionDesktopDevice_Release(dcomp_device); + + IDXGIDevice_Release(dxgi_device); +} + +START_TEST(dcomp) +{ + CoInitialize(NULL); + + test_CreateInstance2_DesktopDevice(); + test_create_surface_and_target(); + + CoUninitialize(); +} diff --git a/dlls/dcomp/visual2.c b/dlls/dcomp/visual2.c new file mode 100644 index 00000000000..74d81199d44 --- /dev/null +++ b/dlls/dcomp/visual2.c @@ -0,0 +1,277 @@ +/* + * Copyright 2025 Jaakko Hannikainen + * + * 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 <stdarg.h> +#include <stdlib.h> + +#include "windef.h" +#include "winbase.h" +#include "objidl.h" +#include "dxgi.h" +#include "wine/debug.h" +#include "dcomp.h" +#include "dcomp_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dcomp); + +static inline struct composition_visual *impl_from_IDCompositionVisual2(IDCompositionVisual2 *iface) +{ + return CONTAINING_RECORD(iface, struct composition_visual, IDCompositionVisual2_iface); +} + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_visual_QueryInterface( + IDCompositionVisual2 *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IDCompositionVisual)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE composition_visual_AddRef(IDCompositionVisual2 *iface) +{ + struct composition_visual *factory = impl_from_IDCompositionVisual2(iface); + ULONG refcount = InterlockedIncrement(&factory->refcount); + + TRACE("%p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE composition_visual_Release(IDCompositionVisual2 *iface) +{ + struct composition_visual *composition_visual = impl_from_IDCompositionVisual2(iface); + ULONG refcount = InterlockedDecrement(&composition_visual->refcount); + + TRACE("%p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + { + free(composition_visual); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetOffsetXAnimation( + IDCompositionVisual2 *iface, IDCompositionAnimation *animation) +{ + FIXME("iface %p animation %p stub!\n", iface, animation); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetOffsetX( + IDCompositionVisual2 *iface, float offset_x) +{ + FIXME("iface %p offset_x %.8e stub!\n", iface, offset_x); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetOffsetYAnimation( + IDCompositionVisual2 *iface, IDCompositionAnimation *animation) +{ + FIXME("iface %p animation %p stub!\n", iface, animation); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetOffsetY( + IDCompositionVisual2 *iface, float offset_y) +{ + FIXME("iface %p offset_y %.8e stub!\n", iface, offset_y); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetTransformObject( + IDCompositionVisual2 *iface, IDCompositionTransform *transform) +{ + FIXME("iface %p transform %p stub!\n", iface, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetTransform( + IDCompositionVisual2 *iface, const D2D_MATRIX_3X2_F *matrix) +{ + FIXME("iface %p matrix %p stub!\n", iface, matrix); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetTransformParent( + IDCompositionVisual2 *iface, IDCompositionVisual *visual) +{ + FIXME("iface %p visual %p stub!\n", iface, visual); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetEffect( + IDCompositionVisual2 *iface, IDCompositionEffect *effect) +{ + FIXME("iface %p effect %p stub!\n", iface, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetBitmapInterpolationMode( + IDCompositionVisual2 *iface, enum DCOMPOSITION_BITMAP_INTERPOLATION_MODE interpolation_mode) +{ + FIXME("iface %p interpolation_mode %d stub!\n", iface, interpolation_mode); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetBorderMode( + IDCompositionVisual2 *iface, enum DCOMPOSITION_BORDER_MODE border_mode) +{ + FIXME("iface %p border_mode %d stub!\n", iface, border_mode); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetClipObject( + IDCompositionVisual2 *iface, IDCompositionClip *clip) +{ + FIXME("iface %p clip %p stub!\n", iface, clip); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetClip( + IDCompositionVisual2 *iface, const D2D_RECT_F *rect) +{ + FIXME("iface %p rect %p stub!\n", iface, rect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetContent( + IDCompositionVisual2 *iface, IUnknown *content) +{ + FIXME("iface %p content %p stub!\n", iface, content); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_AddVisual( + IDCompositionVisual2 *iface, IDCompositionVisual *visual, BOOL insert_above, + IDCompositionVisual *reference_visual) +{ + FIXME("iface %p visual %p insert_above %d reference_visual %p stub!\n", + iface, visual, insert_above, reference_visual); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_RemoveVisual( + IDCompositionVisual2 *iface, IDCompositionVisual *visual) +{ + FIXME("iface %p visual %p stub!\n", iface, visual); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_RemoveAllVisuals(IDCompositionVisual2 *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetCompositeMode( + IDCompositionVisual2 *iface, enum DCOMPOSITION_COMPOSITE_MODE composite_mode) +{ + FIXME("iface %p composite_mode %d stub!\n", iface, composite_mode); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetOpacityMode( + IDCompositionVisual2 *iface, enum DCOMPOSITION_OPACITY_MODE opacity_mode) +{ + FIXME("iface %p opacity_mode %d stub!\n", iface, opacity_mode); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_visual_SetBackFaceVisibility( + IDCompositionVisual2 *iface, enum DCOMPOSITION_BACKFACE_VISIBILITY visibility) +{ + FIXME("iface %p visibility %d stub!\n", iface, visibility); + return E_NOTIMPL; +} + +static const struct IDCompositionVisual2Vtbl composition_visual_vtbl = +{ + composition_visual_QueryInterface, + composition_visual_AddRef, + composition_visual_Release, + + /* IDCompositionVisual methods */ + composition_visual_SetOffsetXAnimation, + composition_visual_SetOffsetX, + composition_visual_SetOffsetYAnimation, + composition_visual_SetOffsetY, + composition_visual_SetTransformObject, + composition_visual_SetTransform, + composition_visual_SetTransformParent, + composition_visual_SetEffect, + composition_visual_SetBitmapInterpolationMode, + composition_visual_SetBorderMode, + composition_visual_SetClipObject, + composition_visual_SetClip, + composition_visual_SetContent, + composition_visual_AddVisual, + composition_visual_RemoveVisual, + composition_visual_RemoveAllVisuals, + composition_visual_SetCompositeMode, + + /* IDCompositionVisual2 methods */ + composition_visual_SetOpacityMode, + composition_visual_SetBackFaceVisibility, +}; + +static HRESULT STDMETHODCALLTYPE composition_visual_init(struct composition_visual *composition_visual) +{ + composition_visual->IDCompositionVisual2_iface.lpVtbl = &composition_visual_vtbl; + composition_visual->refcount = 1; + return S_OK; +} + +HRESULT create_composition_visual(IDCompositionVisual2 **visual) +{ + struct composition_visual *composition_visual; + HRESULT hr; + + if(!(composition_visual = calloc(1, sizeof(*composition_visual)))) + { + ERR("Failed to allocate composition visual memory.\n"); + return E_OUTOFMEMORY; + } + + hr = composition_visual_init(composition_visual); + if (FAILED(hr)) + { + WARN("Failed to initialize composition visual, hr %#lx.\n", hr); + free(composition_visual); + *visual = NULL; + return hr; + } + + TRACE("Created composition visual %p.\n", composition_visual); + *visual = &composition_visual->IDCompositionVisual2_iface; + + return S_OK; +} -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9839
From: Jaakko Hannikainen <jgke@jgke.fi> --- dlls/dcomp/Makefile.in | 5 +- dlls/dcomp/composition_desktop_device.c | 322 ------ dlls/dcomp/composition_device.c | 330 ------ dlls/dcomp/dcomp_private.h | 11 +- dlls/dcomp/device.c | 1272 +++++++++++++++++++++++ dlls/dcomp/main.c | 69 +- dlls/dcomp/surface.c | 4 - dlls/dcomp/surface_factory.c | 4 - dlls/dcomp/target.c | 4 - dlls/dcomp/tests/dcomp.c | 38 +- dlls/dcomp/visual2.c | 4 - include/dcomp.idl | 28 + 12 files changed, 1392 insertions(+), 699 deletions(-) delete mode 100644 dlls/dcomp/composition_desktop_device.c delete mode 100644 dlls/dcomp/composition_device.c create mode 100644 dlls/dcomp/device.c diff --git a/dlls/dcomp/Makefile.in b/dlls/dcomp/Makefile.in index 1664d40aec9..48bda8e9533 100644 --- a/dlls/dcomp/Makefile.in +++ b/dlls/dcomp/Makefile.in @@ -6,10 +6,9 @@ IMPORTS = dxgi uuid ole32 user32 SOURCES = \ main.c \ - composition_device.c \ - composition_desktop_device.c \ - surface_factory.c \ + device.c \ surface.c \ + surface_factory.c \ target.c \ visual2.c \ version.rc diff --git a/dlls/dcomp/composition_desktop_device.c b/dlls/dcomp/composition_desktop_device.c deleted file mode 100644 index 7cd5a159d68..00000000000 --- a/dlls/dcomp/composition_desktop_device.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright 2025 Jaakko Hannikainen - * - * 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 <stdarg.h> -#include <stdlib.h> - -#include "windef.h" -#include "winbase.h" -#include "objidl.h" -#include "dxgi.h" -#include "wine/debug.h" -#include "dcomp.h" -#include "dcomp_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(dcomp); - -static inline struct composition_desktop_device *impl_from_IDCompositionDesktopDevice(IDCompositionDesktopDevice *iface) -{ - return CONTAINING_RECORD(iface, struct composition_desktop_device, IDCompositionDesktopDevice_iface); -} - -static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_desktop_device_QueryInterface( - IDCompositionDesktopDevice *iface, REFIID iid, void **out) -{ - TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - - if (IsEqualGUID(iid, &IID_IDCompositionDesktopDevice)) - { - IUnknown_AddRef(iface); - *out = iface; - return S_OK; - } - - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - - *out = NULL; - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE composition_desktop_device_AddRef(IDCompositionDesktopDevice *iface) -{ - struct composition_desktop_device *factory = impl_from_IDCompositionDesktopDevice(iface); - ULONG refcount = InterlockedIncrement(&factory->refcount); - - TRACE("%p increasing refcount to %lu.\n", iface, refcount); - - return refcount; -} - -static ULONG STDMETHODCALLTYPE composition_desktop_device_Release(IDCompositionDesktopDevice *iface) -{ - struct composition_desktop_device *device = impl_from_IDCompositionDesktopDevice(iface); - ULONG refcount = InterlockedDecrement(&device->refcount); - - TRACE("%p decreasing refcount to %lu.\n", iface, refcount); - - if (!refcount) - { - free(device); - } - - return refcount; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_Commit(IDCompositionDesktopDevice *iface) -{ - FIXME("iface %p stub!\n", iface); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_WaitForCommitCompletion(IDCompositionDesktopDevice *iface) -{ - FIXME("iface %p stub!\n", iface); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_GetFrameStatistics( - IDCompositionDesktopDevice *iface, DCOMPOSITION_FRAME_STATISTICS *statistics) -{ - FIXME("iface %p statistics %p stub!\n", iface, statistics); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateVisual( - IDCompositionDesktopDevice *iface, IDCompositionVisual2 **visual) -{ - return create_composition_visual(visual); -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSurfaceFactory( - IDCompositionDesktopDevice *iface, - IUnknown *rendering_device, - IDCompositionSurfaceFactory **surface_factory) -{ - return create_composition_surface_factory(surface_factory); -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSurface( - IDCompositionDesktopDevice *iface, UINT width, UINT height, - DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionSurface **surface) -{ - FIXME("iface %p width %u height %u pixel_format %#x alpha_mode %#x surface %p stub!\n", - iface, width, height, pixel_format, alpha_mode, surface); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateVirtualSurface( - IDCompositionDesktopDevice *iface, UINT width, UINT height, - DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionVirtualSurface **surface) -{ - FIXME("iface %p width %u height %u pixel_format %#x alpha_mode %#x surface %p stub!\n", - iface, width, height, pixel_format, alpha_mode, surface); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTranslateTransform( - IDCompositionDesktopDevice *iface, IDCompositionTranslateTransform **transform) -{ - FIXME("iface %p transform %p stub!\n", iface, transform); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateScaleTransform( - IDCompositionDesktopDevice *iface, IDCompositionScaleTransform **transform) -{ - FIXME("iface %p transform %p stub!\n", iface, transform); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateRotateTransform( - IDCompositionDesktopDevice *iface, IDCompositionRotateTransform **transform) -{ - FIXME("iface %p transform %p stub!\n", iface, transform); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSkewTransform( - IDCompositionDesktopDevice *iface, IDCompositionSkewTransform **transform) -{ - FIXME("iface %p transform %p stub!\n", iface, transform); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateMatrixTransform( - IDCompositionDesktopDevice *iface, IDCompositionMatrixTransform **transform) -{ - FIXME("iface %p transform %p stub!\n", iface, transform); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTransformGroup( - IDCompositionDesktopDevice *iface, IDCompositionTransform **transforms, - UINT elements, IDCompositionTransform **transform_group) -{ - FIXME("iface %p transforms %p elemens %u transform_group %p stub!\n", - iface, transforms, elements, transform_group); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTranslateTransform3D( - IDCompositionDesktopDevice *iface, IDCompositionTranslateTransform3D **transform_3d) -{ - FIXME("iface %p transform_3d %p stub!\n", iface, transform_3d); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_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 composition_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 composition_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 composition_desktop_device_CreateTransform3DGroup( - IDCompositionDesktopDevice *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 composition_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 composition_desktop_device_CreateRectangleClip( - IDCompositionDesktopDevice *iface, IDCompositionRectangleClip **clip) -{ - FIXME("iface %p clip %p stub!\n", iface, clip); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateAnimation( - IDCompositionDesktopDevice *iface, IDCompositionAnimation **animation) -{ - FIXME("iface %p animation %p stub!\n", iface, animation); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTargetForHwnd( - IDCompositionDesktopDevice *iface, HWND hwnd, BOOL topmost, IDCompositionTarget **target) -{ - return create_composition_target(hwnd, topmost, target); -} - -static HRESULT STDMETHODCALLTYPE composition_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 composition_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 composition_desktop_device_vtbl = -{ - composition_desktop_device_QueryInterface, - composition_desktop_device_AddRef, - composition_desktop_device_Release, - - /* IDCompositionDevice2 methods */ - composition_desktop_device_Commit, - composition_desktop_device_WaitForCommitCompletion, - composition_desktop_device_GetFrameStatistics, - composition_desktop_device_CreateVisual, - composition_desktop_device_CreateSurfaceFactory, - composition_desktop_device_CreateSurface, - composition_desktop_device_CreateVirtualSurface, - composition_desktop_device_CreateTranslateTransform, - composition_desktop_device_CreateScaleTransform, - composition_desktop_device_CreateRotateTransform, - composition_desktop_device_CreateSkewTransform, - composition_desktop_device_CreateMatrixTransform, - composition_desktop_device_CreateTransformGroup, - composition_desktop_device_CreateTranslateTransform3D, - composition_desktop_device_CreateScaleTransform3D, - composition_desktop_device_CreateRotateTransform3D, - composition_desktop_device_CreateMatrixTransform3D, - composition_desktop_device_CreateTransform3DGroup, - composition_desktop_device_CreateEffectGroup, - composition_desktop_device_CreateRectangleClip, - composition_desktop_device_CreateAnimation, - - /* IDCompositionDesktopDevice methods */ - composition_desktop_device_CreateTargetForHwnd, - composition_desktop_device_CreateSurfaceFromHandle, - composition_desktop_device_CreateSurfaceFromHwnd, -}; - -static HRESULT STDMETHODCALLTYPE composition_desktop_device_init( - IUnknown *rendering_device, struct composition_desktop_device *device) -{ - device->IDCompositionDesktopDevice_iface.lpVtbl = &composition_desktop_device_vtbl; - device->refcount = 1; - return S_OK; -} - -HRESULT create_composition_desktop_device(IUnknown *rendering_device, void **device) -{ - struct composition_desktop_device *composition_device; - HRESULT hr; - - if(!(composition_device = calloc(1, sizeof(*composition_device)))) - { - ERR("Failed to allocate composition_device memory.\n"); - return E_OUTOFMEMORY; - } - - hr = composition_desktop_device_init(rendering_device, composition_device); - if (FAILED(hr)) - { - WARN("Failed to initialize composition_device, hr %#lx.\n", hr); - free(composition_device); - *device = NULL; - return hr; - } - - TRACE("Created composition_device %p.\n", composition_device); - *device = &composition_device->IDCompositionDesktopDevice_iface; - - return S_OK; -} diff --git a/dlls/dcomp/composition_device.c b/dlls/dcomp/composition_device.c deleted file mode 100644 index 0087bba5608..00000000000 --- a/dlls/dcomp/composition_device.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2025 Jaakko Hannikainen - * - * 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 <stdarg.h> -#include <stdlib.h> - -#include "windef.h" -#include "winbase.h" -#include "objidl.h" -#include "dxgi.h" -#include "wine/debug.h" -#include "dcomp.h" -#include "dcomp_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(dcomp); - -static inline struct composition_device *impl_from_IDCompositionDevice(IDCompositionDevice *iface) -{ - return CONTAINING_RECORD(iface, struct composition_device, IDCompositionDevice_iface); -} - -static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_device_QueryInterface( - IDCompositionDevice *iface, REFIID iid, void **out) -{ - TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - - if (IsEqualGUID(iid, &IID_IDCompositionDevice)) - { - IUnknown_AddRef(iface); - *out = iface; - return S_OK; - } - - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - - *out = NULL; - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE composition_device_AddRef(IDCompositionDevice *iface) -{ - struct composition_device *factory = impl_from_IDCompositionDevice(iface); - ULONG refcount = InterlockedIncrement(&factory->refcount); - - TRACE("%p increasing refcount to %lu.\n", iface, refcount); - - return refcount; -} - -static ULONG STDMETHODCALLTYPE composition_device_Release(IDCompositionDevice *iface) -{ - struct composition_device *composition_device = impl_from_IDCompositionDevice(iface); - ULONG refcount = InterlockedDecrement(&composition_device->refcount); - - TRACE("%p decreasing refcount to %lu.\n", iface, refcount); - - if (!refcount) - { - free(composition_device); - } - - return refcount; -} - -static HRESULT STDMETHODCALLTYPE composition_device_Commit(IDCompositionDevice *iface) -{ - FIXME("iface %p stub!\n", iface); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_WaitForCommitCompletion(IDCompositionDevice *iface) -{ - FIXME("iface %p stub!\n", iface); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_GetFrameStatistics( - IDCompositionDevice *iface, DCOMPOSITION_FRAME_STATISTICS *statistics) -{ - FIXME("iface %p statistics %p stub!\n", iface, statistics); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateTargetForHwnd( - IDCompositionDevice *iface, HWND hwnd, BOOL topmost, IDCompositionTarget **target) -{ - return create_composition_target(hwnd, topmost, target); -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateVisual( - IDCompositionDevice *iface, IDCompositionVisual **visual) -{ - FIXME("iface %p visual %p stub!\n", iface, visual); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_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 pixel_format %#x alpha_mode %#x surface %p stub!\n", - iface, width, height, pixel_format, alpha_mode, surface); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_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 pixel_format %#x alpha_mode %#x surface %p stub!\n", - iface, width, height, pixel_format, alpha_mode, surface); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_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 composition_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 composition_device_CreateTranslateTransform( - IDCompositionDevice *iface, IDCompositionTranslateTransform **transform) -{ - FIXME("iface %p transform %p stub!\n", iface, transform); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateScaleTransform( - IDCompositionDevice *iface, IDCompositionScaleTransform **transform) -{ - FIXME("iface %p transform %p stub!\n", iface, transform); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateRotateTransform( - IDCompositionDevice *iface, IDCompositionRotateTransform **transform) -{ - FIXME("iface %p transform %p stub!\n", iface, transform); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateSkewTransform( - IDCompositionDevice *iface, IDCompositionSkewTransform **transform) -{ - FIXME("iface %p transform %p stub!\n", iface, transform); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateMatrixTransform( - IDCompositionDevice *iface, IDCompositionMatrixTransform **transform) -{ - FIXME("iface %p transform %p stub!\n", iface, transform); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_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 composition_device_CreateTranslateTransform3D( - IDCompositionDevice *iface, IDCompositionTranslateTransform3D **transform_3d) -{ - FIXME("iface %p transform_3d %p stub!\n", iface, transform_3d); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateScaleTransform3D( - IDCompositionDevice *iface, IDCompositionScaleTransform3D **transform_3d) -{ - FIXME("iface %p transform_3d %p stub!\n", iface, transform_3d); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateRotateTransform3D( - IDCompositionDevice *iface, IDCompositionRotateTransform3D **transform_3d) -{ - FIXME("iface %p transform_3d %p stub!\n", iface, transform_3d); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateMatrixTransform3D( - IDCompositionDevice *iface, IDCompositionMatrixTransform3D **transform_3d) -{ - FIXME("iface %p transform_3d %p stub!\n", iface, transform_3d); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_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 composition_device_CreateEffectGroup( - IDCompositionDevice *iface, IDCompositionEffectGroup **effect_group) -{ - FIXME("iface %p effect_group %p stub!\n", iface, effect_group); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateRectangleClip( - IDCompositionDevice *iface, IDCompositionRectangleClip **clip) -{ - FIXME("iface %p clip %p stub!\n", iface, clip); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CreateAnimation( - IDCompositionDevice *iface, IDCompositionAnimation **animation) -{ - FIXME("iface %p animation %p stub!\n", iface, animation); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE composition_device_CheckDeviceState( - IDCompositionDevice *iface, BOOL *valid) -{ - FIXME("iface %p valid %p stub!\n", iface, valid); - return E_NOTIMPL; -} - -static const struct IDCompositionDeviceVtbl composition_device_vtbl = -{ - composition_device_QueryInterface, - composition_device_AddRef, - composition_device_Release, - composition_device_Commit, - composition_device_WaitForCommitCompletion, - composition_device_GetFrameStatistics, - composition_device_CreateTargetForHwnd, - composition_device_CreateVisual, - composition_device_CreateSurface, - composition_device_CreateVirtualSurface, - composition_device_CreateSurfaceFromHandle, - composition_device_CreateSurfaceFromHwnd, - composition_device_CreateTranslateTransform, - composition_device_CreateScaleTransform, - composition_device_CreateRotateTransform, - composition_device_CreateSkewTransform, - composition_device_CreateMatrixTransform, - composition_device_CreateTransformGroup, - composition_device_CreateTranslateTransform3D, - composition_device_CreateScaleTransform3D, - composition_device_CreateRotateTransform3D, - composition_device_CreateMatrixTransform3D, - composition_device_CreateTransform3DGroup, - composition_device_CreateEffectGroup, - composition_device_CreateRectangleClip, - composition_device_CreateAnimation, - composition_device_CheckDeviceState, -}; - -static HRESULT STDMETHODCALLTYPE composition_device_init( - IDXGIDevice *dxgi_device, struct composition_device *composition_device) -{ - composition_device->IDCompositionDevice_iface.lpVtbl = &composition_device_vtbl; - composition_device->refcount = 1; - return S_OK; -} - -HRESULT create_composition_device(IDXGIDevice *dxgi_device, void **device) -{ - struct composition_device *composition_device; - HRESULT hr; - - if(!(composition_device = calloc(1, sizeof(*composition_device)))) - { - ERR("Failed to allocate device memory.\n"); - return E_OUTOFMEMORY; - } - - hr = composition_device_init(dxgi_device, composition_device); - if (FAILED(hr)) - { - WARN("Failed to initialize device, hr %#lx.\n", hr); - free(composition_device); - *device = NULL; - return hr; - } - - TRACE("Created device %p.\n", composition_device); - *device = &composition_device->IDCompositionDevice_iface; - - return S_OK; -} diff --git a/dlls/dcomp/dcomp_private.h b/dlls/dcomp/dcomp_private.h index 330a8ce2468..e53c179ea22 100644 --- a/dlls/dcomp/dcomp_private.h +++ b/dlls/dcomp/dcomp_private.h @@ -25,13 +25,9 @@ struct composition_device { IDCompositionDevice IDCompositionDevice_iface; - LONG refcount; -}; - -/* IDCompositionDesktopDevice */ -struct composition_desktop_device -{ + IDCompositionDevice2 IDCompositionDevice2_iface; IDCompositionDesktopDevice IDCompositionDesktopDevice_iface; + IDCompositionDevice3 IDCompositionDevice3_iface; LONG refcount; }; @@ -63,8 +59,7 @@ struct composition_virtual_surface LONG refcount; }; -HRESULT create_composition_device(IDXGIDevice *dxgi_device, void **device); -HRESULT create_composition_desktop_device(IUnknown *rendering_device, void **device); +HRESULT create_composition_device(IUnknown *rendering_device, struct composition_device **device); HRESULT create_composition_target(HWND hwnd, BOOL topmost, IDCompositionTarget **target); HRESULT create_composition_visual(IDCompositionVisual2 **visual); HRESULT create_composition_surface_factory(IDCompositionSurfaceFactory **surface_factory); diff --git a/dlls/dcomp/device.c b/dlls/dcomp/device.c new file mode 100644 index 00000000000..7cd7462fb8e --- /dev/null +++ b/dlls/dcomp/device.c @@ -0,0 +1,1272 @@ +/* + * Copyright 2025 Jaakko Hannikainen + * + * 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 03110-1301, USA + */ + +#define COBJMACROS + +#include <stdarg.h> +#include <stdlib.h> + +#include "windef.h" +#include "wine/debug.h" +#include "dcomp_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dcomp); + +static ULONG STDMETHODCALLTYPE composition_device_AddRef_impl(struct composition_device *device); + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_device_QueryInterface_impl( + struct composition_device *device, REFIID iid, void **out) +{ + TRACE("device %p, iid %s, out %p.\n", device, debugstr_guid(iid), out); + + *out = NULL; + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IDCompositionDevice)) + { + *out = &device->IDCompositionDevice_iface; + } + else if (IsEqualGUID(iid, &IID_IDCompositionDevice2)) + { + *out = &device->IDCompositionDevice2_iface; + } + else if (IsEqualGUID(iid, &IID_IDCompositionDesktopDevice)) + { + *out = &device->IDCompositionDesktopDevice_iface; + } + else if (IsEqualGUID(iid, &IID_IDCompositionDevice3)) + { + *out = device; + } + + if(*out) + { + composition_device_AddRef_impl(device); + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE composition_device_AddRef_impl(struct composition_device *device) +{ + ULONG refcount = InterlockedIncrement(&device->refcount); + + TRACE("%p increasing refcount to %lu.\n", device, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE composition_device_Release_impl(struct composition_device *device) +{ + ULONG refcount = InterlockedDecrement(&device->refcount); + + TRACE("%p decreasing refcount to %lu.\n", device, refcount); + + if (!refcount) + { + free(device); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE composition_device_Commit_impl(struct composition_device *device) +{ + FIXME("device %p stub!\n", device); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_WaitForCommitCompletion_impl(struct composition_device *device) +{ + FIXME("device %p stub!\n", device); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_GetFrameStatistics_impl( + struct composition_device *device, DCOMPOSITION_FRAME_STATISTICS *statistics) +{ + FIXME("device %p statistics %p stub!\n", device, statistics); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateVisual_impl( + struct composition_device *device, IDCompositionVisual **visual) +{ + FIXME("device %p visual %p stub!\n", device, visual); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateVisual2_impl( + struct composition_device *device, IDCompositionVisual2 **visual) +{ + return create_composition_visual(visual); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSurfaceFactory_impl( + struct composition_device *device, IUnknown *rendering_device, + IDCompositionSurfaceFactory **surface_factory) +{ + return create_composition_surface_factory(surface_factory); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSurface_impl( + struct composition_device *device, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionSurface **surface) +{ + FIXME("device %p width %u height %u pixel_format %#x alpha_mode %#x surface %p stub!\n", + device, width, height, pixel_format, alpha_mode, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateVirtualSurface_impl( + struct composition_device *device, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionVirtualSurface **surface) +{ + FIXME("device %p width %u height %u pixel_format %#x alpha_mode %#x surface %p stub!\n", + device, width, height, pixel_format, alpha_mode, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTranslateTransform_impl( + struct composition_device *device, IDCompositionTranslateTransform **transform) +{ + FIXME("device %p transform %p stub!\n", device, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateScaleTransform_impl( + struct composition_device *device, IDCompositionScaleTransform **transform) +{ + FIXME("device %p transform %p stub!\n", device, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateRotateTransform_impl( + struct composition_device *device, IDCompositionRotateTransform **transform) +{ + FIXME("device %p transform %p stub!\n", device, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSkewTransform_impl( + struct composition_device *device, IDCompositionSkewTransform **transform) +{ + FIXME("device %p transform %p stub!\n", device, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateMatrixTransform_impl( + struct composition_device *device, IDCompositionMatrixTransform **transform) +{ + FIXME("device %p transform %p stub!\n", device, transform); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTransformGroup_impl( + struct composition_device *device, IDCompositionTransform **transforms, UINT elements, + IDCompositionTransform **transform_group) +{ + FIXME("device %p transforms %p elemens %u transform_group %p stub!\n", + device, transforms, elements, transform_group); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTranslateTransform3D_impl( + struct composition_device *device, IDCompositionTranslateTransform3D **transform_3d) +{ + FIXME("device %p transform_3d %p stub!\n", device, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateScaleTransform3D_impl( + struct composition_device *device, IDCompositionScaleTransform3D **transform_3d) +{ + FIXME("device %p transform_3d %p stub!\n", device, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateRotateTransform3D_impl( + struct composition_device *device, IDCompositionRotateTransform3D **transform_3d) +{ + FIXME("device %p transform_3d %p stub!\n", device, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateMatrixTransform3D_impl( + struct composition_device *device, IDCompositionMatrixTransform3D **transform_3d) +{ + FIXME("device %p transform_3d %p stub!\n", device, transform_3d); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTransform3DGroup_impl( + struct composition_device *device, IDCompositionTransform3D **transforms_3d, + UINT elements, IDCompositionTransform3D **transform_3d_group) +{ + FIXME("device %p transforms_3d %p elements %u transform_3d_group %p stub!\n", + device, transforms_3d, elements, transform_3d_group); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateEffectGroup_impl( + struct composition_device *device, IDCompositionEffectGroup **effect_group) +{ + FIXME("device %p effect_group %p stub!\n", device, effect_group); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateRectangleClip_impl( + struct composition_device *device, IDCompositionRectangleClip **clip) +{ + FIXME("device %p clip %p stub!\n", device, clip); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateAnimation_impl( + struct composition_device *device, IDCompositionAnimation **animation) +{ + FIXME("device %p animation %p stub!\n", device, animation); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CheckDeviceState_impl( + struct composition_device *device, BOOL *valid) +{ + FIXME("device %p valid %p stub!\n", device, valid); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTargetForHwnd_impl( + struct composition_device *device, HWND hwnd, BOOL topmost, IDCompositionTarget **target) +{ + return create_composition_target(hwnd, topmost, target); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSurfaceFromHandle_impl( + struct composition_device *device, HANDLE handle, IUnknown **surface) +{ + FIXME("device %p handle %p surface %p stub!\n", device, handle, surface); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSurfaceFromHwnd_impl( + struct composition_device *device, HWND hwnd, IUnknown **surface) +{ + FIXME("device %p hwnd %p surface %p stub!\n", device, hwnd, surface); + return E_NOTIMPL; +} + +/* FIXME: 'effect' should be IDCompositionAffineTransform2DEffect **, not void **, + * same applies to the other *Effect functions. */ +static HRESULT STDMETHODCALLTYPE composition_device_CreateGaussianBlurEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateBrightnessEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateColorMatrixEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateShadowEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateHueRotationEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSaturationEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTurbulenceEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateLinearTransferEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTableTransferEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateCompositeEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateBlendEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateArithmeticCompositeEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateAffineTransform2DEffect_impl( + struct composition_device *device, void **effect) +{ + FIXME("device %p effect %p stub!\n", device, effect); + return E_NOTIMPL; +} + +static inline struct composition_device *impl_from_IDCompositionDevice(IDCompositionDevice *iface) +{ + 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); +} + +static inline struct composition_device *impl_from_IDCompositionDesktopDevice(IDCompositionDesktopDevice *iface) +{ + return CONTAINING_RECORD(iface, struct composition_device, IDCompositionDesktopDevice_iface); +} + +static inline struct composition_device *impl_from_IDCompositionDevice3(IDCompositionDevice3 *iface) +{ + return CONTAINING_RECORD(iface, struct composition_device, IDCompositionDevice3_iface); +} + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_device_QueryInterface( + IDCompositionDevice *iface, REFIID iid, void **out) +{ + return composition_device_QueryInterface_impl(impl_from_IDCompositionDevice(iface), iid, out); +} + +static ULONG STDMETHODCALLTYPE composition_device_AddRef(IDCompositionDevice *iface) +{ + return composition_device_AddRef_impl(impl_from_IDCompositionDevice(iface)); +} + +static ULONG STDMETHODCALLTYPE composition_device_Release(IDCompositionDevice *iface) +{ + return composition_device_Release_impl(impl_from_IDCompositionDevice(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_device_Commit(IDCompositionDevice *iface) +{ + return composition_device_Commit_impl(impl_from_IDCompositionDevice(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_device_WaitForCommitCompletion(IDCompositionDevice *iface) +{ + return composition_device_WaitForCommitCompletion_impl(impl_from_IDCompositionDevice(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_device_GetFrameStatistics( + IDCompositionDevice *iface, DCOMPOSITION_FRAME_STATISTICS *statistics) +{ + return composition_device_GetFrameStatistics_impl(impl_from_IDCompositionDevice(iface), statistics); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTargetForHwnd( + IDCompositionDevice *iface, HWND hwnd, BOOL topmost, IDCompositionTarget **target) +{ + return create_composition_target(hwnd, topmost, target); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateVisual( + IDCompositionDevice *iface, IDCompositionVisual **visual) +{ + return composition_device_CreateVisual_impl(impl_from_IDCompositionDevice(iface), visual); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSurface( + IDCompositionDevice *iface, + UINT width, + UINT height, + DXGI_FORMAT pixel_format, + DXGI_ALPHA_MODE alpha_mode, + IDCompositionSurface **surface) +{ + return composition_device_CreateSurface_impl( + impl_from_IDCompositionDevice(iface), width, height, pixel_format, alpha_mode, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateVirtualSurface( + IDCompositionDevice *iface, + UINT width, + UINT height, + DXGI_FORMAT pixel_format, + DXGI_ALPHA_MODE alpha_mode, + IDCompositionVirtualSurface **surface) +{ + return composition_device_CreateVirtualSurface_impl( + impl_from_IDCompositionDevice(iface), width, height, pixel_format, alpha_mode, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSurfaceFromHandle( + IDCompositionDevice *iface, HANDLE handle, IUnknown **surface) +{ + return composition_device_CreateSurfaceFromHandle_impl(impl_from_IDCompositionDevice(iface), handle, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSurfaceFromHwnd( + IDCompositionDevice *iface, HWND hwnd, IUnknown **surface) +{ + return composition_device_CreateSurfaceFromHwnd_impl(impl_from_IDCompositionDevice(iface), hwnd, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTranslateTransform( + IDCompositionDevice *iface, IDCompositionTranslateTransform **transform) +{ + return composition_device_CreateTranslateTransform_impl(impl_from_IDCompositionDevice(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateScaleTransform( + IDCompositionDevice *iface, IDCompositionScaleTransform **transform) +{ + return composition_device_CreateScaleTransform_impl(impl_from_IDCompositionDevice(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateRotateTransform( + IDCompositionDevice *iface, IDCompositionRotateTransform **transform) +{ + return composition_device_CreateRotateTransform_impl(impl_from_IDCompositionDevice(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateSkewTransform( + IDCompositionDevice *iface, IDCompositionSkewTransform **transform) +{ + return composition_device_CreateSkewTransform_impl(impl_from_IDCompositionDevice(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateMatrixTransform( + IDCompositionDevice *iface, IDCompositionMatrixTransform **transform) +{ + return composition_device_CreateMatrixTransform_impl(impl_from_IDCompositionDevice(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTransformGroup( + IDCompositionDevice *iface, + IDCompositionTransform **transforms, + UINT elements, + IDCompositionTransform **transform_group) +{ + return composition_device_CreateTransformGroup_impl( + impl_from_IDCompositionDevice(iface), transforms, elements, transform_group); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTranslateTransform3D( + IDCompositionDevice *iface, IDCompositionTranslateTransform3D **transform_3d) +{ + return composition_device_CreateTranslateTransform3D_impl(impl_from_IDCompositionDevice(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateScaleTransform3D( + IDCompositionDevice *iface, IDCompositionScaleTransform3D **transform_3d) +{ + return composition_device_CreateScaleTransform3D_impl(impl_from_IDCompositionDevice(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateRotateTransform3D( + IDCompositionDevice *iface, IDCompositionRotateTransform3D **transform_3d) +{ + return composition_device_CreateRotateTransform3D_impl(impl_from_IDCompositionDevice(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateMatrixTransform3D( + IDCompositionDevice *iface, IDCompositionMatrixTransform3D **transform_3d) +{ + return composition_device_CreateMatrixTransform3D_impl(impl_from_IDCompositionDevice(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateTransform3DGroup( + IDCompositionDevice *iface, + IDCompositionTransform3D **transforms_3d, + UINT elements, + IDCompositionTransform3D **transform_3d_group) +{ + return composition_device_CreateTransform3DGroup_impl( + impl_from_IDCompositionDevice(iface), transforms_3d, elements, transform_3d_group); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateEffectGroup( + IDCompositionDevice *iface, IDCompositionEffectGroup **effect_group) +{ + return composition_device_CreateEffectGroup_impl(impl_from_IDCompositionDevice(iface), effect_group); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateRectangleClip( + IDCompositionDevice *iface, IDCompositionRectangleClip **clip) +{ + return composition_device_CreateRectangleClip_impl(impl_from_IDCompositionDevice(iface), clip); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CreateAnimation( + IDCompositionDevice *iface, IDCompositionAnimation **animation) +{ + return composition_device_CreateAnimation_impl(impl_from_IDCompositionDevice(iface), animation); +} + +static HRESULT STDMETHODCALLTYPE composition_device_CheckDeviceState( + IDCompositionDevice *iface, BOOL *valid) +{ + return composition_device_CheckDeviceState_impl(impl_from_IDCompositionDevice(iface), valid); +} + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_device2_QueryInterface( + IDCompositionDevice2 *iface, REFIID iid, void **out) +{ + return composition_device_QueryInterface_impl(impl_from_IDCompositionDevice2(iface), iid, out); +} + +static ULONG STDMETHODCALLTYPE composition_device2_AddRef(IDCompositionDevice2 *iface) +{ + return composition_device_AddRef_impl(impl_from_IDCompositionDevice2(iface)); +} + +static ULONG STDMETHODCALLTYPE composition_device2_Release(IDCompositionDevice2 *iface) +{ + return composition_device_Release_impl(impl_from_IDCompositionDevice2(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_Commit(IDCompositionDevice2 *iface) +{ + return composition_device_Commit_impl(impl_from_IDCompositionDevice2(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_WaitForCommitCompletion(IDCompositionDevice2 *iface) +{ + return composition_device_WaitForCommitCompletion_impl(impl_from_IDCompositionDevice2(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_GetFrameStatistics( + IDCompositionDevice2 *iface, DCOMPOSITION_FRAME_STATISTICS *statistics) +{ + return composition_device_GetFrameStatistics_impl(impl_from_IDCompositionDevice2(iface), statistics); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateVisual( + IDCompositionDevice2 *iface, IDCompositionVisual2 **visual) +{ + return composition_device_CreateVisual2_impl(impl_from_IDCompositionDevice2(iface), visual); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateSurfaceFactory( + IDCompositionDevice2 *iface, IUnknown *rendering_device, + IDCompositionSurfaceFactory **surface_factory) +{ + return composition_device_CreateSurfaceFactory_impl( + impl_from_IDCompositionDevice2(iface), rendering_device, surface_factory); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateSurface( + IDCompositionDevice2 *iface, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionSurface **surface) +{ + return composition_device_CreateSurface_impl( + impl_from_IDCompositionDevice2(iface), width, height, pixel_format, alpha_mode, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateVirtualSurface( + IDCompositionDevice2 *iface, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionVirtualSurface **surface) +{ + return composition_device_CreateVirtualSurface_impl( + impl_from_IDCompositionDevice2(iface), width, height, pixel_format, alpha_mode, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateTranslateTransform( + IDCompositionDevice2 *iface, IDCompositionTranslateTransform **transform) +{ + return composition_device_CreateTranslateTransform_impl(impl_from_IDCompositionDevice2(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateScaleTransform( + IDCompositionDevice2 *iface, IDCompositionScaleTransform **transform) +{ + return composition_device_CreateScaleTransform_impl(impl_from_IDCompositionDevice2(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateRotateTransform( + IDCompositionDevice2 *iface, IDCompositionRotateTransform **transform) +{ + return composition_device_CreateRotateTransform_impl(impl_from_IDCompositionDevice2(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateSkewTransform( + IDCompositionDevice2 *iface, IDCompositionSkewTransform **transform) +{ + return composition_device_CreateSkewTransform_impl(impl_from_IDCompositionDevice2(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateMatrixTransform( + IDCompositionDevice2 *iface, IDCompositionMatrixTransform **transform) +{ + return composition_device_CreateMatrixTransform_impl(impl_from_IDCompositionDevice2(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateTransformGroup( + IDCompositionDevice2 *iface, IDCompositionTransform **transforms, UINT elements, + IDCompositionTransform **transform_group) +{ + return composition_device_CreateTransformGroup_impl( + impl_from_IDCompositionDevice2(iface), transforms, elements, transform_group); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateTranslateTransform3D( + IDCompositionDevice2 *iface, IDCompositionTranslateTransform3D **transform_3d) +{ + return composition_device_CreateTranslateTransform3D_impl(impl_from_IDCompositionDevice2(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateScaleTransform3D( + IDCompositionDevice2 *iface, IDCompositionScaleTransform3D **transform_3d) +{ + return composition_device_CreateScaleTransform3D_impl(impl_from_IDCompositionDevice2(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateRotateTransform3D( + IDCompositionDevice2 *iface, IDCompositionRotateTransform3D **transform_3d) +{ + return composition_device_CreateRotateTransform3D_impl(impl_from_IDCompositionDevice2(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateMatrixTransform3D( + IDCompositionDevice2 *iface, IDCompositionMatrixTransform3D **transform_3d) +{ + return composition_device_CreateMatrixTransform3D_impl(impl_from_IDCompositionDevice2(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateTransform3DGroup( + IDCompositionDevice2 *iface, IDCompositionTransform3D **transforms_3d, UINT elements, + IDCompositionTransform3D **transform_3d_group) +{ + return composition_device_CreateTransform3DGroup_impl( + impl_from_IDCompositionDevice2(iface), transforms_3d, elements, transform_3d_group); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateEffectGroup( + IDCompositionDevice2 *iface, IDCompositionEffectGroup **effect_group) +{ + return composition_device_CreateEffectGroup_impl(impl_from_IDCompositionDevice2(iface), effect_group); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateRectangleClip( + IDCompositionDevice2 *iface, IDCompositionRectangleClip **clip) +{ + return composition_device_CreateRectangleClip_impl(impl_from_IDCompositionDevice2(iface), clip); +} + +static HRESULT STDMETHODCALLTYPE composition_device2_CreateAnimation( + IDCompositionDevice2 *iface, IDCompositionAnimation **animation) +{ + return composition_device_CreateAnimation_impl(impl_from_IDCompositionDevice2(iface), animation); +} + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_desktop_device_QueryInterface( + IDCompositionDesktopDevice *iface, REFIID iid, void **out) +{ + return composition_device_QueryInterface_impl(impl_from_IDCompositionDesktopDevice(iface), iid, out); +} + +static ULONG STDMETHODCALLTYPE composition_desktop_device_AddRef(IDCompositionDesktopDevice *iface) +{ + return composition_device_AddRef_impl(impl_from_IDCompositionDesktopDevice(iface)); +} + +static ULONG STDMETHODCALLTYPE composition_desktop_device_Release(IDCompositionDesktopDevice *iface) +{ + return composition_device_Release_impl(impl_from_IDCompositionDesktopDevice(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_Commit(IDCompositionDesktopDevice *iface) +{ + return composition_device_Commit_impl(impl_from_IDCompositionDesktopDevice(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_WaitForCommitCompletion(IDCompositionDesktopDevice *iface) +{ + return composition_device_WaitForCommitCompletion_impl(impl_from_IDCompositionDesktopDevice(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_GetFrameStatistics( + IDCompositionDesktopDevice *iface, DCOMPOSITION_FRAME_STATISTICS *statistics) +{ + return composition_device_GetFrameStatistics_impl(impl_from_IDCompositionDesktopDevice(iface), statistics); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateVisual( + IDCompositionDesktopDevice *iface, IDCompositionVisual2 **visual) +{ + return composition_device_CreateVisual2_impl(impl_from_IDCompositionDesktopDevice(iface), visual); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSurfaceFactory( + IDCompositionDesktopDevice *iface, + IUnknown *rendering_device, + IDCompositionSurfaceFactory **surface_factory) +{ + return composition_device_CreateSurfaceFactory_impl(impl_from_IDCompositionDesktopDevice(iface), + rendering_device, surface_factory); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSurface( + IDCompositionDesktopDevice *iface, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionSurface **surface) +{ + return composition_device_CreateSurface_impl( + impl_from_IDCompositionDesktopDevice(iface), width, height, pixel_format, alpha_mode, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateVirtualSurface( + IDCompositionDesktopDevice *iface, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionVirtualSurface **surface) +{ + return composition_device_CreateVirtualSurface_impl( + impl_from_IDCompositionDesktopDevice(iface), width, height, pixel_format, alpha_mode, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTranslateTransform( + IDCompositionDesktopDevice *iface, IDCompositionTranslateTransform **transform) +{ + return composition_device_CreateTranslateTransform_impl(impl_from_IDCompositionDesktopDevice(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateScaleTransform( + IDCompositionDesktopDevice *iface, IDCompositionScaleTransform **transform) +{ + return composition_device_CreateScaleTransform_impl(impl_from_IDCompositionDesktopDevice(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateRotateTransform( + IDCompositionDesktopDevice *iface, IDCompositionRotateTransform **transform) +{ + return composition_device_CreateRotateTransform_impl(impl_from_IDCompositionDesktopDevice(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSkewTransform( + IDCompositionDesktopDevice *iface, IDCompositionSkewTransform **transform) +{ + return composition_device_CreateSkewTransform_impl(impl_from_IDCompositionDesktopDevice(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateMatrixTransform( + IDCompositionDesktopDevice *iface, IDCompositionMatrixTransform **transform) +{ + return composition_device_CreateMatrixTransform_impl(impl_from_IDCompositionDesktopDevice(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTransformGroup( + IDCompositionDesktopDevice *iface, IDCompositionTransform **transforms, + UINT elements, IDCompositionTransform **transform_group) +{ + return composition_device_CreateTransformGroup_impl( + impl_from_IDCompositionDesktopDevice(iface), transforms, elements, transform_group); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTranslateTransform3D( + IDCompositionDesktopDevice *iface, IDCompositionTranslateTransform3D **transform_3d) +{ + return composition_device_CreateTranslateTransform3D_impl(impl_from_IDCompositionDesktopDevice(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateScaleTransform3D( + IDCompositionDesktopDevice *iface, IDCompositionScaleTransform3D **transform_3d) +{ + return composition_device_CreateScaleTransform3D_impl(impl_from_IDCompositionDesktopDevice(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateRotateTransform3D( + IDCompositionDesktopDevice *iface, IDCompositionRotateTransform3D **transform_3d) +{ + return composition_device_CreateRotateTransform3D_impl(impl_from_IDCompositionDesktopDevice(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateMatrixTransform3D( + IDCompositionDesktopDevice *iface, IDCompositionMatrixTransform3D **transform_3d) +{ + return composition_device_CreateMatrixTransform3D_impl(impl_from_IDCompositionDesktopDevice(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTransform3DGroup( + IDCompositionDesktopDevice *iface, IDCompositionTransform3D **transforms_3d, + UINT elements, IDCompositionTransform3D **transform_3d_group) +{ + return composition_device_CreateTransform3DGroup_impl( + impl_from_IDCompositionDesktopDevice(iface), transforms_3d, elements, transform_3d_group); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateEffectGroup( + IDCompositionDesktopDevice *iface, IDCompositionEffectGroup **effect_group) +{ + return composition_device_CreateEffectGroup_impl(impl_from_IDCompositionDesktopDevice(iface), effect_group); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateRectangleClip( + IDCompositionDesktopDevice *iface, IDCompositionRectangleClip **clip) +{ + return composition_device_CreateRectangleClip_impl(impl_from_IDCompositionDesktopDevice(iface), clip); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateAnimation( + IDCompositionDesktopDevice *iface, IDCompositionAnimation **animation) +{ + return composition_device_CreateAnimation_impl(impl_from_IDCompositionDesktopDevice(iface), animation); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateTargetForHwnd( + IDCompositionDesktopDevice *iface, HWND hwnd, BOOL topmost, IDCompositionTarget **target) +{ + return composition_device_CreateTargetForHwnd_impl(impl_from_IDCompositionDesktopDevice(iface), hwnd, topmost, target); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSurfaceFromHandle( + IDCompositionDesktopDevice *iface, HANDLE handle, IUnknown **surface) +{ + return composition_device_CreateSurfaceFromHandle_impl(impl_from_IDCompositionDesktopDevice(iface), handle, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_desktop_device_CreateSurfaceFromHwnd( + IDCompositionDesktopDevice *iface, HWND hwnd, IUnknown **surface) +{ + return composition_device_CreateSurfaceFromHwnd_impl(impl_from_IDCompositionDesktopDevice(iface), hwnd, surface); +} + +static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_device3_QueryInterface( + IDCompositionDevice3 *iface, REFIID iid, void **out) +{ + return composition_device_QueryInterface_impl(impl_from_IDCompositionDevice3(iface), iid, out); +} + +static ULONG STDMETHODCALLTYPE composition_device3_AddRef(IDCompositionDevice3 *iface) +{ + return composition_device_AddRef_impl(impl_from_IDCompositionDevice3(iface)); +} + +static ULONG STDMETHODCALLTYPE composition_device3_Release(IDCompositionDevice3 *iface) +{ + return composition_device_Release_impl(impl_from_IDCompositionDevice3(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_Commit(IDCompositionDevice3 *iface) +{ + return composition_device_Commit_impl(impl_from_IDCompositionDevice3(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_WaitForCommitCompletion(IDCompositionDevice3 *iface) +{ + return composition_device_WaitForCommitCompletion_impl(impl_from_IDCompositionDevice3(iface)); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_GetFrameStatistics( + IDCompositionDevice3 *iface, DCOMPOSITION_FRAME_STATISTICS *statistics) +{ + return composition_device_GetFrameStatistics_impl(impl_from_IDCompositionDevice3(iface), statistics); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateVisual( + IDCompositionDevice3 *iface, IDCompositionVisual2 **visual) +{ + return composition_device_CreateVisual2_impl(impl_from_IDCompositionDevice3(iface), visual); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateSurfaceFactory( + IDCompositionDevice3 *iface, IUnknown *rendering_device, + IDCompositionSurfaceFactory **surface_factory) +{ + return composition_device_CreateSurfaceFactory_impl( + impl_from_IDCompositionDevice3(iface), rendering_device, surface_factory); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateSurface( + IDCompositionDevice3 *iface, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionSurface **surface) +{ + return composition_device_CreateSurface_impl( + impl_from_IDCompositionDevice3(iface), width, height, pixel_format, alpha_mode, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateVirtualSurface( + IDCompositionDevice3 *iface, UINT width, UINT height, + DXGI_FORMAT pixel_format, DXGI_ALPHA_MODE alpha_mode, IDCompositionVirtualSurface **surface) +{ + return composition_device_CreateVirtualSurface_impl( + impl_from_IDCompositionDevice3(iface), width, height, pixel_format, alpha_mode, surface); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateTranslateTransform( + IDCompositionDevice3 *iface, IDCompositionTranslateTransform **transform) +{ + return composition_device_CreateTranslateTransform_impl(impl_from_IDCompositionDevice3(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateScaleTransform( + IDCompositionDevice3 *iface, IDCompositionScaleTransform **transform) +{ + return composition_device_CreateScaleTransform_impl(impl_from_IDCompositionDevice3(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateRotateTransform( + IDCompositionDevice3 *iface, IDCompositionRotateTransform **transform) +{ + return composition_device_CreateRotateTransform_impl(impl_from_IDCompositionDevice3(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateSkewTransform( + IDCompositionDevice3 *iface, IDCompositionSkewTransform **transform) +{ + return composition_device_CreateSkewTransform_impl(impl_from_IDCompositionDevice3(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateMatrixTransform( + IDCompositionDevice3 *iface, IDCompositionMatrixTransform **transform) +{ + return composition_device_CreateMatrixTransform_impl(impl_from_IDCompositionDevice3(iface), transform); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateTransformGroup( + IDCompositionDevice3 *iface, IDCompositionTransform **transforms, UINT elements, + IDCompositionTransform **transform_group) +{ + return composition_device_CreateTransformGroup_impl( + impl_from_IDCompositionDevice3(iface), transforms, elements, transform_group); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateTranslateTransform3D( + IDCompositionDevice3 *iface, IDCompositionTranslateTransform3D **transform_3d) +{ + return composition_device_CreateTranslateTransform3D_impl(impl_from_IDCompositionDevice3(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateScaleTransform3D( + IDCompositionDevice3 *iface, IDCompositionScaleTransform3D **transform_3d) +{ + return composition_device_CreateScaleTransform3D_impl(impl_from_IDCompositionDevice3(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateRotateTransform3D( + IDCompositionDevice3 *iface, IDCompositionRotateTransform3D **transform_3d) +{ + return composition_device_CreateRotateTransform3D_impl(impl_from_IDCompositionDevice3(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateMatrixTransform3D( + IDCompositionDevice3 *iface, IDCompositionMatrixTransform3D **transform_3d) +{ + return composition_device_CreateMatrixTransform3D_impl(impl_from_IDCompositionDevice3(iface), transform_3d); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateTransform3DGroup( + IDCompositionDevice3 *iface, IDCompositionTransform3D **transforms_3d, + UINT elements, IDCompositionTransform3D **transform_3d_group) +{ + return composition_device_CreateTransform3DGroup_impl( + impl_from_IDCompositionDevice3(iface), transforms_3d, elements, transform_3d_group); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateEffectGroup( + IDCompositionDevice3 *iface, IDCompositionEffectGroup **effect_group) +{ + return composition_device_CreateEffectGroup_impl(impl_from_IDCompositionDevice3(iface), effect_group); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateRectangleClip( + IDCompositionDevice3 *iface, IDCompositionRectangleClip **clip) +{ + return composition_device_CreateRectangleClip_impl(impl_from_IDCompositionDevice3(iface), clip); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateAnimation( + IDCompositionDevice3 *iface, IDCompositionAnimation **animation) +{ + return composition_device_CreateAnimation_impl(impl_from_IDCompositionDevice3(iface), animation); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateGaussianBlurEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateGaussianBlurEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateBrightnessEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateBrightnessEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateColorMatrixEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateColorMatrixEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateShadowEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateShadowEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateHueRotationEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateHueRotationEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateSaturationEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateSaturationEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateTurbulenceEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateTurbulenceEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateLinearTransferEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateLinearTransferEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateTableTransferEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateTableTransferEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateCompositeEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateCompositeEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateBlendEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateBlendEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateArithmeticCompositeEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateArithmeticCompositeEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static HRESULT STDMETHODCALLTYPE composition_device3_CreateAffineTransform2DEffect( + IDCompositionDevice3 *iface, void **effect) +{ + return composition_device_CreateAffineTransform2DEffect_impl(impl_from_IDCompositionDevice3(iface), effect); +} + +static const struct IDCompositionDeviceVtbl composition_device_vtbl = +{ + composition_device_QueryInterface, + composition_device_AddRef, + composition_device_Release, + composition_device_Commit, + composition_device_WaitForCommitCompletion, + composition_device_GetFrameStatistics, + composition_device_CreateTargetForHwnd, + composition_device_CreateVisual, + composition_device_CreateSurface, + composition_device_CreateVirtualSurface, + composition_device_CreateSurfaceFromHandle, + composition_device_CreateSurfaceFromHwnd, + composition_device_CreateTranslateTransform, + composition_device_CreateScaleTransform, + composition_device_CreateRotateTransform, + composition_device_CreateSkewTransform, + composition_device_CreateMatrixTransform, + composition_device_CreateTransformGroup, + composition_device_CreateTranslateTransform3D, + composition_device_CreateScaleTransform3D, + composition_device_CreateRotateTransform3D, + composition_device_CreateMatrixTransform3D, + composition_device_CreateTransform3DGroup, + composition_device_CreateEffectGroup, + composition_device_CreateRectangleClip, + composition_device_CreateAnimation, + composition_device_CheckDeviceState, +}; + +static const struct IDCompositionDevice2Vtbl composition_device2_vtbl = +{ + composition_device2_QueryInterface, + composition_device2_AddRef, + composition_device2_Release, + composition_device2_Commit, + composition_device2_WaitForCommitCompletion, + composition_device2_GetFrameStatistics, + composition_device2_CreateVisual, + composition_device2_CreateSurfaceFactory, + composition_device2_CreateSurface, + composition_device2_CreateVirtualSurface, + composition_device2_CreateTranslateTransform, + composition_device2_CreateScaleTransform, + composition_device2_CreateRotateTransform, + composition_device2_CreateSkewTransform, + composition_device2_CreateMatrixTransform, + composition_device2_CreateTransformGroup, + composition_device2_CreateTranslateTransform3D, + composition_device2_CreateScaleTransform3D, + composition_device2_CreateRotateTransform3D, + composition_device2_CreateMatrixTransform3D, + composition_device2_CreateTransform3DGroup, + composition_device2_CreateEffectGroup, + composition_device2_CreateRectangleClip, + composition_device2_CreateAnimation, +}; + +static const struct IDCompositionDesktopDeviceVtbl composition_desktop_device_vtbl = +{ + composition_desktop_device_QueryInterface, + composition_desktop_device_AddRef, + composition_desktop_device_Release, + + /* IDCompositionDevice2 methods */ + composition_desktop_device_Commit, + composition_desktop_device_WaitForCommitCompletion, + composition_desktop_device_GetFrameStatistics, + composition_desktop_device_CreateVisual, + composition_desktop_device_CreateSurfaceFactory, + composition_desktop_device_CreateSurface, + composition_desktop_device_CreateVirtualSurface, + composition_desktop_device_CreateTranslateTransform, + composition_desktop_device_CreateScaleTransform, + composition_desktop_device_CreateRotateTransform, + composition_desktop_device_CreateSkewTransform, + composition_desktop_device_CreateMatrixTransform, + composition_desktop_device_CreateTransformGroup, + composition_desktop_device_CreateTranslateTransform3D, + composition_desktop_device_CreateScaleTransform3D, + composition_desktop_device_CreateRotateTransform3D, + composition_desktop_device_CreateMatrixTransform3D, + composition_desktop_device_CreateTransform3DGroup, + composition_desktop_device_CreateEffectGroup, + composition_desktop_device_CreateRectangleClip, + composition_desktop_device_CreateAnimation, + + /* IDCompositionDesktopDevice methods */ + composition_desktop_device_CreateTargetForHwnd, + composition_desktop_device_CreateSurfaceFromHandle, + composition_desktop_device_CreateSurfaceFromHwnd, +}; + + +static const struct IDCompositionDevice3Vtbl composition_device3_vtbl = +{ + composition_device3_QueryInterface, + composition_device3_AddRef, + composition_device3_Release, + + /* IDCompositionDevice2 methods */ + composition_device3_Commit, + composition_device3_WaitForCommitCompletion, + composition_device3_GetFrameStatistics, + composition_device3_CreateVisual, + composition_device3_CreateSurfaceFactory, + composition_device3_CreateSurface, + composition_device3_CreateVirtualSurface, + composition_device3_CreateTranslateTransform, + composition_device3_CreateScaleTransform, + composition_device3_CreateRotateTransform, + composition_device3_CreateSkewTransform, + composition_device3_CreateMatrixTransform, + composition_device3_CreateTransformGroup, + composition_device3_CreateTranslateTransform3D, + composition_device3_CreateScaleTransform3D, + composition_device3_CreateRotateTransform3D, + composition_device3_CreateMatrixTransform3D, + composition_device3_CreateTransform3DGroup, + composition_device3_CreateEffectGroup, + composition_device3_CreateRectangleClip, + composition_device3_CreateAnimation, + + /* IDCompositionDevice3 methods */ + composition_device3_CreateGaussianBlurEffect, + composition_device3_CreateBrightnessEffect, + composition_device3_CreateColorMatrixEffect, + composition_device3_CreateShadowEffect, + composition_device3_CreateHueRotationEffect, + composition_device3_CreateSaturationEffect, + composition_device3_CreateTurbulenceEffect, + composition_device3_CreateLinearTransferEffect, + composition_device3_CreateTableTransferEffect, + composition_device3_CreateCompositeEffect, + composition_device3_CreateBlendEffect, + composition_device3_CreateArithmeticCompositeEffect, + composition_device3_CreateAffineTransform2DEffect, +}; + +HRESULT create_composition_device(IUnknown *rendering_device, struct composition_device **device) +{ + struct composition_device *composition_device; + + if(!(composition_device = calloc(1, sizeof(*composition_device)))) + { + ERR("Failed to allocate composition_device memory.\n"); + return E_OUTOFMEMORY; + } + + composition_device->IDCompositionDevice_iface.lpVtbl = &composition_device_vtbl; + composition_device->IDCompositionDevice2_iface.lpVtbl = &composition_device2_vtbl; + composition_device->IDCompositionDesktopDevice_iface.lpVtbl = &composition_desktop_device_vtbl; + composition_device->IDCompositionDevice3_iface.lpVtbl = &composition_device3_vtbl; + composition_device->refcount = 1; + + TRACE("Created composition_device %p.\n", composition_device); + *device = composition_device; + + return S_OK; +} diff --git a/dlls/dcomp/main.c b/dlls/dcomp/main.c index 780b20d37f0..96ac80a66a7 100644 --- a/dlls/dcomp/main.c +++ b/dlls/dcomp/main.c @@ -16,53 +16,98 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + #include <stdarg.h> #include "windef.h" -#include "winbase.h" -#include "objidl.h" -#include "dxgi.h" #include "wine/debug.h" #include "initguid.h" -#include "dcomp.h" #include "dcomp_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dcomp); HRESULT WINAPI DCompositionCreateDevice(IDXGIDevice *dxgi_device, REFIID iid, void **device) { + HRESULT hr; + struct composition_device *composition_device; + + *device = NULL; + if(IsEqualGUID(iid, &IID_IDCompositionDevice)) { - return create_composition_device(dxgi_device, device); + hr = create_composition_device((IUnknown *)dxgi_device, &composition_device); + if(hr == S_OK) + { + *device = &composition_device->IDCompositionDevice_iface; + } + return hr; } WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - *device = NULL; return E_NOINTERFACE; } HRESULT WINAPI DCompositionCreateDevice2(IUnknown *rendering_device, REFIID iid, void **device) { + HRESULT hr; + struct composition_device *composition_device; + + *device = NULL; + + /* Check for &IID_IDCompositionDevice rather than &IID_IDCompositionDevice2, + * even though we are returning IDCompositionDevice2 from here */ if(IsEqualGUID(iid, &IID_IDCompositionDevice)) { - FIXME("%p, %s, %p.\n", rendering_device, debugstr_guid(iid), device); - return E_NOTIMPL; + hr = create_composition_device(rendering_device, &composition_device); + if(hr == S_OK) + { + *device = &composition_device->IDCompositionDevice2_iface; + } + return hr; } if(IsEqualGUID(iid, &IID_IDCompositionDesktopDevice)) { - return create_composition_desktop_device(rendering_device, device); + hr = create_composition_device(rendering_device, &composition_device); + if(hr == S_OK) + { + *device = &composition_device->IDCompositionDesktopDevice_iface; + } + return hr; } WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - *device = NULL; return E_NOINTERFACE; } HRESULT WINAPI DCompositionCreateDevice3(IUnknown *rendering_device, REFIID iid, void **device) { - FIXME("%p, %s, %p.\n", rendering_device, debugstr_guid(iid), device); + HRESULT hr; + struct composition_device *composition_device; + + *device = NULL; - return E_NOTIMPL; + if(IsEqualGUID(iid, &IID_IDCompositionDevice)) + { + hr = create_composition_device(rendering_device, &composition_device); + if(hr == S_OK) + { + *device = &composition_device->IDCompositionDevice3_iface; + } + return hr; + } + if(IsEqualGUID(iid, &IID_IDCompositionDesktopDevice)) + { + hr = create_composition_device(rendering_device, &composition_device); + if(hr == S_OK) + { + *device = &composition_device->IDCompositionDesktopDevice_iface; + } + return hr; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + + return E_NOINTERFACE; } diff --git a/dlls/dcomp/surface.c b/dlls/dcomp/surface.c index 38648a9f920..5718073e1e9 100644 --- a/dlls/dcomp/surface.c +++ b/dlls/dcomp/surface.c @@ -22,11 +22,7 @@ #include <stdlib.h> #include "windef.h" -#include "winbase.h" -#include "objidl.h" -#include "dxgi.h" #include "wine/debug.h" -#include "dcomp.h" #include "dcomp_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dcomp); diff --git a/dlls/dcomp/surface_factory.c b/dlls/dcomp/surface_factory.c index 273c8801f3b..7013d0bafae 100644 --- a/dlls/dcomp/surface_factory.c +++ b/dlls/dcomp/surface_factory.c @@ -22,11 +22,7 @@ #include <stdlib.h> #include "windef.h" -#include "winbase.h" -#include "objidl.h" -#include "dxgi.h" #include "wine/debug.h" -#include "dcomp.h" #include "dcomp_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dcomp); diff --git a/dlls/dcomp/target.c b/dlls/dcomp/target.c index eaa91165161..52baa85fd26 100644 --- a/dlls/dcomp/target.c +++ b/dlls/dcomp/target.c @@ -22,11 +22,7 @@ #include <stdlib.h> #include "windef.h" -#include "winbase.h" -#include "objidl.h" -#include "dxgi.h" #include "wine/debug.h" -#include "dcomp.h" #include "dcomp_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dcomp); diff --git a/dlls/dcomp/tests/dcomp.c b/dlls/dcomp/tests/dcomp.c index a3659592409..963636f88eb 100644 --- a/dlls/dcomp/tests/dcomp.c +++ b/dlls/dcomp/tests/dcomp.c @@ -85,27 +85,35 @@ static HRESULT create_window_and_device(HWND *hwnd, ID3D11Device **d3d11_device, return hr; } -static void test_CreateInstance2_DesktopDevice(void) +static void test_CreateInstance(HRESULT (WINAPI *create_device)(IUnknown *rendering_device, REFIID iid, void **device), REFIID iid, HRESULT expected_result) { HRESULT hr; ID3D11Device *d3d11_device; HWND hwnd; IDXGIDevice *dxgi_device = NULL; - IDCompositionDesktopDevice *dcomp_device; + IUnknown *dcomp_device; hr = create_window_and_device(&hwnd, &d3d11_device, &dxgi_device); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - hr = DCompositionCreateDevice2((IUnknown *)dxgi_device, - &IID_IDCompositionDesktopDevice, - (void **)&dcomp_device); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = create_device((IUnknown *)dxgi_device, iid, (void **)&dcomp_device); + ok(hr == expected_result, "Unexpected hr %#lx.\n", hr); - IDCompositionDesktopDevice_Release(dcomp_device); + if(hr == S_OK) + { + IUnknown_Release(dcomp_device); + } IDXGIDevice_Release(dxgi_device); } +static void test_CreateInstance1(HRESULT (WINAPI *create_device)(IDXGIDevice *rendering_device, REFIID iid, void **device), REFIID iid, HRESULT expected_result) +{ + test_CreateInstance( + (HRESULT WINAPI (*)(IUnknown *rendering_device, REFIID iid, void **device))create_device, + iid, expected_result); +} + static void test_create_surface_and_target(void) { HRESULT hr; @@ -159,7 +167,21 @@ START_TEST(dcomp) { CoInitialize(NULL); - test_CreateInstance2_DesktopDevice(); + test_CreateInstance1(&DCompositionCreateDevice, &IID_IDCompositionDevice, S_OK); + test_CreateInstance1(&DCompositionCreateDevice, &IID_IDCompositionDevice2, E_NOINTERFACE); + test_CreateInstance1(&DCompositionCreateDevice, &IID_IDCompositionDesktopDevice, E_NOINTERFACE); + test_CreateInstance1(&DCompositionCreateDevice, &IID_IDCompositionDevice3, E_NOINTERFACE); + + test_CreateInstance(&DCompositionCreateDevice2, &IID_IDCompositionDevice, S_OK); + test_CreateInstance(&DCompositionCreateDevice2, &IID_IDCompositionDevice2, E_NOINTERFACE); + test_CreateInstance(&DCompositionCreateDevice2, &IID_IDCompositionDesktopDevice, S_OK); + test_CreateInstance(&DCompositionCreateDevice2, &IID_IDCompositionDevice3, E_NOINTERFACE); + + test_CreateInstance(&DCompositionCreateDevice3, &IID_IDCompositionDevice, S_OK); + test_CreateInstance(&DCompositionCreateDevice3, &IID_IDCompositionDevice2, E_NOINTERFACE); + test_CreateInstance(&DCompositionCreateDevice3, &IID_IDCompositionDesktopDevice, S_OK); + test_CreateInstance(&DCompositionCreateDevice3, &IID_IDCompositionDevice3, E_NOINTERFACE); + test_create_surface_and_target(); CoUninitialize(); diff --git a/dlls/dcomp/visual2.c b/dlls/dcomp/visual2.c index 74d81199d44..ee2141cb61f 100644 --- a/dlls/dcomp/visual2.c +++ b/dlls/dcomp/visual2.c @@ -22,11 +22,7 @@ #include <stdlib.h> #include "windef.h" -#include "winbase.h" -#include "objidl.h" -#include "dxgi.h" #include "wine/debug.h" -#include "dcomp.h" #include "dcomp_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dcomp); diff --git a/include/dcomp.idl b/include/dcomp.idl index 40aa6aa1d9d..1647e6a2093 100644 --- a/include/dcomp.idl +++ b/include/dcomp.idl @@ -427,6 +427,33 @@ interface IDCompositionDevice2 : IUnknown HRESULT CreateAnimation([out] IDCompositionAnimation **animation); } +[ + object, + uuid(0987cb06-f916-48bf-8d35-ce7641781bd9), + local, + pointer_default(unique) +] +interface IDCompositionDevice3 : IDCompositionDevice2 +{ + /* FIXME: these should actually be eg. + * HRESULT CreateAffineTransform2DEffect([out] IDCompositionAffineTransform2DEffect **effect); + * These are currently unimplemented, so void ** keeps this file simpler. + */ + HRESULT CreateGaussianBlurEffect([out] void **effect); + HRESULT CreateBrightnessEffect([out] void **effect); + HRESULT CreateColorMatrixEffect([out] void **effect); + HRESULT CreateShadowEffect([out] void **effect); + HRESULT CreateHueRotationEffect([out] void **effect); + HRESULT CreateSaturationEffect([out] void **effect); + HRESULT CreateTurbulenceEffect([out] void **effect); + HRESULT CreateLinearTransferEffect([out] void **effect); + HRESULT CreateTableTransferEffect([out] void **effect); + HRESULT CreateCompositeEffect([out] void **effect); + HRESULT CreateBlendEffect([out] void **effect); + HRESULT CreateArithmeticCompositeEffect([out] void **effect); + HRESULT CreateAffineTransform2DEffect([out] void **effect); +} + [ object, uuid(5f4633fe-1e08-4cb8-8c75-ce24333f5602), @@ -442,3 +469,4 @@ interface IDCompositionDesktopDevice : IDCompositionDevice2 cpp_quote("STDAPI DCompositionCreateDevice(IDXGIDevice *dxgi_device, REFIID iid, void **device);") cpp_quote("STDAPI DCompositionCreateDevice2(IUnknown *rendering_device, REFIID iid, void **device);") +cpp_quote("STDAPI DCompositionCreateDevice3(IUnknown *rendering_device, REFIID iid, void **device);") -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9839
From: Jaakko Hannikainen <jgke@jgke.fi> This prevents the 'edit instrument' screen in Dorico from crashing the entire software, now merely rendering a completely white screen. --- dlls/dcomp/device.c | 3 ++- dlls/dcomp/target.c | 3 ++- dlls/dcomp/tests/dcomp.c | 48 ++++++++++++++++++++++++++++++++++++++++ dlls/dcomp/visual2.c | 3 ++- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/dlls/dcomp/device.c b/dlls/dcomp/device.c index 7cd7462fb8e..e33e52e450f 100644 --- a/dlls/dcomp/device.c +++ b/dlls/dcomp/device.c @@ -88,7 +88,8 @@ static ULONG STDMETHODCALLTYPE composition_device_Release_impl(struct compositio static HRESULT STDMETHODCALLTYPE composition_device_Commit_impl(struct composition_device *device) { FIXME("device %p stub!\n", device); - return E_NOTIMPL; + /* FIXME: this should be E_NOTIMPL but it causes crashes */ + return S_OK; } static HRESULT STDMETHODCALLTYPE composition_device_WaitForCommitCompletion_impl(struct composition_device *device) diff --git a/dlls/dcomp/target.c b/dlls/dcomp/target.c index 52baa85fd26..06caf825751 100644 --- a/dlls/dcomp/target.c +++ b/dlls/dcomp/target.c @@ -80,7 +80,8 @@ static HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE composition_target_SetRoot( IDCompositionTarget *iface, IDCompositionVisual *visual) { FIXME("iface %p, visual %p stub!\n", iface, visual); - return E_NOTIMPL; + /* FIXME: should be E_NOTIMPL but it causes crashes */ + return S_OK; } static const struct IDCompositionTargetVtbl composition_target_vtbl = diff --git a/dlls/dcomp/tests/dcomp.c b/dlls/dcomp/tests/dcomp.c index 963636f88eb..28de6ee67e3 100644 --- a/dlls/dcomp/tests/dcomp.c +++ b/dlls/dcomp/tests/dcomp.c @@ -163,6 +163,53 @@ static void test_create_surface_and_target(void) IDXGIDevice_Release(dxgi_device); } +static void test_hacks(void) +{ + HRESULT hr; + ID3D11Device *d3d11_device; + HWND hwnd; + IDXGIDevice *dxgi_device = NULL; + IDCompositionDesktopDevice *dcomp_device; + IDCompositionTarget *target; + IDCompositionVisual2 *visual; + + hr = create_window_and_device(&hwnd, &d3d11_device, &dxgi_device); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = DCompositionCreateDevice2((IUnknown *)dxgi_device, + &IID_IDCompositionDesktopDevice, + (void **)&dcomp_device); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDCompositionDesktopDevice_CreateTargetForHwnd(dcomp_device, hwnd, FALSE, &target); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDCompositionDesktopDevice_CreateVisual(dcomp_device, &visual); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + + /* These 3 functions should currently return E_NOTIMPL, but it crashes Dorico. */ + hr = IDCompositionVisual2_SetContent(visual, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDCompositionTarget_SetRoot(target, (IDCompositionVisual *)visual); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDCompositionDesktopDevice_Commit(dcomp_device); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + + IDCompositionTarget_Release(target); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IDCompositionVisual2_Release(visual); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IDCompositionDesktopDevice_Release(dcomp_device); + + IDXGIDevice_Release(dxgi_device); +} + START_TEST(dcomp) { CoInitialize(NULL); @@ -183,6 +230,7 @@ START_TEST(dcomp) test_CreateInstance(&DCompositionCreateDevice3, &IID_IDCompositionDevice3, E_NOINTERFACE); test_create_surface_and_target(); + test_hacks(); CoUninitialize(); } diff --git a/dlls/dcomp/visual2.c b/dlls/dcomp/visual2.c index ee2141cb61f..889d4436490 100644 --- a/dlls/dcomp/visual2.c +++ b/dlls/dcomp/visual2.c @@ -163,7 +163,8 @@ static HRESULT STDMETHODCALLTYPE composition_visual_SetContent( IDCompositionVisual2 *iface, IUnknown *content) { FIXME("iface %p content %p stub!\n", iface, content); - return E_NOTIMPL; + /* FIXME: should be E_NOTIMPL but it causes crashes */ + return S_OK; } static HRESULT STDMETHODCALLTYPE composition_visual_AddVisual( -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9839
Hi Jaakko, thanks for looking into dcomp. The problem with dcomp is that while adding stubs is enough to make some games happy, it's not good enough for upstream. After you add the stubs, other applications will start calling those stub functions, and more methods will be needed. Eventually, we will need a complete solution. Not having those stubs forces some games to fall back to other code paths that don't require dcomp. A proper solution would be to implement a compositor, utilizing Rémi's recent shared resource work, which allows sharing images across different processes. To do that, we need to support shared resources for wined3d first, then implement a compositor(dwm.exe?), then implement dcomp to control the compositor. It wouldn't be trivial. For what it's worth, I have a slightly better version of dcomp at https://gitlab.winehq.org/zhiyi/wine/-/commits/bug-23698-react-native. It's still not a proper implementation, but it helps some applications. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9839#note_126236
The problem with dcomp is that while adding stubs is enough to make some games happy, it's not good enough for upstream. After you add the stubs, other applications will start calling those stub functions, and more methods will be needed.
Darn, I was thinking a bit about this. Would it be feasible to have some implementation behind a feature flag, or some similar construct? That way applications checking, but not really using dcomp (...Dorico, at least) could function, without affecting applications and games outside that wineprefix.
For what it's worth, I have a slightly better version of dcomp at \[...\]
Thanks for the link! Looks like that implementation is indeed further than this blob of stubs. I'll have to try that branch out later today. I probably can't help develop that further since I don't really know a lot about any related topic. If there's some trivial changes that would help my use case, do you want patches? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9839#note_126237
Would it be feasible to have some implementation behind a feature flag, or some similar construct?
I don't think so.
If there's some trivial changes that would help my use case, do you want patches?
If it's something suitable for upstream, then yes. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9839#note_126238
This merge request was closed by Jaakko Hannikainen. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9839
participants (3)
-
Jaakko Hannikainen -
Jaakko Hannikainen (@jgke) -
Zhiyi Zhang (@zhiyi)