changeset 2276:558a9397c250

improved gl, please check performance and correct display
author sven
date Fri, 19 Oct 2001 10:09:29 +0000
parents 0e0e6ab17207
children 22452cfc3a55
files libvo/vo_gl2.c
diffstat 1 files changed, 543 insertions(+), 179 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/vo_gl2.c	Fri Oct 19 09:38:43 2001 +0000
+++ b/libvo/vo_gl2.c	Fri Oct 19 10:09:29 2001 +0000
@@ -1,10 +1,5 @@
 #define DISP
 
-// this can be 3 or 4  (regarding 24bpp and 32bpp)
-#define BYTES_PP 3
-
-#define TEXTUREFORMAT_32BPP
-
 /* 
  * video_out_gl.c, X11/OpenGL interface
  * based on video_out_x11 by Aaron Holtzman,
@@ -20,7 +15,6 @@
 #include "video_out.h"
 #include "video_out_internal.h"
 
-
 LIBVO_EXTERN(gl2)
 
 #include <X11/Xlib.h>
@@ -36,7 +30,7 @@
 #include "aspect.h"
 
 #define NDEBUG
-// #undef NDEBUG
+//#undef NDEBUG
 
 static vo_info_t vo_info = 
 {
@@ -47,29 +41,23 @@
 };
 
 /* private prototypes */
-// static void Display_Image (unsigned char *ImageData);
 
 /* local data */
+static unsigned char *ImageDataLocal=NULL;
 static unsigned char *ImageData=NULL;
 
 /* X11 related variables */
-//static Display *mydisplay;
 static Window mywindow;
-//static GC mygc;
-//static XImage *myximage;
-//static int depth,mode;
-//static XWindowAttributes attribs;
 static int X_already_started = 0;
 
 //static int texture_id=1;
 
 static GLXContext wsGLXContext;
-//XVisualInfo        * wsVisualInfo;
 static int                  wsGLXAttrib[] = { GLX_RGBA,
                                        GLX_RED_SIZE,1,
                                        GLX_GREEN_SIZE,1,
                                        GLX_BLUE_SIZE,1,
-//                                       GLX_DEPTH_SIZE,16,
+                                       GLX_ALPHA_SIZE,0,
                                        GLX_DOUBLEBUFFER,
                                        None };
 
@@ -78,6 +66,7 @@
 static uint32_t image_height;
 static uint32_t image_format;
 static uint32_t image_bpp;
+static int      image_mode;
 static uint32_t image_bytes;
 
 static uint32_t texture_width;
@@ -85,6 +74,24 @@
 static int texnumx, texnumy, memory_x_len, memory_x_start_offset, raw_line_len;
 static GLfloat texpercx, texpercy;
 static struct TexSquare * texgrid;
+static GLint    gl_internal_format;
+static char *   gl_internal_format_s;
+static int      rgb_sz, r_sz, g_sz, b_sz, a_sz;
+static GLint    gl_bitmap_format;
+static char *   gl_bitmap_format_s;
+static GLint    gl_bitmap_type;
+static char *   gl_bitmap_type_s;
+static int      gl_alignment;
+static int      isGL12 = GL_FALSE;
+static int      isFullscreen = GL_FALSE;
+
+static int      gl_bilinear=1;
+static int      gl_antialias=0;
+
+static int      used_s=0, used_r=0, used_b=0, used_info_done=0;
+
+static void (*draw_alpha_fnc)
+                 (int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride);
 
 /* The squares that are tiled to make up the game screen polygon */
 
@@ -95,6 +102,8 @@
   int isTexture;
   GLfloat fx1, fy1, fx2, fy2, fx3, fy3, fx4, fy4;
   GLfloat xcov, ycov;
+  int isDirty;
+  int dirtyXoff, dirtyYoff, dirtyWidth, dirtyHeight;
 };
 
 static void CalcFlatPoint(int x,int y,GLfloat *px,GLfloat *py)
@@ -130,16 +139,16 @@
   do
   {
     glTexImage2D (GL_PROXY_TEXTURE_2D, 0,
-		  BYTES_PP,
+		  gl_internal_format,
 		  texture_width, texture_height,
-		  0, (image_bytes==4)?GL_RGBA:GL_BGR, GL_UNSIGNED_BYTE, NULL); 
+		  0, gl_bitmap_format, gl_bitmap_type, NULL); 
 
     glGetTexLevelParameteriv
       (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);
 
-    if (format != BYTES_PP)
+    if (format != gl_internal_format)
     {
-      fprintf (stderr, "GLINFO: Needed texture [%dx%d] too big, trying ",
+      fprintf (stderr, "[gl2] Needed texture [%dx%d] too big, trying ",
 		texture_height, texture_width);
 
       if (texture_width > texture_height)
@@ -166,7 +175,7 @@
       }
     }
   }
