static void End ( vout_thread_t * );
static int Manage ( vout_thread_t * );
static void Display ( vout_thread_t *, picture_t * );
+static void FirstDisplay( vout_thread_t *, picture_t * );
static int Direct3DVoutCreate ( vout_thread_t * );
static void Direct3DVoutRelease ( vout_thread_t * );
p_vout->pf_end = End;
p_vout->pf_manage = Manage;
p_vout->pf_render = Direct3DVoutRenderScene;
- p_vout->pf_display = Display;
+ p_vout->pf_display = FirstDisplay;
p_vout->p_sys->hwnd = p_vout->p_sys->hvideownd = NULL;
p_vout->p_sys->hparent = p_vout->p_sys->hfswnd = NULL;
HRESULT hr = IDirect3DDevice9_Present(p_d3ddev, NULL, NULL, NULL, NULL);
if( FAILED(hr) )
msg_Dbg( p_vout, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
+}
- /* if set, remove the black brush to avoid flickering in repaint operations */
- if( 0UL != GetClassLong( p_vout->p_sys->hvideownd, GCL_HBRBACKGROUND) )
- {
- SetClassLong( p_vout->p_sys->hvideownd, GCL_HBRBACKGROUND, 0UL);
- }
+/*
+** this function is only used once when the first picture is received
+** this function will show the video window once a picture is ready
+*/
+
+static void FirstDisplay( vout_thread_t *p_vout, picture_t *p_pic )
+{
+ /* get initial picture presented through D3D */
+ Display(p_vout, p_pic);
+
+ /*
+ ** Video window is initially hidden, show it now since we got a
+ ** picture to show.
+ */
+ SetWindowPos( p_vout->p_sys->hvideownd, NULL, 0, 0, 0, 0,
+ SWP_ASYNCWINDOWPOS|
+ SWP_FRAMECHANGED|
+ SWP_SHOWWINDOW|
+ SWP_NOMOVE|
+ SWP_NOSIZE|
+ SWP_NOZORDER );
+
+ /* use and restores proper display function for further pictures */
+ p_vout->pf_display = Display;
}
/*****************************************************************************
static void End ( vout_thread_t * );
static int Manage ( vout_thread_t * );
static void Display ( vout_thread_t *, picture_t * );
-static void OverlayDisplay( vout_thread_t *, picture_t * );
+static void FirstDisplay( vout_thread_t *, picture_t * );
static void SetPalette( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * );
static int NewPictureVec ( vout_thread_t *, picture_t *, int );
p_vout->pf_end = End;
p_vout->pf_manage = Manage;
p_vout->pf_render = NULL;
- p_vout->pf_display = Display;
+ p_vout->pf_display = FirstDisplay;
p_vout->p_sys->p_ddobject = NULL;
p_vout->p_sys->p_display = NULL;
NewPictureVec( p_vout, p_vout->p_picture, MAX_DIRECTBUFFERS );
}
- if( p_vout->p_sys->b_using_overlay )
- {
- p_vout->pf_display = OverlayDisplay;
- }
-
/* Change the window title bar text */
PostMessage( p_vout->p_sys->hwnd, WM_VLC_CHANGE_TEXT, 0, 0 );
msg_Warn( p_vout, "could not blit surface (error %li)", dxresult );
return;
}
- else
- {
- /* if set, remove the black brush to avoid flickering in repaint operations */
- if( 0UL != GetClassLong( p_vout->p_sys->hvideownd, GCL_HBRBACKGROUND) )
- {
- SetClassLong(p_vout->p_sys->hvideownd, GCL_HBRBACKGROUND, (ULONG)0UL);
- }
- }
-
}
else /* using overlay */
{
/*
** this function is only used once when the first picture is received
-** The overlay colorkey replaces black as the background color on the
-** video window; this will cause the overlay surface to be displayed
+** this function will show the video window once video is ready for
+** display.
*/
-static void OverlayDisplay( vout_thread_t *p_vout, picture_t *p_pic )
+
+static void FirstDisplay( vout_thread_t *p_vout, picture_t *p_pic )
{
/* get initial picture rendered on overlay surface */
Display(p_vout, p_pic);
IDirectDraw_WaitForVerticalBlank(p_vout->p_sys->p_ddobject,
DDWAITVB_BLOCKBEGIN, NULL);
- /* set the colorkey as the backgound brush for the video window */
- SetClassLong( p_vout->p_sys->hvideownd, GCL_HBRBACKGROUND,
- (LONG)CreateSolidBrush( p_vout->p_sys->i_rgb_colorkey ) );
- InvalidateRect( p_vout->p_sys->hvideownd, NULL, TRUE );
+ if( p_vout->p_sys->b_using_overlay )
+ {
+ /* set the colorkey as the backgound brush for the video window */
+ SetClassLong( p_vout->p_sys->hvideownd, GCL_HBRBACKGROUND,
+ (LONG)CreateSolidBrush( p_vout->p_sys->i_rgb_colorkey ) );
+ }
+ /*
+ ** Video window is initially hidden, show it now since we got a
+ ** picture to show.
+ */
+ SetWindowPos( p_vout->p_sys->hvideownd, NULL, 0, 0, 0, 0,
+ SWP_ASYNCWINDOWPOS|
+ SWP_FRAMECHANGED|
+ SWP_SHOWWINDOW|
+ SWP_NOMOVE|
+ SWP_NOSIZE|
+ SWP_NOZORDER );
/* use and restores proper display function for further pictures */
p_vout->pf_display = Display;
p_vout->p_sys->i_rgb_colorkey =
DirectXFindColorkey( p_vout, &p_vout->p_sys->i_colorkey );
- /* use black brush as the video background color,
- if overlay video is used, this will be replaced by the
- colorkey when the first picture is received */
- SetClassLong( p_vout->p_sys->hvideownd, GCL_HBRBACKGROUND,
- (LONG)GetStockObject( BLACK_BRUSH ) );
- InvalidateRect( p_vout->p_sys->hvideownd, NULL, TRUE );
E_(DirectXUpdateRects)( p_vout, VLC_TRUE );
return VLC_SUCCESS;
/* Register the video sub-window class */
wc.lpszClassName = _T("VLC DirectX video"); wc.hIcon = 0;
+ wc.hbrBackground = NULL; /* no background color */
if( !RegisterClass(&wc) )
{
WNDCLASS wndclass;
* without having them shown outside of the video area. */
p_vout->p_sys->hvideownd =
CreateWindow( _T("VLC DirectX video"), _T(""), /* window class */
- WS_CHILD | WS_VISIBLE, /* window style */
+ WS_CHILD, /* window style, not visible initially */
0, 0,
p_vout->render.i_width, /* default width */
p_vout->render.i_height, /* default height */
(LPVOID)p_vout ); /* send p_vout to WM_CREATE */
if( !p_vout->p_sys->hvideownd )
- msg_Warn( p_vout, "can't create video sub-window" );
+ msg_Warn( p_vout, "can't create video sub-window" );
else
- msg_Dbg( p_vout, "created video sub-window" );
+ msg_Dbg( p_vout, "created video sub-window" );
/* Now display the window */
ShowWindow( p_vout->p_sys->hwnd, SW_SHOW );
{
switch( message )
{
+#ifdef MODULE_NAME_IS_vout_directx
case WM_ERASEBKGND:
- // erase the background only if a brush is set
- return ( 0UL == GetClassLong( hwnd, GCL_HBRBACKGROUND) ) ?
+ /* For overlay, we need to erase background */
+ return !p_vout->p_sys->b_using_overlay ?
1 : DefWindowProc(hwnd, message, wParam, lParam);
case WM_PAINT:
- if( 0UL == GetClassLong( hwnd, GCL_HBRBACKGROUND) )
+ /*
+ ** For overlay, DefWindowProc() will erase dirty regions
+ ** with colorkey.
+ ** For non-overlay, vout will paint the whole window at
+ ** regular interval, therefore dirty regions can be ignored
+ ** to minimize repaint.
+ */
+ if( !p_vout->p_sys->b_using_overlay )
{
- // vout paints the whole area, no need to repaint it
ValidateRect(hwnd, NULL);
}
+ // fall through to default
+#else
+ /*
+ ** For OpenGL and Direct3D, vout will update the whole
+ ** window at regular interval, therefore dirty region
+ ** can be ignored to minimize repaint.
+ */
+ case WM_ERASEBKGND:
+ /* nothing to erase */
+ return 1;
+ case WM_PAINT:
+ /* nothing to repaint */
+ ValidateRect(hwnd, NULL);
// fall through
+#endif
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
static void End ( vout_thread_t * );
static int Manage ( vout_thread_t * );
static void GLSwapBuffers( vout_thread_t * );
+static void FirstSwap( vout_thread_t * );
/*****************************************************************************
* Module descriptor
p_vout->pf_init = Init;
p_vout->pf_end = End;
p_vout->pf_manage = Manage;
- p_vout->pf_swap = GLSwapBuffers;
+ p_vout->pf_swap = FirstSwap;
p_vout->p_sys->hwnd = p_vout->p_sys->hvideownd = NULL;
p_vout->p_sys->hparent = p_vout->p_sys->hfswnd = NULL;
{
SwapBuffers( p_vout->p_sys->hGLDC );
}
+
+/*
+** this function is only used once when the first picture is received
+** this function will show the video window once a picture is ready
+*/
+
+static void FirstSwap( vout_thread_t *p_vout )
+{
+ /* get initial picture buffer swapped to front buffer */
+ GLSwapBuffers( p_vout );
+
+ /*
+ ** Video window is initially hidden, show it now since we got a
+ ** picture to show.
+ */
+ SetWindowPos( p_vout->p_sys->hvideownd, NULL, 0, 0, 0, 0,
+ SWP_ASYNCWINDOWPOS|
+ SWP_FRAMECHANGED|
+ SWP_SHOWWINDOW|
+ SWP_NOMOVE|
+ SWP_NOSIZE|
+ SWP_NOZORDER );
+
+ /* use and restores proper swap function for further pictures */
+ p_vout->pf_swap = GLSwapBuffers;
+}