Ok here's a new triple buffering patch.
What's different to the previous patch:
- I left DSCAPS_FLIPPING as a double buffer only cap. The previous patch
had DSCAPS_TRIPLE imply DSCAPS_FLIPPING. Not sure which way is better
though.
- fbdev support. It's pretty much _untested_ as of yet. I've been running
XDirectFB w/ desktop-buffer-mode=frontonly and mplayer w/
single,double,triple buffering for a few days without problems but I
haven't tested the fbdev double and triple buffering and changing between
buffer modes.
- I paid more attention to buffer allocation,deallocation etc.
- I like this one a whole lot more :) I think it could be commited to cvs
if the fbdev part doesn't break somehow. Comments, testing and code review
are welcome.
***
I've also attached few patches to mplayer. First one implements new
command lined options -triple and -notriple. Second one is for dfbmga and
include alut44 changes, single, double and triple buffering changes and
some general cleanups.
- If you use -triple you shouldn't need -vsync.
- With -double you need -vsync to avoid tearing.
- Without -double and -triple you get single buffering and obviosly -vsync
is needed to avoid tearing.
CRTC2 seems to like triple buffering very much but BES isn't happy with
it. -double -vsync is much better for BES.
--
Ville Syrj�l�
[EMAIL PROTECTED]
http://www.sci.fi/~syrjala/
diff -urN DirectFB/include/directfb.h DirectFB/include/directfb.h
--- DirectFB/include/directfb.h 2003-03-20 21:15:20.000000000 +0200
+++ DirectFB/include/directfb.h 2003-03-21 22:14:47.000000000 +0200
@@ -409,7 +409,8 @@
typedef enum {
DLBM_FRONTONLY = 0x00000000, /* no backbuffer */
DLBM_BACKVIDEO = 0x00000001, /* backbuffer in video memory */
- DLBM_BACKSYSTEM = 0x00000002 /* backbuffer in system memory */
+ DLBM_BACKSYSTEM = 0x00000002, /* backbuffer in system memory */
+ DLBM_TRIPLE = 0x00000004 /* triple buffering */
} DFBDisplayLayerBufferMode;
/*
@@ -474,7 +475,7 @@
by line in the buffer. <br>The first
field is followed by the second one
in the buffer. */
- DSCAPS_STATIC_ALLOC = 0x00000100 /* The amount of video or system memory
+ DSCAPS_STATIC_ALLOC = 0x00000100, /* The amount of video or system memory
allocated for the surface is never
less than its initial value. This
way a surface can be resized
@@ -484,6 +485,7 @@
surfaces that need a guaranteed
space in video memory after
resizing. */
+ DSCAPS_TRIPLE = 0x00000200 /* Surface is triple buffered */
} DFBSurfaceCapabilities;
/*
diff -urN DirectFB/src/core/fbdev/fbdev.c DirectFB/src/core/fbdev/fbdev.c
--- DirectFB/src/core/fbdev/fbdev.c 2003-03-20 21:15:21.000000000 +0200
+++ DirectFB/src/core/fbdev/fbdev.c 2003-03-21 22:15:10.000000000 +0200
@@ -224,7 +224,7 @@
#ifdef SUPPORT_RGB332
static DFBResult dfb_fbdev_set_rgb332_palette();
#endif
-static DFBResult dfb_fbdev_pan( int buffer );
+static DFBResult dfb_fbdev_pan( int offset );
static DFBResult dfb_fbdev_set_mode( DisplayLayer *layer,
VideoMode *mode,
DFBDisplayLayerConfig *config );
@@ -967,8 +967,8 @@
if ((flags & DSFLIP_WAITFORSYNC) && !dfb_config->pollvsync_after)
dfb_layer_wait_vsync( layer );
-
- ret = dfb_fbdev_pan( surface->back_buffer->video.offset ? 1 : 0 );
+
+ ret = dfb_fbdev_pan( surface->back_buffer->video.offset );
if (ret)
return ret;
@@ -1172,7 +1172,9 @@
DFBSurfaceCapabilities caps = DSCAPS_VIDEOONLY;
/* determine further capabilities */
- if (config->buffermode != DLBM_FRONTONLY)
+ if (config->buffermode == DLBM_TRIPLE)
+ caps |= DSCAPS_TRIPLE;
+ else if (config->buffermode != DLBM_FRONTONLY)
caps |= DSCAPS_FLIPPING;
/* allocate surface object */
@@ -1181,7 +1183,7 @@
return DFB_FAILURE;
/* reallocation just needs an allocated buffer structure */
- surface->back_buffer =
+ surface->idle_buffer = surface->back_buffer =
surface->front_buffer = shcalloc( 1, sizeof(SurfaceBuffer) );
if (!surface->front_buffer) {
@@ -1325,19 +1327,19 @@
/*
* pans display (flips buffer) using fbdev ioctl
*/
-static DFBResult dfb_fbdev_pan( int buffer )
+static DFBResult dfb_fbdev_pan( int offset )
{
struct fb_var_screeninfo var;
var = dfb_fbdev->shared->current_var;
- if (var.yres_virtual < var.yres*(buffer+1)) {
+ if (var.yres_virtual < offset + var.yres) {
BUG( "panning buffer out of range" );
return DFB_BUG;
}
var.xoffset = 0;
- var.yoffset = var.yres * buffer;
+ var.yoffset = offset;
dfb_gfxcard_sync();
@@ -1380,8 +1382,10 @@
var.yoffset = 0;
if (config) {
- if (config->buffermode == DLBM_BACKVIDEO)
- vyres <<= 1;
+ if (config->buffermode == DLBM_TRIPLE)
+ vyres *= 3;
+ else if (config->buffermode == DLBM_BACKVIDEO)
+ vyres *= 2;
var.bits_per_pixel = DFB_BYTES_PER_PIXEL(config->pixelformat) * 8;
@@ -1558,7 +1562,8 @@
switch (config->buffermode) {
case DLBM_FRONTONLY:
- surface->caps &= ~DSCAPS_FLIPPING;
+ surface->caps &= ~(DSCAPS_FLIPPING | DSCAPS_TRIPLE);
+
if (surface->back_buffer != surface->front_buffer) {
if (surface->back_buffer->system.addr)
shfree( surface->back_buffer->system.addr );
@@ -1567,9 +1572,50 @@
surface->back_buffer = surface->front_buffer;
}
+
+ if (surface->idle_buffer != surface->front_buffer) {
+ if (surface->idle_buffer->system.addr)
+ shfree( surface->idle_buffer->system.addr );
+
+ shfree( surface->idle_buffer );
+
+ surface->idle_buffer = surface->front_buffer;
+ }
break;
case DLBM_BACKVIDEO:
surface->caps |= DSCAPS_FLIPPING;
+ surface->caps &= ~DSCAPS_TRIPLE;
+
+ if (surface->back_buffer == surface->front_buffer) {
+ surface->back_buffer = shcalloc( 1, sizeof(SurfaceBuffer) );
+ }
+ else {
+ if (surface->back_buffer->system.addr) {
+ shfree( surface->back_buffer->system.addr );
+ surface->back_buffer->system.addr = NULL;
+ }
+
+ surface->back_buffer->system.health = CSH_INVALID;
+ }
+ surface->back_buffer->surface = surface;
+ surface->back_buffer->policy = CSP_VIDEOONLY;
+ surface->back_buffer->video.health = CSH_STORED;
+ surface->back_buffer->video.pitch = fix.line_length;
+ surface->back_buffer->video.offset =
+ surface->back_buffer->video.pitch * var.yres;
+
+ if (surface->idle_buffer != surface->front_buffer) {
+ if (surface->idle_buffer->system.addr)
+ shfree( surface->idle_buffer->system.addr );
+
+ shfree( surface->idle_buffer );
+
+ surface->idle_buffer = surface->front_buffer;
+ }
+ break;
+ case DLBM_TRIPLE:
+ surface->caps |= DSCAPS_FLIPPING | DSCAPS_TRIPLE;
+
if (surface->back_buffer == surface->front_buffer) {
surface->back_buffer = shcalloc( 1, sizeof(SurfaceBuffer) );
}
@@ -1587,9 +1633,29 @@
surface->back_buffer->video.pitch = fix.line_length;
surface->back_buffer->video.offset =
surface->back_buffer->video.pitch * var.yres;
+
+ if (surface->idle_buffer == surface->front_buffer) {
+ surface->idle_buffer = shcalloc( 1, sizeof(SurfaceBuffer) );
+ }
+ else {
+ if (surface->idle_buffer->system.addr) {
+ shfree( surface->idle_buffer->system.addr );
+ surface->idle_buffer->system.addr = NULL;
+ }
+
+ surface->idle_buffer->system.health = CSH_INVALID;
+ }
+ surface->idle_buffer->surface = surface;
+ surface->idle_buffer->policy = CSP_VIDEOONLY;
+ surface->idle_buffer->video.health = CSH_STORED;
+ surface->idle_buffer->video.pitch = fix.line_length;
+ surface->idle_buffer->video.offset =
+ surface->idle_buffer->video.pitch * var.yres * 2;
break;
case DLBM_BACKSYSTEM:
surface->caps |= DSCAPS_FLIPPING;
+ surface->caps &= ~DSCAPS_TRIPLE;
+
if (surface->back_buffer == surface->front_buffer) {
surface->back_buffer = shcalloc( 1, sizeof(SurfaceBuffer) );
}
@@ -1605,6 +1671,15 @@
surface->back_buffer->system.addr =
shmalloc( surface->back_buffer->system.pitch * var.yres );
+
+ if (surface->idle_buffer != surface->front_buffer) {
+ if (surface->idle_buffer->system.addr)
+ shfree( surface->idle_buffer->system.addr );
+
+ shfree( surface->idle_buffer );
+
+ surface->idle_buffer = surface->front_buffer;
+ }
break;
}
diff -urN DirectFB/src/core/input.c DirectFB/src/core/input.c
--- DirectFB/src/core/input.c 2003-02-18 22:49:04.000000000 +0200
+++ DirectFB/src/core/input.c 2003-03-21 22:14:47.000000000 +0200
@@ -1315,7 +1315,7 @@
} while (errno == EEXIST);
if (dfb_surface_soft_lock( surface, DSLF_READ, &data, &pitch,
- (surface->caps & DSCAPS_FLIPPING) )) {
+ surface->caps & (DSCAPS_FLIPPING | DSCAPS_TRIPLE) )) {
close( fd );
return;
}
@@ -1356,7 +1356,8 @@
((__u8*)data) += pitch;
}
- dfb_surface_unlock( surface, (surface->caps & DSCAPS_FLIPPING) );
+ dfb_surface_unlock( surface,
+ surface->caps & (DSCAPS_FLIPPING | DSCAPS_TRIPLE) );
close( fd );
}
diff -urN DirectFB/src/core/layers.c DirectFB/src/core/layers.c
--- DirectFB/src/core/layers.c 2003-03-19 13:32:15.000000000 +0200
+++ DirectFB/src/core/layers.c 2003-03-21 22:14:47.000000000 +0200
@@ -1042,6 +1042,7 @@
case DLBM_FRONTONLY:
return DFB_UNSUPPORTED;
+ case DLBM_TRIPLE:
case DLBM_BACKVIDEO:
return layer->funcs->FlipBuffers( layer,
layer->driver_data,
@@ -1808,6 +1809,10 @@
case DLBM_FRONTONLY:
break;
+ case DLBM_TRIPLE:
+ caps |= DSCAPS_TRIPLE;
+ break;
+
case DLBM_BACKVIDEO:
caps |= DSCAPS_FLIPPING;
break;
@@ -1851,18 +1856,26 @@
if (shared->config.buffermode != config->buffermode) {
switch (config->buffermode) {
+ case DLBM_TRIPLE:
+ shared->surface->caps |= DSCAPS_TRIPLE;
+ shared->surface->caps &= ~DSCAPS_FLIPPING;
+ ret = dfb_surface_reconfig( shared->surface,
+ CSP_VIDEOONLY, CSP_VIDEOONLY );
+ break;
case DLBM_BACKVIDEO:
shared->surface->caps |= DSCAPS_FLIPPING;
+ shared->surface->caps &= ~DSCAPS_TRIPLE;
ret = dfb_surface_reconfig( shared->surface,
CSP_VIDEOONLY, CSP_VIDEOONLY );
break;
case DLBM_BACKSYSTEM:
shared->surface->caps |= DSCAPS_FLIPPING;
+ shared->surface->caps &= ~DSCAPS_TRIPLE;
ret = dfb_surface_reconfig( shared->surface,
CSP_VIDEOONLY, CSP_SYSTEMONLY );
break;
case DLBM_FRONTONLY:
- shared->surface->caps &= ~DSCAPS_FLIPPING;
+ shared->surface->caps &= ~(DSCAPS_FLIPPING | DSCAPS_TRIPLE);
ret = dfb_surface_reconfig( shared->surface,
CSP_VIDEOONLY, CSP_VIDEOONLY );
break;
diff -urN DirectFB/src/core/sdl/primary.c DirectFB/src/core/sdl/primary.c
--- DirectFB/src/core/sdl/primary.c 2003-01-29 17:41:45.000000000 +0200
+++ DirectFB/src/core/sdl/primary.c 2003-03-21 22:14:47.000000000 +0200
@@ -273,6 +273,9 @@
/* if (config->buffermode == DLBM_FRONTONLY)
fail |= DLCONF_BUFFERMODE;*/
+ if (config->buffermode == DLBM_TRIPLE)
+ fail |= DLCONF_BUFFERMODE;
+
if (failed)
*failed = fail;
@@ -293,6 +296,9 @@
flags = SDL_HWSURFACE;
+ if (config->buffermode == DLBM_TRIPLE)
+ return DFB_UNSUPPORTED;
+
if (config->buffermode != DLBM_FRONTONLY)
flags |= SDL_DOUBLEBUF;
diff -urN DirectFB/src/core/surfaces.c DirectFB/src/core/surfaces.c
--- DirectFB/src/core/surfaces.c 2003-03-20 21:15:21.000000000 +0200
+++ DirectFB/src/core/surfaces.c 2003-03-21 22:14:47.000000000 +0200
@@ -132,7 +132,7 @@
return ret;
}
- if (caps & DSCAPS_FLIPPING) {
+ if (caps & (DSCAPS_FLIPPING | DSCAPS_TRIPLE)) {
ret = dfb_surface_allocate_buffer( s, policy, &s->back_buffer );
if (ret) {
dfb_surface_deallocate_buffer( s, s->front_buffer );
@@ -144,6 +144,18 @@
else
s->back_buffer = s->front_buffer;
+ if (caps & DSCAPS_TRIPLE) {
+ ret = dfb_surface_allocate_buffer( s, policy, &s->idle_buffer );
+ if (ret) {
+ dfb_surface_deallocate_buffer( s, s->back_buffer );
+ dfb_surface_deallocate_buffer( s, s->front_buffer );
+
+ fusion_object_destroy( &s->object );
+ return ret;
+ }
+ }
+ else
+ s->idle_buffer = s->front_buffer;
fusion_object_activate( &s->object );
@@ -198,6 +210,8 @@
else
s->back_buffer = s->front_buffer;
+ /* No triple buffering */
+ s->idle_buffer = s->front_buffer;
fusion_object_activate( &s->object );
@@ -268,7 +282,7 @@
return ret;
}
- if (surface->caps & DSCAPS_FLIPPING) {
+ if (surface->caps & (DSCAPS_FLIPPING | DSCAPS_TRIPLE)) {
ret = dfb_surface_reallocate_buffer( surface, surface->back_buffer );
if (ret) {
surface->width = old_width;
@@ -285,6 +299,24 @@
}
}
+ if (surface->caps & DSCAPS_TRIPLE) {
+ ret = dfb_surface_reallocate_buffer( surface, surface->idle_buffer );
+ if (ret) {
+ surface->width = old_width;
+ surface->height = old_height;
+ surface->format = old_format;
+
+ dfb_surface_reallocate_buffer( surface, surface->back_buffer );
+ dfb_surface_reallocate_buffer( surface, surface->front_buffer );
+
+ skirmish_dismiss( &surface->front_lock );
+ skirmish_dismiss( &surface->back_lock );
+
+ dfb_surfacemanager_unlock( surface->manager );
+ return ret;
+ }
+ }
+
dfb_surfacemanager_unlock( surface->manager );
if (DFB_PIXELFORMAT_IS_INDEXED( format ) && !surface->palette) {
@@ -317,6 +349,7 @@
DFBResult ret;
SurfaceBuffer *old_front;
SurfaceBuffer *old_back;
+ SurfaceBuffer *old_idle;
bool new_front = surface->front_buffer->policy != front_policy;
if (surface->front_buffer->flags & SBF_FOREIGN_SYSTEM ||
@@ -332,6 +365,7 @@
old_front = surface->front_buffer;
old_back = surface->back_buffer;
+ old_idle = surface->idle_buffer;
if (new_front) {
ret = dfb_surface_allocate_buffer( surface, front_policy,
&surface->front_buffer );
@@ -342,7 +376,7 @@
}
}
- if (surface->caps & DSCAPS_FLIPPING) {
+ if (surface->caps & (DSCAPS_FLIPPING | DSCAPS_TRIPLE)) {
ret = dfb_surface_allocate_buffer( surface, back_policy,
&surface->back_buffer );
if (ret) {
if (new_front) {
@@ -355,9 +389,27 @@
return ret;
}
}
- else {
+ else
surface->back_buffer = surface->front_buffer;
+
+ if (surface->caps & DSCAPS_TRIPLE) {
+ ret = dfb_surface_allocate_buffer( surface, back_policy,
&surface->idle_buffer );
+ if (ret) {
+ dfb_surface_deallocate_buffer( surface, surface->back_buffer );
+ surface->back_buffer = old_back;
+
+ if (new_front) {
+ dfb_surface_deallocate_buffer( surface, surface->front_buffer );
+ surface->front_buffer = old_front;
+ }
+
+ skirmish_dismiss( &surface->front_lock );
+ skirmish_dismiss( &surface->back_lock );
+ return ret;
+ }
}
+ else
+ surface->idle_buffer = surface->front_buffer;
if (new_front)
dfb_surface_deallocate_buffer( surface, old_front );
@@ -365,6 +417,9 @@
if (old_front != old_back)
dfb_surface_deallocate_buffer ( surface, old_back );
+ if (old_front != old_idle)
+ dfb_surface_deallocate_buffer ( surface, old_idle );
+
dfb_surface_notify_listeners( surface, CSNF_SIZEFORMAT |
CSNF_SYSTEM | CSNF_VIDEO );
@@ -414,9 +469,19 @@
skirmish_prevail( &surface->front_lock );
skirmish_prevail( &surface->back_lock );
- tmp = surface->front_buffer;
- surface->front_buffer = surface->back_buffer;
- surface->back_buffer = tmp;
+ if (surface->caps & DSCAPS_TRIPLE) {
+ tmp = surface->front_buffer;
+ surface->front_buffer = surface->back_buffer;
+ surface->back_buffer = surface->idle_buffer;
+ surface->idle_buffer = tmp;
+ } else {
+ tmp = surface->front_buffer;
+ surface->front_buffer = surface->back_buffer;
+ surface->back_buffer = tmp;
+
+ /* To avoid problems with buffer deallocation */
+ surface->idle_buffer = surface->front_buffer;
+ }
dfb_surfacemanager_unlock( surface->manager );
@@ -648,6 +713,10 @@
if (surface->back_buffer != surface->front_buffer)
dfb_surface_deallocate_buffer( surface, surface->back_buffer );
+ /* deallocate third buffer if it's another one */
+ if (surface->idle_buffer != surface->front_buffer)
+ dfb_surface_deallocate_buffer( surface, surface->idle_buffer );
+
/* destroy the locks */
skirmish_destroy( &surface->front_lock );
skirmish_destroy( &surface->back_lock );
diff -urN DirectFB/src/core/surfaces.h DirectFB/src/core/surfaces.h
--- DirectFB/src/core/surfaces.h 2002-12-27 21:39:12.000000000 +0200
+++ DirectFB/src/core/surfaces.h 2003-03-21 22:14:47.000000000 +0200
@@ -154,6 +154,7 @@
mutexes are outside of
SurfaceBuffer because of flipping
that just swaps the pointers */
+ SurfaceBuffer *idle_buffer; /* triple buffering */
SurfaceManager *manager;
};
diff -urN DirectFB/src/core/windows.c DirectFB/src/core/windows.c
--- DirectFB/src/core/windows.c 2003-03-19 13:32:15.000000000 +0200
+++ DirectFB/src/core/windows.c 2003-03-21 22:14:47.000000000 +0200
@@ -1461,7 +1461,7 @@
update_region( stack, state, stack->num_windows - 1,
region->x1, region->y1, region->x2, region->y2 );
- if (surface->caps & DSCAPS_FLIPPING) {
+ if (surface->caps & (DSCAPS_FLIPPING | DSCAPS_TRIPLE)) {
if (region->x1 == 0 &&
region->y1 == 0 &&
region->x2 == surface->width - 1 &&
diff -urN DirectFB/src/display/idirectfbsurface.c
DirectFB/src/display/idirectfbsurface.c
--- DirectFB/src/display/idirectfbsurface.c 2002-11-21 17:50:54.000000000 +0200
+++ DirectFB/src/display/idirectfbsurface.c 2003-03-21 22:14:47.000000000 +0200
@@ -333,7 +333,7 @@
if (data->locked)
return DFB_LOCKED;
- if (!(data->caps & DSCAPS_FLIPPING))
+ if (!(data->caps & (DSCAPS_FLIPPING | DSCAPS_TRIPLE)))
return DFB_UNSUPPORTED;
if (!data->area.current.w || !data->area.current.h)
diff -urN DirectFB/src/display/idirectfbsurface_layer.c
DirectFB/src/display/idirectfbsurface_layer.c
--- DirectFB/src/display/idirectfbsurface_layer.c 2002-11-18 20:42:43.000000000
+0200
+++ DirectFB/src/display/idirectfbsurface_layer.c 2003-03-21 22:14:47.000000000
+0200
@@ -91,7 +91,7 @@
if (data->base.locked)
return DFB_LOCKED;
- if (!(data->base.caps & DSCAPS_FLIPPING))
+ if (!(data->base.caps & (DSCAPS_FLIPPING | DSCAPS_TRIPLE)))
return DFB_UNSUPPORTED;
if (!data->base.area.current.w || !data->base.area.current.h)
diff -urN DirectFB/src/idirectfb.c DirectFB/src/idirectfb.c
--- DirectFB/src/idirectfb.c 2003-03-20 21:15:21.000000000 +0200
+++ DirectFB/src/idirectfb.c 2003-03-21 22:14:47.000000000 +0200
@@ -419,6 +419,9 @@
CoreWindow *window;
DFBWindowCapabilities window_caps = DWCAPS_NONE;
+ if (caps & DSCAPS_TRIPLE)
+ return DFB_UNSUPOORTED;
+
if (! (desc->flags & DSDESC_WIDTH))
width = data->primary.width;
@@ -478,7 +481,11 @@
case DFSCL_EXCLUSIVE:
config.flags |= DLCONF_BUFFERMODE;
- if (caps & DSCAPS_FLIPPING) {
+ if (caps & DSCAPS_TRIPLE) {
+ if (caps & DSCAPS_SYSTEMONLY)
+ return DFB_UNSUPPORTED;
+ config.buffermode = DLBM_TRIPLE;
+ } else if (caps & DSCAPS_FLIPPING) {
if (caps & DSCAPS_SYSTEMONLY)
config.buffermode = DLBM_BACKSYSTEM;
else
@@ -531,6 +538,8 @@
}
}
+ if (caps & DSCAPS_TRIPLE)
+ return DFB_UNSUPPORTED;
if (caps & DSCAPS_VIDEOONLY)
policy = CSP_VIDEOONLY;
diff -urN DirectFB/src/misc/conf.c DirectFB/src/misc/conf.c
--- DirectFB/src/misc/conf.c 2003-03-20 21:15:21.000000000 +0200
+++ DirectFB/src/misc/conf.c 2003-03-21 22:14:47.000000000 +0200
@@ -139,8 +139,9 @@
" videoonly: Window surface is always stored in video memory.\n"
"\n"
" Desktop buffer mode:\n"
- " desktop-buffer-mode=(auto|backvideo|backsystem|frontonly)\n"
+ " desktop-buffer-mode=(auto|triple|backvideo|backsystem|frontonly)\n"
" auto: DirectFB decides depending on hardware.\n"
+ " triple: Triple buffering (video only).\n"
" backvideo: Front and back buffer are video only.\n"
" backsystem: Back buffer is system only.\n"
" frontonly: There is no back buffer.\n"
@@ -539,6 +540,9 @@
if (strcmp( value, "auto" ) == 0) {
dfb_config->buffer_mode = -1;
} else
+ if (strcmp( value, "triple" ) == 0) {
+ dfb_config->buffer_mode = DLBM_TRIPLE;
+ } else
if (strcmp( value, "backvideo" ) == 0) {
dfb_config->buffer_mode = DLBM_BACKVIDEO;
} else
diff -urN DirectFB/tools/dfbdump.c DirectFB/tools/dfbdump.c
--- DirectFB/tools/dfbdump.c 2003-03-20 21:15:21.000000000 +0200
+++ DirectFB/tools/dfbdump.c 2003-03-21 22:14:47.000000000 +0200
@@ -121,7 +121,8 @@
}
mem = DFB_BYTES_PER_LINE( surface->format, surface->width ) *
- surface->height * ((surface->caps & DSCAPS_FLIPPING) ? 2 : 1);
+ surface->height * ((surface->caps & DSCAPS_TRIPLE) ? 3 :
+ (surface->caps & DSCAPS_FLIPPING) ? 2 : 1);
if (mem < 1024)
mem = 1024;
@@ -139,6 +140,9 @@
if (surface->caps & DSCAPS_FLIPPING)
printf( "flipping " );
+ if (surface->caps & DSCAPS_TRIPLE)
+ printf( "triple " );
+
if (surface->caps & DSCAPS_INTERLACED)
printf( "interlaced " );
diff -urN main/Gui/cfg.c main/Gui/cfg.c
--- main/Gui/cfg.c 2003-03-22 02:10:10.000000000 +0200
+++ main/Gui/cfg.c 2003-03-22 02:12:43.000000000 +0200
@@ -80,6 +80,7 @@
{ "vo_driver",&video_driver_list,CONF_TYPE_STRING_LIST,0,0,0,NULL },
{ "vo_panscan",&vo_panscan,CONF_TYPE_FLOAT,CONF_RANGE,0.0,1.0,NULL },
{ "vo_doublebuffering",&vo_doublebuffering,CONF_TYPE_FLAG,0,0,1,NULL },
+ { "vo_triplebuffering",&vo_triplebuffering,CONF_TYPE_FLAG,0,0,1,NULL },
{ "vo_direct_render",&vo_directrendering,CONF_TYPE_FLAG,0,0,1,NULL },
#ifdef HAVE_DXR3
{ "vo_dxr3_device",>kDXR3Device,CONF_TYPE_STRING,0,0,0,NULL },
diff -urN main/Gui/mplayer/gtk/opts.c main/Gui/mplayer/gtk/opts.c
--- main/Gui/mplayer/gtk/opts.c 2003-03-22 02:10:10.000000000 +0200
+++ main/Gui/mplayer/gtk/opts.c 2003-03-22 02:14:32.000000000 +0200
@@ -53,6 +53,7 @@
static GtkWidget * CBExtraStereo;
static GtkWidget * CBNormalize;
static GtkWidget * CBDoubleBuffer;
+static GtkWidget * CBTripleBuffer;
static GtkWidget * CBDR;
static GtkWidget * CBFramedrop;
static GtkWidget * CBHFramedrop;
@@ -221,6 +222,7 @@
// -- 2. page
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( CBDoubleBuffer ),vo_doublebuffering
);
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( CBTripleBuffer ),vo_triplebuffering
);
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( CBDR ),vo_directrendering );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( CBFramedrop ),FALSE );
@@ -529,6 +531,7 @@
// -- 2. page
vo_doublebuffering=gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(
CBDoubleBuffer ) );
+ vo_triplebuffering=gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(
CBTripleBuffer ) );
vo_directrendering=gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( CBDR ) );
frame_dropping=0;
@@ -903,6 +906,7 @@
gtk_widget_set_usize( vbox5,250,-2 );
CBDoubleBuffer=AddCheckButton( MSGTR_PREFERENCES_DoubleBuffer,vbox5 );
+ CBTripleBuffer=AddCheckButton( MSGTR_PREFERENCES_TripleBuffer,vbox5 );
CBDR=AddCheckButton( MSGTR_PREFERENCES_DirectRender,vbox5 );
CBFramedrop=AddCheckButton( MSGTR_PREFERENCES_FrameDrop,vbox5 );
CBHFramedrop=AddCheckButton( MSGTR_PREFERENCES_HFrameDrop,vbox5 );
@@ -1267,6 +1271,7 @@
gtk_signal_connect( GTK_OBJECT( CBSurround ),"toggled",GTK_SIGNAL_FUNC(
on_CBSurround_toggled ),NULL );
gtk_signal_connect( GTK_OBJECT( CBExtraStereo ),"toggled",GTK_SIGNAL_FUNC(
on_CBExtraStereo_toggled ),NULL );
gtk_signal_connect( GTK_OBJECT( CBDoubleBuffer ),"toggled",GTK_SIGNAL_FUNC(
on_CBDoubleBuffer_toggled ),NULL );
+ gtk_signal_connect( GTK_OBJECT( CBTripleBuffer ),"toggled",GTK_SIGNAL_FUNC(
on_CBTripleBuffer_toggled ),NULL );
gtk_signal_connect( GTK_OBJECT( CBDR ),"toggled",GTK_SIGNAL_FUNC( on_CBDR_toggled
),NULL );
gtk_signal_connect( GTK_OBJECT( CBFramedrop ),"toggled",GTK_SIGNAL_FUNC(
on_CBFramedrop_toggled ),NULL );
gtk_signal_connect( GTK_OBJECT( CBHFramedrop ),"toggled",GTK_SIGNAL_FUNC(
on_CBHFramedrop_toggled ),NULL );
diff -urN main/cfg-mplayer.h main/cfg-mplayer.h
--- main/cfg-mplayer.h 2003-02-08 22:52:25.000000000 +0200
+++ main/cfg-mplayer.h 2003-03-22 02:16:31.000000000 +0200
@@ -52,6 +52,7 @@
#endif
extern int vo_doublebuffering;
+extern int vo_triplebuffering;
extern int vo_vsync;
extern int vo_fsmode;
extern int vo_dbpp;
@@ -273,6 +274,9 @@
// double buffering: (mga/xmga, xv, vidix, vesa, fbdev)
{"double", &vo_doublebuffering, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"nodouble", &vo_doublebuffering, CONF_TYPE_FLAG, 0, 1, 0, NULL},
+ // triple buffering
+ {"triple", &vo_triplebuffering, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+ {"notriple", &vo_triplebuffering, CONF_TYPE_FLAG, 0, 1, 0, NULL},
// wait for v-sync (vesa)
{"vsync", &vo_vsync, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"novsync", &vo_vsync, CONF_TYPE_FLAG, 0, 1, 0, NULL},
diff -urN main/help/help_mp-en.h main/help/help_mp-en.h
--- main/help/help_mp-en.h 2003-03-22 02:10:10.000000000 +0200
+++ main/help/help_mp-en.h 2003-03-22 02:17:07.000000000 +0200
@@ -513,6 +513,7 @@
#define MSGTR_PREFERENCES_Coefficient "Coefficient:"
#define MSGTR_PREFERENCES_AudioDelay "Audio delay"
#define MSGTR_PREFERENCES_DoubleBuffer "Enable double buffering"
+#define MSGTR_PREFERENCES_TripleBuffer "Enable triple buffering"
#define MSGTR_PREFERENCES_DirectRender "Enable direct rendering"
#define MSGTR_PREFERENCES_FrameDrop "Enable frame dropping"
#define MSGTR_PREFERENCES_HFrameDrop "Enable HARD frame dropping (dangerous)"
diff -urN main/libvo/video_out.c main/libvo/video_out.c
--- main/libvo/video_out.c 2003-03-13 23:13:13.000000000 +0200
+++ main/libvo/video_out.c 2003-03-22 02:15:34.000000000 +0200
@@ -35,6 +35,7 @@
int vo_grabpointer = 1;
int vo_doublebuffering = 0;
+int vo_triplebuffering = 0;
int vo_vsync = 0;
int vo_fs = 0;
int vo_fsmode = 0;
diff -urN main/libvo/video_out.h main/libvo/video_out.h
--- main/libvo/video_out.h 2003-03-13 23:13:13.000000000 +0200
+++ main/libvo/video_out.h 2003-03-22 02:17:27.000000000 +0200
@@ -189,6 +189,7 @@
extern int vo_grabpointer;
extern int vo_doublebuffering;
+extern int vo_triplebuffering;
extern int vo_directrendering;
extern int vo_vsync;
extern int vo_fs;
diff -urN main/mencoder.c main/mencoder.c
--- main/mencoder.c 2003-03-19 18:32:22.000000000 +0200
+++ main/mencoder.c 2003-03-22 02:15:15.000000000 +0200
@@ -79,6 +79,7 @@
#include "osdep/timer.h"
int vo_doublebuffering=0;
+int vo_triplebuffering=0;
int vo_directrendering=0;
int vo_config_count=0;
diff -urN main/libvo/vo_dfbmga.c main/libvo/vo_dfbmga.c
--- main/libvo/vo_dfbmga.c 2003-02-19 18:01:46.000000000 +0200
+++ main/libvo/vo_dfbmga.c 2003-03-22 02:46:23.000000000 +0200
@@ -68,6 +68,7 @@
static IDirectFBSurface *bufs[3];
static IDirectFBSurface *frame;
+static IDirectFBSurface *besframe;
static IDirectFBSurface *c2frame;
static IDirectFBSurface *subframe;
@@ -79,9 +80,6 @@
static IDirectFBInputDevice *keyboard;
static IDirectFBEventBuffer *buffer;
-static unsigned int frame_pixel_size;
-static unsigned int subframe_pixel_size;
-
static int inited = 0;
static int blit_done;
@@ -96,11 +94,20 @@
static int osd_changed;
static int osd_dirty;
static int osd_current;
+static int osd_max;
/******************************
-* vo_directfb *
+* vo_dfbmga *
******************************/
+#if DIRECTFBVERSION < 917
+ #define DSPF_ALUT44 DSPF_LUT8
+#endif
+
+#if DIRECTFBVERSION < 916
+ #define DSPF_ARGB1555 DSPF_RGB15
+#endif
+
/* command line/config file options */
#ifdef HAVE_FBDEV
extern char *fb_dev_name;
@@ -127,13 +134,8 @@
return "RGB24";
case DSPF_RGB16:
return "RGB16";
-#if DIRECTFBVERSION > 915
case DSPF_ARGB1555:
return "ARGB1555";
-#else
- case DSPF_RGB15:
- return "RGB15";
-#endif
case DSPF_YUY2:
return "YUY2";
case DSPF_UYVY:
@@ -142,8 +144,8 @@
return "YV12";
case DSPF_I420:
return "I420";
- case DSPF_LUT8:
- return "LUT8";
+ case DSPF_ALUT44:
+ return "ALUT44";
default:
return "Unknown pixel format";
}
@@ -164,11 +166,7 @@
return DSPF_RGB16;
case IMGFMT_RGB15:
case IMGFMT_BGR15:
-#if DIRECTFBVERSION > 915
return DSPF_ARGB1555;
-#else
- return DSPF_RGB15;
-#endif
case IMGFMT_YUY2:
return DSPF_YUY2;
case IMGFMT_UYVY:
@@ -219,13 +217,17 @@
{
DFBResult res;
+ bes = NULL;
+ crtc2 = NULL;
+
/* Some defaults */
use_bes = 0;
use_crtc2 = 1;
use_spic = 1;
- use_input = 1;
field_parity = -1;
+ use_input = getenv( "DISPLAY" ) ? 0 : 1;
+
if (vo_subdevice) {
int opt_no = 0;
while (*vo_subdevice != '\0') {
@@ -242,7 +244,7 @@
vo_subdevice += 4;
opt_no = 0;
} else if (!strncmp(vo_subdevice, "input", 5)) {
- use_spic = !opt_no;
+ use_input = !opt_no;
vo_subdevice += 5;
opt_no = 0;
} else if (!strncmp(vo_subdevice, "fieldparity=", 12)) {
@@ -354,6 +356,7 @@
uint32_t out_width;
uint32_t out_height;
+ besframe = NULL;
c2frame = NULL;
spic = NULL;
subframe = NULL;
@@ -367,31 +370,7 @@
dlc.pixelformat = imgfmt_to_pixelformat( format );
- if (use_bes) {
- /* Draw to BES surface */
- dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
DLCONF_BUFFERMODE;
- dlc.width = in_width;
- dlc.height = in_height;
- dlc.buffermode = DLBM_BACKVIDEO;
-
- if (bes->TestConfiguration( bes, &dlc, &failed ) != DFB_OK) {
- mp_msg( MSGT_VO, MSGL_ERR,
- "vo_dfbmga: Invalid BES configuration!\n" );
- return -1;
- }
- bes->SetConfiguration( bes, &dlc );
- bes->GetSurface( bes, &frame );
-
- aspect_save_screenres( 10000, 10000 );
- aspect( &out_width, &out_height, A_ZOOM );
- bes->SetScreenLocation( bes,
- (1.0f - (float) out_width / 10000.0f) / 2.0f,
- (1.0f - (float) out_height / 10000.0f) / 2.0f,
- (float) out_width / 10000.0f,
- (float) out_height / 10000.0f );
- bufs[0] = frame;
- num_bufs = 1;
- } else {
+ {
/* Draw to a temporary surface */
DFBSurfaceDescription dsc;
@@ -401,6 +380,12 @@
dsc.height = in_height;
dsc.pixelformat = dlc.pixelformat;
+ /* Don't waste video memory since we don't need stretchblit */
+ if (use_bes) {
+ dsc.flags |= DSDESC_CAPS;
+ dsc.caps = DSCAPS_SYSTEMONLY;
+ }
+
for (num_bufs = 0; num_bufs < 3; num_bufs++) {
if ((res = dfb->CreateSurface( dfb, &dsc, &bufs[num_bufs] )) !=
DFB_OK) {
if (num_bufs == 0) {
@@ -409,20 +394,87 @@
DirectFBErrorString( res ) );
return -1;
}
+ break;
}
}
frame = bufs[0];
current_buf = 0;
current_ip_buf = 0;
}
+ frame->GetPixelFormat( frame, &frame_format );
+ mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Video surface %dx%d %s\n",
+ in_width, in_height,
+ pixelformat_name( frame_format ) );
+
+
+ /*
+ * BES
+ */
+ if (use_bes) {
+ dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
DLCONF_BUFFERMODE;
+ dlc.width = in_width;
+ dlc.height = in_height;
+
+ if (use_crtc2) {
+ dlc.buffermode = DLBM_FRONTONLY;
+ osd_max = 1;
+ } else if (vo_triplebuffering) {
+ dlc.buffermode = DLBM_TRIPLE;
+ osd_max = 4;
+ } else if (vo_doublebuffering) {
+ dlc.buffermode = DLBM_BACKVIDEO;
+ osd_max = 2;
+ } else {
+ dlc.buffermode = DLBM_FRONTONLY;
+ osd_max = 1;
+ }
+
+ if (bes->TestConfiguration( bes, &dlc, &failed ) != DFB_OK) {
+ mp_msg( MSGT_VO, MSGL_ERR,
+ "vo_dfbmga: Invalid BES configuration!\n" );
+ return -1;
+ }
+ bes->SetConfiguration( bes, &dlc );
+ bes->GetSurface( bes, &besframe );
+ besframe->SetBlittingFlags( besframe, DSBLIT_NOFX );
+ aspect_save_screenres( 10000, 10000 );
+ aspect( &out_width, &out_height, A_ZOOM );
+ bes->SetScreenLocation( bes,
+ (1.0f - (float) out_width / 10000.0f) / 2.0f,
+ (1.0f - (float) out_height / 10000.0f) / 2.0f,
+ (float) out_width / 10000.0f,
+ (float) out_height / 10000.0f );
+
+ besframe->Clear( besframe, 0, 0, 0, 0xff );
+ besframe->Flip( besframe, NULL, 0 );
+ besframe->Clear( besframe, 0, 0, 0, 0xff );
+ besframe->Flip( besframe, NULL, 0 );
+ besframe->Clear( besframe, 0, 0, 0, 0xff );
+
+ mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: BES surface %dx%d %s\n", dlc.width,
dlc.height, pixelformat_name( dlc.pixelformat ) );
+ }
+
+ /*
+ * CRTC2
+ */
if (use_crtc2) {
- dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
- dlc.buffermode = DLBM_BACKVIDEO;
+ dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS;
+
+ if (vo_triplebuffering) {
+ dlc.buffermode = DLBM_TRIPLE;
+ osd_max = 4;
+ } else if (vo_doublebuffering) {
+ dlc.buffermode = DLBM_BACKVIDEO;
+ osd_max = 2;
+ } else {
+ dlc.buffermode = DLBM_FRONTONLY;
+ osd_max = 1;
+ }
+ dlc.options = DLOP_FLICKER_FILTERING;
#if DIRECTFBVERSION > 916
if (field_parity != -1) {
- dlc.flags |= DLCONF_OPTIONS;
dlc.options = DLOP_FIELD_PARITY;
}
#endif
@@ -457,6 +509,7 @@
#endif
crtc2->GetSurface( crtc2, &c2frame );
+ c2frame->SetBlittingFlags( c2frame, DSBLIT_NOFX );
c2frame->GetSize( c2frame, &screen_width, &screen_height );
@@ -489,21 +542,17 @@
c2frame->Clear( c2frame, 0, 0, 0, 0xff );
c2frame->Flip( c2frame, NULL, 0 );
c2frame->Clear( c2frame, 0, 0, 0, 0xff );
+ c2frame->Flip( c2frame, NULL, 0 );
+ c2frame->Clear( c2frame, 0, 0, 0, 0xff );
mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC2 surface %dx%d %s\n",
dlc.width, dlc.height, pixelformat_name( dlc.pixelformat ) );
} else {
- screen_width = in_width;
- screen_height = in_height;
use_spic = 0;
}
- frame->GetPixelFormat( frame, &frame_format );
- frame_pixel_size = DFB_BYTES_PER_PIXEL( frame_format );
- mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Video surface %dx%d %s (%s)\n",
- in_width, in_height,
- pixelformat_name( frame_format ),
- use_bes ? "BES" : "offscreen" );
-
+ /*
+ * Sub-picture
+ */
if (use_spic) {
/* Draw OSD to sub-picture surface */
IDirectFBPalette *palette;
@@ -523,8 +572,19 @@
spic->SetOpacity( spic, 0 );
dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
- dlc.pixelformat = DSPF_LUT8;
- dlc.buffermode = DLBM_BACKVIDEO;
+ dlc.pixelformat = DSPF_ALUT44;
+
+ if (vo_triplebuffering) {
+ dlc.buffermode = DLBM_TRIPLE;
+ osd_max = 4;
+ } else if (vo_doublebuffering) {
+ dlc.buffermode = DLBM_BACKVIDEO;
+ osd_max = 2;
+ } else {
+ dlc.buffermode = DLBM_FRONTONLY;
+ osd_max = 1;
+ }
+
#if DIRECTFBVERSION > 916
dlc.flags |= DLCONF_OPTIONS;
dlc.options = DLOP_ALPHACHANNEL;
@@ -548,20 +608,21 @@
}
palette->Release( palette );
- subframe->Clear( subframe, 0, 0, 0, 0xff );
+ subframe->Clear( subframe, 0, 0, 0, 0 );
+ subframe->Flip( subframe, NULL, 0 );
+ subframe->Clear( subframe, 0, 0, 0, 0 );
subframe->Flip( subframe, NULL, 0 );
- subframe->Clear( subframe, 0, 0, 0, 0xff );
+ subframe->Clear( subframe, 0, 0, 0, 0 );
} else if (use_crtc2) {
/* Draw OSD to CRTC2 surface */
subframe = c2frame;
} else {
/* Draw OSD to BES surface */
- subframe = frame;
+ subframe = besframe;
}
subframe->GetSize( subframe, &sub_width, &sub_height );
subframe->GetPixelFormat( subframe, &subframe_format );
- subframe_pixel_size = DFB_BYTES_PER_PIXEL( subframe_format );
mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Sub-picture surface %dx%d %s (%s)\n",
sub_width, sub_height,
pixelformat_name( subframe_format ),
@@ -610,12 +671,12 @@
}
static void
-vo_draw_alpha_lut8( int w, int h,
- unsigned char* src,
- unsigned char *srca,
- int srcstride,
- unsigned char* dst,
- int dststride )
+vo_draw_alpha_alut44( int w, int h,
+ unsigned char* src,
+ unsigned char *srca,
+ int srcstride,
+ unsigned char* dst,
+ int dststride )
{
int x;
@@ -652,54 +713,50 @@
osd_dirty |= osd_current;
}
- if (subframe->Lock( subframe, DSLF_WRITE, &dst, &pitch ) != DFB_OK)
+ if (subframe->Lock( subframe, DSLF_READ | DSLF_WRITE, &dst, &pitch ) != DFB_OK)
return;
switch (subframe_format) {
- case DSPF_LUT8:
- vo_draw_alpha_lut8( w, h, src, srca, stride,
- ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size *
x0,
- pitch );
+ case DSPF_ALUT44:
+ vo_draw_alpha_alut44( w, h, src, srca, stride,
+ ((uint8_t *) dst) + pitch * y0 + x0,
+ pitch );
break;
case DSPF_RGB32:
case DSPF_ARGB:
vo_draw_alpha_rgb32( w, h, src, srca, stride,
- (( uint8_t *) dst) + pitch * y0 + subframe_pixel_size *
x0,
+ (( uint8_t *) dst) + pitch * y0 + 4 * x0,
pitch );
break;
case DSPF_RGB24:
vo_draw_alpha_rgb24( w, h, src, srca, stride,
- ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size *
x0,
+ ((uint8_t *) dst) + pitch * y0 + 3 * x0,
pitch );
break;
case DSPF_RGB16:
vo_draw_alpha_rgb16( w, h, src, srca, stride,
- ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size *
x0,
+ ((uint8_t *) dst) + pitch * y0 + 2 * x0,
pitch );
break;
-#if DIRECTFBVERSION > 915
case DSPF_ARGB1555:
-#else
- case DSPF_RGB15:
-#endif
vo_draw_alpha_rgb15( w, h, src, srca, stride,
- ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size *
x0,
+ ((uint8_t *) dst) + pitch * y0 + 2 * x0,
pitch );
break;
case DSPF_YUY2:
vo_draw_alpha_yuy2( w, h, src, srca, stride,
- ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size *
x0,
+ ((uint8_t *) dst) + pitch * y0 + 2 * x0,
pitch );
break;
case DSPF_UYVY:
vo_draw_alpha_yuy2( w, h, src, srca, stride,
- ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size *
x0 + 1,
+ ((uint8_t *) dst) + pitch * y0 + 2 * x0 + 1,
pitch );
break;
case DSPF_I420:
case DSPF_YV12:
vo_draw_alpha_yv12( w, h, src, srca, stride,
- ((uint8_t *) dst) + pitch * y0 + subframe_pixel_size *
x0,
+ ((uint8_t *) dst) + pitch * y0 + x0,
pitch );
break;
default:
@@ -756,16 +813,26 @@
static void
blit_to_screen( void )
{
- /* Flip BES */
- if (use_bes)
- frame->Flip( frame, NULL, 0 );
+ IDirectFBSurface *blitsrc = frame;
+ int waitvsync = vo_vsync && !vo_doublebuffering && !vo_triplebuffering;
- /* Blit from BES/temp to CRTC2 */
- c2frame->SetBlittingFlags( c2frame, DSBLIT_NOFX );
- if (stretch)
- c2frame->StretchBlit( c2frame, frame, NULL, &drect );
- else
- c2frame->Blit( c2frame, frame, NULL, drect.x, drect.y );
+ if (use_bes) {
+ if (waitvsync && !use_crtc2)
+ bes->WaitForSync( bes );
+
+ besframe->Blit( besframe, blitsrc, NULL, 0, 0 );
+ blitsrc = besframe;
+ }
+
+ if (use_crtc2) {
+ if (waitvsync)
+ crtc2->WaitForSync( crtc2 );
+
+ if (stretch)
+ c2frame->StretchBlit( c2frame, blitsrc, NULL, &drect );
+ else
+ c2frame->Blit( c2frame, blitsrc, NULL, drect.x, drect.y );
+ }
}
static void
@@ -778,7 +845,7 @@
if (osd_dirty & osd_current) {
if (use_spic) {
- subframe->Clear( subframe, 0, 0, 0, 0xff );
+ subframe->Clear( subframe, 0, 0, 0, 0 );
} else if (use_crtc2) {
/* Clear black bars around the picture */
subframe->SetColor( subframe, 0, 0, 0, 0xff );
@@ -798,36 +865,39 @@
osd_dirty &= ~osd_current;
}
- if (use_crtc2) {
- blit_to_screen();
- blit_done = 1;
- }
+ blit_to_screen();
+ blit_done = 1;
vo_draw_text( sub_width, sub_height, draw_alpha );
- if (use_spic && osd_changed) {
+ if (use_spic && osd_changed &&
+ (vo_doublebuffering || vo_triplebuffering)) {
subframe->Flip( subframe, NULL, 0 );
- osd_current ^= 3;
+ osd_current <<= 1;
+ if (osd_current > osd_max)
+ osd_current = 1;
}
}
static void
flip_page( void )
{
- if (!use_crtc2) {
- /* Flip BES */
- frame->Flip( frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 );
- } else {
- if (!blit_done)
- blit_to_screen();
+ if (!blit_done)
+ blit_to_screen();
- /* Flip CRTC2 */
- c2frame->Flip( c2frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 );
- if (!use_spic)
- osd_current ^= 3;
- blit_done = 0;
+ if (vo_doublebuffering || vo_triplebuffering) {
+ if (use_crtc2)
+ c2frame->Flip( c2frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 );
+ else
+ besframe->Flip( besframe, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : 0 );
+ if (!use_spic) {
+ osd_current <<= 1;
+ if (osd_current > osd_max)
+ osd_current = 1;
+ }
}
-
+
+ blit_done = 0;
current_buf = vo_directrendering ? 0 : (current_buf + 1) % num_bufs;
}
@@ -845,18 +915,23 @@
frame->Release( frame );
bufs[num_bufs] = NULL;
}
- if (use_bes) {
+ if (bes) {
+ if (besframe)
+ besframe->Release( besframe );
bes->SetOpacity( bes, 0 );
bes->Release( bes );
+ besframe = NULL;
+ bes = NULL;
}
- if (use_crtc2) {
+ if (crtc2) {
if (c2frame)
c2frame->Release( c2frame );
crtc2->SetOpacity( crtc2, 0 );
crtc2->Release( crtc2 );
c2frame = NULL;
+ crtc2 = NULL;
}
- if (use_spic && spic) {
+ if (spic) {
if (subframe)
subframe->Release( subframe );
spic->SetOpacity( spic, 0 );