comparison libvo/vo_dfbmga.c @ 9021:070b91093606

* Remove unneeded includes & macros * Get layers by name rather that fixed ID. Only works for DirectFB >= 0.9.16 so fall back to ID based stuff for older releases. * New option "noinput" (useful in X) * Add some NULL pointer checks to uninit() * Improve error messages and use mp_msg() * Direct rendering fix (at least IPB was broken) * Use 0xff for alpha component in all colors * Blit from temp surface to screen was only done in draw_osd() which doesn't always get called. Do the blit in flip_page() in this case. * Add GUI support to control() * Change the driver name to include G450/G550 ;) patch by Ville Syrj¸«£l¸«£ <syrjala@sci.fi>
author arpi
date Sun, 19 Jan 2003 15:41:26 +0000
parents 554e6aa7da5f
children edfe34c5405d
comparison
equal deleted inserted replaced
9020:721a7b3dde59 9021:070b91093606
1 /* 1 /*
2 MPlayer video driver for DirectFB / Matrox G400 2 MPlayer video driver for DirectFB / Matrox G400/G450/G550
3 3
4 Copyright (C) 2002 Ville Syrjala <syrjala@sci.fi> 4 Copyright (C) 2002,2003 Ville Syrjala <syrjala@sci.fi>
5 5
6 Originally based on vo_directfb.c by 6 Originally based on vo_directfb.c by
7 Jiri Svoboda <Jiri.Svoboda@seznam.cz> 7 Jiri Svoboda <Jiri.Svoboda@seznam.cz>
8 8
9 This library is free software; you can redistribute it and/or 9 This library is free software; you can redistribute it and/or
27 27
28 /* other things */ 28 /* other things */
29 #include <stdio.h> 29 #include <stdio.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.h> 31 #include <string.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <errno.h>
35 #include <assert.h>
36
37 #include <sys/mman.h>
38 #include <sys/ioctl.h>
39 #include <sys/kd.h>
40 #include <linux/fb.h>
41 32
42 #include "config.h" 33 #include "config.h"
43 #include "video_out.h" 34 #include "video_out.h"
44 #include "video_out_internal.h" 35 #include "video_out_internal.h"
45 #include "fastmemcpy.h" 36 #include "fastmemcpy.h"
46 #include "sub.h" 37 #include "sub.h"
47 #include "../postproc/rgb2rgb.h" 38 #include "mp_msg.h"
48
49 #include "aspect.h" 39 #include "aspect.h"
50 40
51 #ifndef min
52 #define min(x,y) (((x)<(y))?(x):(y))
53 #endif
54
55 static vo_info_t info = { 41 static vo_info_t info = {
56 "DirectFB / Matrox G400", 42 "DirectFB / Matrox G400/G450/G550",
57 "dfbmga", 43 "dfbmga",
58 "Ville Syrjala <syrjala@sci.fi>", 44 "Ville Syrjala <syrjala@sci.fi>",
59 "" 45 ""
60 }; 46 };
61 47
96 static unsigned int frame_pixel_size; 82 static unsigned int frame_pixel_size;
97 static unsigned int subframe_pixel_size; 83 static unsigned int subframe_pixel_size;
98 84
99 static int inited = 0; 85 static int inited = 0;
100 86
101 static int stretch = 0; 87 static int blit_done;
102 88 static int stretch;
103 static int use_bes = 0; 89
104 static int use_crtc2 = 1; 90 static int use_bes;
105 static int use_spic = 1; 91 static int use_crtc2;
92 static int use_spic;
93 static int use_input;
106 94
107 static int osd_changed; 95 static int osd_changed;
108 static int osd_dirty; 96 static int osd_dirty;
109 static int osd_current; 97 static int osd_current;
110 98
192 default: 180 default:
193 return DSPF_UNKNOWN; 181 return DSPF_UNKNOWN;
194 } 182 }
195 } 183 }
196 184
185 struct layer_enum
186 {
187 const char *name;
188 IDirectFBDisplayLayer **layer;
189 DFBResult res;
190 };
191
192 static DFBEnumerationResult
193 get_layer_by_name( DFBDisplayLayerID id,
194 DFBDisplayLayerDescription desc,
195 void *data )
196 {
197 struct layer_enum *l = (struct layer_enum *) data;
198
199 #if DIRECTFBVERSION > 915
200 /* We have desc.name so use it */
201 if (!strcmp( l->name, desc.name ))
202 if ((l->res = dfb->GetDisplayLayer( dfb, id, l->layer )) == DFB_OK)
203 return DFENUM_CANCEL;
204 #else
205 /* Fake it according to id */
206 if ((id == 1 && !strcmp( l->name, "Matrox Backend Scaler" )) ||
207 (id == 2 && !strcmp( l->name, "Matrox CRTC2" )) ||
208 (id == 3 && !strcmp( l->name, "Matrox CRTC2 Sub-Picture" )))
209 if ((l->res = dfb->GetDisplayLayer( dfb, id, l->layer )) == DFB_OK)
210 return DFENUM_CANCEL;
211 #endif
212
213 return DFENUM_OK;
214 }
215
197 static uint32_t 216 static uint32_t
198 preinit( const char *arg ) 217 preinit( const char *arg )
199 { 218 {
219 DFBResult res;
220
221 /* Some defaults */
222 use_bes = 0;
223 use_crtc2 = 1;
224 use_spic = 1;
225 use_input = 1;
226
200 if (vo_subdevice) { 227 if (vo_subdevice) {
228 int opt_no = 0;
201 while (*vo_subdevice != '\0') { 229 while (*vo_subdevice != '\0') {
202 if (!strncmp(vo_subdevice, "bes", 3)) { 230 if (!strncmp(vo_subdevice, "bes", 3)) {
203 use_bes = 1; 231 use_bes = !opt_no;
204 vo_subdevice += 3; 232 vo_subdevice += 3;
205 } else if (!strncmp(vo_subdevice, "nocrtc2", 7)) { 233 opt_no = 0;
206 use_crtc2 = 0; 234 } else if (!strncmp(vo_subdevice, "crtc2", 5)) {
207 vo_subdevice += 7; 235 use_crtc2 = !opt_no;
208 } else if (!strncmp(vo_subdevice, "nospic", 6)) { 236 vo_subdevice += 5;
209 use_spic = 0; 237 opt_no = 0;
210 vo_subdevice += 6; 238 } else if (!strncmp(vo_subdevice, "spic", 4)) {
211 } else 239 use_spic = !opt_no;
240 vo_subdevice += 4;
241 opt_no = 0;
242 } else if (!strncmp(vo_subdevice, "input", 5)) {
243 use_spic = !opt_no;
244 vo_subdevice += 5;
245 opt_no = 0;
246 } else if (!strncmp(vo_subdevice, "no", 2)) {
247 vo_subdevice += 2;
248 opt_no = 1;
249 } else {
212 vo_subdevice++; 250 vo_subdevice++;
251 opt_no = 0;
252 }
213 } 253 }
214 } 254 }
215 if (!use_bes && !use_crtc2) { 255 if (!use_bes && !use_crtc2) {
216 fprintf( stderr, "vo_dfbmga: No output selected\n" ); 256 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: No output selected\n" );
217 return -1; 257 return -1;
218 } 258 }
219 259
220 if (!inited) { 260 if (!inited) {
221 if (DirectFBInit( NULL, NULL ) != DFB_OK) 261 if ((res = DirectFBInit( NULL, NULL )) != DFB_OK) {
262 mp_msg( MSGT_VO, MSGL_ERR,
263 "vo_dfbmga: DirectFBInit() failed - %s\n",
264 DirectFBErrorString( res ) );
222 return -1; 265 return -1;
266 }
223 267
224 if (!fb_dev_name && !(fb_dev_name = getenv( "FRAMEBUFFER" ))) 268 if (!fb_dev_name && !(fb_dev_name = getenv( "FRAMEBUFFER" )))
225 fb_dev_name = "/dev/fb0"; 269 fb_dev_name = "/dev/fb0";
226 DirectFBSetOption( "fbdev", fb_dev_name ); 270 DirectFBSetOption( "fbdev", fb_dev_name );
227 DirectFBSetOption( "no-cursor", "" ); 271 DirectFBSetOption( "no-cursor", "" );
228 DirectFBSetOption( "bg-color", "00000000" ); 272 DirectFBSetOption( "bg-color", "00000000" );
229 273
230 if (DirectFBCreate( &dfb ) != DFB_OK) 274 if ((res = DirectFBCreate( &dfb )) != DFB_OK) {
275 mp_msg( MSGT_VO, MSGL_ERR,
276 "vo_dfbmga: DirectFBCreate() failed - %s\n",
277 DirectFBErrorString( res ) );
231 return -1; 278 return -1;
279 }
232 280
233 inited = 1; 281 inited = 1;
234 } 282 }
235 283
236 if (use_bes) { 284 if (use_bes) {
237 if (dfb->GetDisplayLayer( dfb, 1, &bes ) != DFB_OK) 285 struct layer_enum l = {
286 "Matrox Backend Scaler",
287 &bes,
288 DFB_UNSUPPORTED
289 };
290
291 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l );
292 if (l.res != DFB_OK) {
293 mp_msg( MSGT_VO, MSGL_ERR, "Can't get BES layer - %s\n",
294 DirectFBErrorString( l.res ) );
238 return -1; 295 return -1;
296 }
239 bes->SetCooperativeLevel( bes, DLSCL_EXCLUSIVE ); 297 bes->SetCooperativeLevel( bes, DLSCL_EXCLUSIVE );
240 bes->SetOpacity( bes, 0 ); 298 bes->SetOpacity( bes, 0 );
241 } 299 }
242 300
243 if (use_crtc2) { 301 if (use_crtc2) {
244 if (dfb->GetDisplayLayer( dfb, 2, &crtc2 ) != DFB_OK) 302 struct layer_enum l = {
303 "Matrox CRTC2",
304 &crtc2,
305 DFB_UNSUPPORTED
306 };
307
308 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l );
309 if (l.res != DFB_OK) {
310 mp_msg( MSGT_VO, MSGL_ERR, "Can't get CRTC2 layer - %s\n",
311 DirectFBErrorString( l.res ) );
245 return -1; 312 return -1;
313 }
246 crtc2->SetCooperativeLevel( crtc2, DLSCL_EXCLUSIVE ); 314 crtc2->SetCooperativeLevel( crtc2, DLSCL_EXCLUSIVE );
247 crtc2->SetOpacity( crtc2, 0 ); 315 crtc2->SetOpacity( crtc2, 0 );
248 } 316 }
249 317
250 if (dfb->GetInputDevice( dfb, DIDID_KEYBOARD, &keyboard ) != DFB_OK) 318 if (use_input) {
251 return -1; 319 if ((res = dfb->GetInputDevice( dfb, DIDID_KEYBOARD, &keyboard )) != DFB_OK) {
252 keyboard->CreateEventBuffer( keyboard, &buffer ); 320 mp_msg( MSGT_VO, MSGL_ERR,
253 buffer->Reset( buffer ); 321 "vo_dfbmga: Can't get keyboard - %s\n",
322 DirectFBErrorString( res ) );
323 return -1;
324 }
325 keyboard->CreateEventBuffer( keyboard, &buffer );
326 buffer->Reset( buffer );
327 }
254 328
255 return 0; 329 return 0;
256 } 330 }
257 331
258 static uint32_t 332 static uint32_t
260 uint32_t d_width, uint32_t d_height, 334 uint32_t d_width, uint32_t d_height,
261 uint32_t fullscreen, 335 uint32_t fullscreen,
262 char *title, 336 char *title,
263 uint32_t format ) 337 uint32_t format )
264 { 338 {
339 DFBResult res;
340
265 DFBDisplayLayerConfig dlc; 341 DFBDisplayLayerConfig dlc;
266 DFBDisplayLayerConfigFlags failed; 342 DFBDisplayLayerConfigFlags failed;
267 343
268 uint32_t out_width; 344 uint32_t out_width;
269 uint32_t out_height; 345 uint32_t out_height;
270 346
347 c2frame = NULL;
348 spic = NULL;
349 subframe = NULL;
350 bufs[0] = bufs[1] = bufs[2] = NULL;
351
271 in_width = width; 352 in_width = width;
272 in_height = height; 353 in_height = height;
273 354
274 aspect_save_orig(width, height); 355 aspect_save_orig(width, height);
275 aspect_save_prescale(d_width, d_height); 356 aspect_save_prescale(d_width, d_height);
281 dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; 362 dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
282 dlc.width = in_width; 363 dlc.width = in_width;
283 dlc.height = in_height; 364 dlc.height = in_height;
284 dlc.buffermode = DLBM_BACKVIDEO; 365 dlc.buffermode = DLBM_BACKVIDEO;
285 366
286 if (bes->TestConfiguration( bes, &dlc, &failed ) != DFB_OK) 367 if (bes->TestConfiguration( bes, &dlc, &failed ) != DFB_OK) {
368 mp_msg( MSGT_VO, MSGL_ERR,
369 "vo_dfbmga: Invalid BES configuration!\n" );
287 return -1; 370 return -1;
371 }
288 bes->SetConfiguration( bes, &dlc ); 372 bes->SetConfiguration( bes, &dlc );
289 bes->GetSurface( bes, &frame ); 373 bes->GetSurface( bes, &frame );
290 374
291 aspect_save_screenres( 10000, 10000 ); 375 aspect_save_screenres( 10000, 10000 );
292 aspect( &out_width, &out_height, A_ZOOM ); 376 aspect( &out_width, &out_height, A_ZOOM );
306 dsc.width = in_width; 390 dsc.width = in_width;
307 dsc.height = in_height; 391 dsc.height = in_height;
308 dsc.pixelformat = dlc.pixelformat; 392 dsc.pixelformat = dlc.pixelformat;
309 393
310 for (num_bufs = 0; num_bufs < 3; num_bufs++) { 394 for (num_bufs = 0; num_bufs < 3; num_bufs++) {
311 if (dfb->CreateSurface( dfb, &dsc, &bufs[num_bufs] ) != DFB_OK) { 395 if ((res = dfb->CreateSurface( dfb, &dsc, &bufs[num_bufs] )) != DFB_OK) {
312 if (num_bufs == 0) 396 if (num_bufs == 0) {
397 mp_msg( MSGT_VO, MSGL_ERR,
398 "vo_dfbmga: Can't create surfaces - %s!\n",
399 DirectFBErrorString( res ) );
313 return -1; 400 return -1;
401 }
314 } 402 }
315 } 403 }
316 frame = bufs[0]; 404 frame = bufs[0];
317 current_buf = 0; 405 current_buf = 0;
318 current_ip_buf = 0; 406 current_ip_buf = 0;
337 default: 425 default:
338 /* sub-picture not supported */ 426 /* sub-picture not supported */
339 use_spic = 0; 427 use_spic = 0;
340 } 428 }
341 429
342 if (crtc2->TestConfiguration( crtc2, &dlc, &failed ) != DFB_OK) 430 if (crtc2->TestConfiguration( crtc2, &dlc, &failed ) != DFB_OK) {
431 mp_msg( MSGT_VO, MSGL_ERR,
432 "vo_dfbmga: Invalid CRTC2 configuration!\n" );
343 return -1; 433 return -1;
434 }
344 crtc2->SetConfiguration( crtc2, &dlc ); 435 crtc2->SetConfiguration( crtc2, &dlc );
345 crtc2->GetSurface( crtc2, &c2frame ); 436 crtc2->GetSurface( crtc2, &c2frame );
346 437
347 c2frame->GetSize( c2frame, &screen_width, &screen_height ); 438 c2frame->GetSize( c2frame, &screen_width, &screen_height );
348 439
370 drect.x = (screen_width - out_width) / 2; 461 drect.x = (screen_width - out_width) / 2;
371 drect.y = (screen_height - out_height) / 2; 462 drect.y = (screen_height - out_height) / 2;
372 drect.w = out_width; 463 drect.w = out_width;
373 drect.h = out_height; 464 drect.h = out_height;
374 465
375 c2frame->Clear( c2frame, 0, 0, 0, 0 ); 466 c2frame->Clear( c2frame, 0, 0, 0, 0xff );
376 c2frame->Flip( c2frame, NULL, 0 ); 467 c2frame->Flip( c2frame, NULL, 0 );
377 c2frame->Clear( c2frame, 0, 0, 0, 0 ); 468 c2frame->Clear( c2frame, 0, 0, 0, 0xff );
378 469
379 printf( "vo_dfbmga: CRTC2 surface %dx%d %s\n", dlc.width, dlc.height, pixelformat_name( dlc.pixelformat ) ); 470 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC2 surface %dx%d %s\n", dlc.width, dlc.height, pixelformat_name( dlc.pixelformat ) );
380 } else { 471 } else {
381 screen_width = in_width; 472 screen_width = in_width;
382 screen_height = in_height; 473 screen_height = in_height;
383 use_spic = 0; 474 use_spic = 0;
384 } 475 }
385 476
386 frame->GetPixelFormat( frame, &frame_format ); 477 frame->GetPixelFormat( frame, &frame_format );
387 frame_pixel_size = DFB_BYTES_PER_PIXEL( frame_format ); 478 frame_pixel_size = DFB_BYTES_PER_PIXEL( frame_format );
388 printf( "vo_dfbmga: Video surface %dx%d %s (%s)\n", 479 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Video surface %dx%d %s (%s)\n",
389 in_width, in_height, 480 in_width, in_height,
390 pixelformat_name( frame_format ), 481 pixelformat_name( frame_format ),
391 use_bes ? "BES" : "offscreen" ); 482 use_bes ? "BES" : "offscreen" );
392 483
393 if (use_spic) { 484 if (use_spic) {
394 /* Draw OSD to sub-picture surface */ 485 /* Draw OSD to sub-picture surface */
395 IDirectFBPalette *palette; 486 IDirectFBPalette *palette;
396 DFBColor color; 487 DFBColor color;
397 int i; 488 int i;
398 489 struct layer_enum l = {
399 if (dfb->GetDisplayLayer( dfb, 3, &spic ) != DFB_OK) 490 "Matrox CRTC2 Sub-Picture",
491 &spic,
492 DFB_UNSUPPORTED
493 };
494 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l );
495 if (l.res != DFB_OK) {
496 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: Can't get sub-picture layer - %s\n", DirectFBErrorString( l.res ) );
400 return -1; 497 return -1;
498 }
401 spic->SetCooperativeLevel( spic, DLSCL_EXCLUSIVE ); 499 spic->SetCooperativeLevel( spic, DLSCL_EXCLUSIVE );
402 spic->SetOpacity( spic, 0 ); 500 spic->SetOpacity( spic, 0 );
403 501
404 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; 502 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
405 dlc.pixelformat = DSPF_LUT8; 503 dlc.pixelformat = DSPF_LUT8;
406 dlc.buffermode = DLBM_BACKVIDEO; 504 dlc.buffermode = DLBM_BACKVIDEO;
407 if (spic->TestConfiguration( spic, &dlc, &failed ) != DFB_OK) 505 if (spic->TestConfiguration( spic, &dlc, &failed ) != DFB_OK) {
506 mp_msg( MSGT_VO, MSGL_ERR,
507 "vo_dfbmga: Invalid sub-picture configuration!\n" );
408 return -1; 508 return -1;
509 }
409 spic->SetConfiguration( spic, &dlc ); 510 spic->SetConfiguration( spic, &dlc );
410 511
411 spic->GetSurface( spic, &subframe ); 512 spic->GetSurface( spic, &subframe );
412 513
413 subframe->GetPalette( subframe, &palette ); 514 subframe->GetPalette( subframe, &palette );
414 color.a = 0; 515 color.a = 0xff;
415 for (i = 0; i < 16; i++) { 516 for (i = 0; i < 16; i++) {
416 color.r = i * 17; 517 color.r = i * 17;
417 color.g = i * 17; 518 color.g = i * 17;
418 color.b = i * 17; 519 color.b = i * 17;
419 palette->SetEntries( palette, &color, 1, i ); 520 palette->SetEntries( palette, &color, 1, i );
420 } 521 }
421 palette->Release( palette ); 522 palette->Release( palette );
422 523
423 subframe->Clear( subframe, 0, 0, 0, 0 ); 524 subframe->Clear( subframe, 0, 0, 0, 0xff );
424 subframe->Flip( subframe, NULL, 0 ); 525 subframe->Flip( subframe, NULL, 0 );
425 subframe->Clear( subframe, 0, 0, 0, 0 ); 526 subframe->Clear( subframe, 0, 0, 0, 0xff );
426 } else if (use_crtc2) { 527 } else if (use_crtc2) {
427 /* Draw OSD to CRTC2 surface */ 528 /* Draw OSD to CRTC2 surface */
428 subframe = c2frame; 529 subframe = c2frame;
429 } else { 530 } else {
430 /* Draw OSD to BES surface */ 531 /* Draw OSD to BES surface */
432 } 533 }
433 534
434 subframe->GetSize( subframe, &sub_width, &sub_height ); 535 subframe->GetSize( subframe, &sub_width, &sub_height );
435 subframe->GetPixelFormat( subframe, &subframe_format ); 536 subframe->GetPixelFormat( subframe, &subframe_format );
436 subframe_pixel_size = DFB_BYTES_PER_PIXEL( subframe_format ); 537 subframe_pixel_size = DFB_BYTES_PER_PIXEL( subframe_format );
437 printf( "vo_dfbmga: Sub-picture surface %dx%d %s (%s)\n", 538 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Sub-picture surface %dx%d %s (%s)\n",
438 sub_width, sub_height, 539 sub_width, sub_height,
439 pixelformat_name( subframe_format ), 540 pixelformat_name( subframe_format ),
440 use_crtc2 ? (use_spic ? "Sub-picture layer" : "CRTC2") : "BES" ); 541 use_crtc2 ? (use_spic ? "Sub-picture layer" : "CRTC2") : "BES" );
441 542
442 /* Display all needed layers */ 543 /* Display all needed layers */
447 if (use_spic) 548 if (use_spic)
448 spic->SetOpacity( spic, 0xFF ); 549 spic->SetOpacity( spic, 0xFF );
449 550
450 osd_dirty = 0; 551 osd_dirty = 0;
451 osd_current = 1; 552 osd_current = 1;
553 blit_done = 0;
452 554
453 return 0; 555 return 0;
454 } 556 }
455 557
456 static uint32_t 558 static uint32_t
589 draw_slice( uint8_t * src[], int stride[], int w, int h, int x, int y ) 691 draw_slice( uint8_t * src[], int stride[], int w, int h, int x, int y )
590 { 692 {
591 void *dst; 693 void *dst;
592 int pitch; 694 int pitch;
593 695
594 if (vo_directrendering)
595 frame->Unlock( frame );
596
597 if (frame->Lock( frame, DSLF_WRITE, &dst, &pitch ) != DFB_OK) 696 if (frame->Lock( frame, DSLF_WRITE, &dst, &pitch ) != DFB_OK)
598 return VO_FALSE; 697 return VO_FALSE;
599 698
600 memcpy_pic( dst + pitch * y + x, src[0], 699 memcpy_pic( dst + pitch * y + x, src[0],
601 w, h, pitch, stride[0] ); 700 w, h, pitch, stride[0] );
626 725
627 return VO_TRUE; 726 return VO_TRUE;
628 } 727 }
629 728
630 static void 729 static void
730 blit_to_screen( void )
731 {
732 /* Flip BES */
733 if (use_bes)
734 frame->Flip( frame, NULL, 0 );
735
736 /* Blit from BES/temp to CRTC2 */
737 c2frame->SetBlittingFlags( c2frame, DSBLIT_NOFX );
738 if (stretch)
739 c2frame->StretchBlit( c2frame, frame, NULL, &drect );
740 else
741 c2frame->Blit( c2frame, frame, NULL, drect.x, drect.y );
742 }
743
744 static void
631 draw_osd( void ) 745 draw_osd( void )
632 { 746 {
633 if (vo_directrendering) 747 frame = bufs[current_buf];
634 frame->Unlock( frame ); 748 frame->Unlock( frame );
635 749
636 osd_changed = vo_osd_changed( 0 ); 750 osd_changed = vo_osd_changed( 0 );
637 751
638 if (osd_dirty & osd_current) { 752 if (osd_dirty & osd_current) {
639 if (use_spic) { 753 if (use_spic) {
640 subframe->Clear( subframe, 0, 0, 0, 0 ); 754 subframe->Clear( subframe, 0, 0, 0, 0xff );
641 } else if (use_crtc2) { 755 } else if (use_crtc2) {
642 /* Clear black bars around the picture */ 756 /* Clear black bars around the picture */
643 subframe->SetColor( subframe, 0, 0, 0, 0 ); 757 subframe->SetColor( subframe, 0, 0, 0, 0xff );
644 subframe->FillRectangle( subframe, 758 subframe->FillRectangle( subframe,
645 0, 0, 759 0, 0,
646 screen_width, drect.y ); 760 screen_width, drect.y );
647 subframe->FillRectangle( subframe, 761 subframe->FillRectangle( subframe,
648 0, drect.y + drect.h, 762 0, drect.y + drect.h,
656 } 770 }
657 osd_dirty &= ~osd_current; 771 osd_dirty &= ~osd_current;
658 } 772 }
659 773
660 if (use_crtc2) { 774 if (use_crtc2) {
661 /* Flip BES */ 775 blit_to_screen();
662 if (use_bes) 776 blit_done = 1;
663 frame->Flip( frame, NULL, 0 );
664
665 /* Blit from BES/temp to CRTC2 */
666 c2frame->SetBlittingFlags( c2frame, DSBLIT_NOFX );
667 if (stretch)
668 c2frame->StretchBlit( c2frame, frame, NULL, &drect );
669 else
670 c2frame->Blit( c2frame, frame, NULL, drect.x, drect.y );
671 } 777 }
672 778
673 vo_draw_text( sub_width, sub_height, draw_alpha ); 779 vo_draw_text( sub_width, sub_height, draw_alpha );
674 780
675 if (use_spic && osd_changed) { 781 if (use_spic && osd_changed) {
683 { 789 {
684 if (!use_crtc2) { 790 if (!use_crtc2) {
685 /* Flip BES */ 791 /* Flip BES */
686 frame->Flip( frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 ); 792 frame->Flip( frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 );
687 } else { 793 } else {
794 if (!blit_done)
795 blit_to_screen();
796
688 /* Flip CRTC2 */ 797 /* Flip CRTC2 */
689 c2frame->Flip( c2frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 ); 798 c2frame->Flip( c2frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 );
690 if (!use_spic) 799 if (!use_spic)
691 osd_current ^= 3; 800 osd_current ^= 3;
692 } 801 blit_done = 0;
693 802 }
694 current_buf = 0; 803
804 current_buf = vo_directrendering ? 0 : (current_buf + 1) % num_bufs;
695 } 805 }
696 806
697 static void 807 static void
698 uninit( void ) 808 uninit( void )
699 { 809 {
700 buffer->Release( buffer ); 810 if (use_input) {
701 keyboard->Release( keyboard ); 811 buffer->Release( buffer );
812 keyboard->Release( keyboard );
813 }
702 814
703 while (num_bufs--) { 815 while (num_bufs--) {
704 frame = bufs[num_bufs]; 816 frame = bufs[num_bufs];
705 frame->Release( frame ); 817 if (frame)
818 frame->Release( frame );
819 bufs[num_bufs] = NULL;
706 } 820 }
707 if (use_bes) { 821 if (use_bes) {
708 bes->SetOpacity( bes, 0 ); 822 bes->SetOpacity( bes, 0 );
709 bes->Release( bes ); 823 bes->Release( bes );
710 } 824 }
711 if (use_crtc2) { 825 if (use_crtc2) {
712 c2frame->Release( c2frame ); 826 if (c2frame)
827 c2frame->Release( c2frame );
713 crtc2->SetOpacity( crtc2, 0 ); 828 crtc2->SetOpacity( crtc2, 0 );
714 crtc2->Release( crtc2 ); 829 crtc2->Release( crtc2 );
715 } 830 c2frame = NULL;
716 if (use_spic) { 831 }
717 subframe->Release( subframe ); 832 if (use_spic && spic) {
833 if (subframe)
834 subframe->Release( subframe );
718 spic->SetOpacity( spic, 0 ); 835 spic->SetOpacity( spic, 0 );
719 spic->Release( spic ); 836 spic->Release( spic );
837 subframe = NULL;
838 spic = NULL;
720 } 839 }
721 840
722 /* 841 /*
723 * Don't release. Segfault in preinit() if 842 * Don't release. Segfault in preinit() if
724 * DirectFBCreate() called more than once. 843 * DirectFBCreate() called more than once.
728 } 847 }
729 848
730 static uint32_t 849 static uint32_t
731 get_image( mp_image_t *mpi ) 850 get_image( mp_image_t *mpi )
732 { 851 {
852 int buf = current_buf;
733 void *dst; 853 void *dst;
734 int pitch; 854 int pitch;
735 855
736 if (use_bes && 856 if (use_bes &&
737 (mpi->type == MP_IMGTYPE_STATIC || 857 (mpi->type == MP_IMGTYPE_STATIC ||
738 mpi->flags & MP_IMGFLAG_READABLE)) 858 mpi->flags & MP_IMGFLAG_READABLE))
739 return VO_FALSE; 859 return VO_FALSE;
740 860
741 if (mpi->flags & MP_IMGFLAG_READABLE && 861 if (mpi->flags & MP_IMGFLAG_READABLE &&
742 (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP)) { 862 (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP)) {
743 int buf = current_buf;
744
745 if (num_bufs < 2) 863 if (num_bufs < 2)
746 return VO_FALSE; 864 return VO_FALSE;
747 865
748 current_ip_buf ^= 1; 866 current_ip_buf ^= 1;
749 867
752 870
753 buf = current_ip_buf; 871 buf = current_ip_buf;
754 872
755 if (mpi->type == MP_IMGTYPE_IPB) 873 if (mpi->type == MP_IMGTYPE_IPB)
756 buf++; 874 buf++;
757 875 }
758 current_buf = buf; 876 frame = bufs[buf];
759 frame = bufs[current_buf]; 877 frame->Unlock( frame );
760 } 878
761 879 /* Always use DSLF_READ to preserve system memory copy */
762 if (frame->Lock( frame, DSLF_WRITE | (mpi->flags & MP_IMGFLAG_READABLE ? DSLF_READ : 0), 880 if (frame->Lock( frame, DSLF_WRITE | DSLF_READ,
763 &dst, &pitch ) != DFB_OK) 881 &dst, &pitch ) != DFB_OK)
764 return VO_FALSE; 882 return VO_FALSE;
765 883
766 if ((mpi->width == pitch) || 884 if ((mpi->width == pitch) ||
767 (mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH))) { 885 (mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH))) {
781 mpi->planes[1] = mpi->planes[2] + in_height * pitch / 4; 899 mpi->planes[1] = mpi->planes[2] + in_height * pitch / 4;
782 } 900 }
783 } 901 }
784 902
785 mpi->flags |= MP_IMGFLAG_DIRECT; 903 mpi->flags |= MP_IMGFLAG_DIRECT;
904 mpi->priv = (void *) buf;
905 current_buf = buf;
786 906
787 return VO_TRUE; 907 return VO_TRUE;
788 } 908 }
789 909
790 frame->Unlock( frame ); 910 frame->Unlock( frame );
795 915
796 916
797 static uint32_t 917 static uint32_t
798 draw_image( mp_image_t *mpi ) 918 draw_image( mp_image_t *mpi )
799 { 919 {
800 if (mpi->flags & (MP_IMGFLAG_DIRECT | MP_IMGFLAG_DRAW_CALLBACK)) 920 if (mpi->flags & MP_IMGFLAG_DIRECT) {
921 current_buf = (int) mpi->priv;
922 return VO_TRUE;
923 }
924 if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
801 return VO_TRUE; 925 return VO_TRUE;
802 926
803 if (mpi->flags & MP_IMGFLAG_PLANAR) 927 if (mpi->flags & MP_IMGFLAG_PLANAR)
804 return draw_slice( mpi->planes, mpi->stride, 928 return draw_slice( mpi->planes, mpi->stride,
805 mpi->w, mpi->h, 0, 0 ); 929 mpi->w, mpi->h, 0, 0 );
890 1014
891 static uint32_t 1015 static uint32_t
892 control( uint32_t request, void *data, ... ) 1016 control( uint32_t request, void *data, ... )
893 { 1017 {
894 switch (request) { 1018 switch (request) {
1019 case VOCTRL_GUISUPPORT:
1020 case VOCTRL_GUI_NOWINDOW:
1021 return VO_TRUE;
1022
895 case VOCTRL_QUERY_FORMAT: 1023 case VOCTRL_QUERY_FORMAT:
896 return query_format( *((uint32_t *) data) ); 1024 return query_format( *((uint32_t *) data) );
897 1025
898 case VOCTRL_GET_IMAGE: 1026 case VOCTRL_GET_IMAGE:
899 return get_image( data ); 1027 return get_image( data );
934 1062
935 static void 1063 static void
936 check_events( void ) 1064 check_events( void )
937 { 1065 {
938 DFBInputEvent event; 1066 DFBInputEvent event;
1067
1068 if (!use_input)
1069 return;
939 1070
940 if (buffer->GetEvent( buffer, DFB_EVENT( &event )) == DFB_OK) { 1071 if (buffer->GetEvent( buffer, DFB_EVENT( &event )) == DFB_OK) {
941 if (event.type == DIET_KEYPRESS) { 1072 if (event.type == DIET_KEYPRESS) {
942 switch (event.key_symbol) { 1073 switch (event.key_symbol) {
943 case DIKS_ESCAPE: 1074 case DIKS_ESCAPE: