summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stone <daniels@collabora.com>2017-10-05 15:31:26 +0100
committerDaniel Stone <daniels@collabora.com>2017-12-01 16:36:38 +0000
commitb040974398e708101a08f4aa5f0a7177a267ef1c (patch)
treeb555e79403f7f5c5d8b5ca6c558554d6519d6f65
parent8093fd5db2e31230cd4ef18dfb9bb9df5cf6a8ff (diff)
gl-renderer: Set pitch correctly for subsampled textures
zwp_linux_dmabuf_v1 allows clients to pass an explicit pitch for each plane, but wl_shm only takes a single pitch parameter; the pitch for secondary planes must be inferred. Multi-plane sub-sampled textures have partial width/height, e.g. YUV420/I420 has a full-size Y plane, followed by a half-width/height U plane, and a half-width/height V plane. GStreamer's waylandsink - the only user of wl_shm YUV formats - expects the implementation to follow the example of Xv and implicitly divide the pitch for secondary planes by the subsampling factor. gl-renderer was not doing this, and instead just using the (larger) stride provided by the client for all planes in the buffer. Fix gl-renderer to divide pitch by the subsampling factor when uploading from subsampled SHM buffers into GL textures, also dividing co-ordinates when doing offset partial uploads. Tested with: $ gst-launch-1.0 videotestsrc ! waylandsink Signed-off-by: Daniel Stone <daniels@collabora.com> Reported-by: Fabien Lahoudere <fabien.lahoudere@collabora.co.uk> Tested-by: Fabien Lahoudere <fabien.lahoudere@collabora.co.uk> Reviewed-by: Arnaud Vrac <avrac@freebox.fr> Acked-by: Vincent ABRIOU <vincent.abriou@st.com> Acked-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Acked-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Fixes: fdeefe42418 ("gl-renderer: add support of WL_SHM_FORMAT_YUV420") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103063
-rw-r--r--libweston/gl-renderer.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/libweston/gl-renderer.c b/libweston/gl-renderer.c
index 94d81ef4..bd7bb2aa 100644
--- a/libweston/gl-renderer.c
+++ b/libweston/gl-renderer.c
@@ -1445,14 +1445,14 @@ gl_renderer_flush_damage(struct weston_surface *surface)
goto done;
}
- glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, gs->pitch);
-
if (gs->needs_full_upload) {
glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0);
wl_shm_buffer_begin_access(buffer->shm_buffer);
for (j = 0; j < gs->num_textures; j++) {
glBindTexture(GL_TEXTURE_2D, gs->textures[j]);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT,
+ gs->pitch / gs->hsub[j]);
glTexImage2D(GL_TEXTURE_2D, 0,
gs->gl_format[j],
gs->pitch / gs->hsub[j],
@@ -1473,10 +1473,14 @@ gl_renderer_flush_damage(struct weston_surface *surface)
r = weston_surface_to_buffer_rect(surface, rectangles[i]);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, r.x1);
- glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, r.y1);
for (j = 0; j < gs->num_textures; j++) {
glBindTexture(GL_TEXTURE_2D, gs->textures[j]);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT,
+ gs->pitch / gs->hsub[j]);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT,
+ r.x1 / gs->hsub[j]);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT,
+ r.y1 / gs->hsub[j]);
glTexSubImage2D(GL_TEXTURE_2D, 0,
r.x1 / gs->hsub[j],
r.y1 / gs->vsub[j],