[vlc-commits] Cached texture created for subpicture rendering (direct3d).

Laurent Aimar git at videolan.org
Thu Apr 28 23:35:09 CEST 2011


vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Fri Apr 15 20:57:14 2011 +0200| [c513cf2ac3103734e4ef515d2ba044c1f09a43c2] | committer: Laurent Aimar

Cached texture created for subpicture rendering (direct3d).

It avoids creating/destroying texture uselessly.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c513cf2ac3103734e4ef515d2ba044c1f09a43c2
---

 modules/video_output/msw/common.h   |    2 +
 modules/video_output/msw/direct3d.c |   76 ++++++++++++++++++++++++++--------
 2 files changed, 60 insertions(+), 18 deletions(-)

diff --git a/modules/video_output/msw/common.h b/modules/video_output/msw/common.h
index af66808..303f3a2 100644
--- a/modules/video_output/msw/common.h
+++ b/modules/video_output/msw/common.h
@@ -182,6 +182,8 @@ struct vout_display_sys_t
     // scene objects
     LPDIRECT3DTEXTURE9      d3dtex;
     LPDIRECT3DVERTEXBUFFER9 d3dvtc;
+    int                     d3dregion_count;
+    struct d3d_region_t     *d3dregion;
 
     picture_resource_t      resource;
 
diff --git a/modules/video_output/msw/direct3d.c b/modules/video_output/msw/direct3d.c
index d1fbf9d..639c315 100644
--- a/modules/video_output/msw/direct3d.c
+++ b/modules/video_output/msw/direct3d.c
@@ -125,11 +125,16 @@ typedef struct
 } CUSTOMVERTEX;
 #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
 
-typedef struct {
+typedef struct d3d_region_t {
+    D3DFORMAT          format;
+    unsigned           width;
+    unsigned           height;
     CUSTOMVERTEX       vertex[4];
     LPDIRECT3DTEXTURE9 texture;
 } d3d_region_t;
 
+static void Direct3DDeleteRegions(int, d3d_region_t *);
+
 static int  Direct3DImportPicture(vout_display_t *vd, d3d_region_t *, LPDIRECT3DSURFACE9 surface);
 static void Direct3DImportSubpicture(vout_display_t *vd, int *, d3d_region_t **, subpicture_t *);
 
@@ -316,9 +321,9 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
         Direct3DRenderScene(vd, &picture_region,
                             subpicture_region_count, subpicture_region);
 
-        for (int i = 0; i < subpicture_region_count; i++)
-            IDirect3DTexture9_Release(subpicture_region[i].texture);
-        free(subpicture_region);
+        Direct3DDeleteRegions(sys->d3dregion_count, sys->d3dregion);
+        sys->d3dregion_count = subpicture_region_count;
+        sys->d3dregion       = subpicture_region;
     }
 }
 
@@ -1015,6 +1020,9 @@ static int Direct3DCreateScene(vout_display_t *vd, const video_format_t *fmt)
     sys->d3dtex = d3dtex;
     sys->d3dvtc = d3dvtc;
 
+    sys->d3dregion_count = 0;
+    sys->d3dregion       = NULL;
+
     // Texture coordinates outside the range [0.0, 1.0] are set
     // to the texture color at 0.0 or 1.0, respectively.
     IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
@@ -1085,6 +1093,8 @@ static void Direct3DDestroyScene(vout_display_t *vd)
 {
     vout_display_sys_t *sys = vd->sys;
 
+    Direct3DDeleteRegions(sys->d3dregion_count, sys->d3dregion);
+
     LPDIRECT3DVERTEXBUFFER9 d3dvtc = sys->d3dvtc;
     if (d3dvtc)
         IDirect3DVertexBuffer9_Release(d3dvtc);
@@ -1095,6 +1105,10 @@ static void Direct3DDestroyScene(vout_display_t *vd)
 
     sys->d3dvtc = NULL;
     sys->d3dtex = NULL;
+
+    sys->d3dregion_count = 0;
+    sys->d3dregion       = NULL;
+
     msg_Dbg(vd, "Direct3D scene released successfully");
 }
 
@@ -1179,6 +1193,15 @@ static int Direct3DImportPicture(vout_display_t *vd,
     return VLC_SUCCESS;
 }
 
+static void Direct3DDeleteRegions(int count, d3d_region_t *region)
+{
+    for (int i = 0; i < count; i++) {
+        if (region[i].texture)
+            IDirect3DTexture9_Release(region[i].texture);
+    }
+    free(region);
+}
+
 static void Direct3DImportSubpicture(vout_display_t *vd,
                                      int *count_ptr, d3d_region_t **region,
                                      subpicture_t *subpicture)
@@ -1202,22 +1225,39 @@ static void Direct3DImportSubpicture(vout_display_t *vd,
         HRESULT hr;
 
         d3dr->texture = NULL;
-        hr = IDirect3DDevice9_CreateTexture(sys->d3ddev,
-                                            r->fmt.i_visible_width, r->fmt.i_visible_height,
-                                            1,
-                                            D3DUSAGE_DYNAMIC,
-                                            D3DFMT_A8R8G8B8,
-                                            D3DPOOL_DEFAULT,
-                                            &d3dr->texture,
-                                            NULL);
-        if (FAILED(hr)) {
-            d3dr->texture = NULL;
-            msg_Err(vd, "Failed to create %dx%d texture for OSD",
+        for (int j = 0; j < sys->d3dregion_count; j++) {
+            d3d_region_t *cache = &sys->d3dregion[j];
+            if (cache->texture &&
+                cache->format == D3DFMT_A8R8G8B8 &&
+                cache->width  == r->fmt.i_visible_width &&
+                cache->height == r->fmt.i_visible_height) {
+                msg_Dbg(vd, "Reusing %dx%d texture for OSD",
+                        cache->width, cache->height);
+                *d3dr = *cache;
+                memset(cache, 0, sizeof(*cache));
+            }
+        }
+        if (!d3dr->texture) {
+            d3dr->format = D3DFMT_A8R8G8B8;
+            d3dr->width  = r->fmt.i_visible_width;
+            d3dr->height = r->fmt.i_visible_height;
+            hr = IDirect3DDevice9_CreateTexture(sys->d3ddev,
+                                                d3dr->width, d3dr->height,
+                                                1,
+                                                D3DUSAGE_DYNAMIC,
+                                                d3dr->format,
+                                                D3DPOOL_DEFAULT,
+                                                &d3dr->texture,
+                                                NULL);
+            if (FAILED(hr)) {
+                d3dr->texture = NULL;
+                msg_Err(vd, "Failed to create %dx%d texture for OSD",
+                        d3dr->width, d3dr->height);
+                continue;
+            }
+            msg_Dbg(vd, "Created %dx%d texture for OSD",
                     r->fmt.i_visible_width, r->fmt.i_visible_height);
-            continue;
         }
-        msg_Dbg(vd, "Created %dx%d texture for OSD",
-                r->fmt.i_visible_width, r->fmt.i_visible_height);
 
         D3DLOCKED_RECT lock;
         hr = IDirect3DTexture9_LockRect(d3dr->texture, 0, &lock, NULL, 0);



More information about the vlc-commits mailing list