-  while (format != BYTES_PP && texture_width > 1 && texture_height > 1);
+  while (format != gl_internal_format && texture_width > 1 && texture_height > 1);
 
   texnumx = image_width / texture_width;
   if ((image_width % texture_width) > 0)
@@ -176,6 +185,9 @@
   if ((image_height % texture_height) > 0)
     texnumy++;
 
+  printf("[gl2] Creating %dx%d textures of size %dx%d ...\n",
+	texnumx, texnumy, texture_width,texture_height, gl_bitmap_format_s);
+
   /* Allocate the texture memory */
 
   texpercx = (GLfloat) texture_width / (GLfloat) image_width;
@@ -189,17 +201,17 @@
   texgrid = (struct TexSquare *)
     calloc (texnumx * texnumy, sizeof (struct TexSquare));
 
-  line_1 = (unsigned char *) ImageData;
-  line_2 = (unsigned char *) ImageData+(image_width*image_bytes);
+  line_1 = (unsigned char *) ImageDataLocal;
+  line_2 = (unsigned char *) ImageDataLocal+(image_width*image_bytes);
 
-  mem_start = (unsigned char *) ImageData;
+  mem_start = (unsigned char *) ImageDataLocal;
 
   raw_line_len = line_2 - line_1;
 
   memory_x_len = raw_line_len / image_bytes;
 
 #ifndef NDEBUG
-  fprintf (stderr, "GLINFO: texture-usage %d*width=%d, %d*height=%d\n",
+  fprintf (stderr, "[gl2] texture-usage %d*width=%d, %d*height=%d\n",
 		 (int) texnumx, (int) texture_width, (int) texnumy,
 		 (int) texture_height);
 #endif
@@ -237,8 +249,10 @@
 		     y * texture_height * raw_line_len +  
 		     memory_x_start_offset;           
 
+      tsq->isDirty=GL_TRUE;
       tsq->isTexture=GL_FALSE;
       tsq->texobj=0;
+      tsq->dirtyXoff=0; tsq->dirtyYoff=0; tsq->dirtyWidth=-1; tsq->dirtyHeight=-1;
 
       glGenTextures (1, &(tsq->texobj));
 
@@ -258,9 +272,10 @@
       }
 
       glTexImage2D (GL_TEXTURE_2D, 0,
-		    BYTES_PP,
+		    gl_internal_format,
 		    texture_width, texture_height,
-		    0, (image_bytes==4)?GL_RGBA:GL_BGR, GL_UNSIGNED_BYTE, NULL); 
+		    0, gl_bitmap_format, gl_bitmap_type, NULL); 
+
       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0);
 
       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -275,6 +290,184 @@
   }  /* for all texnumy */
 }
 
