summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@mplayer2.org>2011-11-04 07:33:51 +0100
committerwm4 <wm4@mplayer2.org>2012-03-17 21:05:38 +0100
commit5ee7797bf840c2ad4a4e0a864ac65a46a55978ed (patch)
treef3204edd9924d79dd2227fedb4524cb6aeb5acda
parent1eaf5d262607fdce6f525e0b53c5d76fb23dc84a (diff)
downloadmpv-5ee7797bf840c2ad4a4e0a864ac65a46a55978ed.tar.bz2
mpv-5ee7797bf840c2ad4a4e0a864ac65a46a55978ed.tar.xz
vo_direct3d: use new VO API, and do some minor reformatting
The minor reformats are mainly about adding more line breaks to fit a 80 column limit. Using the new VO API implies removing all non-const global variables (because that is one important goal of the new API), so do that as well. The code already had all variables in a context struct, and changing all the functions to pass this context struct along was all what had to be done. Also handle redrawing properly: if something changes that requires an immediate redrawing operation (e.g. setting video equalizers when paused or when playback is slow), vo->want_redraw should be set, instead of redrawing on your own.
-rw-r--r--libvo/vo_direct3d.c567
1 files changed, 298 insertions, 269 deletions
diff --git a/libvo/vo_direct3d.c b/libvo/vo_direct3d.c
index 79c91cbea3..c7529dadd0 100644
--- a/libvo/vo_direct3d.c
+++ b/libvo/vo_direct3d.c
@@ -31,8 +31,11 @@
#include "subopt-helper.h"
#include "talloc.h"
#include "video_out.h"
-#include "video_out_internal.h"
+#include "libmpcodecs/vfcap.h"
+// for global_vo
+#include "old_vo_wrapper.h"
#include "csputils.h"
+#include "libmpcodecs/mp_image.h"
#include "libmpcodecs/img_format.h"
#include "fastmemcpy.h"
#include "mp_msg.h"
@@ -64,12 +67,6 @@ static const vo_info_t info =
#define DEVTYPE D3DDEVTYPE_HAL
//#define DEVTYPE D3DDEVTYPE_REF
-/*
- * Link essential libvo functions: preinit, config, control, draw_frame,
- * draw_slice, draw_osd, flip_page, check_events, uninit and
- * the structure info.
- */
-const LIBVO_EXTERN(direct3d)
#define D3DFVF_OSD_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1)
@@ -94,6 +91,7 @@ typedef struct {
float t[3][2];
} vertex_video;
+
struct d3dtex {
// user-requested size
int w, h;
@@ -128,7 +126,7 @@ struct texplane {
/* Global variables "priv" structure. I try to keep their count low.
*/
-static struct global_priv {
+typedef struct d3d_priv {
int opt_prefer_stretchrect;
int opt_disable_textures;
int opt_disable_stretchrect;
@@ -137,8 +135,8 @@ static struct global_priv {
int opt_disable_eosd;
int opt_disable_texture_align;
- int is_paused; /**< 1 = Movie is paused,
- 0 = Movie is not paused */
+ struct vo *vo;
+
int is_clear_needed; /**< 1 = Clear the backbuffer before StretchRect
0 = (default) Don't clear it */
D3DLOCKED_RECT locked_rect; /**< The locked offscreen surface */
@@ -199,7 +197,7 @@ static struct global_priv {
struct eosd_packer *eosd; /**< EOSD packer (image positions etc.) */
vertex_eosd *eosd_vb; /**< temporary memory for D3D when rendering EOSD */
-} *priv;
+} d3d_priv;
struct fmt_entry {
const unsigned int mplayer_fmt; /**< Given by MPlayer */
@@ -237,11 +235,18 @@ typedef enum back_buffer_action {
BACKBUFFER_RESET
} back_buffer_action_e;
-static void generate_eosd(mp_eosd_images_t *);
-static void draw_eosd(void);
-static void update_colorspace(void);
-static void d3d_clear_video_textures(void);
-static int resize_d3d(void);
+static void generate_eosd(d3d_priv *priv, mp_eosd_images_t *);
+static void draw_eosd(d3d_priv *priv);
+static void update_colorspace(d3d_priv *priv);
+static void d3d_clear_video_textures(d3d_priv *priv);
+static int resize_d3d(d3d_priv *priv);
+static uint32_t d3d_draw_frame(d3d_priv *priv);
+static int draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h,
+ int x, int y);
+static void uninit(struct vo *vo);
+static void draw_osd(struct vo *vo, struct osd_state *osd);
+static void flip_page(struct vo *vo);
+
static void d3d_matrix_identity(D3DMATRIX *m)
{
@@ -272,7 +277,7 @@ static void d3d_matrix_ortho(D3DMATRIX *m, float left, float right,
* *
****************************************************************************/
-static bool d3d_begin_scene(void)
+static bool d3d_begin_scene(d3d_priv *priv)
{
if (!priv->d3d_in_scene) {
if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) {
@@ -287,12 +292,13 @@ static bool d3d_begin_scene(void)
/** @brief Calculate scaled fullscreen movie rectangle with
* preserved aspect ratio.
*/
-static void calc_fs_rect(void)
+static void calc_fs_rect(d3d_priv *priv)
{
struct vo_rect src_rect;
struct vo_rect dst_rect;
struct vo_rect borders;
- calc_src_dst_rects(priv->src_width, priv->src_height, &src_rect, &dst_rect, &borders, NULL);
+ calc_src_dst_rects(priv->vo, priv->src_width, priv->src_height, &src_rect,
+ &dst_rect, &borders, NULL);
priv->fs_movie_rect.left = dst_rect.left;
priv->fs_movie_rect.right = dst_rect.right;
@@ -306,7 +312,7 @@ static void calc_fs_rect(void)
priv->border_y = borders.top;
mp_msg(MSGT_VO, MSGL_V,
- "<vo_direct3d>Fullscreen movie rectangle: t: %ld, l: %ld, r: %ld, b:%ld\n",
+ "<vo_direct3d>Video rectangle: t: %ld, l: %ld, r: %ld, b:%ld\n",
priv->fs_movie_rect.top, priv->fs_movie_rect.left,
priv->fs_movie_rect.right, priv->fs_movie_rect.bottom);
@@ -319,8 +325,7 @@ static void calc_fs_rect(void)
// Adjust the texture size *width/*height to fit the requirements of the D3D
// device. The texture size is only increased.
-// xxx make clear what happens when exceeding max_texture_width/height
-static void d3d_fix_texture_size(int *width, int *height)
+static void d3d_fix_texture_size(d3d_priv *priv, int *width, int *height)
{
int tex_width = *width;
int tex_height = *height;
@@ -337,7 +342,7 @@ static void d3d_fix_texture_size(int *width, int *height)
}
if (priv->device_caps_square_only)
/* device only supports square textures */
- tex_width = tex_height = tex_width > tex_height ? tex_width : tex_height;
+ tex_width = tex_height = FFMAX(tex_width, tex_height);
// better round up to a multiple of 16
if (!priv->opt_disable_texture_align) {
tex_width = (tex_width + 15) & ~15;
@@ -348,7 +353,7 @@ static void d3d_fix_texture_size(int *width, int *height)
*height = tex_height;
}
-static void d3dtex_release(struct d3dtex *tex)
+static void d3dtex_release(d3d_priv *priv, struct d3dtex *tex)
{
if (tex->system)
IDirect3DTexture9_Release(tex->system);
@@ -361,15 +366,16 @@ static void d3dtex_release(struct d3dtex *tex)
tex->tex_w = tex->tex_h = 0;
}
-static bool d3dtex_allocate(struct d3dtex *tex, D3DFORMAT fmt, int w, int h)
+static bool d3dtex_allocate(d3d_priv *priv, struct d3dtex *tex, D3DFORMAT fmt,
+ int w, int h)
{
- d3dtex_release(tex);
+ d3dtex_release(priv, tex);
tex->w = w;
tex->h = h;
int tw = w, th = h;
- d3d_fix_texture_size(&tw, &th);
+ d3d_fix_texture_size(priv, &tw, &th);
if (FAILED(IDirect3DDevice9_CreateTexture(priv->d3d_device, tw, th, 1,
D3DUSAGE_DYNAMIC, fmt, D3DPOOL_SYSTEMMEM, &tex->system, NULL)))
@@ -397,17 +403,18 @@ static bool d3dtex_allocate(struct d3dtex *tex, D3DFORMAT fmt, int w, int h)
return true;
error_exit:
- d3dtex_release(tex);
+ d3dtex_release(priv, tex);
return false;
}
-static IDirect3DBaseTexture9 *d3dtex_get_render_texture(struct d3dtex *tex)
+static IDirect3DBaseTexture9 *d3dtex_get_render_texture(d3d_priv *priv,
+ struct d3dtex *tex)
{
return (IDirect3DBaseTexture9 *)(tex->device ? tex->device : tex->system);
}
// Copy system texture contents to device texture.
-static bool d3dtex_update(struct d3dtex *tex)
+static bool d3dtex_update(d3d_priv *priv, struct d3dtex *tex)
{
if (!tex->device)
return true;
@@ -416,7 +423,7 @@ static bool d3dtex_update(struct d3dtex *tex)
(IDirect3DBaseTexture9 *)tex->device));
}
-static void d3d_unlock_video_objects(void)
+static void d3d_unlock_video_objects(d3d_priv *priv)
{
bool any_failed = false;
@@ -435,21 +442,23 @@ static void d3d_unlock_video_objects(void)
plane->locked_rect.pBits = NULL;
}
- if (any_failed)
- mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Unlocking video objects failed.\n");
+ if (any_failed) {
+ mp_msg(MSGT_VO, MSGL_V,
+ "<vo_direct3d>Unlocking video objects failed.\n");
+ }
}
// Free video surface/textures, shaders, etc.
-static void d3d_destroy_video_objects(void)
+static void d3d_destroy_video_objects(d3d_priv *priv)
{
- d3d_unlock_video_objects();
+ d3d_unlock_video_objects(priv);
if (priv->d3d_surface)
IDirect3DSurface9_Release(priv->d3d_surface);
priv->d3d_surface = NULL;
for (int n = 0; n < priv->plane_count; n++) {
- d3dtex_release(&priv->planes[n].texture);
+ d3dtex_release(priv, &priv->planes[n].texture);
}
if (priv->pixel_shader)
@@ -459,27 +468,26 @@ static void d3d_destroy_video_objects(void)
/** @brief Destroy D3D Offscreen and Backbuffer surfaces.
*/
-static void destroy_d3d_surfaces(void)
+static void destroy_d3d_surfaces(d3d_priv *priv)
{
mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>destroy_d3d_surfaces called.\n");
- /* Let's destroy the old (if any) D3D Surfaces */
- d3d_destroy_video_objects();
+ d3d_destroy_video_objects(priv);
- d3dtex_release(&priv->texture_osd);
+ d3dtex_release(priv, &priv->texture_osd);
if (priv->d3d_backbuf)
IDirect3DSurface9_Release(priv->d3d_backbuf);
priv->d3d_backbuf = NULL;
- d3dtex_release(&priv->texture_eosd);
+ d3dtex_release(priv, &priv->texture_eosd);
if (priv->eosd)
eosd_packer_reinit(priv->eosd, 0, 0);
}
// Allocate video surface or textures, and create shaders if needed.
-static bool d3d_configure_video_objects(void)
+static bool d3d_configure_video_objects(d3d_priv *priv)
{
int n;
bool need_clear = false;
@@ -491,7 +499,8 @@ static bool d3d_configure_video_objects(void)
struct texplane *plane = &priv->planes[n];
if (!plane->texture.system) {
- if (!d3dtex_allocate(&plane->texture,
+ if (!d3dtex_allocate(priv,
+ &plane->texture,
plane->d3d_format,
priv->src_width >> plane->shift_x,
priv->src_height >> plane->shift_y))
@@ -513,7 +522,7 @@ static bool d3d_configure_video_objects(void)
}
if (need_clear)
- d3d_clear_video_textures();
+ d3d_clear_video_textures(priv);
if (priv->pixel_shader_data) {
if (!priv->pixel_shader &&
@@ -531,7 +540,8 @@ static bool d3d_configure_video_objects(void)
if (!priv->d3d_surface &&
FAILED(IDirect3DDevice9_CreateOffscreenPlainSurface(
priv->d3d_device, priv->src_width, priv->src_height,
- priv->movie_src_fmt, D3DPOOL_DEFAULT, &priv->d3d_surface, NULL))) {
+ priv->movie_src_fmt, D3DPOOL_DEFAULT, &priv->d3d_surface, NULL)))
+ {
mp_msg(MSGT_VO, MSGL_ERR,
"<vo_direct3d>Allocating offscreen surface failed.\n");
return false;
@@ -541,7 +551,7 @@ static bool d3d_configure_video_objects(void)
return true;
}
-static bool d3d_lock_video_textures(void)
+static bool d3d_lock_video_textures(d3d_priv *priv)
{
for (int n = 0; n < priv->plane_count; n++) {
struct texplane *plane = &priv->planes[n];
@@ -551,7 +561,7 @@ static bool d3d_lock_video_textures(void)
&plane->locked_rect, NULL, 0)))
{
mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Texture lock failure.\n");
- d3d_unlock_video_objects();
+ d3d_unlock_video_objects(priv);
return false;
}
}
@@ -560,9 +570,9 @@ static bool d3d_lock_video_textures(void)
return true;
}
-static void d3d_clear_video_textures(void)
+static void d3d_clear_video_textures(d3d_priv *priv)
{
- if (!d3d_lock_video_textures())
+ if (!d3d_lock_video_textures(priv))
return;
for (int n = 0; n < priv->plane_count; n++) {
@@ -571,16 +581,16 @@ static void d3d_clear_video_textures(void)
plane->locked_rect.Pitch * plane->texture.tex_h);
}
- d3d_unlock_video_objects();
+ d3d_unlock_video_objects(priv);
}
/** @brief Create D3D Offscreen and Backbuffer surfaces. Each
* surface is created only if it's not already present.
* @return 1 on success, 0 on failure
*/
-static int create_d3d_surfaces(void)
+static int create_d3d_surfaces(d3d_priv *priv)
{
- int osd_width = vo_dwidth, osd_height = vo_dheight;
+ int osd_width = priv->vo->dwidth, osd_height = priv->vo->dheight;
int tex_width = osd_width, tex_height = osd_height;
mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>create_d3d_surfaces called.\n");
@@ -592,15 +602,16 @@ static int create_d3d_surfaces(void)
return 0;
}
- if (!d3d_configure_video_objects())
+ if (!d3d_configure_video_objects(priv))
return 0;
/* create OSD */
- d3d_fix_texture_size(&tex_width, &tex_height);
+ d3d_fix_texture_size(priv, &tex_width, &tex_height);
- // make sure we respect the size limits without breaking aspect or pow2-requirements
- while (tex_width > priv->max_texture_width || tex_height > priv->max_texture_height) {
+ while (tex_width > priv->max_texture_width
+ || tex_height > priv->max_texture_height)
+ {
osd_width >>= 1;
osd_height >>= 1;
tex_width >>= 1;
@@ -610,12 +621,13 @@ static int create_d3d_surfaces(void)
if (priv->texture_osd.tex_w < tex_width
|| priv->texture_osd.tex_h < tex_height)
{
- d3dtex_release(&priv->texture_osd);
+ d3dtex_release(priv, &priv->texture_osd);
- mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>OSD texture size (%dx%d), requested (%dx%d).\n",
- vo_dwidth, vo_dheight, tex_width, tex_height);
+ mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>OSD texture size (%dx%d),"
+ " requested (%dx%d).\n", osd_width, osd_height, tex_width,
+ tex_height);
- if (!d3dtex_allocate(&priv->texture_osd, D3DFMT_A8L8, tex_width,
+ if (!d3dtex_allocate(priv, &priv->texture_osd, D3DFMT_A8L8, tex_width,
tex_height))
{
mp_msg(MSGT_VO, MSGL_ERR,
@@ -628,11 +640,16 @@ static int create_d3d_surfaces(void)
priv->texture_osd.h = osd_height;
/* setup default renderstate */
- IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
- IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
- IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHAFUNC, D3DCMP_GREATER);
- IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHAREF, (DWORD)0x0);
- IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_LIGHTING, FALSE);
+ IDirect3DDevice9_SetRenderState(priv->d3d_device,
+ D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ IDirect3DDevice9_SetRenderState(priv->d3d_device,
+ D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ IDirect3DDevice9_SetRenderState(priv->d3d_device,
+ D3DRS_ALPHAFUNC, D3DCMP_GREATER);
+ IDirect3DDevice9_SetRenderState(priv->d3d_device,
+ D3DRS_ALPHAREF, (DWORD)0x0);
+ IDirect3DDevice9_SetRenderState(priv->d3d_device,
+ D3DRS_LIGHTING, FALSE);
// we use up to 3 samplers for up to 3 YUV planes
for (int n = 0; n < 3; n++) {
@@ -655,7 +672,8 @@ static int create_d3d_surfaces(void)
/** @brief Fill D3D Presentation parameters
*/
-static void fill_d3d_presentparams(D3DPRESENT_PARAMETERS *present_params)
+static void fill_d3d_presentparams(d3d_priv *priv,
+ D3DPRESENT_PARAMETERS *present_params)
{
/* Prepare Direct3D initialization parameters. */
memset(present_params, 0, sizeof(D3DPRESENT_PARAMETERS));
@@ -677,23 +695,26 @@ static void fill_d3d_presentparams(D3DPRESENT_PARAMETERS *present_params)
* device.
* @return 1 on success, 0 on failure
*/
-static int change_d3d_backbuffer(back_buffer_action_e action)
+static int change_d3d_backbuffer(d3d_priv *priv, back_buffer_action_e action)
{
D3DPRESENT_PARAMETERS present_params;
- destroy_d3d_surfaces();
+ destroy_d3d_surfaces(priv);
+
+ int window_w = priv->vo->dwidth;
+ int window_h = priv->vo->dheight;
/* Grow the backbuffer in the required dimension. */
- if (vo_dwidth > priv->cur_backbuf_width)
- priv->cur_backbuf_width = vo_dwidth;
+ if (window_w > priv->cur_backbuf_width)
+ priv->cur_backbuf_width = window_w;
- if (vo_dheight > priv->cur_backbuf_height)
- priv->cur_backbuf_height = vo_dheight;
+ if (window_h > priv->cur_backbuf_height)
+ priv->cur_backbuf_height = window_h;
/* The grown backbuffer dimensions are ready and fill_d3d_presentparams
* will use them, so we can reset the device.
*/
- fill_d3d_presentparams(&present_params);
+ fill_d3d_presentparams(priv, &present_params);
/* vo_w32_window is w32_common variable. It's a handle to the window. */
if (action == BACKBUFFER_CREATE &&
@@ -717,7 +738,7 @@ static int change_d3d_backbuffer(back_buffer_action_e action)
mp_msg(MSGT_VO, MSGL_V,
"<vo_direct3d>New backbuffer (%dx%d), VO (%dx%d)\n",
present_params.BackBufferWidth, present_params.BackBufferHeight,
- vo_dwidth, vo_dheight);
+ window_w, window_h);
return 1;
}
@@ -726,13 +747,13 @@ static int change_d3d_backbuffer(back_buffer_action_e action)
* function called to initialize the D3D context.
* @return 1 on success, 0 on failure
*/
-static int configure_d3d(void)
+static int configure_d3d(d3d_priv *priv)
{
D3DDISPLAYMODE disp_mode;
mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>configure_d3d called.\n");
- destroy_d3d_surfaces();
+ destroy_d3d_surfaces(priv);
/* Get the current desktop display mode, so we can set up a back buffer
* of the same format. */
@@ -744,16 +765,15 @@ static int configure_d3d(void)
return 0;
}
- /* Write current Desktop's colorspace format in the global storage. */
priv->desktop_fmt = disp_mode.Format;
- if (!change_d3d_backbuffer(BACKBUFFER_CREATE))
+ if (!change_d3d_backbuffer(priv, BACKBUFFER_CREATE))
return 0;
- if (!create_d3d_surfaces())
+ if (!create_d3d_surfaces(priv))
return 0;
- resize_d3d();
+ resize_d3d(priv);
return 1;
}
@@ -762,30 +782,25 @@ static int configure_d3d(void)
* when the video adapter becomes uncooperative.
* @return 1 on success, 0 on failure
*/
-static int reconfigure_d3d(void)
+static int reconfigure_d3d(d3d_priv *priv)
{
mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>reconfigure_d3d called.\n");
- /* Destroy the offscreen, OSD and backbuffer surfaces */
- destroy_d3d_surfaces();
+ destroy_d3d_surfaces(priv);
- /* Destroy the D3D Device */
if (priv->d3d_device)
IDirect3DDevice9_Release(priv->d3d_device);
priv->d3d_device = NULL;
- /* Stop the whole Direct3D */
IDirect3D9_Release(priv->d3d_handle);
- /* Initialize Direct3D from the beginning */
priv->d3d_handle = priv->pDirect3DCreate9(D3D_SDK_VERSION);
if (!priv->d3d_handle) {
mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Initializing Direct3D failed.\n");
return 0;
}
- /* Configure Direct3D */
- if (!configure_d3d())
+ if (!configure_d3d(priv))
return 0;
return 1;
@@ -794,18 +809,19 @@ static int reconfigure_d3d(void)
/** @brief Resize Direct3D context on window resize.
* @return 1 on success, 0 on failure
*/
-static int resize_d3d(void)
+static int resize_d3d(d3d_priv *priv)
{
- D3DVIEWPORT9 vp = {0, 0, vo_dwidth, vo_dheight, 0, 1};
+ D3DVIEWPORT9 vp = {0, 0, priv->vo->dwidth, priv->vo->dheight, 0, 1};
mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>resize_d3d called.\n");
/* Make sure that backbuffer is large enough to accomodate the new
viewport dimensions. Grow it if necessary. */
- if (vo_dwidth > priv->cur_backbuf_width ||
- vo_dheight > priv->cur_backbuf_height) {
- if (!change_d3d_backbuffer(BACKBUFFER_RESET))
+ if (priv->vo->dwidth > priv->cur_backbuf_width ||
+ priv->vo->dheight > priv->cur_backbuf_height)
+ {
+ if (!change_d3d_backbuffer(priv, BACKBUFFER_RESET))
return 0;
}
@@ -814,11 +830,10 @@ static int resize_d3d(void)
* effectively recreating only the OSD.
*/
- if (!create_d3d_surfaces())
+ if (!create_d3d_surfaces(priv))
return 0;
- if (FAILED(IDirect3DDevice9_SetViewport(priv->d3d_device,
- &vp))) {
+ if (FAILED(IDirect3DDevice9_SetViewport(priv->d3d_device, &vp))) {
mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Setting viewport failed.\n");
return 0;
}
@@ -828,7 +843,7 @@ static int resize_d3d(void)
d3d_matrix_ortho(&view, 0.5f, vp.Width + 0.5f, vp.Height + 0.5f, 0.5f);
IDirect3DDevice9_SetTransform(priv->d3d_device, D3DTS_VIEW, &view);
- calc_fs_rect();
+ calc_fs_rect(priv);
#ifdef CONFIG_FREETYPE
// font needs to be adjusted
@@ -837,23 +852,23 @@ static int resize_d3d(void)
// OSD needs to be drawn fresh for new size
vo_osd_changed(OSDTYPE_OSD);
+ priv->vo->want_redraw = true;
+
return 1;
}
/** @brief Uninitialize Direct3D and close the window.
*/
-static void uninit_d3d(void)
+static void uninit_d3d(d3d_priv *priv)
{
mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>uninit_d3d called.\n");
- destroy_d3d_surfaces();
+ destroy_d3d_surfaces(priv);
- /* Destroy the D3D Device */
if (priv->d3d_device)
IDirect3DDevice9_Release(priv->d3d_device);
priv->d3d_device = NULL;
- /* Stop the whole D3D. */
if (priv->d3d_handle) {
mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Stopping Direct3D.\n");
IDirect3D9_Release(priv->d3d_handle);
@@ -861,45 +876,40 @@ static void uninit_d3d(void)
priv->d3d_handle = NULL;
}
-static uint32_t d3d_draw_frame(void);
-
-static uint32_t d3d_upload_and_render_frame_texture(mp_image_t *mpi)
+static uint32_t d3d_upload_and_render_frame_texture(d3d_priv *priv,
+ mp_image_t *mpi)
{
if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK))
- draw_slice(mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
+ draw_slice(priv->vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
- d3d_unlock_video_objects();
+ d3d_unlock_video_objects(priv);
for (int n = 0; n < priv->plane_count; n++) {
- d3dtex_update(&priv->planes[n].texture);
+ d3dtex_update(priv, &priv->planes[n].texture);
}
- return d3d_draw_frame();
+ return d3d_draw_frame(priv);
}
/** @brief Render a frame on the screen.
* @param mpi mpi structure with the decoded frame inside
* @return VO_TRUE on success, VO_ERROR on failure
*/
-static uint32_t d3d_upload_and_render_frame(mp_image_t *mpi)
+static uint32_t d3d_upload_and_render_frame(d3d_priv *priv, mp_image_t *mpi)
{
- /* Uncomment when direct rendering is implemented.
- * if (mpi->flags & MP_IMGFLAG_DIRECT) ...
- */
-
/* If the D3D device is uncooperative (not initialized), return success.
The device will be probed for reinitialization in the next flip_page() */
if (!priv->d3d_device)
return VO_TRUE;
if (priv->use_textures)
- return d3d_upload_and_render_frame_texture(mpi);
+ return d3d_upload_and_render_frame_texture(priv, mpi);
if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
goto skip_upload;
if (mpi->flags & MP_IMGFLAG_PLANAR) { /* Copy a planar frame. */
- draw_slice(mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
+ draw_slice(priv->vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
goto skip_upload;
}
@@ -916,16 +926,16 @@ static uint32_t d3d_upload_and_render_frame(mp_image_t *mpi)
mpi->height, priv->locked_rect.Pitch, mpi->stride[0]);
skip_upload:
- d3d_unlock_video_objects();
+ d3d_unlock_video_objects(priv);
- return d3d_draw_frame();
+ return d3d_draw_frame(priv);
}
-static uint32_t d3d_draw_frame(void)
+static uint32_t d3d_draw_frame(d3d_priv *priv)
{
int n;
- if (!d3d_begin_scene())
+ if (!d3d_begin_scene(priv))
return VO_ERROR;
if (priv->is_clear_needed) {
@@ -938,7 +948,7 @@ static uint32_t d3d_draw_frame(void)
for (n = 0; n < priv->plane_count; n++) {
IDirect3DDevice9_SetTexture(priv->d3d_device, n,
- d3dtex_get_render_texture(&priv->planes[n].texture));
+ d3dtex_get_render_texture(priv, &priv->planes[n].texture));
}
RECT rm = priv->fs_movie_rect;
@@ -1010,7 +1020,8 @@ static int get_chroma_clear_val(int bit_depth)
// this macro is supposed to work on all formats supported by 3D rendering, and
// that produce "reasonable" output (i.e. no mixed up colors)
-#define IMGFMT_IS_ANY_RND(x) (IMGFMT_IS_BGR(x) || IMGFMT_IS_RGB(x) || IMGFMT_IS_Y(x))
+#define IMGFMT_IS_ANY_RND(x) \
+ (IMGFMT_IS_BGR(x) || IMGFMT_IS_RGB(x) || IMGFMT_IS_Y(x))
// pixel size in bit for any IMGFMT_IS_ANY_RND(x)==true
// we assume that the actual pixel strides are always aligned on bytes
@@ -1026,7 +1037,8 @@ static int imgfmt_any_rnd_depth(int fmt)
return 0;
}
-static D3DFORMAT check_format(uint32_t movie_fmt, bool as_texture)
+static D3DFORMAT check_format(d3d_priv *priv, uint32_t movie_fmt,
+ bool as_texture)
{
const char *type = as_texture ? "texture rendering" : "StretchRect";
const struct fmt_entry *cur = &fmt_table[0];
@@ -1077,7 +1089,7 @@ static D3DFORMAT check_format(uint32_t movie_fmt, bool as_texture)
// Check whether YUV conversion with shaders can be done.
// Returns the format the individual planes should use (or 0 on failure)
-static D3DFORMAT check_shader_conversion(uint32_t fmt)
+static D3DFORMAT check_shader_conversion(d3d_priv *priv, uint32_t fmt)
{
if (priv->opt_disable_shaders)
return 0;
@@ -1089,19 +1101,19 @@ static D3DFORMAT check_shader_conversion(uint32_t fmt)
bool is_8bit = component_bits == 8;
if (!is_8bit && priv->opt_only_8bit)
return 0;
- return check_format(is_8bit ? IMGFMT_Y8 : IMGFMT_Y16, true);
+ return check_format(priv, is_8bit ? IMGFMT_Y8 : IMGFMT_Y16, true);
}
// Return if the image format can be used. If it can, decide which rendering
// and conversion mode to use.
// If initialize is true, actually setup all variables to use the picked
// rendering mode.
-static bool init_rendering_mode(uint32_t fmt, bool initialize)
+static bool init_rendering_mode(d3d_priv *priv, uint32_t fmt, bool initialize)
{
int n;
- int blit_d3dfmt = check_format(fmt, false);
- int texture_d3dfmt = check_format(fmt, true);
- int shader_d3dfmt = check_shader_conversion(fmt);
+ int blit_d3dfmt = check_format(priv, fmt, false);
+ int texture_d3dfmt = check_format(priv, fmt, true);
+ int shader_d3dfmt = check_shader_conversion(priv, fmt);
if (priv->opt_disable_textures)
texture_d3dfmt = 0;
@@ -1181,7 +1193,7 @@ static bool init_rendering_mode(uint32_t fmt, bool initialize)
priv->movie_src_fmt = blit_d3dfmt;
}
- update_colorspace();
+ update_colorspace(priv);
return true;
}
@@ -1190,9 +1202,9 @@ static bool init_rendering_mode(uint32_t fmt, bool initialize)
* @return 0 on failure, device capabilities (not probed
* currently) on success.
*/
-static int query_format(uint32_t movie_fmt)
+static int query_format(d3d_priv *priv, uint32_t movie_fmt)
{
- if (!init_rendering_mode(movie_fmt, false))
+ if (!init_rendering_mode(priv, movie_fmt, false))
return 0;
int eosd_caps = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW
@@ -1212,7 +1224,7 @@ static int query_format(uint32_t movie_fmt)
* *
****************************************************************************/
-static void update_colorspace(void)
+static void update_colorspace(d3d_priv *priv)
{
float coeff[3][4];
struct mp_csp_params csp = { .colorspace = priv->colorspace };
@@ -1266,16 +1278,19 @@ const char *options_help_text = "-vo direct3d command line help:\n"
* @return 0 on success, -1 on failure
*/
-static int preinit(const char *arg)
+static int preinit(struct vo *vo, const char *arg)
{
D3DDISPLAYMODE disp_mode;
D3DCAPS9 disp_caps;
DWORD texture_caps;
DWORD dev_caps;
- /* Set to zero all global variables. */
- priv = talloc_zero(NULL, struct global_priv);
- *priv = (struct global_priv) {
+ d3d_priv *priv = talloc_zero(vo, d3d_priv);
+ vo->priv = priv;
+
+ *priv = (d3d_priv) {
+ .vo = vo,
+
.colorspace = MP_CSP_DETAILS_DEFAULTS,
.video_eq = { MP_CSP_EQ_CAPS_COLORMATRIX },
};
@@ -1283,14 +1298,14 @@ static int preinit(const char *arg)
int opt_force_power_of_2 = false;
const opt_t subopts[] = {
- {"prefer-stretchrect", OPT_ARG_BOOL, &priv->opt_prefer_stretchrect, NULL},
- {"disable-textures", OPT_ARG_BOOL, &priv->opt_disable_textures, NULL},
- {"disable-stretchrect", OPT_ARG_BOOL, &priv->opt_disable_stretchrect, NULL},
- {"disable-shaders", OPT_ARG_BOOL, &priv->opt_disable_shaders, NULL},
- {"only-8bit", OPT_ARG_BOOL, &priv->opt_only_8bit, NULL},
- {"disable-eosd", OPT_ARG_BOOL, &priv->opt_disable_eosd, NULL},
- {"force-power-of-2", OPT_ARG_BOOL, &opt_force_power_of_2, NULL},
- {"disable-texture-align", OPT_ARG_BOOL, &priv->opt_disable_texture_align, NULL},
+ {"prefer-stretchrect", OPT_ARG_BOOL, &priv->opt_prefer_stretchrect},
+ {"disable-textures", OPT_ARG_BOOL, &priv->opt_disable_textures},
+ {"disable-stretchrect", OPT_ARG_BOOL, &priv->opt_disable_stretchrect},
+ {"disable-shaders", OPT_ARG_BOOL, &priv->opt_disable_shaders},
+ {"only-8bit", OPT_ARG_BOOL, &priv->opt_only_8bit},
+ {"disable-eosd", OPT_ARG_BOOL, &priv->opt_disable_eosd},
+ {"force-power-of-2", OPT_ARG_BOOL, &opt_force_power_of_2},
+ {"disable-texture-align", OPT_ARG_BOOL, &priv->opt_disable_texture_align},
{NULL}
};
if (subopt_parse(arg, subopts) != 0) {
@@ -1303,42 +1318,49 @@ static int preinit(const char *arg)
priv->d3d9_dll = LoadLibraryA("d3d9.dll");
if (!priv->d3d9_dll) {
- mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Unable to dynamically load d3d9.dll\n");
+ mp_msg(MSGT_VO, MSGL_ERR,
+ "<vo_direct3d>Unable to dynamically load d3d9.dll\n");
goto err_out;
}
- priv->pDirect3DCreate9 = (void *)GetProcAddress(priv->d3d9_dll, "Direct3DCreate9");
+ priv->pDirect3DCreate9 = (void *)GetProcAddress(priv->d3d9_dll,
+ "Direct3DCreate9");
if (!priv->pDirect3DCreate9) {
- mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Unable to find entry point of Direct3DCreate9\n");
+ mp_msg(MSGT_VO, MSGL_ERR,
+ "<vo_direct3d>Unable to find entry point of Direct3DCreate9\n");
goto err_out;
}
priv->d3d_handle = priv->pDirect3DCreate9(D3D_SDK_VERSION);
if (!priv->d3d_handle) {
- mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Initializing Direct3D failed.\n");
+ mp_msg(MSGT_VO, MSGL_ERR,
+ "<vo_direct3d>Initializing Direct3D failed.\n");
goto err_out;
}
if (FAILED(IDirect3D9_GetAdapterDisplayMode(priv->d3d_handle,
D3DADAPTER_DEFAULT,
&disp_mode))) {
- mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Reading display mode failed.\n");
+ mp_msg(MSGT_VO, MSGL_ERR,
+ "<vo_direct3d>Reading display mode failed.\n");
goto err_out;
}
- /* Store in priv->desktop_fmt the user desktop's colorspace. Usually XRGB. */
priv->desktop_fmt = disp_mode.Format;
priv->cur_backbuf_width = disp_mode.Width;
priv->cur_backbuf_height = disp_mode.Height;
- mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Setting backbuffer dimensions to (%dx%d).\n",
+ mp_msg(MSGT_VO, MSGL_V,
+ "<vo_direct3d>Setting backbuffer dimensions to (%dx%d).\n",
disp_mode.Width, disp_mode.Height);
if (FAILED(IDirect3D9_GetDeviceCaps(priv->d3d_handle,
D3DADAPTER_DEFAULT,
DEVTYPE,
- &disp_caps))) {
- mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Reading display capabilities failed.\n");
+ &disp_caps)))
+ {
+ mp_msg(MSGT_VO, MSGL_ERR,
+ "<vo_direct3d>Reading display capabilities failed.\n");
goto err_out;
}
@@ -1346,7 +1368,7 @@ static int preinit(const char *arg)
texture_caps = disp_caps.TextureCaps;
dev_caps = disp_caps.DevCaps;
priv->device_caps_power2_only = (texture_caps & D3DPTEXTURECAPS_POW2) &&
- !(texture_caps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL);
+ !(texture_caps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL);
priv->device_caps_square_only = texture_caps & D3DPTEXTURECAPS_SQUAREONLY;
priv->device_texture_sys = dev_caps & D3DDEVCAPS_TEXTURESYSTEMMEMORY;
priv->max_texture_width = disp_caps.MaxTextureWidth;
@@ -1355,9 +1377,10 @@ static int preinit(const char *arg)
if (opt_force_power_of_2)
priv->device_caps_power2_only = 1;
- mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>device_caps_power2_only %d, device_caps_square_only %d\n"
- "<vo_direct3d>device_texture_sys %d\n"
- "<vo_direct3d>max_texture_width %d, max_texture_height %d\n",
+ mp_msg(MSGT_VO, MSGL_V,
+ "<vo_direct3d>device_caps_power2_only %d, device_caps_square_only %d\n"
+ "<vo_direct3d>device_texture_sys %d\n"
+ "<vo_direct3d>max_texture_width %d, max_texture_height %d\n",
priv->device_caps_power2_only, priv->device_caps_square_only,
priv->device_texture_sys, priv->max_texture_width,
priv->max_texture_height);
@@ -1365,61 +1388,50 @@ static int preinit(const char *arg)
/* w32_common framework call. Configures window on the screen, gets
* fullscreen dimensions and does other useful stuff.
*/
+ global_vo = vo;
if (!vo_w32_init()) {
- mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Configuring onscreen window failed.\n");
+ mp_msg(MSGT_VO, MSGL_V,
+ "<vo_direct3d>Configuring onscreen window failed.\n");
goto err_out;
}
return 0;
err_out:
- uninit();
+ uninit(vo);
return -1;
}
-static void full_redraw(void)
-{
- priv->is_clear_needed = 1;
- d3d_draw_frame();
- draw_osd();
- draw_eosd();
- flip_page();
-}
-
/**