render/gles2: produce 16f screencopy data

This commit introduces fairly awkward code to work around that
fact that the GL ES implementation is allowed to provide either
of the two distinct constants GL_HALF_FLOAT and GL_HALF_FLOAT_OES
as the gl_type to use when reading data from a render buffer
created from a DMABUF with half-float channels.

The 'GLES3/gl3.h' header is also provided by the pkg-config library
confusingly called 'glesv2', so no build changes are necessary.
This commit is contained in:
Manuel Stoeckl 2022-07-20 19:57:48 -04:00
parent 1b6fac4aa6
commit 1ff7bbb0d3
2 changed files with 31 additions and 3 deletions

View file

@ -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);
}
}