+static void resetTexturePointers(unsigned char *imageSource)
+{
+  unsigned char *line_1=0, *line_2=0, *mem_start=0;
+  struct TexSquare *tsq=0;
+  int x=0, y=0;
+
+  line_1 = (unsigned char *) imageSource;
+  line_2 = (unsigned char *) imageSource+(image_width*image_bytes);
+
+  mem_start = (unsigned char *) imageSource;
+
+  for (y = 0; y < texnumy; y++)
+  {
+    for (x = 0; x < texnumx; x++)
+    {
+      tsq = texgrid + y * texnumx + x;
+
+      /* calculate the pixel store data,
+         to use the machine-bitmap for our texture 
+      */
+      memory_x_start_offset = 0 * image_bytes + 
+                              x * texture_width * image_bytes;
+
+      tsq->texture = line_1 +                           
+		     y * texture_height * raw_line_len +  
+		     memory_x_start_offset;           
+
+    }	/* for all texnumx */
+  }  /* for all texnumy */
+}
+
+static void setupTextureDirtyArea(int x, int y, int w,int h)
+{
+  struct TexSquare *square;
+  int xi, yi, wd, ht, wh, hh;
+  int wdecr, hdecr, xh, yh;
+    
+  wdecr=w; hdecr=h; xh=x; yh=y;
+
+  for (yi = 0; hdecr>0 && yi < texnumy; yi++)
+  {
+    if (yi < texnumy - 1)
+      ht = texture_height;
+    else
+      ht = image_height - texture_height * yi;
+
+    xh =x;
+    wdecr =w;
+
+    for (xi = 0; wdecr>0 && xi < texnumx; xi++)
+    {
+        square = texgrid + yi * texnumx + xi;
+
+	if (xi < texnumx - 1)
+	  wd = texture_width;
+	else
+	  wd = image_width - texture_width * xi;
+
+	if( 0 <= xh && xh < wd &&
+            0 <= yh && yh < ht
+          )
+        {
+        	square->isDirty=GL_TRUE;
+
+		wh=(wdecr<wd)?wdecr:wd-xh;
+		if(wh<0) wh=0;
+
+		hh=(hdecr<ht)?hdecr:ht-yh;
+		if(hh<0) hh=0;
+
+/*
+#ifndef NDEBUG
+     printf("\t %dx%d, %d/%d (%dx%d): %d/%d (%dx%d)\n", 
+	xi, yi, xh, yh, wdecr, hdecr, xh, yh, wh, hh);
+#endif
+*/
+
+		if(xh<square->dirtyXoff)
+			square->dirtyXoff=xh;
+
+		if(yh<square->dirtyYoff)
+			square->dirtyYoff=yh;
+
+		square->dirtyWidth = wd-square->dirtyXoff;
+		square->dirtyHeight = ht-square->dirtyYoff;
+		
+		wdecr-=wh;
+
+		if ( xi == texnumx - 1 )
+			hdecr-=hh;
+        }
+
+	xh-=wd;
+	if(xh<0) xh=0;
+    }
+    yh-=ht;
+    if(yh<0) yh=0;
+  }
+}
+
+static void gl_set_bilinear (int val)
+{
+  int x, y;
+
+  if(val>=0)
+	  gl_bilinear = val;
+  else 
+	  gl_bilinear++;
+
+  gl_bilinear=gl_bilinear%2;
+  /* no mipmap yet .. */
+
+  for (y = 0; y < texnumy; y++)
+  {
+      for (x = 0; x < texnumx; x++)
+      {
+        glBindTexture (GL_TEXTURE_2D, texgrid[y * texnumx + x].texobj);
+
+	switch (gl_bilinear)
+	{
+		case 0:
+			glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
+				GL_NEAREST);
+			glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
+				GL_NEAREST);
+			printf("[gl2] bilinear off\n");
+			break;
+		case 1:
+			glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
+				GL_LINEAR);
+			glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
+				GL_LINEAR);
+			printf("[gl2] bilinear linear\n");
+			break;
+		case 2:
+			glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
+				GL_LINEAR_MIPMAP_NEAREST);
+			glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
+				GL_LINEAR_MIPMAP_NEAREST);
+			printf("[gl2] bilinear mipmap nearest\n");
+			break;
+		case 3:
+			glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
+				GL_LINEAR_MIPMAP_LINEAR);
+			glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
+				GL_LINEAR_MIPMAP_LINEAR);
+			printf("[gl2] bilinear mipmap linear\n");
+			break;
+        }
+      }
+  }
+  fflush(0);
+}
+
+static void gl_set_antialias (int val)
+{
+  gl_antialias=val;
+
+  if (gl_antialias)
+  {
+    glShadeModel (GL_SMOOTH);
+    glEnable (GL_POLYGON_SMOOTH);
+    glEnable (GL_LINE_SMOOTH);
+    glEnable (GL_POINT_SMOOTH);
+    printf("[gl2] antialiasing on\n");
+  }
+  else
+  {
+    glShadeModel (GL_FLAT);
+    glDisable (GL_POLYGON_SMOOTH);
+    glDisable (GL_LINE_SMOOTH);
+    glDisable (GL_POINT_SMOOTH);
+    printf("[gl2] antialiasing off\n");
+  }
+  fflush(0);
+}
+
+
 static void drawTextureDisplay ()
 {
   struct TexSquare *square;
@@ -292,7 +485,7 @@
       if(square->isTexture==GL_FALSE)
       {
 	#ifndef NDEBUG
-	  fprintf (stderr, "GLINFO ain't a texture(update): texnum x=%d, y=%d, texture=%d\n",
+	  fprintf (stderr, "[gl2] ain't a texture(update): texnum x=%d, y=%d, texture=%d\n",
 	  	x, y, square->texobj);
 	#endif
       	continue;
@@ -317,26 +510,20 @@
 		x, y, square->texobj);
       }
 
-      /* This is the quickest way I know of to update the texture */
-	if (x < texnumx - 1)
-	  wd = texture_width;
-	else
-	  wd = image_width - texture_width * x;
+      if(square->isDirty)
+      {
+	glTexSubImage2D (GL_TEXTURE_2D, 0, 
+		 square->dirtyXoff, square->dirtyYoff,
+		 square->dirtyWidth, square->dirtyHeight,
+		 gl_bitmap_format, gl_bitmap_type, square->texture);
 
-	if (y < texnumy - 1)
-	  ht = texture_height;
-	else
-	  ht = image_height - texture_height * y;
-
-	glTexSubImage2D (GL_TEXTURE_2D, 0, 
-		 xoff, yoff,
-		 wd, ht,
-		 (BYTES_PP==4)?GL_RGBA:GL_RGB,        // format
-		 GL_UNSIGNED_BYTE, // type
-		 square->texture);
+        square->isDirty=GL_FALSE;
+        square->dirtyXoff=0; square->dirtyYoff=0; square->dirtyWidth=-1; square->dirtyHeight=-1;
+      }
 
 #ifndef NDEBUG
-        fprintf (stdout, "GLINFO glTexSubImage2D texnum x=%d, y=%d, %d/%d - %d/%d\n", x, y, xoff, yoff, wd, ht);
+        fprintf (stdout, "[gl2] glTexSubImage2D texnum x=%d, y=%d, %d/%d - %d/%d\n", 
+		x, y, square->dirtyXoff, square->dirtyYoff, square->dirtyWidth, square->dirtyHeight);
 #endif
 
 	glBegin(GL_QUADS);
@@ -353,19 +540,13 @@
 	glTexCoord2f (square->xcov, 0);
 	glVertex2f (square->fx2, square->fy2);
 
+	glEnd();
+/*
 #ifndef NDEBUG
-        fprintf (stdout, "GLINFO GL_QUADS texnum x=%d, y=%d, %f/%f %f/%f %f/%f %f/%f\n\n", x, y, square->fx1, square->fy1, square->fx4, square->fy4,
+        fprintf (stdout, "[gl2] GL_QUADS texnum x=%d, y=%d, %f/%f %f/%f %f/%f %f/%f\n\n", x, y, square->fx1, square->fy1, square->fx4, square->fy4,
 	square->fx3, square->fy3, square->fx2, square->fy2);
 #endif
-
-   /*
-    glTexCoord2f(0,0);glVertex2i(0,0);
-    glTexCoord2f(0,1);glVertex2i(0,texture_height);
-    glTexCoord2f(1,1);glVertex2i(texture_width,texture_height);
-    glTexCoord2f(1,0);glVertex2i(texture_width,0);
-   */
-
-	glEnd();
+*/
     } /* for all texnumx */
   } /* for all texnumy */
 
