[vlc-devel] [PATCH] direct3d11: fix video position on Windows Phone and WinRT
Steve Lhomme
robux4 at gmail.com
Tue Jun 23 13:47:39 CEST 2015
From: Steve Lhomme <robux4 at gmail.com>
the SwapChain dimensions are read from shared private data in the DXGI swap chain
---
modules/video_output/msw/common.c | 431 ++++++++++++++++++----------------
modules/video_output/msw/common.h | 5 +
modules/video_output/msw/direct3d11.c | 217 ++++++++++-------
3 files changed, 364 insertions(+), 289 deletions(-)
diff --git a/modules/video_output/msw/common.c b/modules/video_output/msw/common.c
index 1e5b5f7..1f9ee0b 100644
--- a/modules/video_output/msw/common.c
+++ b/modules/video_output/msw/common.c
@@ -38,12 +38,14 @@
#include <windows.h>
#include <assert.h>
+#define COBJMACROS
+
#include "common.h"
#include <vlc_windows_interfaces.h>
-#if !VLC_WINSTORE_APP
static void CommonChangeThumbnailClip(vout_display_t *, bool show);
+#if !VLC_WINSTORE_APP
static int CommonControlSetFullscreen(vout_display_t *, bool is_fullscreen);
static void DisableScreensaver(vout_display_t *);
@@ -118,6 +120,229 @@ picture_pool_t *CommonPool(vout_display_t *vd, unsigned count)
return vd->sys->pool;
}
+/*****************************************************************************
+* UpdateRects: update clipping rectangles
+*****************************************************************************
+* This function is called when the window position or size are changed, and
+* its job is to update the source and destination RECTs used to display the
+* picture.
+*****************************************************************************/
+void UpdateRects(vout_display_t *vd,
+ const vout_display_cfg_t *cfg,
+ const video_format_t *source,
+ bool is_forced)
+{
+ vout_display_sys_t *sys = vd->sys;
+#define rect_src sys->rect_src
+#define rect_src_clipped sys->rect_src_clipped
+#define rect_dest sys->rect_dest
+#define rect_dest_clipped sys->rect_dest_clipped
+
+ RECT rect;
+ POINT point;
+
+ /* */
+ if (!cfg)
+ cfg = vd->cfg;
+ if (!source)
+ source = &vd->source;
+
+ /* Retrieve the window size */
+#if VLC_WINSTORE_APP
+ rect.left = 0;
+ rect.top = 0;
+ uint32_t i_width;
+ uint32_t i_height;
+ UINT dataSize = sizeof(i_width);
+ HRESULT hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_WIDTH, &dataSize, &i_width);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Can't get swapchain width, size %d. (hr=0x%lX)", hr, dataSize);
+ return;
+ }
+ dataSize = sizeof(i_height);
+ hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_HEIGHT, &dataSize, &i_height);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Can't get swapchain height, size %d. (hr=0x%lX)", hr, dataSize);
+ return;
+ }
+ rect.right = i_width;
+ rect.bottom = i_height;
+#else
+ GetClientRect(sys->hwnd, &rect);
+#endif
+
+ /* Retrieve the window position */
+ point.x = point.y = 0;
+#if !VLC_WINSTORE_APP
+ ClientToScreen(sys->hwnd, &point);
+#endif
+
+ /* If nothing changed, we can return */
+ bool has_moved;
+ bool is_resized;
+#if VLC_WINSTORE_APP
+ has_moved = false;
+ is_resized = rect.right != (sys->rect_display.right - sys->rect_display.left) ||
+ rect.bottom != (sys->rect_display.bottom - sys->rect_display.top);
+ sys->rect_display = rect;
+#else
+ EventThreadUpdateWindowPosition(sys->event, &has_moved, &is_resized,
+ point.x, point.y,
+ rect.right, rect.bottom);
+#endif
+ if (is_resized)
+ vout_display_SendEventDisplaySize(vd, rect.right, rect.bottom);
+ if (!is_forced && !has_moved && !is_resized)
+ return;
+
+ /* Update the window position and size */
+ vout_display_cfg_t place_cfg = *cfg;
+ place_cfg.display.width = rect.right;
+ place_cfg.display.height = rect.bottom;
+
+ vout_display_place_t place;
+ vout_display_PlacePicture(&place, source, &place_cfg, false);
+
+#if !VLC_WINSTORE_APP
+ EventThreadUpdateSourceAndPlace(sys->event, source, &place);
+
+ if (sys->hvideownd)
+ SetWindowPos(sys->hvideownd, 0,
+ place.x, place.y, place.width, place.height,
+ SWP_NOCOPYBITS | SWP_NOZORDER | SWP_ASYNCWINDOWPOS);
+#endif
+
+ /* Destination image position and dimensions */
+#if (defined(MODULE_NAME_IS_direct3d9) || defined(MODULE_NAME_IS_direct3d11) || defined(MODULE_NAME_IS_direct2d)) && !VLC_WINSTORE_APP
+ rect_dest.left = 0;
+ rect_dest.right = place.width;
+ rect_dest.top = 0;
+ rect_dest.bottom = place.height;
+#else
+ rect_dest.left = point.x + place.x;
+ rect_dest.right = rect_dest.left + place.width;
+ rect_dest.top = point.y + place.y;
+ rect_dest.bottom = rect_dest.top + place.height;
+
+#ifdef MODULE_NAME_IS_directdraw
+ /* Apply overlay hardware constraints */
+ if (sys->use_overlay)
+ AlignRect(&rect_dest, sys->i_align_dest_boundary, sys->i_align_dest_size);
+#endif
+
+#endif
+
+#if defined(MODULE_NAME_IS_directdraw)
+ /* UpdateOverlay directdraw function doesn't automatically clip to the
+ * display size so we need to do it otherwise it will fail */
+
+ /* Clip the destination window */
+ if (!IntersectRect(&rect_dest_clipped, &rect_dest,
+ &sys->rect_display)) {
+ SetRectEmpty(&rect_src_clipped);
+ goto exit;
+ }
+
+#ifndef NDEBUG
+ msg_Dbg(vd, "DirectXUpdateRects image_dst_clipped coords:"
+ " %li,%li,%li,%li",
+ rect_dest_clipped.left, rect_dest_clipped.top,
+ rect_dest_clipped.right, rect_dest_clipped.bottom);
+#endif
+
+#else
+
+ /* AFAIK, there are no clipping constraints in Direct3D, OpenGL and GDI */
+ rect_dest_clipped = rect_dest;
+
+#endif
+
+ /* the 2 following lines are to fix a bug when clicking on the desktop */
+ if ((rect_dest_clipped.right - rect_dest_clipped.left) == 0 ||
+ (rect_dest_clipped.bottom - rect_dest_clipped.top) == 0) {
+#if !VLC_WINSTORE_APP
+ SetRectEmpty(&rect_src_clipped);
+#endif
+ goto exit;
+ }
+
+ /* src image dimensions */
+ rect_src.left = 0;
+ rect_src.top = 0;
+ rect_src.right = vd->fmt.i_visible_width;
+ rect_src.bottom = vd->fmt.i_visible_height;
+
+ /* Clip the source image */
+ rect_src_clipped.left = source->i_x_offset +
+ (rect_dest_clipped.left - rect_dest.left) *
+ source->i_visible_width / (rect_dest.right - rect_dest.left);
+ rect_src_clipped.right = source->i_x_offset +
+ source->i_visible_width -
+ (rect_dest.right - rect_dest_clipped.right) *
+ source->i_visible_width / (rect_dest.right - rect_dest.left);
+ rect_src_clipped.top = source->i_y_offset +
+ (rect_dest_clipped.top - rect_dest.top) *
+ source->i_visible_height / (rect_dest.bottom - rect_dest.top);
+ rect_src_clipped.bottom = source->i_y_offset +
+ source->i_visible_height -
+ (rect_dest.bottom - rect_dest_clipped.bottom) *
+ source->i_visible_height / (rect_dest.bottom - rect_dest.top);
+
+#ifdef MODULE_NAME_IS_directdraw
+ /* Apply overlay hardware constraints */
+ if (sys->use_overlay)
+ AlignRect(&rect_src_clipped, sys->i_align_src_boundary, sys->i_align_src_size);
+#elif defined(MODULE_NAME_IS_direct3d9) || defined(MODULE_NAME_IS_direct3d11) || defined(MODULE_NAME_IS_direct2d)
+ /* Needed at least with YUV content */
+ rect_src_clipped.left &= ~1;
+ rect_src_clipped.right &= ~1;
+ rect_src_clipped.top &= ~1;
+ rect_src_clipped.bottom &= ~1;
+#endif
+
+#ifndef NDEBUG
+ msg_Dbg(vd, "DirectXUpdateRects souce"
+ " offset: %i,%i visible: %ix%i",
+ source->i_x_offset, source->i_y_offset,
+ source->i_visible_width, source->i_visible_height);
+ msg_Dbg(vd, "DirectXUpdateRects image_src"
+ " coords: %li,%li,%li,%li",
+ rect_src.left, rect_src.top,
+ rect_src.right, rect_src.bottom);
+ msg_Dbg(vd, "DirectXUpdateRects image_src_clipped"
+ " coords: %li,%li,%li,%li",
+ rect_src_clipped.left, rect_src_clipped.top,
+ rect_src_clipped.right, rect_src_clipped.bottom);
+ msg_Dbg(vd, "DirectXUpdateRects image_dst"
+ " coords: %li,%li,%li,%li",
+ rect_dest.left, rect_dest.top,
+ rect_dest.right, rect_dest.bottom);
+ msg_Dbg(vd, "DirectXUpdateRects image_dst_clipped"
+ " coords: %li,%li,%li,%li",
+ rect_dest_clipped.left, rect_dest_clipped.top,
+ rect_dest_clipped.right, rect_dest_clipped.bottom);
+#endif
+
+#ifdef MODULE_NAME_IS_directdraw
+ /* The destination coordinates need to be relative to the current
+ * directdraw primary surface (display) */
+ rect_dest_clipped.left -= sys->rect_display.left;
+ rect_dest_clipped.right -= sys->rect_display.left;
+ rect_dest_clipped.top -= sys->rect_display.top;
+ rect_dest_clipped.bottom -= sys->rect_display.top;
+#endif
+
+ CommonChangeThumbnailClip(vd, true);
+
+exit:
+ /* Signal the change in size/position */
+ sys->changes |= DX_POSITION_CHANGE;
+
+#undef rect_src
+#undef rect_src_clipped
+#undef rect_dest
+#undef rect_dest_clipped
+}
#if !VLC_WINSTORE_APP
/* */
@@ -323,196 +548,6 @@ static void CommonChangeThumbnailClip(vout_display_t *vd, bool show)
CoUninitialize();
}
-/*****************************************************************************
- * UpdateRects: update clipping rectangles
- *****************************************************************************
- * This function is called when the window position or size are changed, and
- * its job is to update the source and destination RECTs used to display the
- * picture.
- *****************************************************************************/
-void UpdateRects(vout_display_t *vd,
- const vout_display_cfg_t *cfg,
- const video_format_t *source,
- bool is_forced)
-{
- vout_display_sys_t *sys = vd->sys;
-#define rect_src sys->rect_src
-#define rect_src_clipped sys->rect_src_clipped
-#define rect_dest sys->rect_dest
-#define rect_dest_clipped sys->rect_dest_clipped
-
- RECT rect;
- POINT point;
-
- /* */
- if (!cfg)
- cfg = vd->cfg;
- if (!source)
- source = &vd->source;
-
- /* Retrieve the window size */
- GetClientRect(sys->hwnd, &rect);
-
- /* Retrieve the window position */
- point.x = point.y = 0;
- ClientToScreen(sys->hwnd, &point);
-
- /* If nothing changed, we can return */
- bool has_moved;
- bool is_resized;
- EventThreadUpdateWindowPosition(sys->event, &has_moved, &is_resized,
- point.x, point.y,
- rect.right, rect.bottom);
- if (is_resized)
- vout_display_SendEventDisplaySize(vd, rect.right, rect.bottom);
- if (!is_forced && !has_moved && !is_resized)
- return;
-
- /* Update the window position and size */
- vout_display_cfg_t place_cfg = *cfg;
- place_cfg.display.width = rect.right;
- place_cfg.display.height = rect.bottom;
-
- vout_display_place_t place;
- vout_display_PlacePicture(&place, source, &place_cfg, false);
-
- EventThreadUpdateSourceAndPlace(sys->event, source, &place);
-
- if (sys->hvideownd)
- SetWindowPos(sys->hvideownd, 0,
- place.x, place.y, place.width, place.height,
- SWP_NOCOPYBITS|SWP_NOZORDER|SWP_ASYNCWINDOWPOS);
-
- /* Destination image position and dimensions */
-#if defined(MODULE_NAME_IS_direct3d9) || defined(MODULE_NAME_IS_direct3d11) || defined(MODULE_NAME_IS_direct2d)
- rect_dest.left = 0;
- rect_dest.right = place.width;
- rect_dest.top = 0;
- rect_dest.bottom = place.height;
-#else
- rect_dest.left = point.x + place.x;
- rect_dest.right = rect_dest.left + place.width;
- rect_dest.top = point.y + place.y;
- rect_dest.bottom = rect_dest.top + place.height;
-
-#ifdef MODULE_NAME_IS_directdraw
- /* Apply overlay hardware constraints */
- if (sys->use_overlay)
- AlignRect(&rect_dest, sys->i_align_dest_boundary, sys->i_align_dest_size);
-#endif
-
-#endif
-
-#if defined(MODULE_NAME_IS_directdraw)
- /* UpdateOverlay directdraw function doesn't automatically clip to the
- * display size so we need to do it otherwise it will fail */
-
- /* Clip the destination window */
- if (!IntersectRect(&rect_dest_clipped, &rect_dest,
- &sys->rect_display)) {
- SetRectEmpty(&rect_src_clipped);
- goto exit;
- }
-
-#ifndef NDEBUG
- msg_Dbg(vd, "DirectXUpdateRects image_dst_clipped coords:"
- " %li,%li,%li,%li",
- rect_dest_clipped.left, rect_dest_clipped.top,
- rect_dest_clipped.right, rect_dest_clipped.bottom);
-#endif
-
-#else
-
- /* AFAIK, there are no clipping constraints in Direct3D, OpenGL and GDI */
- rect_dest_clipped = rect_dest;
-
-#endif
-
- /* the 2 following lines are to fix a bug when clicking on the desktop */
- if ((rect_dest_clipped.right - rect_dest_clipped.left) == 0 ||
- (rect_dest_clipped.bottom - rect_dest_clipped.top) == 0) {
- SetRectEmpty(&rect_src_clipped);
- goto exit;
- }
-
- /* src image dimensions */
- rect_src.left = 0;
- rect_src.top = 0;
- rect_src.right = vd->fmt.i_visible_width;
- rect_src.bottom = vd->fmt.i_visible_height;
-
- /* Clip the source image */
- rect_src_clipped.left = source->i_x_offset +
- (rect_dest_clipped.left - rect_dest.left) *
- source->i_visible_width / (rect_dest.right - rect_dest.left);
- rect_src_clipped.right = source->i_x_offset +
- source->i_visible_width -
- (rect_dest.right - rect_dest_clipped.right) *
- source->i_visible_width / (rect_dest.right - rect_dest.left);
- rect_src_clipped.top = source->i_y_offset +
- (rect_dest_clipped.top - rect_dest.top) *
- source->i_visible_height / (rect_dest.bottom - rect_dest.top);
- rect_src_clipped.bottom = source->i_y_offset +
- source->i_visible_height -
- (rect_dest.bottom - rect_dest_clipped.bottom) *
- source->i_visible_height / (rect_dest.bottom - rect_dest.top);
-
-#ifdef MODULE_NAME_IS_directdraw
- /* Apply overlay hardware constraints */
- if (sys->use_overlay)
- AlignRect(&rect_src_clipped, sys->i_align_src_boundary, sys->i_align_src_size);
-#elif defined(MODULE_NAME_IS_direct3d9) || defined(MODULE_NAME_IS_direct3d11) || defined(MODULE_NAME_IS_direct2d)
- /* Needed at least with YUV content */
- rect_src_clipped.left &= ~1;
- rect_src_clipped.right &= ~1;
- rect_src_clipped.top &= ~1;
- rect_src_clipped.bottom &= ~1;
-#endif
-
-#ifndef NDEBUG
- msg_Dbg(vd, "DirectXUpdateRects souce"
- " offset: %i,%i visible: %ix%i",
- source->i_x_offset, source->i_y_offset,
- source->i_visible_width, source->i_visible_height);
- msg_Dbg(vd, "DirectXUpdateRects image_src"
- " coords: %li,%li,%li,%li",
- rect_src.left, rect_src.top,
- rect_src.right, rect_src.bottom);
- msg_Dbg(vd, "DirectXUpdateRects image_src_clipped"
- " coords: %li,%li,%li,%li",
- rect_src_clipped.left, rect_src_clipped.top,
- rect_src_clipped.right, rect_src_clipped.bottom);
- msg_Dbg(vd, "DirectXUpdateRects image_dst"
- " coords: %li,%li,%li,%li",
- rect_dest.left, rect_dest.top,
- rect_dest.right, rect_dest.bottom);
- msg_Dbg(vd, "DirectXUpdateRects image_dst_clipped"
- " coords: %li,%li,%li,%li",
- rect_dest_clipped.left, rect_dest_clipped.top,
- rect_dest_clipped.right, rect_dest_clipped.bottom);
-#endif
-
-#ifdef MODULE_NAME_IS_directdraw
- /* The destination coordinates need to be relative to the current
- * directdraw primary surface (display) */
- rect_dest_clipped.left -= sys->rect_display.left;
- rect_dest_clipped.right -= sys->rect_display.left;
- rect_dest_clipped.top -= sys->rect_display.top;
- rect_dest_clipped.bottom -= sys->rect_display.top;
-#endif
-
- CommonChangeThumbnailClip(vd, true);
-
-exit:
- /* Signal the change in size/position */
- sys->changes |= DX_POSITION_CHANGE;
-
-#undef rect_src
-#undef rect_src_clipped
-#undef rect_dest
-#undef rect_dest_clipped
-}
-
static int CommonControlSetFullscreen(vout_display_t *vd, bool is_fullscreen)
{
vout_display_sys_t *sys = vd->sys;
@@ -729,12 +764,10 @@ int CommonControl(vout_display_t *vd, int query, va_list args)
}
}
-void CommonManage(vout_display_t *vd) {};
-void CommonClean(vout_display_t *vd) {};
-void CommonDisplay(vout_display_t *vd) {};
-void UpdateRects(vout_display_t *vd,
- const vout_display_cfg_t *cfg,
- const video_format_t *source,
- bool is_forced)
-{};
+void CommonManage(vout_display_t *vd) {
+ UpdateRects(vd, NULL, NULL, false);
+}
+void CommonClean(vout_display_t *vd) {}
+void CommonDisplay(vout_display_t *vd) {}
+void CommonChangeThumbnailClip(vout_display_t *vd, bool show) {}
#endif
diff --git a/modules/video_output/msw/common.h b/modules/video_output/msw/common.h
index 4f7389d..7064dd8 100644
--- a/modules/video_output/msw/common.h
+++ b/modules/video_output/msw/common.h
@@ -69,6 +69,11 @@ typedef struct
} d3d_quad_t;
#endif
+#if VLC_WINSTORE_APP
+extern const GUID GUID_SWAPCHAIN_WIDTH;
+extern const GUID GUID_SWAPCHAIN_HEIGHT;
+#endif
+
/*****************************************************************************
* vout_sys_t: video output method descriptor
*****************************************************************************
diff --git a/modules/video_output/msw/direct3d11.c b/modules/video_output/msw/direct3d11.c
index 481a673..f5d33bb 100644
--- a/modules/video_output/msw/direct3d11.c
+++ b/modules/video_output/msw/direct3d11.c
@@ -32,7 +32,6 @@
#define COBJMACROS
#define INITGUID
#include <d3d11.h>
-#include <d3dtypes.h>
/* avoided until we can pass ISwapchainPanel without c++/cx mode
# include <windows.ui.xaml.media.dxinterop.h> */
@@ -48,6 +47,9 @@
# define D3DCompile(args...) sys->OurD3DCompile(args)
#endif
+DEFINE_GUID(GUID_SWAPCHAIN_WIDTH, 0xf1b59347, 0x1643, 0x411a, 0xad, 0x6b, 0xc7, 0x80, 0x17, 0x7a, 0x06, 0xb6);
+DEFINE_GUID(GUID_SWAPCHAIN_HEIGHT, 0x6ea976a0, 0x9d60, 0x4bb7, 0xa5, 0xa9, 0x7d, 0xd1, 0x18, 0x7f, 0xc9, 0xbd);
+
static int Open(vlc_object_t *);
static void Close(vlc_object_t *);
@@ -66,9 +68,9 @@ vlc_module_begin ()
add_bool("direct3d11-hw-blending", true, HW_BLENDING_TEXT, HW_BLENDING_LONGTEXT, true)
#if VLC_WINSTORE_APP
- add_integer("winrt-d3ddevice", 0x0, NULL, NULL, true);
- add_integer("winrt-d3dcontext", 0x0, NULL, NULL, true);
- add_integer("winrt-dxgiswapchain", 0x0, NULL, NULL, true);
+ add_integer("winrt-d3ddevice", 0x0, NULL, NULL, true); /* ID3D11Device* */
+ add_integer("winrt-d3dcontext", 0x0, NULL, NULL, true); /* ID3D11DeviceContext* */
+ add_integer("winrt-swapchain", 0x0, NULL, NULL, true); /* IDXGISwapChain1* */
#endif
set_capability("vout display", 240)
@@ -128,10 +130,14 @@ typedef struct
/* matches the D3D11_INPUT_ELEMENT_DESC we setup */
typedef struct d3d_vertex_t {
- D3DVECTOR position;
struct {
- D3DVALUE x;
- D3DVALUE y;
+ FLOAT x;
+ FLOAT y;
+ FLOAT z;
+ } position;
+ struct {
+ FLOAT x;
+ FLOAT y;
} texture;
FLOAT opacity;
} d3d_vertex_t;
@@ -166,9 +172,10 @@ static void Direct3D11DeleteRegions(int, picture_t **);
static int Direct3D11MapSubpicture(vout_display_t *, int *, picture_t ***, subpicture_t *);
static int AllocQuad(vout_display_t *, const video_format_t *, d3d_quad_t *,
- d3d_quad_cfg_t *, ID3D11PixelShader *,
- const float vertices[4 * sizeof(d3d_vertex_t)]);
+ d3d_quad_cfg_t *, ID3D11PixelShader *);
static void ReleaseQuad(d3d_quad_t *);
+static void UpdatePicQuadPosition(vout_display_t *);
+static void UpdateQuadPosition(vout_display_t *, const d3d_quad_t *, const RECT *, int w, int h, float o);
static void Manage(vout_display_t *vd);
@@ -396,7 +403,7 @@ static int Open(vlc_object_t *object)
# endif
#else
- IDXGISwapChain1* dxgiswapChain = var_InheritInteger(vd, "winrt-dxgiswapchain");
+ IDXGISwapChain1* dxgiswapChain = var_InheritInteger(vd, "winrt-swapchain");
if (!dxgiswapChain)
return VLC_EGENERIC;
ID3D11Device* d3ddevice = var_InheritInteger(vd, "winrt-d3ddevice");
@@ -636,8 +643,22 @@ static HRESULT UpdateBackBuffer(vout_display_t *vd)
HRESULT hr;
ID3D11Texture2D* pDepthStencil;
ID3D11Texture2D* pBackBuffer;
- int i_width = RECTWidth(sys->rect_dest_clipped);
- int i_height = RECTHeight(sys->rect_dest_clipped);
+ uint32_t i_width = RECTWidth(sys->rect_dest_clipped);
+ uint32_t i_height = RECTHeight(sys->rect_dest_clipped);
+#if VLC_WINSTORE_APP
+ UINT dataSize = sizeof(i_width);
+ hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_WIDTH, &dataSize, &i_width);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Can't get swapchain width, size %d. (hr=0x%lX)", hr, dataSize);
+ return hr;
+ }
+ dataSize = sizeof(i_height);
+ hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_HEIGHT, &dataSize, &i_height);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Can't get swapchain height, size %d. (hr=0x%lX)", hr, dataSize);
+ return hr;
+ }
+#endif
if (sys->d3drenderTargetView) {
ID3D11RenderTargetView_Release(sys->d3drenderTargetView);
@@ -648,13 +669,6 @@ static HRESULT UpdateBackBuffer(vout_display_t *vd)
sys->d3ddepthStencilView = NULL;
}
-#if VLC_WINSTORE_APP
- DXGI_SWAP_CHAIN_DESC1 swapDesc;
- hr = IDXGISwapChain1_GetDesc1(sys->dxgiswapChain, &swapDesc);
- i_width = swapDesc.Width;
- i_height = swapDesc.Height;
-#endif
-
hr = IDXGISwapChain_ResizeBuffers(sys->dxgiswapChain, 0, i_width, i_height,
DXGI_FORMAT_UNKNOWN, 0);
if (FAILED(hr)) {
@@ -737,6 +751,8 @@ static void Manage(vout_display_t *vd)
RECTHeight(sys->rect_dest_clipped));
UpdateBackBuffer(vd);
+
+ UpdatePicQuadPosition(vd);
}
}
@@ -1145,6 +1161,30 @@ static void Direct3D11Close(vout_display_t *vd)
msg_Dbg(vd, "Direct3D11 device adapter closed");
}
+static void UpdatePicQuadPosition(vout_display_t *vd)
+{
+ vout_display_sys_t *sys = vd->sys;
+ int i_width = RECTWidth(sys->rect_dest_clipped);
+ int i_height = RECTHeight(sys->rect_dest_clipped);
+#if VLC_WINSTORE_APP
+ UINT dataSize = sizeof(i_width);
+ HRESULT hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_WIDTH, &dataSize, &i_width);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Can't get swapchain width, size %d. (hr=0x%lX)", hr, dataSize);
+ return hr;
+ }
+ dataSize = sizeof(i_height);
+ hr = IDXGISwapChain_GetPrivateData(sys->dxgiswapChain, &GUID_SWAPCHAIN_HEIGHT, &dataSize, &i_height);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Can't get swapchain height, size %d. (hr=0x%lX)", hr, dataSize);
+ return hr;
+ }
+#endif
+
+ /* Map the subpicture to sys->rect_dest_clipped */
+ UpdateQuadPosition(vd, &sys->picQuad, &sys->rect_dest_clipped, i_width, i_height, 1.0f);
+}
+
/* TODO : handle errors better
TODO : seperate out into smaller functions like createshaders */
static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
@@ -1333,20 +1373,15 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
}
}
- float vertices[4 * sizeof(d3d_vertex_t)] = {
- -1.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, // bottom left
- 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, // bottom right
- 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, // top right
- -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top left
- };
-
- if (AllocQuad( vd, fmt, &sys->picQuad, &sys->picQuadConfig, pPicQuadShader, vertices )!=VLC_SUCCESS) {
+ if (AllocQuad( vd, fmt, &sys->picQuad, &sys->picQuadConfig, pPicQuadShader) != VLC_SUCCESS) {
ID3D11PixelShader_Release(pPicQuadShader);
msg_Err(vd, "Could not Create the main quad picture. (hr=0x%lX)", hr);
return VLC_EGENERIC;
}
ID3D11PixelShader_Release(pPicQuadShader);
+ UpdatePicQuadPosition(vd);
+
D3D11_SAMPLER_DESC sampDesc;
memset(&sampDesc, 0, sizeof(sampDesc));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
@@ -1430,24 +1465,19 @@ static void Direct3D11DestroyPool(vout_display_t *vd)
}
static int AllocQuad(vout_display_t *vd, const video_format_t *fmt, d3d_quad_t *quad,
- d3d_quad_cfg_t *cfg, ID3D11PixelShader *d3dpixelShader,
- const float vertices[4 * sizeof(d3d_vertex_t)])
+ d3d_quad_cfg_t *cfg, ID3D11PixelShader *d3dpixelShader)
{
vout_display_sys_t *sys = vd->sys;
HRESULT hr;
D3D11_BUFFER_DESC bd;
memset(&bd, 0, sizeof(bd));
- bd.Usage = vertices==NULL ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
+ bd.Usage = D3D11_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(d3d_vertex_t) * 4;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
- bd.CPUAccessFlags = vertices==NULL ? D3D11_CPU_ACCESS_WRITE : 0;
-
- D3D11_SUBRESOURCE_DATA InitData = {
- .pSysMem = vertices,
- };
+ bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
- hr = ID3D11Device_CreateBuffer(sys->d3ddevice, &bd, vertices==NULL ? NULL : &InitData, &quad->pVertexBuffer);
+ hr = ID3D11Device_CreateBuffer(sys->d3ddevice, &bd, NULL, &quad->pVertexBuffer);
if(FAILED(hr)) {
msg_Err(vd, "Failed to create vertex buffer.");
goto error;
@@ -1571,6 +1601,60 @@ static void DestroyPictureQuad(picture_t *p_picture)
free( p_picture );
}
+static void UpdateQuadPosition(vout_display_t *vd, const d3d_quad_t *quad, const RECT *dst, int i_width, int i_height, float opacity)
+{
+ vout_display_sys_t *sys = vd->sys;
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+
+ // adjust with the center at 0,0 and the edges at -1/1
+ float left = -1.0f + 2.0f * ((float) dst->left / i_width );
+ float right = -1.0f + 2.0f * ((float) dst->right / i_width );
+ float top = 1.0f - 2.0f * ((float) dst->top / i_height );
+ float bottom = 1.0f - 2.0f * ((float) dst->bottom / i_height );
+
+ HRESULT hr = ID3D11DeviceContext_Map(sys->d3dcontext, (ID3D11Resource *)quad->pVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (SUCCEEDED(hr)) {
+ d3d_vertex_t *dst_data = mappedResource.pData;
+
+ // bottom left
+ dst_data[0].position.x = left;
+ dst_data[0].position.y = bottom;
+ dst_data[0].position.z = 0.0f;
+ dst_data[0].texture.x = 0.0f;
+ dst_data[0].texture.y = 1.0f;
+ dst_data[0].opacity = opacity;
+
+ // bottom right
+ dst_data[1].position.x = right;
+ dst_data[1].position.y = bottom;
+ dst_data[1].position.z = 0.0f;
+ dst_data[1].texture.x = 1.0f;
+ dst_data[1].texture.y = 1.0f;
+ dst_data[1].opacity = opacity;
+
+ // top right
+ dst_data[2].position.x = right;
+ dst_data[2].position.y = top;
+ dst_data[2].position.z = 0.0f;
+ dst_data[2].texture.x = 1.0f;
+ dst_data[2].texture.y = 0.0f;
+ dst_data[2].opacity = opacity;
+
+ // top left
+ dst_data[3].position.x = left;
+ dst_data[3].position.y = top;
+ dst_data[3].position.z = 0.0f;
+ dst_data[3].texture.x = 0.0f;
+ dst_data[3].texture.y = 0.0f;
+ dst_data[3].opacity = opacity;
+
+ ID3D11DeviceContext_Unmap(sys->d3dcontext, (ID3D11Resource *)quad->pVertexBuffer, 0);
+ }
+ else {
+ msg_Err(vd, "Failed to lock the subpicture vertex buffer (hr=0x%lX)", hr);
+ }
+}
+
static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_count,
picture_t ***region, subpicture_t *subpicture)
{
@@ -1619,7 +1703,7 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
.textureFormat = sys->d3dregion_format,
.resourceFormatYRGB = sys->d3dregion_format,
};
- err = AllocQuad(vd, &r->fmt, d3dquad, &rgbaCfg, sys->pSPUPixelShader, NULL);
+ err = AllocQuad(vd, &r->fmt, d3dquad, &rgbaCfg, sys->pSPUPixelShader);
if (err != VLC_SUCCESS) {
msg_Err(vd, "Failed to create %dx%d texture for OSD",
r->fmt.i_visible_width, r->fmt.i_visible_height);
@@ -1661,15 +1745,12 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
picture_CopyPixels(quad_picture, r->p_picture);
/* Map the subpicture to sys->rect_dest */
- RECT src;
- src.left = 0;
- src.right = src.left + r->fmt.i_visible_width;
- src.top = 0;
- src.bottom = src.top + r->fmt.i_visible_height;
+ int i_original_width = subpicture->i_original_picture_width;
+ int i_original_height = subpicture->i_original_picture_height;
const RECT video = sys->rect_dest;
- const float scale_w = (float)(video.right - video.left) / subpicture->i_original_picture_width;
- const float scale_h = (float)(video.bottom - video.top) / subpicture->i_original_picture_height;
+ const float scale_w = (float)(video.right - video.left) / i_original_width;
+ const float scale_h = (float)(video.bottom - video.top) / i_original_height;
RECT dst;
dst.left = video.left + scale_w * r->i_x,
@@ -1677,54 +1758,10 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
dst.top = video.top + scale_h * r->i_y,
dst.bottom = dst.top + scale_h * r->fmt.i_visible_height;
- // adjust with the center at 0,0 and the edges at -1/1
- float left = ((float)dst.left / subpicture->i_original_picture_width ) * 2.0f - 1.0f;
- float right = ((float)dst.right / subpicture->i_original_picture_width ) * 2.0f - 1.0f;
- float top = 1.0f - 2.0f * dst.top / subpicture->i_original_picture_height;
- float bottom = 1.0f - 2.0f * dst.bottom / subpicture->i_original_picture_height;
-
float opacity = (float)r->i_alpha / 255.0f;
- hr = ID3D11DeviceContext_Map(sys->d3dcontext, (ID3D11Resource *)((d3d_quad_t *) quad_picture->p_sys)->pVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
- if( SUCCEEDED(hr) ) {
- d3d_vertex_t *dst_data = mappedResource.pData;
-
- // bottom left
- dst_data[0].position.x = left;
- dst_data[0].position.y = bottom;
- dst_data[0].position.z = 0.0f;
- dst_data[0].texture.x = 0.0f;
- dst_data[0].texture.y = 1.0f;
- dst_data[0].opacity = opacity;
-
- // bottom right
- dst_data[1].position.x = right;
- dst_data[1].position.y = bottom;
- dst_data[1].position.z = 0.0f;
- dst_data[1].texture.x = 1.0f;
- dst_data[1].texture.y = 1.0f;
- dst_data[1].opacity = opacity;
-
- // top right
- dst_data[2].position.x = right;
- dst_data[2].position.y = top;
- dst_data[2].position.z = 0.0f;
- dst_data[2].texture.x = 1.0f;
- dst_data[2].texture.y = 0.0f;
- dst_data[2].opacity = opacity;
-
- // top left
- dst_data[3].position.x = left;
- dst_data[3].position.y = top;
- dst_data[3].position.z = 0.0f;
- dst_data[3].texture.x = 0.0f;
- dst_data[3].texture.y = 0.0f;
- dst_data[3].opacity = opacity;
-
- ID3D11DeviceContext_Unmap(sys->d3dcontext, (ID3D11Resource *)((d3d_quad_t *) quad_picture->p_sys)->pVertexBuffer, 0);
- } else {
- msg_Err(vd, "Failed to lock the subpicture vertex buffer (hr=0x%lX)", hr );
- }
+ UpdateQuadPosition(vd, (d3d_quad_t *)quad_picture->p_sys, &dst,
+ i_original_width, i_original_height, opacity);
}
return VLC_SUCCESS;
}
--
2.4.2
More information about the vlc-devel
mailing list