static void draw_osd(void) { if (!use_osd) return; if (vo_osd_changed(0)) { int osd_h, osd_w; clearOSD(); osd_w = scaled_osd ? image_width : vo_dwidth; osd_h = scaled_osd ? image_height : vo_dheight; vo_draw_text_ext(osd_w, osd_h, ass_border_x, ass_border_y, ass_border_x, ass_border_y, image_width, image_height, create_osd_texture); } if (vo_doublebuffering) do_render_osd(RENDER_OSD); }
/** @brief libvo Callback: Draw OSD/Subtitles, */ static void draw_osd(void) { // we can not render OSD if we lost the device e.g. because it was uncooperative if (!priv->d3d_device) return; if (vo_osd_changed(0)) { D3DLOCKED_RECT locked_rect; /**< Offscreen surface we lock in order to copy MPlayer's frame inside it.*/ /* clear the OSD */ if (FAILED(IDirect3DTexture9_LockRect(priv->d3d_texture_system, 0, &locked_rect, NULL, 0))) { mp_msg(MSGT_VO,MSGL_ERR, "<vo_direct3d>OSD texture lock failed.\n"); return; } /* clear the whole texture to avoid issues due to interpolation */ memset(locked_rect.pBits, 0, locked_rect.Pitch * priv->osd_texture_height); /* this unlock is used for both slice_draw path and D3DRenderFrame path */ if (FAILED(IDirect3DTexture9_UnlockRect(priv->d3d_texture_system, 0))) { mp_msg(MSGT_VO,MSGL_ERR, "<vo_direct3d>OSD texture unlock failed.\n"); return; } priv->is_osd_populated = 0; /* required for if subs are in the boarder region */ priv->is_clear_needed = 1; vo_draw_text_ext(priv->osd_width, priv->osd_height, priv->border_x, priv->border_y, priv->border_x, priv->border_y, priv->src_width, priv->src_height, draw_alpha); if (!priv->device_texture_sys) { /* only DMA to the shadow if its required */ if (FAILED(IDirect3DDevice9_UpdateTexture(priv->d3d_device, (IDirect3DBaseTexture9 *)priv->d3d_texture_system, (IDirect3DBaseTexture9 *)priv->d3d_texture_osd))) { mp_msg(MSGT_VO,MSGL_ERR, "<vo_direct3d>OSD texture transfer failed.\n"); return; } } } /* update OSD */ if (priv->is_osd_populated) { struct_vertex osd_quad_vb[] = { {-1.0f, 1.0f, 0.0f, 0, 0 }, { 1.0f, 1.0f, 0.0f, 1, 0 }, {-1.0f,-1.0f, 0.0f, 0, 1 }, { 1.0f,-1.0f, 0.0f, 1, 1 } }; /* calculate the texture coordinates */ osd_quad_vb[1].tu = osd_quad_vb[3].tu = (float)priv->osd_width / priv->osd_texture_width; osd_quad_vb[2].tv = osd_quad_vb[3].tv = (float)priv->osd_height / priv->osd_texture_height; if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) { mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>BeginScene failed.\n"); return; } /* turn on alpha test */ IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHABLENDENABLE, TRUE); IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHATESTENABLE, TRUE); /* need to use a texture here (done here as we may be able to texture from system memory) */ IDirect3DDevice9_SetTexture(priv->d3d_device, 0, (IDirect3DBaseTexture9 *)(priv->device_texture_sys ? priv->d3d_texture_system : priv->d3d_texture_osd)); IDirect3DDevice9_SetFVF(priv->d3d_device, D3DFVF_MY_VERTEX); IDirect3DDevice9_DrawPrimitiveUP(priv->d3d_device, D3DPT_TRIANGLESTRIP, 2, osd_quad_vb, sizeof(struct_vertex)); /* turn off alpha test */ IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHATESTENABLE, FALSE); IDirect3DDevice9_SetRenderState(priv->d3d_device, D3DRS_ALPHABLENDENABLE, FALSE); if (FAILED(IDirect3DDevice9_EndScene(priv->d3d_device))) { mp_msg(MSGT_VO,MSGL_ERR,"<vo_direct3d>EndScene failed.\n"); return; } } }