symbian-qemu-0.9.1-12/libsdl-trunk/src/video/x11/SDL_x11yuv.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 1997-2006 Sam Lantinga
       
     4 
       
     5     This library is free software; you can redistribute it and/or
       
     6     modify it under the terms of the GNU Lesser General Public
       
     7     License as published by the Free Software Foundation; either
       
     8     version 2.1 of the License, or (at your option) any later version.
       
     9 
       
    10     This library is distributed in the hope that it will be useful,
       
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13     Lesser General Public License for more details.
       
    14 
       
    15     You should have received a copy of the GNU Lesser General Public
       
    16     License along with this library; if not, write to the Free Software
       
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    18 
       
    19     Sam Lantinga
       
    20     slouken@libsdl.org
       
    21 */
       
    22 #include "SDL_config.h"
       
    23 
       
    24 /* This is the XFree86 Xv extension implementation of YUV video overlays */
       
    25 
       
    26 #if SDL_VIDEO_DRIVER_X11_XV
       
    27 
       
    28 #include <X11/Xlib.h>
       
    29 #ifndef NO_SHARED_MEMORY
       
    30 #include <sys/ipc.h>
       
    31 #include <sys/shm.h>
       
    32 #include <X11/extensions/XShm.h>
       
    33 #endif
       
    34 #include "../Xext/extensions/Xvlib.h"
       
    35 
       
    36 #include "SDL_x11yuv_c.h"
       
    37 #include "../SDL_yuvfuncs.h"
       
    38 
       
    39 #define XFREE86_REFRESH_HACK
       
    40 #ifdef XFREE86_REFRESH_HACK
       
    41 #include "SDL_x11image_c.h"
       
    42 #endif
       
    43 
       
    44 /* Workaround when pitch != width */
       
    45 #define PITCH_WORKAROUND
       
    46 
       
    47 /* Workaround intel i810 video overlay waiting with failing until the
       
    48    first Xv[Shm]PutImage call <sigh> */
       
    49 #define INTEL_XV_BADALLOC_WORKAROUND
       
    50 
       
    51 /* Fix for the NVidia GeForce 2 - use the last available adaptor */
       
    52 /*#define USE_LAST_ADAPTOR*/  /* Apparently the NVidia drivers are fixed */
       
    53 
       
    54 /* The functions used to manipulate software video overlays */
       
    55 static struct private_yuvhwfuncs x11_yuvfuncs = {
       
    56 	X11_LockYUVOverlay,
       
    57 	X11_UnlockYUVOverlay,
       
    58 	X11_DisplayYUVOverlay,
       
    59 	X11_FreeYUVOverlay
       
    60 };
       
    61 
       
    62 struct private_yuvhwdata {
       
    63 	int port;
       
    64 #ifndef NO_SHARED_MEMORY
       
    65 	int yuv_use_mitshm;
       
    66 	XShmSegmentInfo yuvshm;
       
    67 #endif
       
    68 	SDL_NAME(XvImage) *image;
       
    69 };
       
    70 
       
    71 
       
    72 static int (*X_handler)(Display *, XErrorEvent *) = NULL;
       
    73 
       
    74 #ifndef NO_SHARED_MEMORY
       
    75 /* Shared memory error handler routine */
       
    76 static int shm_error;
       
    77 static int shm_errhandler(Display *d, XErrorEvent *e)
       
    78 {
       
    79         if ( e->error_code == BadAccess ) {
       
    80         	shm_error = True;
       
    81         	return(0);
       
    82         } else
       
    83 		return(X_handler(d,e));
       
    84 }
       
    85 #endif /* !NO_SHARED_MEMORY */
       
    86 
       
    87 static int xv_error;
       
    88 static int xv_errhandler(Display *d, XErrorEvent *e)
       
    89 {
       
    90         if ( e->error_code == BadMatch ) {
       
    91         	xv_error = True;
       
    92         	return(0);
       
    93         } else
       
    94 		return(X_handler(d,e));
       
    95 }
       
    96 
       
    97 #ifdef INTEL_XV_BADALLOC_WORKAROUND
       
    98 static int intel_errhandler(Display *d, XErrorEvent *e)
       
    99 {
       
   100         if ( e->error_code == BadAlloc ) {
       
   101         	xv_error = True;
       
   102         	return(0);
       
   103         } else
       
   104 		return(X_handler(d,e));
       
   105 }
       
   106 
       
   107 static void X11_ClearYUVOverlay(SDL_Overlay *overlay)
       
   108 {
       
   109 	int x,y;
       
   110 	    
       
   111 	switch (overlay->format)
       
   112 	{
       
   113 	case SDL_YV12_OVERLAY:
       
   114 	case SDL_IYUV_OVERLAY:
       
   115 		for (y = 0; y < overlay->h; y++)
       
   116 			memset(overlay->pixels[0] + y * overlay->pitches[0],
       
   117 				0, overlay->w);
       
   118 		
       
   119 		for (y = 0; y < (overlay->h / 2); y++)
       
   120 		{
       
   121 			memset(overlay->pixels[1] + y * overlay->pitches[1],
       
   122 				-128, overlay->w / 2);
       
   123 			memset(overlay->pixels[2] + y * overlay->pitches[2],
       
   124 				-128, overlay->w / 2);
       
   125 		}
       
   126 		break;
       
   127 	case SDL_YUY2_OVERLAY:
       
   128 	case SDL_YVYU_OVERLAY:
       
   129 		for (y = 0; y < overlay->h; y++)
       
   130 		{
       
   131 			for (x = 0; x < overlay->w; x += 2)
       
   132 			{
       
   133 				Uint8 *pixel_pair = overlay->pixels[0] +
       
   134 					y * overlay->pitches[0] + x * 2;
       
   135 				pixel_pair[0] = 0;
       
   136 				pixel_pair[1] = -128;
       
   137 				pixel_pair[2] = 0;
       
   138 				pixel_pair[3] = -128;
       
   139 			}
       
   140 		}
       
   141 		break;
       
   142 	case SDL_UYVY_OVERLAY:
       
   143 		for (y = 0; y < overlay->h; y++)
       
   144 		{
       
   145 			for (x = 0; x < overlay->w; x += 2)
       
   146 			{
       
   147 				Uint8 *pixel_pair = overlay->pixels[0] +
       
   148 					y * overlay->pitches[0] + x * 2;
       
   149 				pixel_pair[0] = -128;
       
   150 				pixel_pair[1] = 0;
       
   151 				pixel_pair[2] = -128;
       
   152 				pixel_pair[3] = 0;
       
   153 			}
       
   154 		}
       
   155 		break;
       
   156 	}
       
   157 }
       
   158 #endif
       
   159 
       
   160 SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
       
   161 {
       
   162 	SDL_Overlay *overlay;
       
   163 	struct private_yuvhwdata *hwdata;
       
   164 	int xv_port;
       
   165 	unsigned int i, j, k;
       
   166 	unsigned int adaptors;
       
   167 	SDL_NAME(XvAdaptorInfo) *ainfo;
       
   168 	int bpp;
       
   169 #ifndef NO_SHARED_MEMORY
       
   170 	XShmSegmentInfo *yuvshm;
       
   171 #endif
       
   172 #ifdef INTEL_XV_BADALLOC_WORKAROUND
       
   173 	int intel_adapter = False;
       
   174 #endif
       
   175 
       
   176 	/* Look for the XVideo extension with a valid port for this format */
       
   177 	xv_port = -1;
       
   178 	if ( (Success == SDL_NAME(XvQueryExtension)(GFX_Display, &j, &j, &j, &j, &j)) &&
       
   179 	     (Success == SDL_NAME(XvQueryAdaptors)(GFX_Display,
       
   180 	                                 RootWindow(GFX_Display, SDL_Screen),
       
   181 	                                 &adaptors, &ainfo)) ) {
       
   182 #ifdef USE_LAST_ADAPTOR
       
   183 		for ( i=0; i < adaptors; ++i )
       
   184 #else
       
   185 		for ( i=0; (i < adaptors) && (xv_port == -1); ++i )
       
   186 #endif /* USE_LAST_ADAPTOR */
       
   187 		{
       
   188 			/* Check to see if the visual can be used */
       
   189 			if ( BUGGY_XFREE86(<=, 4001) ) {
       
   190 				int visual_ok = 0;
       
   191 				for ( j=0; j<ainfo[i].num_formats; ++j ) {
       
   192 					if ( ainfo[i].formats[j].visual_id ==
       
   193 							SDL_Visual->visualid ) {
       
   194 						visual_ok = 1;
       
   195 						break;
       
   196 					}
       
   197 				}
       
   198 				if ( ! visual_ok ) {
       
   199 					continue;
       
   200 				}
       
   201 			}
       
   202 #ifdef INTEL_XV_BADALLOC_WORKAROUND
       
   203 			if ( !strcmp(ainfo[i].name, "Intel(R) Video Overla"))
       
   204 				intel_adapter = True;
       
   205 			else
       
   206 				intel_adapter = False;
       
   207 #endif
       
   208 			if ( (ainfo[i].type & XvInputMask) &&
       
   209 			     (ainfo[i].type & XvImageMask) ) {
       
   210 				int num_formats;
       
   211 				SDL_NAME(XvImageFormatValues) *formats;
       
   212 				formats = SDL_NAME(XvListImageFormats)(GFX_Display,
       
   213 				              ainfo[i].base_id, &num_formats);
       
   214 #ifdef USE_LAST_ADAPTOR
       
   215 				for ( j=0; j < num_formats; ++j )
       
   216 #else
       
   217 				for ( j=0; (j < num_formats) && (xv_port == -1); ++j )
       
   218 #endif /* USE_LAST_ADAPTOR */
       
   219 				{
       
   220 					if ( (Uint32)formats[j].id == format ) {
       
   221 						for ( k=0; k < ainfo[i].num_ports; ++k ) {
       
   222 							if ( Success == SDL_NAME(XvGrabPort)(GFX_Display, ainfo[i].base_id+k, CurrentTime) ) {
       
   223 								xv_port = ainfo[i].base_id+k;
       
   224 								break;
       
   225 							}
       
   226 						}
       
   227 					}
       
   228 				}
       
   229 				if ( formats ) {
       
   230 					XFree(formats);
       
   231 				}
       
   232 			}
       
   233 		}
       
   234 		SDL_NAME(XvFreeAdaptorInfo)(ainfo);
       
   235 	}
       
   236 
       
   237 	/* Precalculate the bpp for the pitch workaround below */
       
   238 	switch (format) {
       
   239 	    /* Add any other cases we need to support... */
       
   240 	    case SDL_YUY2_OVERLAY:
       
   241 	    case SDL_UYVY_OVERLAY:
       
   242 	    case SDL_YVYU_OVERLAY:
       
   243 		bpp = 2;
       
   244 		break;
       
   245 	    default:
       
   246 		bpp = 1;
       
   247 		break;
       
   248 	}
       
   249 
       
   250 #if 0
       
   251     /*
       
   252      * !!! FIXME:
       
   253      * "Here are some diffs for X11 and yuv.  Note that the last part 2nd
       
   254      *  diff should probably be a new call to XvQueryAdaptorFree with ainfo
       
   255      *  and the number of adaptors, instead of the loop through like I did."
       
   256      *
       
   257      *  ACHTUNG: This is broken! It looks like XvFreeAdaptorInfo does this
       
   258      *  for you, so we end up with a double-free. I need to look at this
       
   259      *  more closely...  --ryan.
       
   260      */
       
   261  	for ( i=0; i < adaptors; ++i ) {
       
   262  	  if (ainfo[i].name != NULL) Xfree(ainfo[i].name);
       
   263  	  if (ainfo[i].formats != NULL) Xfree(ainfo[i].formats);
       
   264    	}
       
   265  	Xfree(ainfo);
       
   266 #endif
       
   267 
       
   268 	if ( xv_port == -1 ) {
       
   269 		SDL_SetError("No available video ports for requested format");
       
   270 		return(NULL);
       
   271 	}
       
   272 
       
   273 	/* Enable auto-painting of the overlay colorkey */
       
   274 	{
       
   275 		static const char *attr[] = { "XV_AUTOPAINT_COLORKEY", "XV_AUTOPAINT_COLOURKEY" };
       
   276 		unsigned int i;
       
   277 
       
   278 		SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, True);
       
   279 		X_handler = XSetErrorHandler(xv_errhandler);
       
   280 		for ( i=0; i < sizeof(attr)/(sizeof attr[0]); ++i ) {
       
   281 			Atom a;
       
   282 
       
   283 			xv_error = False;
       
   284 			a = XInternAtom(GFX_Display, attr[i], True);
       
   285 			if ( a != None ) {
       
   286      				SDL_NAME(XvSetPortAttribute)(GFX_Display, xv_port, a, 1);
       
   287 				XSync(GFX_Display, True);
       
   288 				if ( ! xv_error ) {
       
   289 					break;
       
   290 				}
       
   291 			}
       
   292 		}
       
   293 		XSetErrorHandler(X_handler);
       
   294 		SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, False);
       
   295 	}
       
   296 
       
   297 	/* Create the overlay structure */
       
   298 	overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay);
       
   299 	if ( overlay == NULL ) {
       
   300 		SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime);
       
   301 		SDL_OutOfMemory();
       
   302 		return(NULL);
       
   303 	}
       
   304 	SDL_memset(overlay, 0, (sizeof *overlay));
       
   305 
       
   306 	/* Fill in the basic members */
       
   307 	overlay->format = format;
       
   308 	overlay->w = width;
       
   309 	overlay->h = height;
       
   310 
       
   311 	/* Set up the YUV surface function structure */
       
   312 	overlay->hwfuncs = &x11_yuvfuncs;
       
   313 	overlay->hw_overlay = 1;
       
   314 
       
   315 	/* Create the pixel data and lookup tables */
       
   316 	hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata);
       
   317 	overlay->hwdata = hwdata;
       
   318 	if ( hwdata == NULL ) {
       
   319 		SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime);
       
   320 		SDL_OutOfMemory();
       
   321 		SDL_FreeYUVOverlay(overlay);
       
   322 		return(NULL);
       
   323 	}
       
   324 	hwdata->port = xv_port;
       
   325 #ifndef NO_SHARED_MEMORY
       
   326 	yuvshm = &hwdata->yuvshm;
       
   327 	SDL_memset(yuvshm, 0, sizeof(*yuvshm));
       
   328 	hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format,
       
   329 						   0, width, height, yuvshm);
       
   330 #ifdef PITCH_WORKAROUND
       
   331 	if ( hwdata->image != NULL && hwdata->image->pitches[0] != (width*bpp) ) {
       
   332 		/* Ajust overlay width according to pitch */ 
       
   333 		XFree(hwdata->image);
       
   334 		width = hwdata->image->pitches[0] / bpp;
       
   335 		hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format,
       
   336 							   0, width, height, yuvshm);
       
   337 	}
       
   338 #endif /* PITCH_WORKAROUND */
       
   339 	hwdata->yuv_use_mitshm = (hwdata->image != NULL);
       
   340 	if ( hwdata->yuv_use_mitshm ) {
       
   341 		yuvshm->shmid = shmget(IPC_PRIVATE, hwdata->image->data_size,
       
   342 				       IPC_CREAT | 0777);
       
   343 		if ( yuvshm->shmid >= 0 ) {
       
   344 			yuvshm->shmaddr = (char *)shmat(yuvshm->shmid, 0, 0);
       
   345 			yuvshm->readOnly = False;
       
   346 			if ( yuvshm->shmaddr != (char *)-1 ) {
       
   347 				shm_error = False;
       
   348 				X_handler = XSetErrorHandler(shm_errhandler);
       
   349 				XShmAttach(GFX_Display, yuvshm);
       
   350 				XSync(GFX_Display, True);
       
   351 				XSetErrorHandler(X_handler);
       
   352 				if ( shm_error )
       
   353 					shmdt(yuvshm->shmaddr);
       
   354 			} else {
       
   355 				shm_error = True;
       
   356 			}
       
   357 			shmctl(yuvshm->shmid, IPC_RMID, NULL);
       
   358 		} else {
       
   359 			shm_error = True;
       
   360 		}
       
   361 		if ( shm_error ) {
       
   362 			XFree(hwdata->image);
       
   363 			hwdata->yuv_use_mitshm = 0;
       
   364 		} else {
       
   365 			hwdata->image->data = yuvshm->shmaddr;
       
   366 		}
       
   367 	}
       
   368 	if ( !hwdata->yuv_use_mitshm )
       
   369 #endif /* NO_SHARED_MEMORY */
       
   370 	{
       
   371 		hwdata->image = SDL_NAME(XvCreateImage)(GFX_Display, xv_port, format,
       
   372 							0, width, height);
       
   373 
       
   374 #ifdef PITCH_WORKAROUND
       
   375 		if ( hwdata->image != NULL && hwdata->image->pitches[0] != (width*bpp) ) {
       
   376 			/* Ajust overlay width according to pitch */ 
       
   377 			XFree(hwdata->image);
       
   378 			width = hwdata->image->pitches[0] / bpp;
       
   379 			hwdata->image = SDL_NAME(XvCreateImage)(GFX_Display, xv_port, format,
       
   380 								0, width, height);
       
   381 		}
       
   382 #endif /* PITCH_WORKAROUND */
       
   383 		if ( hwdata->image == NULL ) {
       
   384 			SDL_SetError("Couldn't create XVideo image");
       
   385 			SDL_FreeYUVOverlay(overlay);
       
   386 			return(NULL);
       
   387 		}
       
   388 		hwdata->image->data = SDL_malloc(hwdata->image->data_size);
       
   389 		if ( hwdata->image->data == NULL ) {
       
   390 			SDL_OutOfMemory();
       
   391 			SDL_FreeYUVOverlay(overlay);
       
   392 			return(NULL);
       
   393 		}
       
   394 	}
       
   395 
       
   396 	/* Find the pitch and offset values for the overlay */
       
   397 	overlay->planes = hwdata->image->num_planes;
       
   398 	overlay->pitches = (Uint16 *)SDL_malloc(overlay->planes * sizeof(Uint16));
       
   399 	overlay->pixels = (Uint8 **)SDL_malloc(overlay->planes * sizeof(Uint8 *));
       
   400 	if ( !overlay->pitches || !overlay->pixels ) {
       
   401 		SDL_OutOfMemory();
       
   402 		SDL_FreeYUVOverlay(overlay);
       
   403 		return(NULL);
       
   404 	}
       
   405 	for ( i=0; i<overlay->planes; ++i ) {
       
   406 		overlay->pitches[i] = hwdata->image->pitches[i];
       
   407 		overlay->pixels[i] = (Uint8 *)hwdata->image->data +
       
   408 		                              hwdata->image->offsets[i];
       
   409 	}
       
   410 
       
   411 #ifdef XFREE86_REFRESH_HACK
       
   412 	/* Work around an XFree86 X server bug (?)
       
   413 	   We can't perform normal updates in windows that have video
       
   414 	   being output to them.  See SDL_x11image.c for more details.
       
   415 	 */
       
   416 	X11_DisableAutoRefresh(this);
       
   417 #endif
       
   418 
       
   419 #ifdef INTEL_XV_BADALLOC_WORKAROUND
       
   420 	/* HACK, GRRR sometimes (i810) creating the overlay succeeds, but the
       
   421 	   first call to XvShm[Put]Image to a mapped window fails with:
       
   422 	   "BadAlloc (insufficient resources for operation)". This happens with
       
   423 	   certain formats when the XvImage is too large to the i810's liking.
       
   424 
       
   425 	   We work around this by doing a test XvShm[Put]Image with a black
       
   426 	   Xv image, this may cause some flashing, so only do this check if we
       
   427 	   are running on an intel Xv-adapter. */
       
   428 	if (intel_adapter)
       
   429 	{
       
   430 		xv_error = False;
       
   431 		X_handler = XSetErrorHandler(intel_errhandler);
       
   432 		
       
   433 		X11_ClearYUVOverlay(overlay);
       
   434 
       
   435 		/* We set the destination height and width to 1 pixel to avoid
       
   436 		   putting a large black rectangle over the screen, thus
       
   437 		   strongly reducing possible flashing. */
       
   438 #ifndef NO_SHARED_MEMORY
       
   439 		if ( hwdata->yuv_use_mitshm ) {
       
   440 			SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port,
       
   441 				SDL_Window, SDL_GC,
       
   442 				hwdata->image,
       
   443 				0, 0, overlay->w, overlay->h,
       
   444 				0, 0, 1, 1, False);
       
   445 		}
       
   446 		else
       
   447 #endif
       
   448 		{
       
   449 			SDL_NAME(XvPutImage)(GFX_Display, hwdata->port,
       
   450 				SDL_Window, SDL_GC,
       
   451 				hwdata->image,
       
   452 				0, 0, overlay->w, overlay->h,
       
   453 				0, 0, 1, 1);
       
   454 		}
       
   455 		XSync(GFX_Display, False);
       
   456 		XSetErrorHandler(X_handler);
       
   457 
       
   458 		if (xv_error)
       
   459 		{
       
   460 			X11_FreeYUVOverlay(this, overlay);
       
   461 			return NULL;
       
   462 		}
       
   463 		/* Repair the (1 pixel worth of) damage we've just done */
       
   464 		X11_RefreshDisplay(this);
       
   465 	}
       
   466 #endif
       
   467 
       
   468 	/* We're all done.. */
       
   469 	return(overlay);
       
   470 }
       
   471 
       
   472 int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
       
   473 {
       
   474 	return(0);
       
   475 }
       
   476 
       
   477 void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
       
   478 {
       
   479 	return;
       
   480 }
       
   481 
       
   482 int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst)
       
   483 {
       
   484 	struct private_yuvhwdata *hwdata;
       
   485 
       
   486 	hwdata = overlay->hwdata;
       
   487 
       
   488 #ifndef NO_SHARED_MEMORY
       
   489 	if ( hwdata->yuv_use_mitshm ) {
       
   490 		SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
       
   491 	              hwdata->image,
       
   492 		      src->x, src->y, src->w, src->h,
       
   493 		      dst->x, dst->y, dst->w, dst->h, False);
       
   494 	}
       
   495 	else
       
   496 #endif
       
   497 	{
       
   498 		SDL_NAME(XvPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
       
   499 				     hwdata->image,
       
   500 		                     src->x, src->y, src->w, src->h,
       
   501 		                     dst->x, dst->y, dst->w, dst->h);
       
   502 	}
       
   503 	XSync(GFX_Display, False);
       
   504 	return(0);
       
   505 }
       
   506 
       
   507 void X11_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
       
   508 {
       
   509 	struct private_yuvhwdata *hwdata;
       
   510 
       
   511 	hwdata = overlay->hwdata;
       
   512 	if ( hwdata ) {
       
   513 		SDL_NAME(XvUngrabPort)(GFX_Display, hwdata->port, CurrentTime);
       
   514 #ifndef NO_SHARED_MEMORY
       
   515 		if ( hwdata->yuv_use_mitshm ) {
       
   516 			XShmDetach(GFX_Display, &hwdata->yuvshm);
       
   517 			shmdt(hwdata->yuvshm.shmaddr);
       
   518 		}
       
   519 #endif
       
   520 		if ( hwdata->image ) {
       
   521 			XFree(hwdata->image);
       
   522 		}
       
   523 		SDL_free(hwdata);
       
   524 	}
       
   525 	if ( overlay->pitches ) {
       
   526 		SDL_free(overlay->pitches);
       
   527 		overlay->pitches = NULL;
       
   528 	}
       
   529 	if ( overlay->pixels ) {
       
   530 		SDL_free(overlay->pixels);
       
   531 		overlay->pixels = NULL;
       
   532 	}
       
   533 #ifdef XFREE86_REFRESH_HACK
       
   534 	X11_EnableAutoRefresh(this);
       
   535 #endif
       
   536 }
       
   537 
       
   538 #endif /* SDL_VIDEO_DRIVER_X11_XV */