Re: [PATCH 6/6] glamor: Use Present to delay Xv painting to vblank interval

2014-08-07 Thread Keith Packard
Michel Dänzer  writes:

> On 07.08.2014 14:21, Keith Packard wrote:

> The keyword being 'reduce'. This won't reliably prevent tearing in
> general, so I'm not sure I see the point of jumping through all those hoops.

If the GPU is idle at vblank time, then you'll reliably be able to queue
the Yuv to RGB conversion within the vblank interval and tearing won't
happen. In practice, this technique works quite well.

For non full-screen windows in non-composited environments, you want
this code anyways; page flipping that would be a bit of work.

> If glamor Xv used (something like) present_pixmap(), that would reliably
> prevent tearing at least in the fullscreen case, wouldn't it?

Yeah, converting Yuv to RGB and then using page flipping instead of
doing the conversion directly to the frame buffer would avoid needing
the GPU to be idle at vblank time. Might be worth an experiment.

In fact, a video player could easily do this itself with Xv and
Present. I should try hacking up a couple to see how hard it is.

> If you don't want any tearing ever, use a Wayland compositor? :)

Or any compositor -- note that if your X compositing manager doesn't
"unredirect" your video window, the Yuv to RGB conversion will be done
to the window buffer and the compositor will do it's usual tear-free
presentation.

-- 
keith.pack...@intel.com


pgp32E6gHftrS.pgp
Description: PGP signature
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH 6/6] glamor: Use Present to delay Xv painting to vblank interval

2014-08-07 Thread Michel Dänzer
On 07.08.2014 14:21, Keith Packard wrote:
> For un-redirected windows, this uses present_vblank_window_queue to
> start painting the screen during vblank and reduce tearing on the
> screen

The keyword being 'reduce'. This won't reliably prevent tearing in
general, so I'm not sure I see the point of jumping through all those hoops.

If glamor Xv used (something like) present_pixmap(), that would reliably
prevent tearing at least in the fullscreen case, wouldn't it?

If you don't want any tearing ever, use a Wayland compositor? :)


-- 
Earthling Michel Dänzer|  http://www.amd.com
Libre software enthusiast  |Mesa and X developer
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel


[PATCH 6/6] glamor: Use Present to delay Xv painting to vblank interval

2014-08-06 Thread Keith Packard
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 
---
 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 
 #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

___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel