[vlc-devel] [PATCH 3/8] direct3d9: handle external callbacks to render into an external surface
Steve Lhomme
robux4 at ycbcr.xyz
Mon Jan 21 17:38:46 CET 2019
Instead of the device backbuffer.
---
modules/video_output/win32/direct3d9.c | 90 +++++++++++++++++---------
1 file changed, 58 insertions(+), 32 deletions(-)
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index 6e3bcb799e..0f3d85c47b 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -161,11 +161,8 @@ struct vout_display_sys_t
atomic_bool new_desktop_mode;
/* outside rendering */
- void *outside_opaque;
- void (*swapCb)(void* opaque);
- void (*endRenderCb)(void* opaque);
- bool (*starRenderCb)(void* opaque);
- bool (*resizeCb)(void* opaque, unsigned, unsigned);
+ void *outside_opaque;
+ vlc_video_surface_control ctrlCb;
};
/* */
@@ -582,9 +579,10 @@ static int Direct3D9CreateScene(vout_display_t *vd, const video_format_t *fmt)
IDirect3DDevice9 *d3ddev = p_d3d9_dev->dev;
HRESULT hr;
- if (sys->resizeCb && !sys->resizeCb( sys->outside_opaque,
- fmt->i_visible_width,
- fmt->i_visible_height ))
+ vlc_video_surface_cfg_t cfg;
+ cfg.width = fmt->i_visible_width;
+ cfg.height = fmt->i_visible_height;
+ if (!vlc_video_surface_update_output( sys->outside_opaque, sys->ctrlCb, &cfg ))
{
msg_Err(vd, "Failed to set the external render size");
return VLC_EGENERIC;
@@ -1162,9 +1160,8 @@ static int Direct3D9RenderRegion(vout_display_t *vd,
return 0;
}
-static bool StartRendering(void *opaque)
+static bool StartRendering(vout_display_t *vd)
{
- vout_display_t *vd = opaque;
vout_display_sys_t *sys = vd->sys;
IDirect3DDevice9 *d3ddev = sys->d3d_dev.dev;
HRESULT hr;
@@ -1189,9 +1186,8 @@ static bool StartRendering(void *opaque)
return true;
}
-static void EndRendering(void *opaque)
+static void EndRendering(vout_display_t *vd)
{
- vout_display_t *vd = opaque;
vout_display_sys_t *sys = vd->sys;
IDirect3DDevice9 *d3ddev = sys->d3d_dev.dev;
HRESULT hr;
@@ -1216,7 +1212,7 @@ static void Direct3D9RenderScene(vout_display_t *vd,
vout_display_sys_t *sys = vd->sys;
IDirect3DDevice9 *d3ddev = sys->d3d_dev.dev;
- if (!sys->starRenderCb(sys->outside_opaque))
+ if (!vlc_video_surface_start_rendering( sys->outside_opaque, sys->ctrlCb ))
return;
Direct3D9RenderRegion(vd, picture, true);
@@ -1232,7 +1228,7 @@ static void Direct3D9RenderScene(vout_display_t *vd,
IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHABLENDENABLE, FALSE);
}
- sys->endRenderCb(sys->outside_opaque);
+ vlc_video_surface_finished_rendering( sys->outside_opaque, sys->ctrlCb );
}
static void Prepare(vout_display_t *vd, picture_t *picture,
@@ -1314,9 +1310,8 @@ static void Prepare(vout_display_t *vd, picture_t *picture,
}
}
-static void Swap(void *opaque)
+static void Swap(vout_display_t *vd)
{
- vout_display_t *vd = opaque;
vout_display_sys_t *sys = vd->sys;
const d3d9_device_t *p_d3d9_dev = &sys->d3d_dev;
@@ -1343,7 +1338,7 @@ static void Display(vout_display_t *vd, picture_t *picture)
if (sys->lost_not_ready)
return;
- sys->swapCb(sys->outside_opaque);
+ vlc_video_surface_swap( sys->outside_opaque, sys->ctrlCb );
/* XXX See Prepare() */
if ( !is_d3d9_opaque(picture->format.i_chroma) )
@@ -1364,6 +1359,8 @@ static void Direct3D9Destroy(vout_display_sys_t *sys)
FreeLibrary(sys->hxdll);
sys->hxdll = NULL;
}
+
+ vlc_video_surface_cleanup( sys->outside_opaque, sys->ctrlCb );
}
/**
@@ -1612,6 +1609,35 @@ static int FindShadersCallback(const char *name, char ***values, char ***descs)
}
+static int LocalRender(void* opaque, vlc_video_surface_control_t control, const void *input, void **output)
+{
+ vout_display_t *vd = opaque;
+ switch (control)
+ {
+ case VLC_VIDEO_SURFACE_SETUP:
+ return -1; /* don't used an "external" D3D9 device */
+ case VLC_VIDEO_SURFACE_CLEANUP:
+ case VLC_VIDEO_SURFACE_UPDATE_OUTPUT:
+ /* DO NOTHING */
+ break;
+ case VLC_VIDEO_SURFACE_SWAP:
+ Swap(vd);
+ break;
+ case VLC_VIDEO_SURFACE_START_RENDER:
+ if (!StartRendering(vd))
+ return -1;
+ break;
+ case VLC_VIDEO_SURFACE_FINISHED_RENDERING:
+ EndRendering(vd);
+ break;
+ case VLC_VIDEO_SURFACE_MAKE_CURRENT:
+ case VLC_VIDEO_SURFACE_GET_PROCADDRESS:
+ /* ignore OpenGL specific controls */
+ break;
+ }
+ return 0;
+}
+
/**
* It creates a Direct3D vout display.
*/
@@ -1642,10 +1668,20 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
if (!sys)
return VLC_ENOMEM;
- IDirect3DDevice9 *d3d9_device = var_InheritAddress(vd, "vout-engine-ctx");
- if (d3d9_device != NULL)
+ sys->outside_opaque = var_InheritAddress(vd, "vout-cb-opaque");
+ sys->ctrlCb = var_InheritAddress(vd, "vout-cb-control");
+
+ if ( sys->ctrlCb == NULL )
+ {
+ /* use our own callbacks, since there isn't any external ones */
+ sys->outside_opaque = vd;
+ sys->ctrlCb = LocalRender;
+ }
+
+ IDirect3DDevice9 *external_device = vlc_video_surface_setup( sys->outside_opaque, sys->ctrlCb );
+ if (external_device != NULL)
{
- if (D3D9_CreateExternal(vd, &sys->hd3d, d3d9_device)) {
+ if (D3D9_CreateExternal(vd, &sys->hd3d, external_device)) {
msg_Err(vd, "External Direct3D9 could not be used");
free(sys);
return VLC_EGENERIC;
@@ -1657,16 +1693,6 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
return VLC_EGENERIC;
}
- if (!sys->swapCb || !sys->starRenderCb || !sys->endRenderCb)
- {
- /* use our own callbacks, since there isn't any external ones */
- sys->outside_opaque = vd;
- sys->swapCb = Swap;
- sys->starRenderCb = StartRendering;
- sys->endRenderCb = EndRendering;
- sys->resizeCb = NULL;
- }
-
sys->hxdll = Direct3D9LoadShaderLibrary();
if (!sys->hxdll)
msg_Warn(vd, "cannot load Direct3D9 Shader Library; HLSL pixel shading will be disabled.");
@@ -1678,12 +1704,12 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
sys->desktop_save.is_fullscreen = cfg->is_fullscreen;
sys->desktop_save.is_on_top = false;
- if (CommonInit(vd, d3d9_device != NULL, cfg))
+ if (CommonInit(vd, external_device != NULL, cfg))
goto error;
/* */
video_format_t fmt;
- if (Direct3D9Open(vd, &fmt, d3d9_device)) {
+ if (Direct3D9Open(vd, &fmt, external_device)) {
msg_Err(vd, "Direct3D9 could not be opened");
goto error;
}
--
2.17.1
More information about the vlc-devel
mailing list