# HG changeset patch # User sven # Date 1003486169 0 # Node ID 558a9397c250af14f9ffec0ef060b106cf2c29d3 # Parent 0e0e6ab172076c8f0569703bc9fbebc437f31650 improved gl, please check performance and correct display diff -r 0e0e6ab17207 -r 558a9397c250 libvo/vo_gl2.c --- 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 @@ -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=(wdecrdirtyXoff) + square->dirtyXoff=xh; + + if(yhdirtyYoff) + 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>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