diff --git a/render/gles2/pixel_format.c b/render/gles2/pixel_format.c index acaac5ceb..aa196ff03 100644 --- a/render/gles2/pixel_format.c +++ b/render/gles2/pixel_format.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "render/gles2.h" /* @@ -150,6 +151,16 @@ const struct wlr_gles2_pixel_format *get_gles2_format_from_drm(uint32_t fmt) { const struct wlr_gles2_pixel_format *get_gles2_format_from_gl( GLint gl_format, GLint gl_type, bool alpha) { + // Mesa may provide GL ES >= 3.0 instead of the minimum asked for 2.0; + // in this case, the gl_type associated to render buffers created from + // half float DMABUFs _may_ be the value GL_HALF_FLOAT = 0x140b from + // GL ES 3.0, not the value GL_HALF_FLOAT_OES = 0x8D61 from GL ES 2.0 + // extension OES_texture_half_float, which is used to define texture + // images for half-float shm buffers. + if (gl_type == GL_HALF_FLOAT) { + gl_type = GL_HALF_FLOAT_OES; + } + for (size_t i = 0; i < sizeof(formats) / sizeof(*formats); ++i) { if (formats[i].gl_format == gl_format && formats[i].gl_type == gl_type && diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 6a86b1832..e19c6c8be 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -467,6 +467,23 @@ static bool gles2_read_pixels(struct wlr_renderer *wlr_renderer, push_gles2_debug(renderer); + // The 16F buffer formats have more than one possible color read + // format/type combination; the type can be GL_HALF_FLOAT = 0x140b, + // if the GLES implementation version is >= 3.0, or could be + // GL_HALF_FLOAT_OES (which would be appropriate at GLES 2.0.) + // To match glReadPixels' strict requirements on format+type, + // we submit exactly the implementation suggested format and type, + // if these are compatible with the drm_format. + GLint gl_format = -1, gl_type = -1; + glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_format); + glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_type); + const struct wlr_gles2_pixel_format *impl_format = + get_gles2_format_from_gl(gl_format, gl_type, fmt->has_alpha); + if (impl_format != fmt) { + gl_format = fmt->gl_format; + gl_type = fmt->gl_type; + } + // Make sure any pending drawing is finished before we try to read it glFinish(); @@ -478,14 +495,14 @@ static bool gles2_read_pixels(struct wlr_renderer *wlr_renderer, // Under these particular conditions, we can read the pixels with only // one glReadPixels call - glReadPixels(src_x, src_y, width, height, fmt->gl_format, fmt->gl_type, p); + glReadPixels(src_x, src_y, width, height, gl_format, gl_type, p); } else { // Unfortunately GLES2 doesn't support GL_PACK_*, so we have to read // the lines out row by row for (size_t i = 0; i < height; ++i) { uint32_t y = src_y + i; - glReadPixels(src_x, y, width, 1, fmt->gl_format, - fmt->gl_type, p + i * stride + dst_x * drm_fmt->bpp / 8); + glReadPixels(src_x, y, width, 1, gl_format, + gl_type, p + i * stride + dst_x * drm_fmt->bpp / 8); } }