Patchwork Sync to V-blank

login
register
mail settings
Submitter Boszormenyi Zoltan
Date April 3, 2014, 10:28 a.m.
Message ID <533D37E3.9070109@pr.hu>
Download mbox | patch
Permalink /patch/70059/
State Not Applicable
Delegated to: Otavio Salvador
Headers show

Comments

Boszormenyi Zoltan - April 3, 2014, 10:28 a.m.
Hi,

is there a way to enable double buffering in X on the
I would like to achieve tearing-free/flicker-free video.
I have just tried "gst-launch-1.0 playbin uri=file://..."
on a couple of 720p and 1080p test videos and there is
visible tearing when sideways movement or fast fading in
or fading out happens on the screen.

I found this thread: https://community.freescale.com/thread/303863
but "export FB_MULTI_BUFFER=2" doesn't seem to
do anything. Indeed, the "FB_MULTI_BUFFER" string
is not in any of the libraries in /usr/lib or /lib.

Then I looked into the gstreamer1.0-plugins-imx sources
and came up with the attached patch, rebuilt the package,
removed from the board and installed it again. The flicker
is still there.

Do the Vivante drivers support sync-to-V-blank?

Thanks in advance,
Zoltán Böszörményi
dv - April 3, 2014, 10:32 a.m.
This X11 vsync problem has been bugging several people, and to date, 
there is no proper solution (other than to use framebuffer directly 
instead, or switch to Wayland).

Eric Nelson mentioned details about this, as well as a possible 
workaround. I appended his email here:



=================================================



On 03/18/2014 02:39 PM, Carlos Rafael Giani wrote:
> Hello,
>
> in the past, there has always been a problem with vsync, OpenGL ES
> output, and X11. Very noticeable tearing affects all such applications.
> So far, neither Vivante nor Freescale have ever commented on this. Is
> there anything known? Should the newest drivers fix this?

You have odd timing. I was just looking into this today for a
customer.

In our kernels and the Freescale kernels. there seems to be an
issue with the default allocation of the frame-buffer, such that
only space for  a single buffer is present.

http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/drivers/video/mxc/mxc_ipuv3_fb.c?h=imx_3.0.35_4.1.0#n862 


Without a larger allocation, I don't think the frame buffer
driver has any way of swapping cleanly at vertical sync.

The 3.10.17-beta kernel seems to do the same thing:
http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/drivers/video/mxc/mxc_ipuv3_fb.c?h=imx_3.10.17_1.0.0_beta#n870 


You can see this at run-time by looking in
/sys/class/graphics/fb0/virtual_size.

     # cat /sys/class/graphics/fb0/mode
     U:1280x800p-59
     # cat /sys/class/graphics/fb0/virtual_size
     1280,800

You can also alter things by using sysfs:
     # echo 1280,1600 > /sys/class/graphics/fb0/virtual_size

After changing the size, the FBIO_PAN ioctl does the right
thing. i.e.:

     variable_info.yoffset = x;
     err = ioctl(fdfb,FBIOPAN_DISPLAY,&variable_info);

And you can see the same thing using /sys/class/graphics/fb0/pan.

It's not clear to me who should be doing this though.

In an X environment, I would expect this to be controlled
through xorg.conf somehow, but my attempts to get fbdev
and shadowfb proved fruitless.

I haven't had a chance to look into the Vivante X driver
and I'm not sure where the OpenGL stack this should be
performed, but since the timing really has to be coordinated
by the frame-buffer, there should be a call somewhere.

In my immediate customer case, using the frame buffer calls
directly is sufficient.

Regards,


Eric

Patch

diff --git a/src/eglvivsink/egl_platform_fb.c b/src/eglvivsink/egl_platform_fb.c
index eda6040..ad11a25 100644
--- a/src/eglvivsink/egl_platform_fb.c
+++ b/src/eglvivsink/egl_platform_fb.c
@@ -71,20 +71,25 @@  GstImxEglVivSinkEGLPlatform* gst_imx_egl_viv_sink_egl_platform_create(gchar cons
 		return NULL;
 	}
 
 	if (!eglInitialize(platform->egl_display, &ver_major, &ver_minor))
 	{
 		GST_ERROR("eglInitialize failed: %s", gst_imx_egl_viv_sink_egl_platform_get_last_error_string());
 		g_free(platform);
 		return NULL;
 	}
 
+	if (eglSwapInterval(platform->egl_display, 1) != EGL_TRUE)
+	{
+		GST_WARNING("eglSwapInterval failed, flicker possible!");
+	}
+
 	GST_INFO("FB EGL platform initialized, using EGL %d.%d", ver_major, ver_minor);
 
 	return platform;
 }
 
 
 void gst_imx_egl_viv_sink_egl_platform_destroy(GstImxEglVivSinkEGLPlatform *platform)
 {
 	if (platform != NULL)
 	{
diff --git a/src/eglvivsink/egl_platform_x11.c b/src/eglvivsink/egl_platform_x11.c
index 99ae600..ca7b33e 100644
--- a/src/eglvivsink/egl_platform_x11.c
+++ b/src/eglvivsink/egl_platform_x11.c
@@ -84,20 +84,25 @@  GstImxEglVivSinkEGLPlatform* gst_imx_egl_viv_sink_egl_platform_create(gchar cons
 	}
 
 	if (!eglInitialize(platform->egl_display, &ver_major, &ver_minor))
 	{
 		GST_ERROR("eglInitialize failed: %s", gst_imx_egl_viv_sink_egl_platform_get_last_error_string());
 		XCloseDisplay(x11_display);
 		g_free(platform);
 		return NULL;
 	}
 
+	if (eglSwapInterval(platform->egl_display, 1) != EGL_TRUE)
+	{
+		GST_WARNING("eglSwapInterval failed, flicker possible!");
+	}
+
 	GST_INFO("X11 EGL platform initialized, using EGL %d.%d", ver_major, ver_minor);
 
 	return platform;
 }
 
 
 void gst_imx_egl_viv_sink_egl_platform_destroy(GstImxEglVivSinkEGLPlatform *platform)
 {
 	if (platform != NULL)
 	{