Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11image.c @ 270:37fa1484f71b
From: "Mattias Engdeg�rd" <f91-men@nada.kth.se>
To: slouken@devolution.com
Subject: Re: [SDL] Question about SDL_FillRect()
I benchmarked with and without clipping UpdateRects and was unable to find
any difference on my moderately slow machine. Anyway, I haven't added
clipping in this patch, but fixed a couple of bugs and generally cleaned
up some of the X11 image code. Most importantly, UpdateRects now checks
for both zero height and width. Also, I eliminated the entire code to
byteswap X11 images since X11 can do that automatically if you ask it
nicely :-)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 18 Jan 2002 22:02:03 +0000 |
parents | e8157fcb3114 |
children | f6ffac90895c |
comparison
equal
deleted
inserted
replaced
269:4125b9859c71 | 270:37fa1484f71b |
---|---|
42 static int shm_error; | 42 static int shm_error; |
43 static int (*X_handler)(Display *, XErrorEvent *) = NULL; | 43 static int (*X_handler)(Display *, XErrorEvent *) = NULL; |
44 static int shm_errhandler(Display *d, XErrorEvent *e) | 44 static int shm_errhandler(Display *d, XErrorEvent *e) |
45 { | 45 { |
46 if ( e->error_code == BadAccess ) { | 46 if ( e->error_code == BadAccess ) { |
47 ++shm_error; | 47 shm_error = 1; |
48 return(0); | 48 return(0); |
49 } else | 49 } else |
50 return(X_handler(d,e)); | 50 return(X_handler(d,e)); |
51 } | 51 } |
52 | |
53 static void try_mitshm(_THIS, SDL_Surface *screen) | |
54 { | |
55 if(!use_mitshm) | |
56 return; | |
57 shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch, | |
58 IPC_CREAT | 0777); | |
59 if ( shminfo.shmid >= 0 ) { | |
60 shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0); | |
61 shminfo.readOnly = False; | |
62 if ( shminfo.shmaddr != (char *)-1 ) { | |
63 shm_error = False; | |
64 X_handler = XSetErrorHandler(shm_errhandler); | |
65 XShmAttach(SDL_Display, &shminfo); | |
66 XSync(SDL_Display, True); | |
67 XSetErrorHandler(X_handler); | |
68 if (shm_error) | |
69 shmdt(shminfo.shmaddr); | |
70 } else { | |
71 shm_error = True; | |
72 } | |
73 shmctl(shminfo.shmid, IPC_RMID, NULL); | |
74 } else { | |
75 shm_error = True; | |
76 } | |
77 if ( shm_error ) | |
78 use_mitshm = 0; | |
79 if ( use_mitshm ) | |
80 screen->pixels = shminfo.shmaddr; | |
81 } | |
52 #endif /* ! NO_SHARED_MEMORY */ | 82 #endif /* ! NO_SHARED_MEMORY */ |
53 | 83 |
54 /* Various screen update functions available */ | 84 /* Various screen update functions available */ |
55 static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); | 85 static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); |
56 static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects); | 86 static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects); |
57 | 87 |
58 int X11_SetupImage(_THIS, SDL_Surface *screen) | 88 int X11_SetupImage(_THIS, SDL_Surface *screen) |
59 { | 89 { |
60 #ifdef NO_SHARED_MEMORY | 90 #ifndef NO_SHARED_MEMORY |
61 screen->pixels = malloc(screen->h*screen->pitch); | 91 try_mitshm(this, screen); |
62 #else | 92 if(use_mitshm) { |
63 /* Allocate shared memory if possible */ | 93 SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual, |
64 if ( use_mitshm ) { | 94 this->hidden->depth, ZPixmap, |
65 shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch, | 95 shminfo.shmaddr, &shminfo, |
66 IPC_CREAT|0777); | 96 screen->w, screen->h); |
67 if ( shminfo.shmid >= 0 ) { | 97 if(!SDL_Ximage) { |
68 shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0); | 98 XShmDetach(SDL_Display, &shminfo); |
69 shminfo.readOnly = False; | 99 XSync(SDL_Display, False); |
70 if ( shminfo.shmaddr != (char *)-1 ) { | 100 shmdt(shminfo.shmaddr); |
71 shm_error = False; | 101 screen->pixels = NULL; |
72 X_handler = XSetErrorHandler(shm_errhandler); | 102 goto error; |
73 XShmAttach(SDL_Display, &shminfo); | 103 } |
74 XSync(SDL_Display, True); | 104 this->UpdateRects = X11_MITSHMUpdate; |
75 XSetErrorHandler(X_handler); | 105 } |
76 if ( shm_error == True ) | 106 #endif /* not NO_SHARED_MEMORY */ |
77 shmdt(shminfo.shmaddr); | 107 if(!use_mitshm) { |
78 } else { | 108 int bpp; |
79 shm_error = True; | |
80 } | |
81 shmctl(shminfo.shmid, IPC_RMID, NULL); | |
82 } else { | |
83 shm_error = True; | |
84 } | |
85 if ( shm_error == True ) | |
86 use_mitshm = 0; | |
87 } | |
88 if ( use_mitshm ) { | |
89 screen->pixels = shminfo.shmaddr; | |
90 } else { | |
91 screen->pixels = malloc(screen->h*screen->pitch); | 109 screen->pixels = malloc(screen->h*screen->pitch); |
92 } | 110 if ( screen->pixels == NULL ) { |
93 #endif /* NO_SHARED_MEMORY */ | 111 SDL_OutOfMemory(); |
94 if ( screen->pixels == NULL ) { | 112 return -1; |
95 SDL_OutOfMemory(); | 113 } |
96 return(-1); | 114 bpp = screen->format->BytesPerPixel; |
97 } | |
98 | |
99 #ifdef NO_SHARED_MEMORY | |
100 { | |
101 int bpp = screen->format->BytesPerPixel; | |
102 SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual, | 115 SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual, |
103 this->hidden->depth, ZPixmap, 0, | 116 this->hidden->depth, ZPixmap, 0, |
104 (char *)screen->pixels, | 117 (char *)screen->pixels, |
105 screen->w, screen->h, | 118 screen->w, screen->h, |
106 (bpp == 3) ? 32 : bpp * 8, | 119 32, 0); |
107 0); | 120 if ( SDL_Ximage == NULL ) |
108 } | 121 goto error; |
109 #else | 122 /* XPutImage will convert byte sex automatically */ |
110 if ( use_mitshm ) { | 123 SDL_Ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) |
111 SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual, | 124 ? MSBFirst : LSBFirst; |
112 this->hidden->depth, ZPixmap, | 125 this->UpdateRects = X11_NormalUpdate; |
113 shminfo.shmaddr, &shminfo, | |
114 screen->w, screen->h); | |
115 } else { | |
116 int bpp = screen->format->BytesPerPixel; | |
117 SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual, | |
118 this->hidden->depth, ZPixmap, 0, | |
119 (char *)screen->pixels, | |
120 screen->w, screen->h, | |
121 (bpp == 3) ? 32 : bpp * 8, | |
122 0); | |
123 } | |
124 #endif /* NO_SHARED_MEMORY */ | |
125 if ( SDL_Ximage == NULL ) { | |
126 SDL_SetError("Couldn't create XImage"); | |
127 #ifndef NO_SHARED_MEMORY | |
128 if ( use_mitshm ) { | |
129 XShmDetach(SDL_Display, &shminfo); | |
130 XSync(SDL_Display, False); | |
131 shmdt(shminfo.shmaddr); | |
132 screen->pixels = NULL; | |
133 } | |
134 #endif /* ! NO_SHARED_MEMORY */ | |
135 return(-1); | |
136 } | 126 } |
137 screen->pitch = SDL_Ximage->bytes_per_line; | 127 screen->pitch = SDL_Ximage->bytes_per_line; |
138 | |
139 /* Determine what blit function to use */ | |
140 #ifdef NO_SHARED_MEMORY | |
141 this->UpdateRects = X11_NormalUpdate; | |
142 #else | |
143 if ( use_mitshm ) { | |
144 this->UpdateRects = X11_MITSHMUpdate; | |
145 } else { | |
146 this->UpdateRects = X11_NormalUpdate; | |
147 } | |
148 #endif | |
149 return(0); | 128 return(0); |
129 | |
130 error: | |
131 SDL_SetError("Couldn't create XImage"); | |
132 return 1; | |
150 } | 133 } |
151 | 134 |
152 void X11_DestroyImage(_THIS, SDL_Surface *screen) | 135 void X11_DestroyImage(_THIS, SDL_Surface *screen) |
153 { | 136 { |
154 if ( SDL_Ximage ) { | 137 if ( SDL_Ximage ) { |
248 int X11_FlipHWSurface(_THIS, SDL_Surface *surface) | 231 int X11_FlipHWSurface(_THIS, SDL_Surface *surface) |
249 { | 232 { |
250 return(0); | 233 return(0); |
251 } | 234 } |
252 | 235 |
253 /* Byte-swap the pixels in the display image */ | |
254 static void X11_SwapAllPixels(SDL_Surface *screen) | |
255 { | |
256 int x, y; | |
257 | |
258 switch (screen->format->BytesPerPixel) { | |
259 case 2: { | |
260 Uint16 *spot; | |
261 for ( y=0; y<screen->h; ++y ) { | |
262 spot = (Uint16 *) ((Uint8 *)screen->pixels + | |
263 y * screen->pitch); | |
264 for ( x=0; x<screen->w; ++x, ++spot ) { | |
265 *spot = SDL_Swap16(*spot); | |
266 } | |
267 } | |
268 } | |
269 break; | |
270 | |
271 case 4: { | |
272 Uint32 *spot; | |
273 for ( y=0; y<screen->h; ++y ) { | |
274 spot = (Uint32 *) ((Uint8 *)screen->pixels + | |
275 y * screen->pitch); | |
276 for ( x=0; x<screen->w; ++x, ++spot ) { | |
277 *spot = SDL_Swap32(*spot); | |
278 } | |
279 } | |
280 } | |
281 break; | |
282 | |
283 default: | |
284 /* should never get here */ | |
285 break; | |
286 } | |
287 } | |
288 static void X11_SwapPixels(SDL_Surface *screen, SDL_Rect *rect) | |
289 { | |
290 int x, minx, maxx; | |
291 int y, miny, maxy; | |
292 | |
293 switch (screen->format->BytesPerPixel) { | |
294 case 2: { | |
295 Uint16 *spot; | |
296 minx = rect->x; | |
297 maxx = rect->x + rect->w; | |
298 miny = rect->y; | |
299 maxy = rect->y + rect->h; | |
300 for ( y=miny; y<maxy; ++y ) { | |
301 spot = (Uint16 *) ((Uint8 *)screen->pixels + | |
302 y * screen->pitch + minx * 2); | |
303 for ( x=minx; x<maxx; ++x, ++spot ) { | |
304 *spot = SDL_Swap16(*spot); | |
305 } | |
306 } | |
307 } | |
308 break; | |
309 | |
310 case 4: { | |
311 Uint32 *spot; | |
312 minx = rect->x; | |
313 maxx = rect->x + rect->w; | |
314 miny = rect->y; | |
315 maxy = rect->y + rect->h; | |
316 for ( y=miny; y<maxy; ++y ) { | |
317 spot = (Uint32 *) ((Uint8 *)screen->pixels + | |
318 y * screen->pitch + minx * 4); | |
319 for ( x=minx; x<maxx; ++x, ++spot ) { | |
320 *spot = SDL_Swap32(*spot); | |
321 } | |
322 } | |
323 } | |
324 break; | |
325 | |
326 default: | |
327 /* should never get here */ | |
328 break; | |
329 } | |
330 } | |
331 | |
332 static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) | 236 static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) |
333 { | 237 { |
334 int i; | 238 int i; |
335 | 239 |
336 /* Check for endian-swapped X server, swap if necessary (VERY slow!) */ | 240 for (i = 0; i < numrects; ++i) { |
337 if ( swap_pixels && | 241 if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ |
338 ((this->screen->format->BytesPerPixel%2) == 0) ) { | 242 continue; |
339 for ( i=0; i<numrects; ++i ) { | 243 } |
340 if ( ! rects[i].w ) { /* Clipped? */ | 244 XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, |
341 continue; | 245 rects[i].x, rects[i].y, |
342 } | 246 rects[i].x, rects[i].y, rects[i].w, rects[i].h); |
343 X11_SwapPixels(this->screen, rects + i); | |
344 XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, | |
345 rects[i].x, rects[i].y, | |
346 rects[i].x, rects[i].y, rects[i].w, rects[i].h); | |
347 X11_SwapPixels(this->screen, rects + i); | |
348 } | |
349 } else { | |
350 for ( i=0; i<numrects; ++i ) { | |
351 if ( ! rects[i].w ) { /* Clipped? */ | |
352 continue; | |
353 } | |
354 XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, | |
355 rects[i].x, rects[i].y, | |
356 rects[i].x, rects[i].y, rects[i].w, rects[i].h); | |
357 } | |
358 } | 247 } |
359 if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { | 248 if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { |
360 XFlush(GFX_Display); | 249 XFlush(GFX_Display); |
361 ++blit_queued; | 250 blit_queued = 1; |
362 } else { | 251 } else { |
363 XSync(GFX_Display, False); | 252 XSync(GFX_Display, False); |
364 } | 253 } |
365 } | 254 } |
366 | 255 |
368 { | 257 { |
369 #ifndef NO_SHARED_MEMORY | 258 #ifndef NO_SHARED_MEMORY |
370 int i; | 259 int i; |
371 | 260 |
372 for ( i=0; i<numrects; ++i ) { | 261 for ( i=0; i<numrects; ++i ) { |
373 if ( ! rects[i].w ) { /* Clipped? */ | 262 if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ |
374 continue; | 263 continue; |
375 } | 264 } |
376 XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, | 265 XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, |
377 rects[i].x, rects[i].y, | 266 rects[i].x, rects[i].y, |
378 rects[i].x, rects[i].y, rects[i].w, rects[i].h, | 267 rects[i].x, rects[i].y, rects[i].w, rects[i].h, |
379 False); | 268 False); |
380 } | 269 } |
381 if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { | 270 if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { |
382 XFlush(GFX_Display); | 271 XFlush(GFX_Display); |
383 ++blit_queued; | 272 blit_queued = 1; |
384 } else { | 273 } else { |
385 XSync(GFX_Display, False); | 274 XSync(GFX_Display, False); |
386 } | 275 } |
387 #endif /* ! NO_SHARED_MEMORY */ | 276 #endif /* ! NO_SHARED_MEMORY */ |
388 } | 277 } |
417 #ifndef NO_SHARED_MEMORY | 306 #ifndef NO_SHARED_MEMORY |
418 if ( this->UpdateRects == X11_MITSHMUpdate ) { | 307 if ( this->UpdateRects == X11_MITSHMUpdate ) { |
419 XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, | 308 XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, |
420 0, 0, 0, 0, this->screen->w, this->screen->h, | 309 0, 0, 0, 0, this->screen->w, this->screen->h, |
421 False); | 310 False); |
422 } else { | 311 } else |
423 #else | 312 #endif /* ! NO_SHARED_MEMORY */ |
424 { | 313 { |
425 #endif /* ! NO_SHARED_MEMORY */ | 314 XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, |
426 /* Check for endian-swapped X server, swap if necessary */ | 315 0, 0, 0, 0, this->screen->w, this->screen->h); |
427 if ( swap_pixels && | |
428 ((this->screen->format->BytesPerPixel%2) == 0) ) { | |
429 X11_SwapAllPixels(this->screen); | |
430 XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, | |
431 0, 0, 0, 0, this->screen->w, this->screen->h); | |
432 X11_SwapAllPixels(this->screen); | |
433 } else { | |
434 XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, | |
435 0, 0, 0, 0, this->screen->w, this->screen->h); | |
436 } | |
437 } | 316 } |
438 XSync(SDL_Display, False); | 317 XSync(SDL_Display, False); |
439 } | 318 } |