[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, &copy_rect, destination,
+    hr = IDirect3DDevice9_StretchRect(sys->pool_ctx.d3d_dev.dev, source, &copy_rect, destination,
                                       &copy_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