For un-redirected windows, this uses present_vblank_window_queue to start painting the screen during vblank and reduce tearing on the screen
Signed-off-by: Keith Packard <[email protected]> --- glamor/glamor_priv.h | 2 ++ glamor/glamor_xv.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 05d3eac..a0b790c 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -1016,6 +1016,8 @@ typedef struct { RegionRec clip; PixmapPtr src_pix[3]; /* y, u, v for planar */ int src_pix_w, src_pix_h; + uint64_t present_id; + unsigned long serialNumber; } glamor_port_private; extern XvAttributeRec glamor_xv_attributes[]; diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index 367b89f..a71ac10 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -37,6 +37,7 @@ #endif #include "glamor_priv.h" +#include "present_vblank.h" #include <X11/extensions/Xv.h> #include "../hw/xfree86/common/fourcc.h" @@ -138,6 +139,11 @@ glamor_xv_stop_video(glamor_port_private *port_priv) { int i; + if (port_priv->present_id) { + present_vblank_cancel(port_priv->pDraw->pScreen, port_priv->present_id); + port_priv->present_id = 0; + } + for (i = 0; i < 3; i++) { if (port_priv->src_pix[i]) { glamor_destroy_pixmap(port_priv->src_pix[i]); @@ -260,9 +266,6 @@ glamor_xv_render(glamor_port_private *port_priv) int ref = port_priv->transform_index; GLint uloc, sampler_loc; - if (!glamor_priv->xv_prog) - glamor_init_xv_shader(screen); - cont = RTFContrast(port_priv->contrast); bright = RTFBrightness(port_priv->brightness); gamma = (float) port_priv->gamma / 1000.0; @@ -389,6 +392,29 @@ glamor_xv_render(glamor_port_private *port_priv) DamageDamageRegion(port_priv->pDraw, &port_priv->clip); } +static void +glamor_xv_present(WindowPtr window, + void *closure, + uint64_t ust, + uint64_t msc) +{ + glamor_port_private *port_priv = closure; + + port_priv->present_id = 0; + if (port_priv->serialNumber == window->drawable.serialNumber) { + glamor_xv_render(port_priv); + glFlush(); + } +} + +static Bool +glamor_window_is_redirected(WindowPtr window) +{ + ScreenPtr screen = window->drawable.pScreen; + + return screen->GetWindowPixmap (window) != screen->GetScreenPixmap(screen); +} + int glamor_xv_put_image(glamor_port_private *port_priv, DrawablePtr pDrawable, @@ -404,6 +430,7 @@ glamor_xv_put_image(glamor_port_private *port_priv, RegionPtr clipBoxes) { ScreenPtr pScreen = pDrawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen); int srcPitch, srcPitch2; int top, nlines; int s2offset, s3offset, tmp; @@ -413,6 +440,11 @@ glamor_xv_put_image(glamor_port_private *port_priv, srcPitch = width; srcPitch2 = width >> 1; + glamor_make_current(glamor_priv); + + if (!glamor_priv->xv_prog) + glamor_init_xv_shader(pScreen); + if (!port_priv->src_pix[0] || (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) { int i; @@ -489,7 +521,30 @@ glamor_xv_put_image(glamor_port_private *port_priv, port_priv->w = width; port_priv->h = height; port_priv->pDraw = pDrawable; - glamor_xv_render(port_priv); + + if (port_priv->present_id) { + present_vblank_cancel(pScreen, port_priv->present_id); + port_priv->present_id = 0; + } + + if (pDrawable->type == DRAWABLE_WINDOW && + !glamor_window_is_redirected((WindowPtr) pDrawable)) + { + port_priv->serialNumber = pDrawable->serialNumber; + port_priv->present_id = present_vblank_window_queue((WindowPtr) pDrawable, + present_whence_relative, + 1, + 0, + glamor_xv_present, + port_priv); + } + + if (!port_priv->present_id) + glamor_xv_render(port_priv); + + if (port_priv->present_id == PRESENT_VBLANK_QUEUE_EXECUTED) + port_priv->present_id = 0; + return Success; } -- 2.0.1 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
