comparison src/video/directfb/SDL_DirectFB_video.c @ 477:22581630aab7

Date: Tue, 27 Aug 2002 16:14:11 +0200 From: Denis Oliver Kropp Subject: Palette support and 8bit color keying fix This patch adds support for 8bit palette modes dropping the RGB332 stuff. It also fixes color keying for 8bit. testsprite (without -bpp >8) looks correct again.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 31 Aug 2002 04:06:37 +0000
parents 1c4be4a16410
children f8482d7c9595
comparison
equal deleted inserted replaced
476:a7129c0083f4 477:22581630aab7
156 DFBDisplayLayerConfig dlc; 156 DFBDisplayLayerConfig dlc;
157 int bytes = (bpp + 7) / 8; 157 int bytes = (bpp + 7) / 8;
158 158
159 layer->GetConfiguration (layer, &dlc); 159 layer->GetConfiguration (layer, &dlc);
160 160
161 if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat)) 161 if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1)
162 return dlc.pixelformat; 162 return dlc.pixelformat;
163 163
164 switch (bytes) 164 switch (bytes)
165 { 165 {
166 case 1: 166 case 1:
167 return DSPF_RGB332; 167 return DSPF_LUT8;
168 case 2: 168 case 2:
169 return DSPF_RGB16; 169 return DSPF_RGB16;
170 case 3: 170 case 3:
171 return DSPF_RGB24; 171 return DSPF_RGB24;
172 case 4: 172 case 4:
202 return DFENUM_OK; 202 return DFENUM_OK;
203 } 203 }
204 204
205 struct private_hwdata { 205 struct private_hwdata {
206 IDirectFBSurface *surface; 206 IDirectFBSurface *surface;
207 IDirectFBPalette *palette;
207 }; 208 };
208 209
209 void SetDirectFBerror (const char *function, DFBResult code) 210 void SetDirectFBerror (const char *function, DFBResult code)
210 { 211 {
211 const char *error = DirectFBErrorString (code); 212 const char *error = DirectFBErrorString (code);
220 { 221 {
221 if (format->Rmask && format->Gmask && format->Bmask) 222 if (format->Rmask && format->Gmask && format->Bmask)
222 { 223 {
223 switch (format->BitsPerPixel) 224 switch (format->BitsPerPixel)
224 { 225 {
226 case 8:
227 return DSPF_LUT8;
228
225 case 16: 229 case 16:
226 if (format->Rmask == 0xF800 && 230 if (format->Rmask == 0xF800 &&
227 format->Gmask == 0x07E0 && 231 format->Gmask == 0x07E0 &&
228 format->Bmask == 0x001F) 232 format->Bmask == 0x001F)
229 return DSPF_RGB16; 233 return DSPF_RGB16;
234 format->Gmask == 0x03E0 && 238 format->Gmask == 0x03E0 &&
235 format->Bmask == 0x001F) 239 format->Bmask == 0x001F)
236 return DSPF_RGB15; 240 return DSPF_RGB15;
237 break; 241 break;
238 242
239 case 8:
240 if (format->Rmask == 0xE0 &&
241 format->Gmask == 0x1C &&
242 format->Bmask == 0x03)
243 return DSPF_RGB332;
244 break;
245
246 case 24: 243 case 24:
247 if (format->Rmask == 0xFF0000 && 244 if (format->Rmask == 0xFF0000 &&
248 format->Gmask == 0x00FF00 && 245 format->Gmask == 0x00FF00 &&
249 format->Bmask == 0x0000FF) 246 format->Bmask == 0x0000FF)
250 return DSPF_RGB24; 247 return DSPF_RGB24;
266 else 263 else
267 { 264 {
268 switch (format->BitsPerPixel) 265 switch (format->BitsPerPixel)
269 { 266 {
270 case 8: 267 case 8:
271 return DSPF_RGB332; 268 return DSPF_LUT8;
272 case 15: 269 case 15:
273 return DSPF_RGB15; 270 return DSPF_RGB15;
274 case 16: 271 case 16:
275 return DSPF_RGB16; 272 return DSPF_RGB16;
276 case 24: 273 case 24:
281 } 278 }
282 279
283 return DSPF_UNKNOWN; 280 return DSPF_UNKNOWN;
284 } 281 }
285 282
286 static const __u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff }; 283 static SDL_Palette *AllocatePalette(int size)
287 static const __u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff }; 284 {
288
289 static SDL_Palette *GenerateRGB332Palette()
290 {
291 int i;
292 SDL_Palette *palette; 285 SDL_Palette *palette;
293 SDL_Color *colors; 286 SDL_Color *colors;
294 287
295 palette = calloc (1, sizeof(SDL_Palette)); 288 palette = calloc (1, sizeof(SDL_Palette));
296 if (!palette) 289 if (!palette)
297 { 290 {
298 SDL_OutOfMemory(); 291 SDL_OutOfMemory();
299 return NULL; 292 return NULL;
300 } 293 }
301 294
302 colors = calloc (256, sizeof(SDL_Color)); 295 colors = calloc (size, sizeof(SDL_Color));
303 if (!colors) 296 if (!colors)
304 { 297 {
305 SDL_OutOfMemory(); 298 SDL_OutOfMemory();
306 return NULL; 299 return NULL;
307 } 300 }
308 301
309 for (i=0; i<256; i++) 302 palette->ncolors = size;
310 {
311 colors[i].r = lookup3to8[ i >> 5 ];
312 colors[i].g = lookup3to8[ (i >> 2) & 7 ];
313 colors[i].g = lookup2to8[ i & 3 ];
314 }
315
316 palette->ncolors = 256;
317 palette->colors = colors; 303 palette->colors = colors;
318 304
319 return palette; 305 return palette;
320 } 306 }
321 307
350 format->Rmask = 0x00FF0000; 336 format->Rmask = 0x00FF0000;
351 format->Gmask = 0x0000FF00; 337 format->Gmask = 0x0000FF00;
352 format->Bmask = 0x000000FF; 338 format->Bmask = 0x000000FF;
353 break; 339 break;
354 340
355 case DSPF_RGB332: 341 case DSPF_LUT8:
356 format->Rmask = 0x000000E0; 342 format->Rmask = 0x000000FF;
357 format->Gmask = 0x0000001C; 343 format->Gmask = 0x000000FF;
358 format->Bmask = 0x00000003; 344 format->Bmask = 0x000000FF;
359 345
360 format->palette = GenerateRGB332Palette(); 346 if (!format->palette)
347 format->palette = AllocatePalette(256);
361 break; 348 break;
362 349
363 default: 350 default:
351 fprintf (stderr, "SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n", pixelformat);
364 return -1; 352 return -1;
365 } 353 }
366 354
367 format->BitsPerPixel = DFB_BYTES_PER_PIXEL(pixelformat) * 8; 355 format->BitsPerPixel = DFB_BYTES_PER_PIXEL(pixelformat) * 8;
368 format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat); 356 format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat);
375 { 363 {
376 int i; 364 int i;
377 DFBResult ret; 365 DFBResult ret;
378 DFBCardCapabilities caps; 366 DFBCardCapabilities caps;
379 DFBDisplayLayerConfig dlc; 367 DFBDisplayLayerConfig dlc;
380 DFBSurfacePixelFormat format;
381 struct DirectFBEnumRect *rect; 368 struct DirectFBEnumRect *rect;
382 IDirectFB *dfb = NULL; 369 IDirectFB *dfb = NULL;
383 IDirectFBDisplayLayer *layer = NULL; 370 IDirectFBDisplayLayer *layer = NULL;
384 IDirectFBEventBuffer *events = NULL; 371 IDirectFBEventBuffer *events = NULL;
385 372
415 layer->EnableCursor (layer, 1); 402 layer->EnableCursor (layer, 1);
416 403
417 /* Query layer configuration to determine the current mode and pixelformat */ 404 /* Query layer configuration to determine the current mode and pixelformat */
418 layer->GetConfiguration (layer, &dlc); 405 layer->GetConfiguration (layer, &dlc);
419 406
420 /* FIXME: Returning RGB332 as the default mode doesn't work (everything is black) */ 407 /* If current format is not supported use LUT8 as the default */
421 if ((format = dlc.pixelformat) == DSPF_RGB332) 408 if (DFBToSDLPixelFormat (dlc.pixelformat, vformat))
422 format = DSPF_RGB16; 409 DFBToSDLPixelFormat (DSPF_LUT8, vformat);
423
424 if (DFBToSDLPixelFormat (format, vformat))
425 {
426 SDL_SetError ("Unsupported pixelformat");
427 goto error;
428 }
429 410
430 /* Enumerate the available fullscreen modes */ 411 /* Enumerate the available fullscreen modes */
431 ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this); 412 ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this);
432 if (ret) 413 if (ret)
433 { 414 {
492 return NULL; 473 return NULL;
493 } 474 }
494 475
495 static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) 476 static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
496 { 477 {
497 DFBResult ret; 478 DFBResult ret;
498 DFBSurfaceDescription dsc; 479 DFBSurfaceDescription dsc;
499 DFBSurfacePixelFormat pixelformat; 480 DFBSurfacePixelFormat pixelformat;
481 IDirectFBSurface *surface;
500 482
501 fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n", 483 fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
502 width, height, bpp, flags); 484 width, height, bpp, flags);
503 485
504 flags |= SDL_FULLSCREEN; 486 flags |= SDL_FULLSCREEN;
506 /* Release previous primary surface */ 488 /* Release previous primary surface */
507 if (current->hwdata && current->hwdata->surface) 489 if (current->hwdata && current->hwdata->surface)
508 { 490 {
509 current->hwdata->surface->Release (current->hwdata->surface); 491 current->hwdata->surface->Release (current->hwdata->surface);
510 current->hwdata->surface = NULL; 492 current->hwdata->surface = NULL;
493
494 /* And its palette if present */
495 if (current->hwdata->palette)
496 {
497 current->hwdata->palette->Release (current->hwdata->palette);
498 current->hwdata->palette = NULL;
499 }
511 } 500 }
512 else if (!current->hwdata) 501 else if (!current->hwdata)
513 { 502 {
514 /* Allocate the hardware acceleration data */ 503 /* Allocate the hardware acceleration data */
515 current->hwdata = (struct private_hwdata *) calloc (1, sizeof(*current->hwdata)); 504 current->hwdata = (struct private_hwdata *) calloc (1, sizeof(*current->hwdata));
554 /* Create primary surface */ 543 /* Create primary surface */
555 dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT; 544 dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT;
556 dsc.caps = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0); 545 dsc.caps = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
557 dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer); 546 dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer);
558 547
559 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &current->hwdata->surface); 548 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface);
560 if (ret && (flags & SDL_DOUBLEBUF)) 549 if (ret && (flags & SDL_DOUBLEBUF))
561 { 550 {
562 /* Try without double buffering */ 551 /* Try without double buffering */
563 dsc.caps &= ~DSCAPS_FLIPPING; 552 dsc.caps &= ~DSCAPS_FLIPPING;
564 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &current->hwdata->surface); 553 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface);
565 } 554 }
566 if (ret) 555 if (ret)
567 { 556 {
568 SetDirectFBerror ("dfb->CreateSurface", ret); 557 SetDirectFBerror ("dfb->CreateSurface", ret);
569 current->hwdata->surface = NULL;
570 return NULL; 558 return NULL;
571 } 559 }
572 560
573 current->w = width; 561 current->w = width;
574 current->h = height; 562 current->h = height;
583 this->UpdateRects = DirectFB_WindowedUpdate; 571 this->UpdateRects = DirectFB_WindowedUpdate;
584 572
585 if (dsc.caps & DSCAPS_FLIPPING) 573 if (dsc.caps & DSCAPS_FLIPPING)
586 current->flags |= SDL_DOUBLEBUF; 574 current->flags |= SDL_DOUBLEBUF;
587 575
588 current->hwdata->surface->GetPixelFormat (current->hwdata->surface, &pixelformat); 576 surface->GetPixelFormat (surface, &pixelformat);
577
589 DFBToSDLPixelFormat (pixelformat, current->format); 578 DFBToSDLPixelFormat (pixelformat, current->format);
579
580 /* Get the surface palette (if supported) */
581 if (DFB_PIXELFORMAT_IS_INDEXED( pixelformat ))
582 {
583 surface->GetPalette (surface, &current->hwdata->palette);
584
585 current->flags |= SDL_HWPALETTE;
586 }
587
588 current->hwdata->surface = surface;
590 589
591 return current; 590 return current;
592 } 591 }
593 592
594 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface) 593 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface)
710 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *src, Uint32 key) 709 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *src, Uint32 key)
711 { 710 {
712 SDL_PixelFormat *fmt = src->format; 711 SDL_PixelFormat *fmt = src->format;
713 IDirectFBSurface *surface = src->hwdata->surface; 712 IDirectFBSurface *surface = src->hwdata->surface;
714 713
715 /* ugly */ 714 if (fmt->BitsPerPixel == 8)
716 surface->SetSrcColorKey (surface, 715 surface->SetSrcColorKeyIndex (surface, key);
717 (key & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss), 716 else
718 (key & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss), 717 /* ugly */
719 (key & fmt->Bmask) << (fmt->Bloss - fmt->Bshift)); 718 surface->SetSrcColorKey (surface,
719 (key & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
720 (key & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
721 (key & fmt->Bmask) << (fmt->Bloss - fmt->Bshift));
720 722
721 return 0; 723 return 0;
722 } 724 }
723 725
724 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha) 726 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha)
807 surface->Flip (surface, &region, DSFLIP_WAITFORSYNC); 809 surface->Flip (surface, &region, DSFLIP_WAITFORSYNC);
808 } 810 }
809 811
810 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 812 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
811 { 813 {
812 fprintf(stderr, "SDL: Unimplemented DirectFB_SetColors!\n"); 814 IDirectFBPalette *palette = this->screen->hwdata->palette;
813 return -1; 815
816 if (!palette)
817 return 0;
818
819 if (firstcolor > 255)
820 return 0;
821
822 if (firstcolor + ncolors > 256)
823 ncolors = 256 - firstcolor;
824
825 if (ncolors > 0)
826 {
827 int i;
828 DFBColor entries[ncolors];
829
830 for (i=0; i<ncolors; i++)
831 {
832 entries[i].a = 0xff;
833 entries[i].r = colors[i].r;
834 entries[i].g = colors[i].g;
835 entries[i].b = colors[i].b;
836 }
837
838 palette->SetEntries (palette, entries, ncolors, firstcolor);
839 }
840
841 return 1;
814 } 842 }
815 843
816 void DirectFB_VideoQuit(_THIS) 844 void DirectFB_VideoQuit(_THIS)
817 { 845 {
818 struct DirectFBEnumRect *rect = enumlist; 846 struct DirectFBEnumRect *rect = enumlist;
847 IDirectFBSurface *surface = this->screen->hwdata->surface;
848 IDirectFBPalette *palette = this->screen->hwdata->palette;
849
850 if (palette)
851 palette->Release (palette);
852
853 if (surface)
854 surface->Release (surface);
855
856 this->screen->hwdata->surface = NULL;
857 this->screen->hwdata->palette = NULL;
819 858
820 if (HIDDEN->eventbuffer) 859 if (HIDDEN->eventbuffer)
821 { 860 {
822 HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer); 861 HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer);
823 HIDDEN->eventbuffer = NULL; 862 HIDDEN->eventbuffer = NULL;