From 4954130b158bf8fe3841f53c5403a0f750ca21f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Sun, 13 Mar 2011 17:22:04 +0100 Subject: 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 --- src/vdr/input_vdr.c | 65 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 22 deletions(-) (limited to 'src') 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) -- cgit v1.2.3