d3d11videosink: Fix for ignored initial render rectangle
authorSeungha Yang <seungha@centricular.com>
Mon, 24 Apr 2023 19:59:33 +0000 (04:59 +0900)
committerTim-Philipp Müller <tim@centricular.com>
Thu, 27 Apr 2023 09:18:58 +0000 (10:18 +0100)
Application can set target render rect before internal HWND
configuration

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2518
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4496>

subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_win32.cpp

index c4db036..1c0c1ca 100644 (file)
@@ -331,9 +331,10 @@ gst_d3d11_window_win32_set_render_rectangle (GstD3D11Window * window,
 {
   GstD3D11WindowWin32 *self = GST_D3D11_WINDOW_WIN32 (window);
 
+  self->render_rect = *rect;
+
   if (self->external_hwnd && self->internal_hwnd) {
     g_atomic_int_add (&self->pending_move_window, 1);
-    self->render_rect = *rect;
 
     if (self->internal_hwnd_thread == g_thread_self ()) {
       /* We are on message pumping thread already, handle this synchroniously */
@@ -958,12 +959,21 @@ sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
       /* take changes into account: SWP_FRAMECHANGED */
       GetClientRect (self->external_hwnd, &rect);
+
+      if (self->render_rect.x != 0 || self->render_rect.y != 0 ||
+          self->render_rect.w != 0 || self->render_rect.h != 0) {
+        rect.left = self->render_rect.x;
+        rect.top = self->render_rect.y;
+        rect.right = self->render_rect.x + self->render_rect.w;
+        rect.bottom = self->render_rect.y + self->render_rect.h;
+      }
+
       SetWindowPos (self->internal_hwnd, HWND_TOP, rect.left, rect.top,
-          rect.right, rect.bottom,
+          rect.right - rect.left, rect.bottom - rect.top,
           SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
           SWP_FRAMECHANGED | SWP_NOACTIVATE);
-      MoveWindow (self->internal_hwnd, rect.left, rect.top, rect.right,
-          rect.bottom, FALSE);
+      MoveWindow (self->internal_hwnd, rect.left, rect.top,
+          rect.right - rect.left, rect.bottom - rect.top, FALSE);
 
       self->overlay_state = GST_D3D11_WINDOW_WIN32_OVERLAY_STATE_OPENED;
       WakeAllConditionVariable (&self->cond);
@@ -974,8 +984,15 @@ sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
       return 0;
     }
     case WM_SIZE:
-      MoveWindow (self->internal_hwnd, 0, 0, LOWORD (lParam), HIWORD (lParam),
-          FALSE);
+      if (self->render_rect.x != 0 || self->render_rect.y != 0 ||
+          self->render_rect.w != 0 || self->render_rect.h != 0) {
+        MoveWindow (self->internal_hwnd,
+            self->render_rect.x, self->render_rect.y,
+            self->render_rect.w, self->render_rect.h, FALSE);
+      } else {
+        MoveWindow (self->internal_hwnd, 0, 0, LOWORD (lParam), HIWORD (lParam),
+            FALSE);
+      }
       break;
     case WM_CLOSE:
     case WM_DESTROY:{