[vlc-devel] [PATCH 4/5] direct3d9: move the pool picture allocation in a separate function
Steve Lhomme
robux4 at ycbcr.xyz
Wed Dec 5 09:59:05 CET 2018
---
modules/video_output/win32/direct3d9.c | 177 ++++++++++++++-----------
1 file changed, 98 insertions(+), 79 deletions(-)
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index b6525d8a95..caad663846 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -130,6 +130,13 @@ typedef struct
uint32_t bmask;
} d3d9_format_t;
+struct vout_pool_context
+{
+ vlc_object_t *o;
+ d3d9_device_t d3d_dev;
+ const d3d9_format_t *d3dtexture_format; /* Rendering texture(s) format */
+};
+
struct vout_display_sys_t
{
vout_display_sys_win32_t sys;
@@ -145,8 +152,8 @@ struct vout_display_sys_t
// core objects
d3d9_handle_t hd3d;
HINSTANCE hxdll; /* handle of the opened d3d9x dll */
+ struct vout_pool_context pool_ctx;
IDirect3DPixelShader9* d3dx_shader;
- d3d9_device_t d3d_dev;
// scene objects
IDirect3DTexture9 *sceneTexture;
@@ -154,7 +161,6 @@ struct vout_display_sys_t
D3DFORMAT d3dregion_format; /* Backbuffer output format */
size_t d3dregion_count;
struct d3d_region_t *d3dregion;
- const d3d9_format_t *d3dtexture_format; /* Rendering texture(s) format */
/* */
bool reset_device;
@@ -251,18 +257,8 @@ static void Direct3D9UnlockSurface(picture_t *picture)
}
}
-/* */
-static picture_pool_t *Direct3D9CreatePicturePool(vlc_object_t *o,
- d3d9_device_t *p_d3d9_dev, const d3d9_format_t *default_d3dfmt, const video_format_t *fmt, unsigned count)
+static picture_t *NewPoolPicture(struct vout_pool_context *pctx, const video_format_t *fmt)
{
- picture_pool_t* pool = NULL;
- picture_t** pictures = NULL;
- unsigned picture_count = 0;
-
- pictures = calloc(count, sizeof(*pictures));
- if (!pictures)
- goto error;
-
D3DFORMAT format;
switch (fmt->i_chroma)
{
@@ -273,42 +269,64 @@ static picture_pool_t *Direct3D9CreatePicturePool(vlc_object_t *o,
format = MAKEFOURCC('N','V','1','2');
break;
default:
- if (!default_d3dfmt)
- goto error;
- format = default_d3dfmt->format;
+ if (!pctx->d3dtexture_format)
+ return NULL;
+ format = pctx->d3dtexture_format->format;
break;
}
- for (picture_count = 0; picture_count < count; ++picture_count)
- {
- picture_sys_t *picsys = malloc(sizeof(*picsys));
- if (unlikely(picsys == NULL))
- goto error;
- memset(picsys, 0, sizeof(*picsys));
-
- HRESULT hr = IDirect3DDevice9_CreateOffscreenPlainSurface(p_d3d9_dev->dev,
- fmt->i_width,
- fmt->i_height,
- format,
- D3DPOOL_DEFAULT,
- &picsys->surface,
- NULL);
- if (FAILED(hr)) {
- msg_Err(o, "Failed to allocate surface %d (hr=0x%0lx)", picture_count, hr);
- free(picsys);
- goto error;
- }
+ picture_sys_t *picsys = calloc(1, sizeof(*picsys));
+ if (unlikely(picsys == NULL))
+ return NULL;
- picture_resource_t resource = {
- .p_sys = picsys,
- .pf_destroy = DestroyPicture,
- };
+ HRESULT hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pctx->d3d_dev.dev,
+ fmt->i_width,
+ fmt->i_height,
+ format,
+ D3DPOOL_DEFAULT,
+ &picsys->surface,
+ NULL);
+ if (FAILED(hr)) {
+ msg_Err(pctx->o, "Failed to allocate surface (hr=0x%0lx)", hr);
+ goto error;
+ }
- picture_t *picture = picture_NewFromResource(fmt, &resource);
- if (unlikely(picture == NULL)) {
- free(picsys);
+ picture_resource_t resource = {
+ .p_sys = picsys,
+ .pf_destroy = DestroyPicture,
+ };
+
+ picture_t *picture = picture_NewFromResource(fmt, &resource);
+ if (unlikely(picture == NULL)) {
+ goto error;
+ }
+
+ return picture;
+error:
+ if (picsys->surface)
+ IDirect3DSurface9_Release(picsys->surface);
+ free(picsys);
+ return NULL;
+}
+
+/* */
+static picture_pool_t *Direct3D9CreatePicturePool(struct vout_pool_context *pctx,
+ const video_format_t *fmt,
+ unsigned count)
+{
+ picture_pool_t* pool = NULL;
+ picture_t** pictures = NULL;
+ unsigned picture_count = 0;
+
+ pictures = calloc(count, sizeof(*pictures));
+ if (!pictures)
+ return NULL;
+
+ for (picture_count = 0; picture_count < count; ++picture_count)
+ {
+ picture_t *picture = NewPoolPicture(pctx, fmt);
+ if (unlikely(picture == NULL))
goto error;
- }
pictures[picture_count] = picture;
}
@@ -328,7 +346,7 @@ static picture_pool_t *Direct3D9CreatePicturePool(vlc_object_t *o,
error:
if (pool == NULL && pictures) {
for (unsigned i=0;i<picture_count; ++i)
- DestroyPicture(pictures[i]);
+ picture_Release(pictures[i]);
}
free(pictures);
return pool;
@@ -338,8 +356,8 @@ static picture_pool_t *DisplayPool(vout_display_t *vd, unsigned count)
{
if ( vd->sys->sys.pool != NULL )
return vd->sys->sys.pool;
- vd->sys->sys.pool = Direct3D9CreatePicturePool(VLC_OBJECT(vd), &vd->sys->d3d_dev,
- vd->sys->d3dtexture_format, &vd->fmt, count);
+ vd->sys->sys.pool = Direct3D9CreatePicturePool(&vd->sys->pool_ctx, &vd->fmt,
+ count);
return vd->sys->sys.pool;
}
@@ -498,7 +516,7 @@ static int Direct3D9ImportPicture(vout_display_t *vd,
if ( copy_rect.left & 1 ) copy_rect.left--;
if ( copy_rect.bottom & 1 ) copy_rect.bottom++;
if ( copy_rect.top & 1 ) copy_rect.top--;
- hr = IDirect3DDevice9_StretchRect(sys->d3d_dev.dev, source, ©_rect, destination,
+ hr = IDirect3DDevice9_StretchRect(sys->pool_ctx.d3d_dev.dev, source, ©_rect, destination,
©_rect, D3DTEXF_NONE);
IDirect3DSurface9_Release(destination);
if (FAILED(hr)) {
@@ -579,8 +597,7 @@ static void Direct3D9DestroyResources(vout_display_t *vd)
static int Direct3D9CreateScene(vout_display_t *vd, const video_format_t *fmt)
{
vout_display_sys_t *sys = vd->sys;
- const d3d9_device_t *p_d3d9_dev = &sys->d3d_dev;
- IDirect3DDevice9 *d3ddev = p_d3d9_dev->dev;
+ IDirect3DDevice9 *d3ddev = sys->pool_ctx.d3d_dev.dev;
HRESULT hr;
/*
@@ -593,7 +610,7 @@ static int Direct3D9CreateScene(vout_display_t *vd, const video_format_t *fmt)
fmt->i_height,
1,
D3DUSAGE_RENDERTARGET,
- p_d3d9_dev->pp.BackBufferFormat,
+ sys->pool_ctx.d3d_dev.pp.BackBufferFormat,
D3DPOOL_DEFAULT,
&sys->sceneTexture,
NULL);
@@ -636,14 +653,14 @@ static int Direct3D9CreateScene(vout_display_t *vd, const video_format_t *fmt)
IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
// Set linear filtering quality
- if (sys->d3d_dev.caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR) {
+ if (sys->pool_ctx.d3d_dev.caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR) {
//msg_Dbg(vd, "Using D3DTEXF_LINEAR for minification");
IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
} else {
//msg_Dbg(vd, "Using D3DTEXF_POINT for minification");
IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
}
- if (sys->d3d_dev.caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR) {
+ if (sys->pool_ctx.d3d_dev.caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR) {
//msg_Dbg(vd, "Using D3DTEXF_LINEAR for magnification");
IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
} else {
@@ -674,7 +691,7 @@ static int Direct3D9CreateScene(vout_display_t *vd, const video_format_t *fmt)
IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
- if (sys->d3d_dev.caps.AlphaCmpCaps & D3DPCMPCAPS_GREATER) {
+ if (sys->pool_ctx.d3d_dev.caps.AlphaCmpCaps & D3DPCMPCAPS_GREATER) {
IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHATESTENABLE,TRUE);
IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHAREF, 0x00);
IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHAFUNC,D3DCMP_GREATER);
@@ -732,7 +749,7 @@ static int Direct3D9CompileShader(vout_display_t *vd, const char *shader_source,
return VLC_EGENERIC;
}
- hr = IDirect3DDevice9_CreatePixelShader(sys->d3d_dev.dev,
+ hr = IDirect3DDevice9_CreatePixelShader(sys->pool_ctx.d3d_dev.dev,
ID3DXBuffer_GetBufferPointer(compiled_shader),
&sys->d3dx_shader);
@@ -850,7 +867,7 @@ static int Direct3D9CreateResources(vout_display_t *vd, video_format_t *fmt)
if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(sys->hd3d.obj,
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
- sys->d3d_dev.pp.BackBufferFormat,
+ sys->pool_ctx.d3d_dev.pp.BackBufferFormat,
D3DUSAGE_DYNAMIC,
D3DRTYPE_TEXTURE,
dfmt))) {
@@ -867,7 +884,7 @@ static int Direct3D9CreateResources(vout_display_t *vd, video_format_t *fmt)
static int Direct3D9Reset(vout_display_t *vd, video_format_t *fmtp)
{
vout_display_sys_t *sys = vd->sys;
- d3d9_device_t *p_d3d9_dev = &sys->d3d_dev;
+ d3d9_device_t *p_d3d9_dev = &sys->pool_ctx.d3d_dev;
if (D3D9_FillPresentationParameters(&sys->hd3d, &vd->source, p_d3d9_dev))
{
@@ -979,7 +996,7 @@ static void Direct3D9ImportSubpicture(vout_display_t *vd,
d3dr->format = sys->d3dregion_format;
d3dr->width = r->fmt.i_width;
d3dr->height = r->fmt.i_height;
- hr = IDirect3DDevice9_CreateTexture(sys->d3d_dev.dev,
+ hr = IDirect3DDevice9_CreateTexture(sys->pool_ctx.d3d_dev.dev,
d3dr->width, d3dr->height,
1,
D3DUSAGE_DYNAMIC,
@@ -1068,7 +1085,7 @@ static int Direct3D9RenderRegion(vout_display_t *vd,
{
vout_display_sys_t *sys = vd->sys;
- IDirect3DDevice9 *d3ddev = vd->sys->d3d_dev.dev;
+ IDirect3DDevice9 *d3ddev = vd->sys->pool_ctx.d3d_dev.dev;
HRESULT hr;
@@ -1150,7 +1167,7 @@ static void Direct3D9RenderScene(vout_display_t *vd,
d3d_region_t *subpicture)
{
vout_display_sys_t *sys = vd->sys;
- IDirect3DDevice9 *d3ddev = sys->d3d_dev.dev;
+ IDirect3DDevice9 *d3ddev = sys->pool_ctx.d3d_dev.dev;
HRESULT hr;
if (sys->clear_scene) {
@@ -1200,7 +1217,7 @@ static void Prepare(vout_display_t *vd, picture_t *picture,
vout_display_sys_t *sys = vd->sys;
picture_sys_t *p_sys = picture->p_sys;
IDirect3DSurface9 *surface = p_sys->surface;
- d3d9_device_t *p_d3d9_dev = &sys->d3d_dev;
+ d3d9_device_t *p_d3d9_dev = &sys->pool_ctx.d3d_dev;
/* FIXME it is a bit ugly, we need the surface to be unlocked for
* rendering.
@@ -1274,7 +1291,7 @@ static void Prepare(vout_display_t *vd, picture_t *picture,
static void Display(vout_display_t *vd, picture_t *picture)
{
vout_display_sys_t *sys = vd->sys;
- const d3d9_device_t *p_d3d9_dev = &sys->d3d_dev;
+ const d3d9_device_t *p_d3d9_dev = &sys->pool_ctx.d3d_dev;
if (sys->lost_not_ready)
return;
@@ -1415,14 +1432,15 @@ static int Direct3D9Open(vout_display_t *vd, video_format_t *fmt)
vout_display_sys_t *sys = vd->sys;
HRESULT hr = D3D9_CreateDevice(vd, &sys->hd3d, sys->sys.hvideownd,
- &vd->source, &sys->d3d_dev);
+ &vd->source, &sys->pool_ctx.d3d_dev);
if (FAILED(hr)) {
msg_Err( vd, "D3D9 Creation failed! (hr=0x%0lx)", hr);
return VLC_EGENERIC;
}
+ sys->pool_ctx.o = VLC_OBJECT(vd);
- const d3d9_device_t *p_d3d9_dev = &sys->d3d_dev;
+ const d3d9_device_t *p_d3d9_dev = &sys->pool_ctx.d3d_dev;
/* */
RECT *display = &vd->sys->sys.rect_display;
display->left = 0;
@@ -1444,7 +1462,7 @@ static int Direct3D9Open(vout_display_t *vd, video_format_t *fmt)
fmt->i_rmask = d3dfmt->rmask;
fmt->i_gmask = d3dfmt->gmask;
fmt->i_bmask = d3dfmt->bmask;
- sys->d3dtexture_format = d3dfmt;
+ sys->pool_ctx.d3dtexture_format = d3dfmt;
UpdateRects(vd, true);
@@ -1461,7 +1479,7 @@ static int Direct3D9Open(vout_display_t *vd, video_format_t *fmt)
return VLC_SUCCESS;
error:
- D3D9_ReleaseDevice(&sys->d3d_dev);
+ D3D9_ReleaseDevice(&sys->pool_ctx.d3d_dev);
return VLC_EGENERIC;
}
@@ -1473,7 +1491,7 @@ static void Direct3D9Close(vout_display_t *vd)
vout_display_sys_t *sys = vd->sys;
Direct3D9DestroyResources(vd);
- D3D9_ReleaseDevice(&sys->d3d_dev);
+ D3D9_ReleaseDevice(&sys->pool_ctx.d3d_dev);
}
static int ControlReopenDevice(vout_display_t *vd, video_format_t *fmtp)
@@ -1708,11 +1726,11 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
info.has_pictures_invalid = !is_d3d9_opaque(fmt.i_chroma);
if (var_InheritBool(vd, "direct3d9-hw-blending") &&
sys->d3dregion_format != D3DFMT_UNKNOWN &&
- (sys->d3d_dev.caps.SrcBlendCaps & D3DPBLENDCAPS_SRCALPHA) &&
- (sys->d3d_dev.caps.DestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA) &&
- (sys->d3d_dev.caps.TextureCaps & D3DPTEXTURECAPS_ALPHA) &&
- (sys->d3d_dev.caps.TextureOpCaps & D3DTEXOPCAPS_SELECTARG1) &&
- (sys->d3d_dev.caps.TextureOpCaps & D3DTEXOPCAPS_MODULATE))
+ (sys->pool_ctx.d3d_dev.caps.SrcBlendCaps & D3DPBLENDCAPS_SRCALPHA) &&
+ (sys->pool_ctx.d3d_dev.caps.DestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA) &&
+ (sys->pool_ctx.d3d_dev.caps.TextureCaps & D3DPTEXTURECAPS_ALPHA) &&
+ (sys->pool_ctx.d3d_dev.caps.TextureOpCaps & D3DTEXOPCAPS_SELECTARG1) &&
+ (sys->pool_ctx.d3d_dev.caps.TextureOpCaps & D3DTEXOPCAPS_MODULATE))
info.subpicture_chromas = d3d_subpicture_chromas;
else
info.subpicture_chromas = NULL;
@@ -1782,7 +1800,7 @@ struct glpriv
{
struct wgl_vt vt;
d3d9_handle_t hd3d;
- d3d9_device_t d3d_dev;
+ struct vout_pool_context pool_ctx;
HANDLE gl_handle_d3d;
HANDLE gl_render;
IDirect3DSurface9 *dx_render;
@@ -1813,7 +1831,7 @@ GLConvUpdate(const opengl_tex_converter_t *tc, GLuint *textures,
.right = pic->format.i_visible_width,
.bottom = pic->format.i_visible_height
};
- hr = IDirect3DDevice9Ex_StretchRect(priv->d3d_dev.devex, picsys->surface,
+ hr = IDirect3DDevice9Ex_StretchRect(priv->pool_ctx.d3d_dev.devex, picsys->surface,
&rect, priv->dx_render, NULL, D3DTEXF_NONE);
if (FAILED(hr))
{
@@ -1836,8 +1854,8 @@ static picture_pool_t *
GLConvGetPool(const opengl_tex_converter_t *tc, unsigned requested_count)
{
struct glpriv *priv = tc->priv;
- return Direct3D9CreatePicturePool(VLC_OBJECT(tc->gl), &priv->d3d_dev, NULL,
- &tc->fmt, requested_count);
+ return Direct3D9CreatePicturePool(&priv->pool_ctx, &tc->fmt,
+ requested_count);
}
static int
@@ -1887,7 +1905,7 @@ GLConvClose(vlc_object_t *obj)
if (priv->dx_render)
IDirect3DSurface9_Release(priv->dx_render);
- D3D9_ReleaseDevice(&priv->d3d_dev);
+ D3D9_ReleaseDevice(&priv->pool_ctx.d3d_dev);
D3D9_Destroy(&priv->hd3d);
free(tc->priv);
}
@@ -1942,12 +1960,12 @@ GLConvOpen(vlc_object_t *obj)
}
if (FAILED(D3D9_CreateDevice(obj, &priv->hd3d, tc->gl->surface->handle.hwnd,
- &tc->fmt, &priv->d3d_dev)))
+ &tc->fmt, &priv->pool_ctx.d3d_dev)))
goto error;
HRESULT hr;
HANDLE shared_handle = NULL;
- hr = IDirect3DDevice9Ex_CreateRenderTarget(priv->d3d_dev.devex,
+ hr = IDirect3DDevice9Ex_CreateRenderTarget(priv->pool_ctx.d3d_dev.devex,
tc->fmt.i_visible_width,
tc->fmt.i_visible_height,
D3DFMT_X8R8G8B8,
@@ -1962,12 +1980,13 @@ GLConvOpen(vlc_object_t *obj)
if (shared_handle)
priv->vt.DXSetResourceShareHandleNV(priv->dx_render, shared_handle);
- priv->gl_handle_d3d = priv->vt.DXOpenDeviceNV(priv->d3d_dev.dev);
+ priv->gl_handle_d3d = priv->vt.DXOpenDeviceNV(priv->pool_ctx.d3d_dev.dev);
if (!priv->gl_handle_d3d)
{
msg_Warn(obj, "DXOpenDeviceNV failed: %lu", GetLastError());
goto error;
}
+ priv->pool_ctx.o = obj;
tc->pf_update = GLConvUpdate;
tc->pf_get_pool = GLConvGetPool;
--
2.17.1
More information about the vlc-devel
mailing list