@@ -376,18 +557,39 @@
 
 
 static void resize(int x,int y){
-  printf("[gl] Resize: %dx%d\n",x,y);
-  glViewport( 0, 0, x, y );
+  printf("[gl2] Resize: %dx%d\n",x,y);
+  if( isFullscreen )
+	  glViewport( (vo_screenwidth-x)/2, (vo_screenheight-y)/2, x, y);
+  else 
+	  glViewport( 0, 0, x, y );
 
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
-  //glOrtho(0, image_width, image_height, 0, -1,1);
   glOrtho (0, 1, 1, 0, -1.0, 1.0);
 
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
 }
 
+static void draw_alpha_32(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){
+   vo_draw_alpha_rgb32(w,h,src,srca,stride,ImageData+4*(y0*image_width+x0),4*image_width);
+}
+
+static void draw_alpha_24(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){
+   vo_draw_alpha_rgb24(w,h,src,srca,stride,ImageData+3*(y0*image_width+x0),3*image_width);
+}
+
+static void draw_alpha_16(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){
+   vo_draw_alpha_rgb16(w,h,src,srca,stride,ImageData+2*(y0*image_width+x0),2*image_width);
+}
+
+static void draw_alpha_15(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){
+   vo_draw_alpha_rgb15(w,h,src,srca,stride,ImageData+2*(y0*image_width+x0),2*image_width);
+}
+
+static void draw_alpha_null(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){
+}
+
 /* connect to server, create and map window,
  * allocate colors and (shared) memory
  */
@@ -406,6 +608,8 @@
 	XSetWindowAttributes xswa;
 	unsigned long xswamask;
 
+        const unsigned char * glVersion;
+
 	image_height = height;
 	image_width = width;
 	image_format = format;
@@ -413,23 +617,24 @@
 	if (X_already_started) return -1;
 	if(!vo_init()) return -1;
 
-	aspect_save_orig(width,height);
-	aspect_save_prescale(d_width,d_height);
-	aspect_save_screenres(vo_screenwidth,vo_screenheight);
-
 	X_already_started++;
 
-	aspect(&d_width,&d_height,A_NOZOOM);
-#ifdef X11_FULLSCREEN
-        if( flags&0x01 ){ // (-fs)
-          aspect(&d_width,&d_height,A_ZOOM);
+        if( flags&0x01 )
+        {
+	  isFullscreen = GL_TRUE;
+          aspect(&d_width,&d_height,vo_screenwidth,vo_screenheight);
+		hint.x = 0;
+		hint.y = 0;
+		hint.width = vo_screenwidth;
+		hint.height = vo_screenheight;
+		hint.flags = PPosition | PSize;
+        } else {
+		hint.x = 0;
+		hint.y = 0;
+		hint.width = d_width;
+		hint.height = d_height;
+		hint.flags = PPosition | PSize;
         }
-#endif
-	hint.x = 0;
-	hint.y = 0;
-	hint.width = d_width;
-	hint.height = d_height;
-	hint.flags = PPosition | PSize;
 
 	/* Get some colors */
 
@@ -444,7 +649,7 @@
   vinfo=glXChooseVisual( mDisplay,mScreen,wsGLXAttrib );
   if (vinfo == NULL)
   {
-    printf("[gl] no GLX support present\n");
+    printf("[gl2] no GLX support present\n");
     return -1;
   }
 
@@ -453,18 +658,14 @@
 //	xswa.colormap         = XCreateColormap(mDisplay, mRootWin, vinfo.visual, AllocNone);
 	xswa.colormap         = XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocNone);
 	xswamask = CWBackPixel | CWBorderPixel | CWColormap;
