aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2022-06-16 14:43:24 +0200
committerSimon Ser <contact@emersion.fr>2022-06-16 14:43:24 +0200
commit29291cb47cdaa72d1142a008fef3301dcb86dfac (patch)
tree77616ce5285dea16bc1ebe1a41e02b1ed3b80ce6
parentf28c0e2046c59aeb9f014ef4c22d4517e38f4721 (diff)
render/texture: drop wlr_texture_is_opaque
Whether a texture is opaque or not doesn't depend on the renderer at all, it just depends on the source buffer. Instead of forcing all renderers to implement wlr_texture_impl.is_opaque, let's move this in common code and use the wlr_buffer format to know whether a texture will be opaque.
-rw-r--r--include/types/wlr_buffer.h9
-rw-r--r--include/wlr/render/interface.h1
-rw-r--r--include/wlr/render/wlr_texture.h5
-rw-r--r--include/wlr/types/wlr_compositor.h2
-rw-r--r--render/gles2/texture.c6
-rw-r--r--render/pixman/renderer.c6
-rw-r--r--render/vulkan/texture.c9
-rw-r--r--render/wlr_texture.c7
-rw-r--r--types/wlr_buffer.c26
-rw-r--r--types/wlr_compositor.c6
10 files changed, 42 insertions, 35 deletions
diff --git a/include/types/wlr_buffer.h b/include/types/wlr_buffer.h
index bdb6e5b7..e7097ae2 100644
--- a/include/types/wlr_buffer.h
+++ b/include/types/wlr_buffer.h
@@ -69,4 +69,13 @@ struct wlr_dmabuf_buffer *dmabuf_buffer_create(
*/
bool dmabuf_buffer_drop(struct wlr_dmabuf_buffer *buffer);
+/**
+ * Check whether a buffer is fully opaque.
+ *
+ * When true is returned, the buffer is guaranteed to be fully opaque, but the
+ * reverse is not true: false may be returned in cases where the buffer is fully
+ * opaque.
+ */
+bool buffer_is_opaque(struct wlr_buffer *buffer);
+
#endif
diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h
index 4207bd30..7e923353 100644
--- a/include/wlr/render/interface.h
+++ b/include/wlr/render/interface.h
@@ -54,7 +54,6 @@ void wlr_renderer_init(struct wlr_renderer *renderer,
const struct wlr_renderer_impl *impl);
struct wlr_texture_impl {
- bool (*is_opaque)(struct wlr_texture *texture);
bool (*write_pixels)(struct wlr_texture *texture,
uint32_t stride, uint32_t width, uint32_t height,
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
diff --git a/include/wlr/render/wlr_texture.h b/include/wlr/render/wlr_texture.h
index 93fc221c..0f39b8a8 100644
--- a/include/wlr/render/wlr_texture.h
+++ b/include/wlr/render/wlr_texture.h
@@ -37,11 +37,6 @@ struct wlr_texture *wlr_texture_from_dmabuf(struct wlr_renderer *renderer,
struct wlr_dmabuf_attributes *attribs);
/**
- * Returns true if this texture is using a fully opaque format.
- */
-bool wlr_texture_is_opaque(struct wlr_texture *texture);
-
-/**
* Update a texture with raw pixels. The texture must be mutable, and the input
* data must have the same pixel format that the texture was created with.
*/
diff --git a/include/wlr/types/wlr_compositor.h b/include/wlr/types/wlr_compositor.h
index bff6bc83..034b075b 100644
--- a/include/wlr/types/wlr_compositor.h
+++ b/include/wlr/types/wlr_compositor.h
@@ -162,6 +162,8 @@ struct wlr_surface {
int width, height;
int buffer_width, buffer_height;
} previous;
+
+ bool opaque;
};
struct wlr_renderer;
diff --git a/render/gles2/texture.c b/render/gles2/texture.c
index 57420744..d794e436 100644
--- a/render/gles2/texture.c
+++ b/render/gles2/texture.c
@@ -29,11 +29,6 @@ struct wlr_gles2_texture *gles2_get_texture(
return (struct wlr_gles2_texture *)wlr_texture;
}
-static bool gles2_texture_is_opaque(struct wlr_texture *wlr_texture) {
- struct wlr_gles2_texture *texture = gles2_get_texture(wlr_texture);
- return !texture->has_alpha;
-}
-
static bool check_stride(const struct wlr_pixel_format_info *fmt,
uint32_t stride, uint32_t width) {
if (stride % (fmt->bpp / 8) != 0) {
@@ -161,7 +156,6 @@ static void gles2_texture_unref(struct wlr_texture *wlr_texture) {
}
static const struct wlr_texture_impl texture_impl = {
- .is_opaque = gles2_texture_is_opaque,
.write_pixels = gles2_texture_write_pixels,
.destroy = gles2_texture_unref,
};
diff --git a/render/pixman/renderer.c b/render/pixman/renderer.c
index 13db0880..2853b704 100644
--- a/render/pixman/renderer.c
+++ b/render/pixman/renderer.c
@@ -46,11 +46,6 @@ static struct wlr_pixman_texture *get_texture(
return (struct wlr_pixman_texture *)wlr_texture;
}
-static bool texture_is_opaque(struct wlr_texture *wlr_texture) {
- struct wlr_pixman_texture *texture = get_texture(wlr_texture);
- return !texture->format_info->has_alpha;
-}
-
static void texture_destroy(struct wlr_texture *wlr_texture) {
struct wlr_pixman_texture *texture = get_texture(wlr_texture);
wl_list_remove(&texture->link);
@@ -61,7 +56,6 @@ static void texture_destroy(struct wlr_texture *wlr_texture) {
}
static const struct wlr_texture_impl texture_impl = {
- .is_opaque = texture_is_opaque,
.destroy = texture_destroy,
};
diff --git a/render/vulkan/texture.c b/render/vulkan/texture.c
index 26af9867..35b9562e 100644
--- a/render/vulkan/texture.c
+++ b/render/vulkan/texture.c
@@ -33,14 +33,6 @@ static VkImageAspectFlagBits mem_plane_aspect(unsigned i) {
}
}
-static bool vulkan_texture_is_opaque(struct wlr_texture *wlr_texture) {
- struct wlr_vk_texture *texture = vulkan_get_texture(wlr_texture);
- const struct wlr_pixel_format_info *format_info = drm_get_pixel_format_info(
- texture->format->drm_format);
- assert(format_info);
- return !format_info->has_alpha;
-}
-
// Will transition the texture to shaderReadOnlyOptimal layout for reading
// from fragment shader later on
static bool write_pixels(struct wlr_texture *wlr_texture,
@@ -199,7 +191,6 @@ static void vulkan_texture_unref(struct wlr_texture *wlr_texture) {
}
static const struct wlr_texture_impl texture_impl = {
- .is_opaque = vulkan_texture_is_opaque,
.write_pixels = vulkan_texture_write_pixels,
.destroy = vulkan_texture_unref,
};
diff --git a/render/wlr_texture.c b/render/wlr_texture.c
index 36cbf136..fa864d02 100644
--- a/render/wlr_texture.c
+++ b/render/wlr_texture.c
@@ -71,13 +71,6 @@ struct wlr_texture *wlr_texture_from_buffer(struct wlr_renderer *renderer,
return renderer->impl->texture_from_buffer(renderer, buffer);
}
-bool wlr_texture_is_opaque(struct wlr_texture *texture) {
- if (!texture->impl->is_opaque) {
- return false;
- }
- return texture->impl->is_opaque(texture);
-}
-
bool wlr_texture_write_pixels(struct wlr_texture *texture,
uint32_t stride, uint32_t width, uint32_t height,
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
diff --git a/types/wlr_buffer.c b/types/wlr_buffer.c
index 96e508b2..49e205f3 100644
--- a/types/wlr_buffer.c
+++ b/types/wlr_buffer.c
@@ -237,6 +237,32 @@ struct wlr_buffer *wlr_buffer_from_resource(struct wl_resource *resource) {
return buffer;
}
+bool buffer_is_opaque(struct wlr_buffer *buffer) {
+ void *data;
+ uint32_t format;
+ size_t stride;
+ struct wlr_dmabuf_attributes dmabuf;
+ struct wlr_shm_attributes shm;
+ if (wlr_buffer_get_dmabuf(buffer, &dmabuf)) {
+ format = dmabuf.format;
+ } else if (wlr_buffer_get_shm(buffer, &shm)) {
+ format = shm.format;
+ } else if (wlr_buffer_begin_data_ptr_access(buffer,
+ WLR_BUFFER_DATA_PTR_ACCESS_READ, &data, &format, &stride)) {
+ wlr_buffer_end_data_ptr_access(buffer);
+ } else {
+ return false;
+ }
+
+ const struct wlr_pixel_format_info *format_info =
+ drm_get_pixel_format_info(format);
+ if (format_info == NULL) {
+ return false;
+ }
+
+ return !format_info->has_alpha;
+}
+
struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer,
struct wlr_renderer *renderer) {
struct wlr_texture *texture = wlr_texture_from_buffer(renderer, buffer);
diff --git a/types/wlr_compositor.c b/types/wlr_compositor.c
index 8b84a643..c1cdc3b0 100644
--- a/types/wlr_compositor.c
+++ b/types/wlr_compositor.c
@@ -10,6 +10,7 @@
#include <wlr/types/wlr_output.h>
#include <wlr/util/log.h>
#include <wlr/util/region.h>
+#include "types/wlr_buffer.h"
#include "types/wlr_region.h"
#include "util/signal.h"
#include "util/time.h"
@@ -336,9 +337,12 @@ static void surface_apply_damage(struct wlr_surface *surface) {
wlr_buffer_unlock(&surface->buffer->base);
}
surface->buffer = NULL;
+ surface->opaque = false;
return;
}
+ surface->opaque = buffer_is_opaque(surface->current.buffer);
+
if (surface->buffer != NULL) {
if (wlr_client_buffer_apply_damage(surface->buffer,
surface->current.buffer, &surface->buffer_damage)) {
@@ -372,7 +376,7 @@ static void surface_update_opaque_region(struct wlr_surface *surface) {
return;
}
- if (wlr_texture_is_opaque(texture)) {
+ if (surface->opaque) {
pixman_region32_init_rect(&surface->opaque_region,
0, 0, surface->current.width, surface->current.height);
return;