summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.co.uk>2016-07-04 16:25:16 +0300
committerQuentin Glidic <sardemff7+git@sardemff7.net>2016-08-15 19:07:48 +0200
commit319397e050e2b4833e10093ccefd8ad77a6ef78d (patch)
tree8e06fc08a94af957983045d178014a4919c9d93a
parentdbb85d717355f872e1fd71c4e63a66a1b52d81a2 (diff)
gl-renderer, simple-dmabuf-v4l: fix dmabuf y-invert
Invert the Y_INVERT flag for the EGL import fo dmabufs. This fixes weston-simple-dmabuf-intel to show the same image on both GL-composited and with direct scanout on a hardware plane. Before, the image would y-flip when switching between these two cases. Now the orientation also matches the color values written in simple-dmabuf-intel.c. The GL-renderer uses the OpenGL convention of texture coordinates, where the origin is at the bottom-left of an image. This can be observed in texture_region() where the texcoords are inverted if y_invert is false, since the surface coordinates have origin at top-left. Both wl_shm and dmabuf buffers have origin at the top-left. When wl_shm buffer is imported with glTexImage2D, it gets inverted because glTexImage2D is defined to read in the bottom row first. The shm data is top row first. This incidentally also means, that buffer pixel 0,0 ends up at texture coordinates 0,0. This is now inverted compared to the GL coordinate convention, and therefore gl_renderer_attach_shm() sets y_inverted to true. This causes texture_region() to NOT invert the texcoords. Wayland surface coordinates have origin at top-left, hence the double-inversion. Dmabuf buffers also have the origin at top-left. However, they are imported via EGL to GL, where they should get the GL oriented coordinates but they do not. It is as if pixel 0,0 ends up at texcoords 0,0 - the same thing as with wl_shm buffers. Therefore we need to invert the invert flag. Too bad EGL_EXT_image_dma_buf_import does not seem to specify the image orientation. The GL spec implied result seems to conflict with the reality in Mesa 11.2.2. I asked about this in the Mesa developer mailing list. The question with no answers: https://lists.freedesktop.org/archives/mesa-dev/2016-June/120249.html and the thread I hijacked to get some answers: https://lists.freedesktop.org/archives/mesa-dev/2016-June/120733.html which culminated to the conclusion: https://lists.freedesktop.org/archives/mesa-dev/2016-June/120955.html that supports this patch. simple-dmabuf-v4l is equally fixed to not add Y_INVERT. There is no rational reason to have it, and removing is necessary together with the GL-renderer change to keep the image the right way up. This has been tested with VIVID. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Quentin Glidic <sardemff7+git@sardemff7.net>
-rw-r--r--clients/simple-dmabuf-v4l.c7
-rw-r--r--libweston/gl-renderer.c8
2 files changed, 13 insertions, 2 deletions
diff --git a/clients/simple-dmabuf-v4l.c b/clients/simple-dmabuf-v4l.c
index de77e36d..af25d0ea 100644
--- a/clients/simple-dmabuf-v4l.c
+++ b/clients/simple-dmabuf-v4l.c
@@ -360,7 +360,12 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer)
unsigned i;
modifier = 0;
- flags = ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT;
+ flags = 0;
+
+ /* XXX: apparently some webcams may actually provide y-inverted images,
+ * in which case we should set
+ * flags = ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT
+ */
params = zwp_linux_dmabuf_v1_create_params(display->dmabuf);
for (i = 0; i < display->format.num_planes; ++i)
diff --git a/libweston/gl-renderer.c b/libweston/gl-renderer.c
index ff487908..031576bc 100644
--- a/libweston/gl-renderer.c
+++ b/libweston/gl-renderer.c
@@ -1824,8 +1824,14 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
buffer->width = dmabuf->attributes.width;
buffer->height = dmabuf->attributes.height;
+
+ /*
+ * GL-renderer uses the OpenGL convention of texture coordinates, where
+ * the origin is at bottom-left. Because dmabuf buffers have the origin
+ * at top-left, we must invert the Y_INVERT flag to get the image right.
+ */
buffer->y_inverted =
- !!(dmabuf->attributes.flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT);
+ !(dmabuf->attributes.flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT);
for (i = 0; i < gs->num_images; i++)
egl_image_unref(gs->images[i]);