mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-19 06:47:02 -04:00
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:
parent
1b6fac4aa6
commit
1ff7bbb0d3
2 changed files with 31 additions and 3 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#include <drm_fourcc.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#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 &&
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue