[PATCH 2/6] evr/presenter: Create a swapchain for given output window.
Nikolay Sivov
nsivov at codeweavers.com
Fri Nov 13 06:31:32 CST 2020
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/evr/presenter.c | 54 +++++++++++++++++-
dlls/evr/tests/evr.c | 128 +++++++++++++++++++++++++++++--------------
2 files changed, 139 insertions(+), 43 deletions(-)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c
index c1f29d41e4e..fc3a1b52c51 100644
--- a/dlls/evr/presenter.c
+++ b/dlls/evr/presenter.c
@@ -77,6 +77,9 @@ struct video_presenter
IMediaEventSink *event_sink;
IDirect3DDeviceManager9 *device_manager;
+ IDirect3DSwapChain9 *swapchain;
+ HANDLE hdevice;
+
IMFVideoSampleAllocator *allocator;
struct streaming_thread thread;
IMFMediaType *media_type;
@@ -164,6 +167,19 @@ static unsigned int get_gcd(unsigned int a, unsigned int b)
return a;
}
+static HRESULT video_presenter_get_device(struct video_presenter *presenter, IDirect3DDevice9 **device)
+{
+ HRESULT hr;
+
+ if (!presenter->hdevice)
+ {
+ if (FAILED(hr = IDirect3DDeviceManager9_OpenDeviceHandle(presenter->device_manager, &presenter->hdevice)))
+ return hr;
+ }
+
+ return IDirect3DDeviceManager9_LockDevice(presenter->device_manager, presenter->hdevice, device, TRUE);
+}
+
static void video_presenter_get_native_video_size(struct video_presenter *presenter)
{
IMFMediaType *media_type;
@@ -501,8 +517,13 @@ static ULONG WINAPI video_presenter_inner_Release(IUnknown *iface)
video_presenter_clear_container(presenter);
video_presenter_reset_media_type(presenter);
DeleteCriticalSection(&presenter->cs);
+ if (presenter->swapchain)
+ IDirect3DSwapChain9_Release(presenter->swapchain);
if (presenter->device_manager)
+ {
+ IDirect3DDeviceManager9_CloseDeviceHandle(presenter->device_manager, presenter->hdevice);
IDirect3DDeviceManager9_Release(presenter->device_manager);
+ }
if (presenter->allocator)
IMFVideoSampleAllocator_Release(presenter->allocator);
heap_free(presenter);
@@ -995,9 +1016,32 @@ static HRESULT WINAPI video_presenter_control_GetAspectRatioMode(IMFVideoDisplay
return S_OK;
}
+static HRESULT video_presenter_create_swapchain(struct video_presenter *presenter)
+{
+ D3DPRESENT_PARAMETERS present_params = { 0 };
+ IDirect3DDevice9 *d3d_device;
+ HRESULT hr;
+
+ if (SUCCEEDED(hr = video_presenter_get_device(presenter, &d3d_device)))
+ {
+ present_params.hDeviceWindow = presenter->video_window;
+ present_params.Windowed = TRUE;
+ present_params.SwapEffect = D3DSWAPEFFECT_COPY;
+ present_params.Flags = D3DPRESENTFLAG_VIDEO;
+ present_params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+ hr = IDirect3DDevice9_CreateAdditionalSwapChain(d3d_device, &present_params, &presenter->swapchain);
+
+ IDirect3DDevice9_Release(d3d_device);
+ IDirect3DDeviceManager9_UnlockDevice(presenter->device_manager, presenter->hdevice, FALSE);
+ }
+
+ return hr;
+}
+
static HRESULT WINAPI video_presenter_control_SetVideoWindow(IMFVideoDisplayControl *iface, HWND window)
{
struct video_presenter *presenter = impl_from_IMFVideoDisplayControl(iface);
+ HRESULT hr = S_OK;
TRACE("%p, %p.\n", iface, window);
@@ -1005,10 +1049,16 @@ static HRESULT WINAPI video_presenter_control_SetVideoWindow(IMFVideoDisplayCont
return E_INVALIDARG;
EnterCriticalSection(&presenter->cs);
- presenter->video_window = window;
+ if (presenter->video_window != window)
+ {
+ if (presenter->swapchain)
+ IDirect3DSwapChain9_Release(presenter->swapchain);
+ presenter->video_window = window;
+ hr = video_presenter_create_swapchain(presenter);
+ }
LeaveCriticalSection(&presenter->cs);
- return S_OK;
+ return hr;
}
static HRESULT WINAPI video_presenter_control_GetVideoWindow(IMFVideoDisplayControl *iface, HWND *window)
diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c
index bdf3154c7e5..d4c2ffb0480 100644
--- a/dlls/evr/tests/evr.c
+++ b/dlls/evr/tests/evr.c
@@ -1096,18 +1096,13 @@ done:
static void test_default_presenter(void)
{
- D3DDEVICE_CREATION_PARAMETERS device_params = { 0 };
- D3DPRESENT_PARAMETERS present_params = { 0 };
IMFVideoDisplayControl *display_control;
- IDirect3DSwapChain9 *swapchain;
IMFVideoPresenter *presenter;
IMFRateSupport *rate_support;
- IDirect3DDevice9 *d3d_device;
IDirect3DDeviceManager9 *dm;
IMFVideoDeviceID *deviceid;
IMFGetService *gs;
HWND hwnd, hwnd2;
- HANDLE handle;
IUnknown *unk;
DWORD flags;
float rate;
@@ -1176,33 +1171,6 @@ static void test_default_presenter(void)
hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- hr = IDirect3DDeviceManager9_OpenDeviceHandle(dm, &handle);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-
- hr = IDirect3DDeviceManager9_LockDevice(dm, handle, &d3d_device, FALSE);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-
- hr = IDirect3DDevice9_GetCreationParameters(d3d_device, &device_params);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- ok(device_params.hFocusWindow == GetDesktopWindow(), "Unexpected window %p.\n", device_params.hFocusWindow);
-
- hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-
- hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-
- ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
- ok(present_params.Windowed, "Unexpected windowed mode.\n");
- ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
- ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
- ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
-
- IDirect3DDevice9_Release(d3d_device);
-
- hr = IDirect3DDeviceManager9_UnlockDevice(dm, handle, FALSE);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-
/* Video window */
hwnd = create_window();
ok(!!hwnd, "Failed to create a test window.\n");
@@ -1229,15 +1197,6 @@ static void test_default_presenter(void)
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(hwnd2 == hwnd, "Unexpected window %p.\n", hwnd2);
- /* Video position */
- hr = IDirect3DDeviceManager9_CloseDeviceHandle(dm, handle);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-
- IDirect3DDeviceManager9_Release(dm);
-
- IMFVideoDisplayControl_Release(display_control);
- IMFGetService_Release(gs);
-
/* Rate support. */
hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFRateSupport, (void **)&rate_support);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
@@ -1920,6 +1879,92 @@ static void test_presenter_ar_mode(void)
IMFVideoDisplayControl_Release(display_control);
}
+static void test_presenter_video_window(void)
+{
+ D3DDEVICE_CREATION_PARAMETERS device_params = { 0 };
+ IMFVideoDisplayControl *display_control;
+ IDirect3DDeviceManager9 *dm;
+ IDirect3DDevice9 *d3d_device;
+ HANDLE hdevice;
+ HRESULT hr;
+ IDirect3DSwapChain9 *swapchain;
+ D3DPRESENT_PARAMETERS present_params = { 0 };
+ HWND window;
+
+ hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoDisplayControl, (void **)&display_control);
+ ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
+
+ hr = MFGetService((IUnknown *)display_control, &MR_VIDEO_ACCELERATION_SERVICE,
+ &IID_IDirect3DDeviceManager9, (void **)&dm);
+
+ hr = IDirect3DDeviceManager9_OpenDeviceHandle(dm, &hdevice);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DDeviceManager9_LockDevice(dm, hdevice, &d3d_device, FALSE);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetCreationParameters(d3d_device, &device_params);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(device_params.hFocusWindow == GetDesktopWindow(), "Unexpected window %p.\n", device_params.hFocusWindow);
+
+ hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
+ ok(present_params.Windowed, "Unexpected windowed mode.\n");
+ ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
+ ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
+ ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
+
+ IDirect3DSwapChain9_Release(swapchain);
+ IDirect3DDevice9_Release(d3d_device);
+
+ hr = IDirect3DDeviceManager9_UnlockDevice(dm, hdevice, FALSE);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ /* Setting window. */
+ hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &window);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(!window, "Unexpected window %p.\n", window);
+
+ window = create_window();
+
+ hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ /* Device is not recreated or reset on window change. */
+ hr = IDirect3DDeviceManager9_LockDevice(dm, hdevice, &d3d_device, FALSE);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
+ ok(present_params.Windowed, "Unexpected windowed mode.\n");
+ ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
+ ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
+ ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
+
+ IDirect3DSwapChain9_Release(swapchain);
+ IDirect3DDevice9_Release(d3d_device);
+
+ hr = IDirect3DDeviceManager9_UnlockDevice(dm, hdevice, FALSE);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DDeviceManager9_CloseDeviceHandle(dm, hdevice);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ IMFVideoDisplayControl_Release(display_control);
+
+ DestroyWindow(window);
+}
+
static void test_mixer_output_rectangle(void)
{
IMFVideoMixerControl *mixer_control;
@@ -2370,6 +2415,7 @@ START_TEST(evr)
test_presenter_video_position();
test_presenter_native_video_size();
test_presenter_ar_mode();
+ test_presenter_video_window();
test_mixer_output_rectangle();
test_mixer_zorder();
test_mixer_samples();
--
2.29.2
More information about the wine-devel
mailing list