aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--render/gles2/texture.c47
-rw-r--r--render/pixman/renderer.c8
-rw-r--r--render/vulkan/texture.c6
3 files changed, 60 insertions, 1 deletions
diff --git a/render/gles2/texture.c b/render/gles2/texture.c
index b2421d07..1cfd7bab 100644
--- a/render/gles2/texture.c
+++ b/render/gles2/texture.c
@@ -195,6 +195,8 @@ static bool gles2_texture_read_pixels(struct wlr_texture *wlr_texture,
}
push_gles2_debug(texture->renderer);
+ struct wlr_egl_context prev_ctx;
+ wlr_egl_save_context(&prev_ctx);
if (!wlr_egl_make_current(texture->renderer->egl)) {
return false;
@@ -228,15 +230,58 @@ static bool gles2_texture_read_pixels(struct wlr_texture *wlr_texture,
}
}
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ wlr_egl_restore_context(&prev_ctx);
pop_gles2_debug(texture->renderer);
return glGetError() == GL_NO_ERROR;
}
+static uint32_t gles2_texture_preferred_read_format(struct wlr_texture *wlr_texture) {
+ struct wlr_gles2_texture *texture = gles2_get_texture(wlr_texture);
+
+ push_gles2_debug(texture->renderer);
+ struct wlr_egl_context prev_ctx;
+ wlr_egl_save_context(&prev_ctx);
+
+ uint32_t fmt = DRM_FORMAT_INVALID;
+
+ if (!wlr_egl_make_current(texture->renderer->egl)) {
+ goto out;
+ }
+
+ if (!gles2_texture_bind(texture)) {
+ goto out;
+ }
+
+ GLint gl_format = -1, gl_type = -1, alpha_size = -1;
+ glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_format);
+ glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_type);
+ glGetIntegerv(GL_ALPHA_BITS, &alpha_size);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ pop_gles2_debug(texture->renderer);
+
+ const struct wlr_gles2_pixel_format *pix_fmt =
+ get_gles2_format_from_gl(gl_format, gl_type, alpha_size > 0);
+ if (pix_fmt != NULL) {
+ fmt = pix_fmt->drm_format;
+ goto out;
+ }
+
+ if (texture->renderer->exts.EXT_read_format_bgra) {
+ fmt = DRM_FORMAT_XRGB8888;
+ goto out;
+ }
+
+out:
+ wlr_egl_restore_context(&prev_ctx);
+ return fmt;
+}
+
static const struct wlr_texture_impl texture_impl = {
.update_from_buffer = gles2_texture_update_from_buffer,
.read_pixels = gles2_texture_read_pixels,
+ .preferred_read_format = gles2_texture_preferred_read_format,
.destroy = handle_gles2_texture_destroy,
};
diff --git a/render/pixman/renderer.c b/render/pixman/renderer.c
index 2c92e662..13049e8f 100644
--- a/render/pixman/renderer.c
+++ b/render/pixman/renderer.c
@@ -115,8 +115,16 @@ static bool texture_read_pixels(struct wlr_texture *wlr_texture,
return true;
}
+static uint32_t pixman_texture_preferred_read_format(struct wlr_texture *wlr_texture) {
+ struct wlr_pixman_texture *texture = get_texture(wlr_texture);
+
+ pixman_format_code_t pixman_format = pixman_image_get_format(texture->image);
+ return get_drm_format_from_pixman(pixman_format);
+}
+
static const struct wlr_texture_impl texture_impl = {
.read_pixels = texture_read_pixels,
+ .preferred_read_format = pixman_texture_preferred_read_format,
.destroy = texture_destroy,
};
diff --git a/render/vulkan/texture.c b/render/vulkan/texture.c
index 16c48356..20aa12f1 100644
--- a/render/vulkan/texture.c
+++ b/render/vulkan/texture.c
@@ -262,9 +262,15 @@ static bool vulkan_texture_read_pixels(struct wlr_texture *wlr_texture,
options->format, options->stride, src.width, src.height, src.x, src.y, 0, 0, p);
}
+static uint32_t vulkan_texture_preferred_read_format(struct wlr_texture *wlr_texture) {
+ struct wlr_vk_texture *texture = vulkan_get_texture(wlr_texture);
+ return texture->format->drm;
+}
+
static const struct wlr_texture_impl texture_impl = {
.update_from_buffer = vulkan_texture_update_from_buffer,
.read_pixels = vulkan_texture_read_pixels,
+ .preferred_read_format = vulkan_texture_preferred_read_format,
.destroy = vulkan_texture_unref,
};