changeset 19938:f862045246a9

Aggregate multiple small EOSD textures into one large since hundreds of texture creates are very slow. Might cause artefacts with scaled OSD since large textures are not cleared each time.
author reimar
date Fri, 22 Sep 2006 20:23:17 +0000
parents 34796c9b8667
children 1eb8f5470cba
files libvo/vo_gl.c
diffstat 1 files changed, 57 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/vo_gl.c	Fri Sep 22 20:19:51 2006 +0000
+++ b/libvo/vo_gl.c	Fri Sep 22 20:23:17 2006 +0000
@@ -53,6 +53,7 @@
 static GLuint osdatex[MAX_OSD_PARTS];
 #endif
 static GLuint *eosdtex;
+static GLuint largeeosdtex[2];
 //! Display lists that draw the OSD parts
 static GLuint osdDispList[MAX_OSD_PARTS];
 #ifndef FAST_OSD
@@ -247,36 +248,87 @@
  */
 static void genEOSD(ass_image_t *img) {
   int sx, sy;
+  int tinytexcur = 0;
+  int smalltexcur = 0;
   GLuint *curtex;
   GLint scale_type = (scaled_osd) ? GL_LINEAR : GL_NEAREST;
   ass_image_t *i;
+  int cnt;
   clearEOSD();
   if (!img)
     return;
+  if (!largeeosdtex[0]) {
+    glGenTextures(2, largeeosdtex);
+    BindTexture(gl_target, largeeosdtex[0]);
+    glCreateClearTex(gl_target, GL_ALPHA, scale_type, 512, 512, 0);
+    BindTexture(gl_target, largeeosdtex[1]);
+    glCreateClearTex(gl_target, GL_ALPHA, scale_type, 512, 512, 0);
+  }
   for (i = img; i; i = i->next)
+  {
+    if (i->w <= 0 || i->h <= 0 || i->stride < i->w)
+      continue;
+    if (i->w < 16 && i->h < 16 && tinytexcur < 1024)
+      tinytexcur++;
+    else if (i->w < 32 && i->h < 32 && smalltexcur < 256)
+      smalltexcur++;
+    else
     eosdtexCnt++;
+  }
+  if (eosdtexCnt) {
   eosdtex = calloc(eosdtexCnt, sizeof(GLuint));
   glGenTextures(eosdtexCnt, eosdtex);
+  }
+  tinytexcur = smalltexcur = 0;
   for (i = img, curtex = eosdtex; i; i = i->next) {
+    int x = 0, y = 0;
     if (i->w <= 0 || i->h <= 0 || i->stride < i->w) {
       mp_msg(MSGT_VO, MSGL_V, "Invalid dimensions OSD for part!\n");
       continue;
     }
+    if (i->w < 16 && i->h < 16 && tinytexcur < 1024) {
+      x = (tinytexcur & 31) << 4;
+      y = (tinytexcur >> 5) << 4;
+      BindTexture(gl_target, largeeosdtex[0]);
+      tinytexcur++;
+    } else if (i->w < 32 && i->h < 32 && smalltexcur < 256) {
+      x = (smalltexcur & 15) << 5;
+      y = (smalltexcur >> 4) << 5;
+      BindTexture(gl_target, largeeosdtex[1]);
+      smalltexcur++;
+    } else {
     texSize(i->w, i->h, &sx, &sy);
     BindTexture(gl_target, *curtex++);
     glCreateClearTex(gl_target, GL_ALPHA, scale_type, sx, sy, 0);
+    }
     glUploadTex(gl_target, GL_ALPHA, GL_UNSIGNED_BYTE, i->bitmap, i->stride,
-                0, 0, i->w, i->h, 0);
+                x, y, i->w, i->h, 0);
   }
   eosdDispList = glGenLists(1);
   glNewList(eosdDispList, GL_COMPILE);
+  tinytexcur = smalltexcur = 0;
   for (i = img, curtex = eosdtex; i; i = i->next) {
+    int x = 0, y = 0;
     if (i->w <= 0 || i->h <= 0 || i->stride < i->w)
       continue;
     glColor4ub(i->color >> 24, (i->color >> 16) & 0xff, (i->color >> 8) & 0xff, 255 - (i->color & 0xff));
+    if (i->w < 16 && i->h < 16 && tinytexcur < 1024) {
+      x = (tinytexcur & 31) << 4;
+      y = (tinytexcur >> 5) << 4;
+      sx = sy = 512;
+      BindTexture(gl_target, largeeosdtex[0]);
+      tinytexcur++;
+    } else if (i->w < 32 && i->h < 32 && smalltexcur < 256) {
+      x = (smalltexcur & 15) << 5;
+      y = (smalltexcur >> 4) << 5;
+      sx = sy = 512;
+      BindTexture(gl_target, largeeosdtex[1]);
+      smalltexcur++;
+    } else {
     texSize(i->w, i->h, &sx, &sy);
     BindTexture(gl_target, *curtex++);
-    glDrawTex(i->dst_x, i->dst_y, i->w, i->h, 0, 0, i->w, i->h, sx, sy, use_rectangle == 1, 0, 0);
+    }
+    glDrawTex(i->dst_x, i->dst_y, i->w, i->h, x, y, i->w, i->h, sx, sy, use_rectangle == 1, 0, 0);
   }
   glEndList();
   BindTexture(gl_target, 0);
@@ -297,6 +349,9 @@
   default_texs[0] = 0;
   clearOSD();
   clearEOSD();
+  if (largeeosdtex[0])
+    glDeleteTextures(2, largeeosdtex);
+  largeeosdtex[0] = 0;
   if (DeleteBuffers && gl_buffer)
     DeleteBuffers(1, &gl_buffer);
   gl_buffer = 0; gl_buffersize = 0;