-//  xswamask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWCursor | CWOverrideRedirect | CWSaveUnder | CWX | CWY | CWWidth | CWHeight;
 
   mywindow = XCreateWindow(mDisplay, RootWindow(mDisplay,mScreen),
     hint.x, hint.y, hint.width, hint.height, 4, vinfo->depth,CopyFromParent,vinfo->visual,xswamask,&xswa);
 
-  vo_x11_classhint( mDisplay,mywindow,"gl" );
+  vo_x11_classhint( mDisplay,mywindow,"gl2" );
   vo_hidecursor(mDisplay,mywindow);
 
   wsGLXContext=glXCreateContext( mDisplay,vinfo,NULL,True );
-//  XStoreName( wsDisplay,wsMyWin,wsSysName );
-
-//  printf("GLXcontext ok\n");
 
   if ( flags&0x01 ) vo_x11_decoration( mDisplay,mywindow,0 );
 
@@ -477,6 +678,7 @@
 	/* Map window. */
 
 	XMapWindow(mDisplay, mywindow);
+        XClearWindow(mDisplay,mywindow);
 
 	/* Wait for map. */
 	do 
@@ -492,94 +694,237 @@
 	XFlush(mDisplay);
 	XSync(mDisplay, False);
 
-//	mygc = XCreateGC(mDisplay, mywindow, 0L, &xgcv);
-
-//		myximage = XGetImage(mDisplay, mywindow, 0, 0,
-//		width, image_height, AllPlanes, ZPixmap);
-//		ImageData = myximage->data;
-//	bpp = myximage->bits_per_pixel;
-
 	//XSelectInput(mDisplay, mywindow, StructureNotifyMask); // !!!!
         XSelectInput(mDisplay, mywindow, StructureNotifyMask | KeyPressMask );
 
-//  printf("Window setup ok\n");
+  glVersion = glGetString(GL_VERSION);
+
+  printf("[gl2] OpenGL Driver Information:\n");
+  printf("\tvendor: %s,\n\trenderer %s,\n\tversion %s\n", 
+  	glGetString(GL_VENDOR), 
+	glGetString(GL_RENDERER),
+	glVersion);
+
+  if(glVersion[0]>'1' ||
+     (glVersion[0]=='1' && glVersion[2]>='2') )
+	  isGL12 = GL_TRUE;
+  else
+	  isGL12 = GL_FALSE;
 
-#if 0
-	// If we have blue in the lowest bit then obviously RGB 
-	mode = ((myximage->blue_mask & 0x01) != 0) ? MODE_RGB : MODE_BGR;
-#ifdef WORDS_BIGENDIAN 
-	if (myximage->byte_order != MSBFirst)
-#else
-	if (myximage->byte_order != LSBFirst) 
-#endif
-	{
-		printf("[gl] no support for non-native XImage byte order!\n");
-		return -1;
-	}
+  if(isGL12)
+  {
+	printf("[gl2] You have an OpenGL >= 1.2 capable drivers, GOOD (16bpp and BGR is ok !)\n");
+  } else {
+	printf("[gl2] You have an OpenGL < 1.2 drivers, BAD (16bpp and BGR may be damaged  !)\n");
+  }
+
+  if(glXGetConfig(mDisplay,vinfo,GLX_RED_SIZE, &r_sz)!=0) 
+	  r_sz=0;
+  if(glXGetConfig(mDisplay,vinfo,GLX_RED_SIZE, &g_sz)!=0) 
+	  g_sz=0;
+  if(glXGetConfig(mDisplay,vinfo,GLX_RED_SIZE, &b_sz)!=0) 
+	  b_sz=0;
+  if(glXGetConfig(mDisplay,vinfo,GLX_ALPHA_SIZE, &a_sz)!=0) 
+	  b_sz=0;
+
+  rgb_sz=r_sz+g_sz+b_sz;
+  if(rgb_sz<=0) rgb_sz=24;
 
