diff options
author | wm4 <wm4@mplayer2.org> | 2011-10-28 22:06:33 +0200 |
---|---|---|
committer | wm4 <wm4@mplayer2.org> | 2012-03-17 20:58:16 +0100 |
commit | e1826826f95a93ecb1073d9c78f01139068c2733 (patch) | |
tree | 16291d637724c589be3be928e1a3cfdee90737fd | |
parent | 83889cebbc78e4a9087d95633ded1d65d5690c24 (diff) | |
download | mpv-e1826826f95a93ecb1073d9c78f01139068c2733.tar.bz2 mpv-e1826826f95a93ecb1073d9c78f01139068c2733.tar.xz |
vo_direct3d: make VO re-config faster by not recreating the whole D3D state
The D3D state (the IDirect3DDevice9 and all textures and buffers) were
released and recreated in the config() function. This is completely
unnecessary. Instead explicitly handle changes. The video surface is only
reallocated if the video format or the video size changes. The OSD texture
is only reallocated if the window size is increased. The EOSD texture is
not released. Since the resize code is reused to deal with reconfig
changes, some of these improvements (and possible bugs) apply to normal
window resizing as well.
-rw-r--r-- | libvo/vo_direct3d.c | 74 |
1 files changed, 38 insertions, 36 deletions
diff --git a/libvo/vo_direct3d.c b/libvo/vo_direct3d.c index 218dd761df..0bd00ec6fe 100644 --- a/libvo/vo_direct3d.c +++ b/libvo/vo_direct3d.c @@ -299,6 +299,8 @@ static int create_d3d_surfaces(void) return 0; } + /* create OSD */ + d3d_fix_texture_size(&tex_width, &tex_height); // make sure we respect the size limits without breaking aspect or pow2-requirements @@ -311,13 +313,25 @@ static int create_d3d_surfaces(void) priv->osd_width = osd_width; priv->osd_height = osd_height; - priv->osd_texture_width = tex_width; - priv->osd_texture_height = tex_height; - mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>OSD texture size (%dx%d), requested (%dx%d).\n", - vo_dwidth, vo_dheight, priv->osd_texture_width, priv->osd_texture_height); + if (priv->osd_texture_width < tex_width + || priv->osd_texture_height < tex_height) + { + if (priv->d3d_texture_osd) + IDirect3DTexture9_Release(priv->d3d_texture_osd); + priv->d3d_texture_osd = NULL; + + if (priv->d3d_texture_system) + IDirect3DTexture9_Release(priv->d3d_texture_system); + priv->d3d_texture_system = NULL; + + priv->osd_texture_width = tex_width; + priv->osd_texture_height = tex_height; + + mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>OSD texture size (%dx%d), requested (%dx%d).\n", + vo_dwidth, vo_dheight, priv->osd_texture_width, priv->osd_texture_height); + } - /* create OSD */ if (!priv->d3d_texture_system && FAILED(IDirect3DDevice9_CreateTexture(priv->d3d_device, priv->osd_texture_width, @@ -360,7 +374,7 @@ static int create_d3d_surfaces(void) IDirect3DDevice9_SetSamplerState(priv->d3d_device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); IDirect3DDevice9_SetSamplerState(priv->d3d_device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - if (priv->eosd) + if (priv->eosd && !priv->d3d_texture_eosd) eosd_packer_reinit(priv->eosd, priv->max_texture_width, priv->max_texture_height); @@ -530,19 +544,6 @@ static int resize_d3d(void) return 0; } - /* Destroy the OSD textures. They should always match the new dimensions - * of the onscreen window, so on each resize we need new OSD dimensions. - */ - - if (priv->d3d_texture_osd) - IDirect3DTexture9_Release(priv->d3d_texture_osd); - priv->d3d_texture_osd = NULL; - - if (priv->d3d_texture_system) - IDirect3DTexture9_Release(priv->d3d_texture_system); - priv->d3d_texture_system = NULL; - - /* Recreate the OSD. The function will observe that the offscreen plain * surface and the backbuffer are not destroyed and will skip their creation, * effectively recreating only the OSD. @@ -917,16 +918,10 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t options, char *title, uint32_t format) { - - priv->src_width = width; - priv->src_height = height; - const struct_fmt_table *fmt_entry = check_format(format); if (!fmt_entry) return VO_ERROR; - priv->movie_src_fmt = fmt_entry->fourcc; - /* w32_common framework call. Creates window on the screen with * the given coordinates. */ @@ -935,19 +930,26 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, return VO_ERROR; } - /* "config" may be called several times, so if this is not the first - * call, we should destroy Direct3D adapter and surfaces before - * calling configure_d3d, which will create them again. - */ - destroy_d3d_surfaces(); + if ((priv->movie_src_fmt != fmt_entry->fourcc) + || (priv->src_width != width) + || (priv->src_height != height)) + { + priv->movie_src_fmt = fmt_entry->fourcc; + priv->src_width = width; + priv->src_height = height; - /* Destroy the D3D Device */ - if (priv->d3d_device) - IDirect3DDevice9_Release(priv->d3d_device); - priv->d3d_device = NULL; + if (priv->d3d_surface) + IDirect3DSurface9_Release(priv->d3d_surface); + priv->d3d_surface = NULL; + } - if (!configure_d3d()) - return VO_ERROR; + if (!priv->d3d_device) { + if (!configure_d3d()) + return VO_ERROR; + } else { + if (!resize_d3d()) + return VO_ERROR; + } return 0; /* Success */ } |