comparison src/video/directfb/SDL_DirectFB_render.c @ 2721:e82a0e3e9b0e

Date: Sun, 20 Jul 2008 22:34:37 +0200 From: Couriersud Subject: Updated DirectFB driver for SDL1.3 please find attached a patch for an updated directfb driver for SDL1.3. It does now - properly supported the new input api. - send unicode text events - support directfb windows - support multiple screens - support hardware YUV scaling for the first YUV texture created. - support hardware scaling for textures. - properly interpret streaming access - support software opengl if one manages to install the mesa directfb driver (broken/not broken in mesa svn) Within bugzilla (http://bugzilla.libsdl.org/show_bug.cgi?id=603) there is another patch which fixes a crash due to GL context creation. Kind regards, couriersud
author Sam Lantinga <slouken@libsdl.org>
date Tue, 26 Aug 2008 02:32:45 +0000
parents 5234868559fa
children 91f1706b27be
comparison
equal deleted inserted replaced
2720:4eb759edddf5 2721:e82a0e3e9b0e
85 SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | 85 SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
86 SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED), 86 SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED),
87 (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR | 87 (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
88 SDL_TEXTUREMODULATE_ALPHA), 88 SDL_TEXTUREMODULATE_ALPHA),
89 (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK | 89 (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
90 SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_MOD), 90 SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD |
91 SDL_TEXTUREBLENDMODE_MOD),
91 (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST), 92 (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST),
92 14, 93 14,
93 { 94 {
94 SDL_PIXELFORMAT_INDEX8, 95 SDL_PIXELFORMAT_INDEX8,
95 SDL_PIXELFORMAT_INDEX4LSB, 96 SDL_PIXELFORMAT_INDEX4LSB,
122 IDirectFBSurface *surface; 123 IDirectFBSurface *surface;
123 Uint32 format; 124 Uint32 format;
124 void *pixels; 125 void *pixels;
125 int pitch; 126 int pitch;
126 IDirectFBPalette *palette; 127 IDirectFBPalette *palette;
128 DFB_DisplayData *display;
127 } DirectFB_TextureData; 129 } DirectFB_TextureData;
128
129 static void
130 UpdateYUVTextureData(SDL_Texture * texture)
131 {
132 /*
133 * Not needed - directfb supports yuv surfaces
134 */
135 }
136 130
137 void 131 void
138 DirectFB_AddRenderDriver(_THIS) 132 DirectFB_AddRenderDriver(_THIS)
139 { 133 {
140 int i; 134 int i;
176 renderer->RenderCopy = DirectFB_RenderCopy; 170 renderer->RenderCopy = DirectFB_RenderCopy;
177 renderer->RenderPresent = DirectFB_RenderPresent; 171 renderer->RenderPresent = DirectFB_RenderPresent;
178 renderer->DestroyTexture = DirectFB_DestroyTexture; 172 renderer->DestroyTexture = DirectFB_DestroyTexture;
179 renderer->DestroyRenderer = DirectFB_DestroyRenderer; 173 renderer->DestroyRenderer = DirectFB_DestroyRenderer;
180 renderer->info = DirectFB_RenderDriver.info; 174 renderer->info = DirectFB_RenderDriver.info;
181 renderer->window = window->id; // SDL window id 175 renderer->window = window->id; /* SDL window id */
182 renderer->driverdata = data; 176 renderer->driverdata = data;
183 177
184 renderer->info.flags = 178 renderer->info.flags =
185 SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTDISCARD; 179 SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTDISCARD;
186 180
198 else if (scaps & DSCAPS_TRIPLE) 192 else if (scaps & DSCAPS_TRIPLE)
199 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; 193 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
200 else 194 else
201 renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER; 195 renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
202 196
203 data->isyuvdirect = 0; 197 data->isyuvdirect = 1; /* default is on! */
204 p = getenv("SDL_DIRECTFB_YUV_DIRECT"); 198 p = getenv("SDL_DIRECTFB_YUV_DIRECT");
205 if (p) 199 if (p)
206 data->isyuvdirect = atoi(p); 200 data->isyuvdirect = atoi(p);
207 201
208 return renderer; 202 return renderer;
291 error: 285 error:
292 return -1; 286 return -1;
293 } 287 }
294 288
295 static int 289 static int
296 DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) 290 DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture)
297 { 291 {
298 SDL_DFB_RENDERERDATA(renderer); 292 SDL_DFB_RENDERERDATA(renderer);
299 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 293 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
300 SDL_DFB_WINDOWDATA(window);
301 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); 294 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
302 SDL_DFB_DEVICEDATA(display->device); 295 SDL_DFB_DEVICEDATA(display->device);
303 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; 296 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
304 DirectFB_TextureData *data; 297 DirectFB_TextureData *data = texture->driverdata;
305 DFBResult ret;
306 DFBSurfaceDescription dsc;
307 DFBDisplayLayerDescription laydsc;
308 DFBDisplayLayerConfig layconf; 298 DFBDisplayLayerConfig layconf;
309 299 int ret;
310 SDL_DFB_CALLOC(data, 1, sizeof(*data)); 300
311 texture->driverdata = data;
312
313 data->format = texture->format;
314 data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
315 data->vidlayer = NULL;
316 if (renddata->isyuvdirect && (dispdata->vidID >= 0) 301 if (renddata->isyuvdirect && (dispdata->vidID >= 0)
302 && (!dispdata->vidIDinuse)
317 && SDL_ISPIXELFORMAT_FOURCC(data->format)) { 303 && SDL_ISPIXELFORMAT_FOURCC(data->format)) {
318 SDL_DFB_CHECKERR(devdata->dfb->
319 GetDisplayLayer(devdata->dfb, dispdata->vidID,
320 &data->vidlayer));
321 layconf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT; 304 layconf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
322 layconf.width = texture->w; 305 layconf.width = texture->w;
323 layconf.height = texture->h; 306 layconf.height = texture->h;
324 layconf.pixelformat = SDLToDFBPixelFormat(data->format); 307 layconf.pixelformat = SDLToDFBPixelFormat(data->format);
325 308
309 SDL_DFB_CHECKERR(devdata->dfb->
310 GetDisplayLayer(devdata->dfb, dispdata->vidID,
311 &data->vidlayer));
326 SDL_DFB_CHECKERR(data->vidlayer-> 312 SDL_DFB_CHECKERR(data->vidlayer->
327 SetCooperativeLevel(data->vidlayer, 313 SetCooperativeLevel(data->vidlayer,
328 DLSCL_EXCLUSIVE)); 314 DLSCL_EXCLUSIVE));
329 SDL_DFB_CHECKERR(data->vidlayer-> 315 SDL_DFB_CHECKERR(data->vidlayer->
330 SetConfiguration(data->vidlayer, &layconf)); 316 SetConfiguration(data->vidlayer, &layconf));
331 SDL_DFB_CHECKERR(data->vidlayer-> 317 SDL_DFB_CHECKERR(data->vidlayer->
332 GetSurface(data->vidlayer, &data->surface)); 318 GetSurface(data->vidlayer, &data->surface));
319 //SDL_DFB_CHECKERR(data->vidlayer->GetDescription(data->vidlayer, laydsc));
320 dispdata->vidIDinuse = 1;
321 data->display = dispdata;
322 SDL_DFB_DEBUG("Created HW YUV surface\n");
323
324 return 0;
325 }
326 return 1;
327 error:
328 if (data->vidlayer) {
329 SDL_DFB_RELEASE(data->surface);
333 SDL_DFB_CHECKERR(data->vidlayer-> 330 SDL_DFB_CHECKERR(data->vidlayer->
334 GetDescription(data->vidlayer, &laydsc)); 331 SetCooperativeLevel(data->vidlayer,
335 SDL_DFB_DEBUG("Created HW YUV surface\n"); 332 DLSCL_ADMINISTRATIVE));
336 } 333 SDL_DFB_RELEASE(data->vidlayer);
337 if (!data->vidlayer) { 334 }
335 return 1;
336 }
337
338 static int
339 DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
340 {
341 SDL_DFB_RENDERERDATA(renderer);
342 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
343 SDL_DFB_WINDOWDATA(window);
344 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
345 SDL_DFB_DEVICEDATA(display->device);
346 DirectFB_TextureData *data;
347 DFBResult ret;
348 DFBSurfaceDescription dsc;
349 DFBDisplayLayerDescription laydsc;
350 DFBDisplayLayerConfig layconf;
351
352 SDL_DFB_CALLOC(data, 1, sizeof(*data));
353 texture->driverdata = data;
354
355 data->format = texture->format;
356 data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
357 data->vidlayer = NULL;
358
359 if (DirectFB_AcquireVidLayer(renderer, texture) != 0) {
338 /* fill surface description */ 360 /* fill surface description */
339 dsc.flags = 361 dsc.flags =
340 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; 362 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
341 dsc.width = texture->w; 363 dsc.width = texture->w;
342 dsc.height = texture->h; 364 dsc.height = texture->h;
343 /* Never use DSCAPS_VIDEOONLY here. It kills performance 365 /* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance
344 * No DSCAPS_SYSTEMONLY either - let dfb decide 366 * No DSCAPS_SYSTEMONLY either - let dfb decide
367 * 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8
345 */ 368 */
346 dsc.caps = 0; //DSCAPS_PREMULTIPLIED; 369 dsc.caps = DSCAPS_PREMULTIPLIED;
370
371 if (texture->access == SDL_TEXTUREACCESS_STREAMING)
372 dsc.caps |= DSCAPS_SYSTEMONLY;
373 else
374 dsc.caps |= DSCAPS_VIDEOONLY;
347 375
348 /* find the right pixelformat */ 376 /* find the right pixelformat */
349 377
350 dsc.pixelformat = SDLToDFBPixelFormat(data->format); 378 dsc.pixelformat = SDLToDFBPixelFormat(data->format);
351 if (dsc.pixelformat == DSPF_UNKNOWN) { 379 if (dsc.pixelformat == DSPF_UNKNOWN) {
467 { 495 {
468 switch (texture->blendMode) { 496 switch (texture->blendMode) {
469 case SDL_TEXTUREBLENDMODE_NONE: 497 case SDL_TEXTUREBLENDMODE_NONE:
470 case SDL_TEXTUREBLENDMODE_MASK: 498 case SDL_TEXTUREBLENDMODE_MASK:
471 case SDL_TEXTUREBLENDMODE_BLEND: 499 case SDL_TEXTUREBLENDMODE_BLEND:
500 case SDL_TEXTUREBLENDMODE_ADD:
472 case SDL_TEXTUREBLENDMODE_MOD: 501 case SDL_TEXTUREBLENDMODE_MOD:
473 return 0; 502 return 0;
474 default: 503 default:
475 SDL_Unsupported(); 504 SDL_Unsupported();
476 texture->blendMode = SDL_TEXTUREBLENDMODE_NONE; 505 texture->blendMode = SDL_TEXTUREBLENDMODE_NONE;
511 Uint8 *src, *dst; 540 Uint8 *src, *dst;
512 int row; 541 int row;
513 size_t length; 542 size_t length;
514 543
515 SDL_DFB_CHECKERR(data->surface->Lock(data->surface, 544 SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
516 DSLF_WRITE | DSLF_READ, &dpixels, 545 DSLF_WRITE | DSLF_READ,
517 &dpitch)); 546 ((void **) &dpixels), &dpitch));
518 src = (Uint8 *) pixels; 547 src = (Uint8 *) pixels;
519 dst = 548 dst =
520 (Uint8 *) dpixels + rect->y * dpitch + 549 (Uint8 *) dpixels + rect->y * dpitch +
521 rect->x * SDL_BYTESPERPIXEL(texture->format); 550 rect->x * SDL_BYTESPERPIXEL(texture->format);
522 length = rect->w * SDL_BYTESPERPIXEL(texture->format); 551 length = rect->w * SDL_BYTESPERPIXEL(texture->format);
646 dr.h = dstrect->h; 675 dr.h = dstrect->h;
647 676
648 if (texture-> 677 if (texture->
649 modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA)) 678 modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA))
650 { 679 {
651 u8 alpha = 0xFF; 680 Uint8 alpha = 0xFF;
652 if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) 681 if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
653 alpha = texture->a; 682 alpha = texture->a;
654 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) 683 flags |= DSBLIT_SRC_PREMULTCOLOR;
684 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF,
685 0xFF, 0xFF, alpha));
686 }
687 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
655 SDL_DFB_CHECKERR(data->surface-> 688 SDL_DFB_CHECKERR(data->surface->
656 SetColor(data->surface, texture->r, 689 SetColor(data->surface, texture->r,
657 texture->g, texture->b, alpha)); 690 texture->g, texture->b, alpha));
658 else 691 /* Only works together .... */
659 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF, 692 flags |= DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR;
660 0xFF, 0xFF, alpha)); 693 }
661 // Only works together ....
662 flags |= DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR;
663 } 694 }
664 695
665 if (texture-> 696 switch (texture->blendMode) {
666 blendMode & (SDL_TEXTUREBLENDMODE_MASK | 697 case SDL_TEXTUREBLENDMODE_NONE: /**< No blending */
667 SDL_TEXTUREBLENDMODE_BLEND)) { 698 flags |= DSBLIT_NOFX;
699 data->surface->SetSrcBlendFunction(data->surface, DSBF_ONE);
700 data->surface->SetDstBlendFunction(data->surface, DSBF_ZERO);
701 break;
702 case SDL_TEXTUREBLENDMODE_MASK: /**< dst = A ? src : dst (alpha is mask) */
668 flags |= DSBLIT_BLEND_ALPHACHANNEL; 703 flags |= DSBLIT_BLEND_ALPHACHANNEL;
669 } else { 704 data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
670 flags |= DSBLIT_NOFX; 705 data->surface->SetDstBlendFunction(data->surface,
706 DSBF_INVSRCALPHA);
707 break;
708 case SDL_TEXTUREBLENDMODE_BLEND:/**< dst = (src * A) + (dst * (1-A)) */
709 flags |= DSBLIT_BLEND_ALPHACHANNEL;
710 data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
711 data->surface->SetDstBlendFunction(data->surface,
712 DSBF_INVSRCALPHA);
713 break;
714 case SDL_TEXTUREBLENDMODE_ADD: /**< dst = (src * A) + dst */
715 flags |= DSBLIT_BLEND_ALPHACHANNEL;
716 data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
717 data->surface->SetDstBlendFunction(data->surface, DSBF_ONE);
718 break;
719 case SDL_TEXTUREBLENDMODE_MOD: /**< dst = src * dst */
720 flags |= DSBLIT_BLEND_ALPHACHANNEL;
721 data->surface->SetSrcBlendFunction(data->surface, DSBF_DESTCOLOR);
722 data->surface->SetDstBlendFunction(data->surface, DSBF_ZERO);
723 break;
671 } 724 }
725
672 SDL_DFB_CHECKERR(data->surface-> 726 SDL_DFB_CHECKERR(data->surface->
673 SetBlittingFlags(data->surface, flags)); 727 SetBlittingFlags(data->surface, flags));
674 if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { 728 if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
675 SDL_DFB_CHECKERR(data->surface-> 729 SDL_DFB_CHECKERR(data->surface->
676 Blit(data->surface, texturedata->surface, &sr, 730 Blit(data->surface, texturedata->surface, &sr,
718 if (!data) { 772 if (!data) {
719 return; 773 return;
720 } 774 }
721 SDL_DFB_RELEASE(data->palette); 775 SDL_DFB_RELEASE(data->palette);
722 SDL_DFB_RELEASE(data->surface); 776 SDL_DFB_RELEASE(data->surface);
777 if (data->display) {
778 data->display->vidIDinuse = 0;
779 data->vidlayer->SetCooperativeLevel(data->vidlayer,
780 DLSCL_ADMINISTRATIVE);
781 }
723 SDL_DFB_RELEASE(data->vidlayer); 782 SDL_DFB_RELEASE(data->vidlayer);
724 SDL_free(data); 783 SDL_free(data);
725 texture->driverdata = NULL; 784 texture->driverdata = NULL;
726 } 785 }
727 786