diff options
author | Reinhard Nißl <rnissl@gmx.de> | 2011-03-13 17:22:04 +0100 |
---|---|---|
committer | Reinhard Nißl <rnissl@gmx.de> | 2011-03-13 17:22:04 +0100 |
commit | 4954130b158bf8fe3841f53c5403a0f750ca21f5 (patch) | |
tree | 911a86843543c715fb473dc29f0d745520486c65 | |
parent | 4f3e200e033099bc0cb41e47345bdf97968b029f (diff) | |
download | xine-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
-rw-r--r-- | src/vdr/input_vdr.c | 65 |
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) |