[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