[vlc-commits] direct3d9: factorize the code that is always common with local/host rendering
Steve Lhomme
git at videolan.org
Wed Jun 26 15:48:36 CEST 2019
vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Tue Jun 11 15:39:58 2019 +0200| [303cbe6c89fe9306aac839bb4ab05cde99ae7255] | committer: Steve Lhomme
direct3d9: factorize the code that is always common with local/host rendering
The clear/begin/end scene is always done on our local IDirect3DDevice9. No need
to force the host to do it a second time.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=303cbe6c89fe9306aac839bb4ab05cde99ae7255
---
doc/libvlc/d3d9_player.c | 61 ++++++++--------------------
modules/video_output/win32/direct3d9.c | 72 +++++++++++-----------------------
2 files changed, 39 insertions(+), 94 deletions(-)
diff --git a/doc/libvlc/d3d9_player.c b/doc/libvlc/d3d9_player.c
index 0333702e0d..41745614a6 100644
--- a/doc/libvlc/d3d9_player.c
+++ b/doc/libvlc/d3d9_player.c
@@ -46,48 +46,6 @@ struct CUSTOMVERTEX {FLOAT X, Y, Z, RHW; DWORD COLOR;
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)
/**
- * Callback called just before VLC starts drawing the video.
- *
- * Set the surface VLC will render to (could be the backbuffer if nothing else
- * needs to be displayed). And then call BeginScene().
- *
- * This is called outside of the UI thread (in the VLC rendering thread).
- */
-static bool StartRender(struct render_context *ctx)
-{
- HRESULT hr;
-
- hr = IDirect3DDevice9_SetRenderTarget(ctx->libvlc_d3d, 0, ctx->sharedRenderSurface);
- if (FAILED(hr)) return false;
-
- /* clear the vlc destination texture to black alternatively */
- hr = IDirect3DDevice9_Clear(ctx->libvlc_d3d, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
- if (FAILED(hr)) return false;
-
- hr = IDirect3DDevice9_BeginScene(ctx->libvlc_d3d);
- if (hr == D3DERR_DEVICENOTRESET)
- {
- /* TODO reset the device, this may not work with hardware decoding */
- return false;
- }
- if (FAILED(hr)) return false;
-
- return true;
-}
-
-/**
- * Callback called after VLC has finished drawing the video.
- *
- * This is called outside of the UI thread (in the VLC rendering thread).
- */
-static void EndRender(struct render_context *ctx)
-{
- IDirect3DDevice9_EndScene(ctx->libvlc_d3d);
-
- IDirect3DDevice9_Present(ctx->libvlc_d3d, NULL, NULL, NULL, NULL);
-}
-
-/**
* Callback called when it's time to display the video, in sync with the audio.
*
* This is called outside of the UI thread (in the VLC rendering thread).
@@ -173,6 +131,9 @@ static bool Resize(struct render_context *ctx, unsigned width, unsigned height,
if (FAILED(hr))
return false;
+ hr = IDirect3DDevice9_SetRenderTarget(ctx->libvlc_d3d, 0, ctx->sharedRenderSurface);
+ if (FAILED(hr)) return false;
+
out->surface_format = d3ddm.Format;
out->full_range = true;
out->colorspace = libvlc_video_colorspace_BT709;
@@ -286,15 +247,27 @@ static void Swap_cb( void* opaque )
Swap( ctx );
}
+/**
+ * Callback called just before VLC starts/finishes drawing the video.
+ *
+ * Set the surface VLC will render to (could be the backbuffer if nothing else
+ * needs to be displayed). And then call BeginScene().
+ *
+ * This is called outside of the UI thread (in the VLC rendering thread).
+ */
static bool StartRendering_cb( void *opaque, bool enter, const libvlc_video_direct3d_hdr10_metadata_t *hdr10 )
{
struct render_context *ctx = opaque;
if ( enter )
{
- return StartRender( ctx );
+ /* we already set the RenderTarget on the IDirect3DDevice9 */
+ return true;
}
- EndRender( ctx );
+ /* VLC has finished preparing drawning on our surface, we need do the drawing now
+ so the surface is finished rendering when Swap() is called to do our own
+ rendering */
+ IDirect3DDevice9_Present(ctx->libvlc_d3d, NULL, NULL, NULL, NULL);
return true;
}
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index a0aee23101..b0fe0343dd 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -1167,60 +1167,40 @@ static int Direct3D9RenderRegion(vout_display_t *vd,
return 0;
}
-static bool StartRendering(vout_display_t *vd)
+/**
+ * It renders the scene.
+ *
+ * This function is intented for higher end 3D cards, with pixel shader support
+ * and at least 64 MiB of video RAM.
+ */
+static void Direct3D9RenderScene(vout_display_t *vd,
+ d3d_region_t *picture,
+ size_t subpicture_count,
+ d3d_region_t *subpicture)
{
vout_display_sys_t *sys = vd->sys;
IDirect3DDevice9 *d3ddev = sys->d3d_dev.dev;
HRESULT hr;
+ if (sys->startEndRenderingCb && !sys->startEndRenderingCb( sys->outside_opaque, true, NULL ))
+ return;
+
if (sys->clear_scene) {
/* Clear the backbuffer and the zbuffer */
hr = IDirect3DDevice9_Clear(d3ddev, 0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
if (FAILED(hr)) {
msg_Dbg(vd, "Failed Clear: 0x%lX", hr);
- return false;
+ return;
}
sys->clear_scene = false;
}
- // Begin the scene
hr = IDirect3DDevice9_BeginScene(d3ddev);
if (FAILED(hr)) {
msg_Dbg(vd, "Failed BeginScene: 0x%lX", hr);
- return false;
- }
- return true;
-}
-
-static void EndRendering(vout_display_t *vd)
-{
- vout_display_sys_t *sys = vd->sys;
- IDirect3DDevice9 *d3ddev = sys->d3d_dev.dev;
- HRESULT hr;
-
- // End the scene
- hr = IDirect3DDevice9_EndScene(d3ddev);
- if (FAILED(hr))
- msg_Dbg(vd, "Failed EndScene: 0x%lX", hr);
-}
-
-/**
- * It renders the scene.
- *
- * This function is intented for higher end 3D cards, with pixel shader support
- * and at least 64 MiB of video RAM.
- */
-static void Direct3D9RenderScene(vout_display_t *vd,
- d3d_region_t *picture,
- size_t subpicture_count,
- d3d_region_t *subpicture)
-{
- vout_display_sys_t *sys = vd->sys;
- IDirect3DDevice9 *d3ddev = sys->d3d_dev.dev;
-
- if (!sys->startEndRenderingCb( sys->outside_opaque, true, NULL ))
return;
+ }
Direct3D9RenderRegion(vd, picture, true);
@@ -1235,7 +1215,12 @@ static void Direct3D9RenderScene(vout_display_t *vd,
IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHABLENDENABLE, FALSE);
}
- sys->startEndRenderingCb( sys->outside_opaque, false, NULL );
+ hr = IDirect3DDevice9_EndScene(d3ddev);
+ if (FAILED(hr))
+ msg_Dbg(vd, "Failed EndScene: 0x%lX", hr);
+
+ if (sys->startEndRenderingCb)
+ sys->startEndRenderingCb( sys->outside_opaque, false, NULL );
}
static void Prepare(vout_display_t *vd, picture_t *picture,
@@ -1648,19 +1633,6 @@ static void LocalSwapchainSwap( void *opaque )
Swap( vd );
}
-static bool LocalSwapchainStartEndRendering( void *opaque, bool enter, const libvlc_video_direct3d_hdr10_metadata_t *p_hdr10 )
-{
- VLC_UNUSED(p_hdr10);
- vout_display_t *vd = opaque;
- if ( enter )
- {
- return StartRendering( vd );
- }
-
- EndRendering( vd );
- return true;
-}
-
/**
* It creates a Direct3D vout display.
*/
@@ -1711,7 +1683,7 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
sys->cleanupDeviceCb = LocalSwapchainCleanupDevice;
sys->updateOutputCb = LocalSwapchainUpdateOutput;
sys->swapCb = LocalSwapchainSwap;
- sys->startEndRenderingCb = LocalSwapchainStartEndRendering;
+ sys->startEndRenderingCb = NULL;
}
libvlc_video_direct3d_device_cfg_t surface_cfg = {
More information about the vlc-commits
mailing list