-  printf("DEPTH=%d  BPP=%d\n",depth,bpp);
+  if(r_sz==3 && g_sz==3 && b_sz==2 && a_sz==0) {
+	  gl_internal_format=GL_R3_G3_B2;
+	  gl_internal_format_s="GL_R3_G3_B2";
+	  image_bpp = 8;
+  } else if(r_sz==4 && g_sz==4 && b_sz==4 && a_sz==0) {
+	  gl_internal_format=GL_RGB4;
+	  gl_internal_format_s="GL_RGB4";
+	  image_bpp = 16;
+  } else if(r_sz==5 && g_sz==5 && b_sz==5 && a_sz==0) {
+	  gl_internal_format=GL_RGB5;
+	  gl_internal_format_s="GL_RGB5";
+	  image_bpp = 16;
+  } else if(r_sz==8 && g_sz==8 && b_sz==8 && a_sz==0) {
+	  gl_internal_format=GL_RGB8;
+	  gl_internal_format_s="GL_RGB8";
+#ifdef HAVE_MMX
+	  image_bpp = 32;
+#else
+	  image_bpp = 24;
 #endif
+  } else if(r_sz==10 && g_sz==10 && b_sz==10 && a_sz==0) {
+	  gl_internal_format=GL_RGB10;
+	  gl_internal_format_s="GL_RGB10";
+	  image_bpp = 32;
+  } else if(r_sz==2 && g_sz==2 && b_sz==2 && a_sz==2) {
+	  gl_internal_format=GL_RGBA2;
+	  gl_internal_format_s="GL_RGBA2";
+	  image_bpp = 8;
+  } else if(r_sz==4 && g_sz==4 && b_sz==4 && a_sz==4) {
+	  gl_internal_format=GL_RGBA4;
+	  gl_internal_format_s="GL_RGBA4";
+	  image_bpp = 16;
+  } else if(r_sz==5 && g_sz==5 && b_sz==5 && a_sz==1) {
+	  gl_internal_format=GL_RGB5_A1;
+	  gl_internal_format_s="GL_RGB5_A1";
+	  image_bpp = 16;
+  } else if(r_sz==8 && g_sz==8 && b_sz==8 && a_sz==8) {
+	  gl_internal_format=GL_RGBA8;
+	  gl_internal_format_s="GL_RGBA8";
+#ifdef HAVE_MMX
+	  image_bpp = 32;
+#else
+	  image_bpp = 24;
+#endif
+  } else if(r_sz==10 && g_sz==10 && b_sz==10 && a_sz==2) {
+	  gl_internal_format=GL_RGB10_A2;
+	  gl_internal_format_s="GL_RGB10_A2";
+	  image_bpp = 32;
+  } else {
+	  gl_internal_format=GL_RGB;
+	  gl_internal_format_s="GL_RGB";
+#ifdef HAVE_MMX
+	  image_bpp = 16;
+#else
+	  image_bpp = 24;
+#endif
+  }
 
