[PATCH 6/6] glamor: Use Present to delay Xv painting to vblank interval
Keith Packard
keithp at keithp.com
Wed Aug 6 22:21:07 PDT 2014
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 <keithp at keithp.com>
---
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
More information about the xorg-devel
mailing list