diff options
author | Daniel Stone <daniels@collabora.com> | 2017-10-05 15:31:26 +0100 |
---|---|---|
committer | Daniel Stone <daniels@collabora.com> | 2017-12-01 16:36:38 +0000 |
commit | b040974398e708101a08f4aa5f0a7177a267ef1c (patch) | |
tree | b555e79403f7f5c5d8b5ca6c558554d6519d6f65 | |
parent | 8093fd5db2e31230cd4ef18dfb9bb9df5cf6a8ff (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.c | 12 |
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], |