-	/* 
-	 * If depth is 24 then it may either be a 3 or 4 byte per pixel
-	 * format. We can't use bpp because then we would lose the 
-	 * distinction between 15/16bit depth (2 byte formate assumed).
-	 *
-	 * FIXME - change yuv2rgb_init to take both depth and bpp
-	 * parameters
-	 */
-
-  if(format==IMGFMT_YV12){
-    yuv2rgb_init(8*BYTES_PP, MODE_BGR);
-    printf("[gl] YUV init OK!\n");
-    image_bpp=8*BYTES_PP;
-    image_bytes=BYTES_PP;
+  if(image_format==IMGFMT_YV12) 
+  {
+    image_mode= MODE_RGB;
+    yuv2rgb_init(image_bpp, image_mode);
+    printf("[gl2] YUV init OK!\n");
   } else {
     image_bpp=format&0xFF;
-    image_bytes=(image_bpp+7)/8;
+
+    if((format & IMGFMT_BGR_MASK) == IMGFMT_BGR)
+        image_mode= MODE_BGR;
+    else
+        image_mode= MODE_RGB;
   }
 
-  ImageData=malloc(image_width*image_height*image_bytes);
-  memset(ImageData,128,image_width*image_height*image_bytes);
+  image_bytes=(image_bpp+7)/8;
+
+  draw_alpha_fnc=draw_alpha_null;
+
+  switch(image_bpp)
+  {
+  	case 15:
+  	case 16:	
+                        if(image_mode!=MODE_BGR)
+			{
+			        gl_bitmap_format   = GL_RGB;
+			        gl_bitmap_format_s ="GL_RGB";
+				gl_bitmap_type     = GL_UNSIGNED_SHORT_5_6_5;
+				gl_bitmap_type_s   ="GL_UNSIGNED_SHORT_5_6_5";
+			} else {
+			        gl_bitmap_format   = GL_BGR;
+			        gl_bitmap_format_s ="GL_BGR";
+				gl_bitmap_type     = GL_UNSIGNED_SHORT_5_6_5;
+				gl_bitmap_type_s   ="GL_UNSIGNED_SHORT_5_6_5";
+			}
+
+			if (image_bpp==15)
+			     draw_alpha_fnc=draw_alpha_15;
+			else
+			     draw_alpha_fnc=draw_alpha_16;
+
+			break;
+  	case 24:	
+                        if(image_mode!=MODE_BGR)
+			{
+				/* RGB888 */
+				gl_bitmap_format   = GL_RGB;
+				gl_bitmap_format_s ="GL_RGB";
+			} else {
+				/* BGR888 */
+				gl_bitmap_format   = GL_BGR;
+				gl_bitmap_format_s ="GL_BGR";
+			}
+			gl_bitmap_type   = GL_UNSIGNED_BYTE;
+			gl_bitmap_type_s ="GL_UNSIGNED_BYTE";
+
+			draw_alpha_fnc=draw_alpha_24; break;
+			break;
+  	case 32:	
+			/* RGBA8888 */
+			gl_bitmap_format   = GL_BGRA;
+			gl_bitmap_format_s ="GL_BGRA";
+
+                        if(image_mode!=MODE_BGR)
+			{
+				gl_bitmap_type   = GL_UNSIGNED_INT_8_8_8_8_REV;
+				gl_bitmap_type_s ="GL_UNSIGNED_INT_8_8_8_8_REV";
+			} else {
+				gl_bitmap_type   = GL_UNSIGNED_INT_8_8_8_8;
+				gl_bitmap_type_s ="GL_UNSIGNED_INT_8_8_8_8";
+			}
+
+			draw_alpha_fnc=draw_alpha_32; break;
+			break;
+  }
+
+  r_sz=0; g_sz=0; b_sz=0;
+  rgb_sz=0;
+  a_sz=0;
+
+  ImageDataLocal=malloc(image_width*image_height*image_bytes);
+  memset(ImageDataLocal,128,image_width*image_height*image_bytes);
+
+  ImageData=ImageDataLocal;
 
   texture_width=image_width;
   texture_height=image_height;
   initTextures();
 
-  printf("[gl] Creating %dx%d texture...\n",texture_width,texture_height);
-
   glDisable(GL_BLEND); 
   glDisable(GL_DEPTH_TEST);
   glDepthMask(GL_FALSE);
   glDisable(GL_CULL_FACE);
 
   glPixelStorei (GL_UNPACK_ROW_LENGTH, memory_x_len);
-//  glPixelStorei (GL_UNPACK_ALIGNMENT, 8); // causes non-12*n wide images to be broken
+
+  /**
+   * may give a little speed up for a kinda burst read ..
+   */
+  if( (image_width*image_bpp)%8 == 0 )
+  	gl_alignment=8;
+  else if( (image_width*image_bpp)%4 == 0 )
+  	gl_alignment=4;
+  else if( (image_width*image_bpp)%2 == 0 )
+  	gl_alignment=2;
+  else
+  	gl_alignment=1;
+
+  glPixelStorei (GL_UNPACK_ALIGNMENT, gl_alignment); 
+
   glEnable (GL_TEXTURE_2D);
 
+  gl_set_antialias(0);
+  gl_set_bilinear(1);
+  
   drawTextureDisplay ();
 
-  printf("[gl] Creating %dx%d texture...\n",texture_width,texture_height);
-
-/*
-#if 1
-//  glBindTexture(GL_TEXTURE_2D, texture_id);
-  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-#ifdef TEXTUREFORMAT_32BPP
-  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture_width, texture_height, 0,
+  printf("[gl2] Using image_bpp=%d, image_bytes=%d, isBGR=%d, \n\tgl_bitmap_format=%s, gl_bitmap_type=%s, \n\tgl_alignment=%d, rgb_size=%d (%d,%d,%d), a_sz=%d, \n\tgl_internal_format=%s, tweaks=%s\n",
+  	image_bpp, image_bytes, image_mode==MODE_BGR, 
+        gl_bitmap_format_s, gl_bitmap_type_s, gl_alignment,
+	rgb_sz, r_sz, g_sz, b_sz, a_sz, gl_internal_format_s,
+#ifdef HAVE_MMX
+	"mmx_bpp"
 #else
-  glTexImage2D(GL_TEXTURE_2D, 0, BYTES_PP, texture_width, texture_height, 0,
+	"none"
 #endif
-       (image_bytes==4)?GL_RGBA:GL_BGR, GL_UNSIGNED_BYTE, NULL);
-#endif
-*/
+);
 
   resize(d_width,d_height);
 
-  glClearColor( 1.0f,0.0f,1.0f,0.0f );
+  glClearColor( 0.0f,0.0f,0.0f,0.0f );
   glClear( GL_COLOR_BUFFER_BIT );
 
+  used_s=0;
+  used_r=0;
+  used_b=0;
+  used_info_done=0;
+
 //  printf("OpenGL setup OK!\n");
 
       saver_off(mDisplay);  // turning off screen saver
@@ -602,16 +947,53 @@
 	X_already_started = 0;
 }
 
