mirror of https://code.videolan.org/videolan/vlc
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.
This commit is contained in:
parent
cfaa0bdfe6
commit
303cbe6c89
|
@ -45,48 +45,6 @@ struct CUSTOMVERTEX {FLOAT X, Y, Z, RHW; DWORD COLOR;
|
|||
FLOAT tu, tv; /* texture relative coordinates */};
|
||||
#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.
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1167,44 +1167,6 @@ static int Direct3D9RenderRegion(vout_display_t *vd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool StartRendering(vout_display_t *vd)
|
||||
{
|
||||
vout_display_sys_t *sys = vd->sys;
|
||||
IDirect3DDevice9 *d3ddev = sys->d3d_dev.dev;
|
||||
HRESULT hr;
|
||||
|
||||
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;
|
||||
}
|
||||
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.
|
||||
*
|
||||
|
@ -1218,10 +1180,28 @@ static void Direct3D9RenderScene(vout_display_t *vd,
|
|||
{
|
||||
vout_display_sys_t *sys = vd->sys;
|
||||
IDirect3DDevice9 *d3ddev = sys->d3d_dev.dev;
|
||||
HRESULT hr;
|
||||
|
||||
if (!sys->startEndRenderingCb( sys->outside_opaque, true, NULL ))
|
||||
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;
|
||||
}
|
||||
sys->clear_scene = false;
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_BeginScene(d3ddev);
|
||||
if (FAILED(hr)) {
|
||||
msg_Dbg(vd, "Failed BeginScene: 0x%lX", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
Direct3D9RenderRegion(vd, picture, true);
|
||||
|
||||
if (subpicture_count)
|
||||
|
@ -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 = {
|
||||
|
|
Loading…
Reference in New Issue