summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorReinhard Nißl <rnissl@gmx.de>2011-03-13 17:22:04 +0100
committerReinhard Nißl <rnissl@gmx.de>2011-03-13 17:22:04 +0100
commit4954130b158bf8fe3841f53c5403a0f750ca21f5 (patch)
tree911a86843543c715fb473dc29f0d745520486c65 /src
parent4f3e200e033099bc0cb41e47345bdf97968b029f (diff)
downloadxine-lib-4954130b158bf8fe3841f53c5403a0f750ca21f5.tar.gz
xine-lib-4954130b158bf8fe3841f53c5403a0f750ca21f5.tar.bz2
Double buffer ARGB data for distortion free OSD updates.
This is necessary as VDR expects its OSD flush call to return as quickly as possible. Hence, we can nolonger wait until all changes have appeared on screen. As a result, a following OSD change might be written to the ARGB buffer while the buffer is currently transferred to screen, causing visible distortions. --HG-- extra : rebase_source : 19c4d5a1c73b5791e66f276d57fe62497d00fb7b
Diffstat (limited to 'src')
-rw-r--r--src/vdr/input_vdr.c65
1 files changed, 43 insertions, 22 deletions
diff --git a/src/vdr/input_vdr.c b/src/vdr/input_vdr.c
index 01c654426..3af018e09 100644
--- a/src/vdr/input_vdr.c
+++ b/src/vdr/input_vdr.c
@@ -75,7 +75,7 @@ vdr_metronom_t;
typedef struct vdr_osd_s
{
xine_osd_t *window;
- uint8_t *argb_buffer;
+ uint8_t *argb_buffer[ 2 ];
int width;
int height;
}
@@ -435,6 +435,7 @@ static off_t vdr_execute_rpc_command(vdr_input_plugin_t *this)
case func_osd_free:
{
+ int i;
READ_DATA_OR_FAIL(osd_free, LOG_OSD(lprintf("got OSDFREE\n")));
/*
fprintf(stderr, "vdr: osdfree %d\n", data->window);
@@ -447,8 +448,11 @@ static off_t vdr_execute_rpc_command(vdr_input_plugin_t *this)
this->osd[ data->window ].window = 0;
- free(this->osd[ data->window ].argb_buffer);
- this->osd[ data->window ].argb_buffer = 0;
+ for (i = 0; i < 2; i++)
+ {
+ free(this->osd[ data->window ].argb_buffer[ i ]);
+ this->osd[ data->window ].argb_buffer[ i ] = 0;
+ }
}
break;
@@ -507,6 +511,7 @@ static off_t vdr_execute_rpc_command(vdr_input_plugin_t *this)
while ((r = _x_query_unprocessed_osd_events(this->stream)))
{
+break;
if ((_now() - _t1) > 200)
{
_to = 1;
@@ -521,7 +526,9 @@ static off_t vdr_execute_rpc_command(vdr_input_plugin_t *this)
}
_t2 = _now();
+/*
fprintf(stderr, "vdr: osdflush: n: %d, %.1lf, timeout: %d, result: %d\n", _n, _t2 - _t1, _to, r);
+*/
/*
fprintf(stderr, "redraw_needed: 0\n");
@@ -579,31 +586,42 @@ static off_t vdr_execute_rpc_command(vdr_input_plugin_t *this)
if (data->argb)
{
- if (!osd->argb_buffer)
- osd->argb_buffer = calloc(4 * osd->width, osd->height);
-
+ int i;
+ for (i = 0; i < 2; i++)
{
- int src_stride = 4 * data->width;
- int dst_stride = 4 * osd->width;
-
- uint8_t *src = this->osd_buffer;
- uint8_t *dst = osd->argb_buffer + data->y * dst_stride + data->x * 4;
- int y;
+ if (!osd->argb_buffer[ i ])
+ osd->argb_buffer[ i ] = calloc(4 * osd->width, osd->height);
- if (src_stride == dst_stride)
- xine_fast_memcpy(dst, src, src_stride * data->height);
- else
{
- for (y = 0; y < data->height; y++)
+ int src_stride = 4 * data->width;
+ int dst_stride = 4 * osd->width;
+
+ uint8_t *src = this->osd_buffer;
+ uint8_t *dst = osd->argb_buffer[ i ] + data->y * dst_stride + data->x * 4;
+ int y;
+
+ if (src_stride == dst_stride)
+ xine_fast_memcpy(dst, src, src_stride * data->height);
+ else
{
- xine_fast_memcpy(dst, src, src_stride);
- dst += dst_stride;
- src += src_stride;
+ for (y = 0; y < data->height; y++)
+ {
+ xine_fast_memcpy(dst, src, src_stride);
+ dst += dst_stride;
+ src += src_stride;
+ }
}
}
- }
- xine_osd_set_argb_buffer(osd->window, (uint32_t *)osd->argb_buffer, data->x, data->y, data->width, data->height);
+ if (i == 0)
+ xine_osd_set_argb_buffer(osd->window, (uint32_t *)osd->argb_buffer[ i ], data->x, data->y, data->width, data->height);
+ }
+ /* flip render and display buffer */
+ {
+ uint8_t *argb_buffer = osd->argb_buffer[ 0 ];
+ osd->argb_buffer[ 0 ] = osd->argb_buffer[ 1 ];
+ osd->argb_buffer[ 1 ] = argb_buffer;
+ }
}
else
xine_osd_draw_bitmap(osd->window, this->osd_buffer, data->x, data->y, data->width, data->height, 0);
@@ -1832,13 +1850,16 @@ static void vdr_plugin_dispose(input_plugin_t *this_gen)
for (i = 0; i < VDR_MAX_NUM_WINDOWS; i++)
{
+ int k;
+
if (0 == this->osd[ i ].window)
continue;
xine_osd_hide(this->osd[ i ].window, 0);
xine_osd_free(this->osd[ i ].window);
- free(this->osd[ i ].argb_buffer);
+ for (k = 0; k < 2; k++)
+ free(this->osd[ i ].argb_buffer[ k ]);
}
if (this->osd_buffer)