+static int gl_handlekey(int key)
+{
+	if(key=='a'||key=='A')
+	{
+		gl_set_antialias(!gl_antialias);
+		return 0;
+	}
+	else if(key=='b'||key=='B')
+	{
+		gl_set_bilinear(-1);
+		return 0;
+	}
+	return 1;
+}
 
 static void check_events(void)
 {
-    int e=vo_x11_check_events(mDisplay);
-    if(e&VO_EVENT_RESIZE) resize(vo_dwidth,vo_dheight);
+	 XEvent         Event;
+	 char           buf[100];
+	 KeySym         keySym;
+	 int            key;
+	 static XComposeStatus stat;
+	 int e;
+
+	 while ( XPending( mDisplay ) )
+	 {
+	      XNextEvent( mDisplay,&Event );
+	      if( Event.type == KeyPress )
+	      {
+
+		       XLookupString( &Event.xkey,buf,sizeof(buf),&keySym,&stat );
+		       key = (keySym&0xff00) != 0? ( (keySym&0x00ff) + 256 ) 
+		                                 : ( keySym ) ;
+		       if(gl_handlekey(key))
+			       XPutBackEvent(mDisplay, &Event);
+		       break;
+	      } else {
+	      	       XPutBackEvent(mDisplay, &Event);
+	               break;
+	      }
+         }
+         e=vo_x11_check_events(mDisplay);
+         if(e&VO_EVENT_RESIZE) resize(vo_dwidth,vo_dheight);
 }
 
 static void draw_osd(void)
-{
-}
+{ vo_draw_text(image_width,image_height,draw_alpha_fnc); }
 
 static void
 flip_page(void)
@@ -623,76 +1005,58 @@
   glFinish();
   glXSwapBuffers( mDisplay,mywindow );
   
+  if(!used_info_done)
+  {
+	  if(used_s) printf("[gl2] using slice method yuv\n");
+	  if(used_r) printf("[gl2] using frame method rgb\n");
+	  if(used_b) printf("[gl2] using frame method bgr\n");
+	  used_info_done=1;
+          fflush(0);
+  }
 }
 
 //static inline uint32_t draw_slice_x11(uint8_t *src[], uint32_t slice_num)
 static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
 {
-    int i;
-    int dstride=w*BYTES_PP;
-    
-//    dstride=(dstride+15)&(~15);
-
-	yuv2rgb(ImageData+y*raw_line_len, src[0], src[1], src[2], 
-			w,h, dstride, stride[0],stride[1]);
-
-//	emms ();
+    yuv2rgb(ImageData+y*raw_line_len, src[0], src[1], src[2], 
+			w,h, image_width*image_bytes, stride[0],stride[1]);
 
 #ifndef NDEBUG
      printf("slice: %d/%d -> %d/%d (%dx%d)\n", 
 	x, y, x+w-1, y+h-1, w, h);
 #endif
 
-	return 0;
+     used_s=1;
+
+    setupTextureDirtyArea(x, y, w, h);
+
+    return 0;
 }
 
 static inline uint32_t 
 draw_frame_x11_bgr(uint8_t *src[])
 {
-uint8_t *s=src[0];
-uint8_t *d=ImageData;
-uint8_t *de=d+3*image_width*image_height;
-int i;
+      resetTexturePointers((unsigned char *)src[0]);
+      ImageData=(unsigned char *)src[0];
 
-      // RGB->BGR
-      while(d<de){
-#if 1
-        d[0]=s[2];
-        d[1]=s[1];
-        d[2]=s[0];
-        s+=3;d+=3;
-#else
-	// R1 G1 B1 R2   G2 B2
-	// B1 G1 R1 B2   G2 R2
+      // for(i=0;i<image_height;i++) ImageData[image_width*image_bytes*i+20]=128;
 
-        unsigned int a=*((unsigned int*)s);
-	unsigned short b=*((unsigned short*)(s+4));
-	*((unsigned int*)d)=((a>>16)&0xFF)|(a&0xFF00)|((a&0xFF)<<16)|((b>>8)<<24);
-	*((unsigned short*)(d+4))=(b&0xFF)|((a>>24)<<8);
-	s+=6;d+=6;
-#endif
-      }
+     used_b=1;
 
-    for(i=0;i<image_height;i++) ImageData[image_width*BYTES_PP*i+20]=128;
-
-//     printf("draw_frame_x11_bgr\n");
-//    drawTextureDisplay ();
-
-//	Display_Image(ImageData);
+     setupTextureDirtyArea(0, 0, image_width, image_height);
 	return 0; 
 }
 
 static inline uint32_t 
 draw_frame_x11_rgb(uint8_t *src[])
 {
-int i;
-uint8_t *ImageData=src[0];
+      resetTexturePointers((unsigned char *)src[0]);
+      ImageData=(unsigned char *)src[0];
 
-     printf("draw_frame_x11_rgb not implemented\n");
-//    drawTextureDisplay ();
+     used_r=1;
 
-//	Display_Image(ImageData);
-	return 0; 
+     setupTextureDirtyArea(0, 0, image_width, image_height);
+      return 0; 
 }