aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/render/interface.h17
-rw-r--r--include/wlr/render/wlr_renderer.h68
-rw-r--r--render/meson.build1
-rw-r--r--render/pass.c25
-rw-r--r--render/wlr_renderer.c20
5 files changed, 126 insertions, 5 deletions
diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h
index 07b26fbc..85a98202 100644
--- a/include/wlr/render/interface.h
+++ b/include/wlr/render/interface.h
@@ -48,6 +48,8 @@ struct wlr_renderer_impl {
uint32_t (*get_render_buffer_caps)(struct wlr_renderer *renderer);
struct wlr_texture *(*texture_from_buffer)(struct wlr_renderer *renderer,
struct wlr_buffer *buffer);
+ struct wlr_render_pass *(*begin_buffer_pass)(struct wlr_renderer *renderer,
+ struct wlr_buffer *buffer);
};
void wlr_renderer_init(struct wlr_renderer *renderer,
@@ -62,4 +64,19 @@ struct wlr_texture_impl {
void wlr_texture_init(struct wlr_texture *texture, struct wlr_renderer *rendener,
const struct wlr_texture_impl *impl, uint32_t width, uint32_t height);
+struct wlr_render_pass {
+ const struct wlr_render_pass_impl *impl;
+};
+
+void wlr_render_pass_init(struct wlr_render_pass *pass,
+ const struct wlr_render_pass_impl *impl);
+
+struct wlr_render_pass_impl {
+ bool (*submit)(struct wlr_render_pass *pass);
+ void (*add_texture)(struct wlr_render_pass *pass,
+ const struct wlr_render_texture_options *options);
+ void (*add_rect)(struct wlr_render_pass *pass,
+ const struct wlr_render_rect_options *options);
+};
+
#endif
diff --git a/include/wlr/render/wlr_renderer.h b/include/wlr/render/wlr_renderer.h
index 0e08fe24..f6b58df5 100644
--- a/include/wlr/render/wlr_renderer.h
+++ b/include/wlr/render/wlr_renderer.h
@@ -12,6 +12,7 @@
#include <stdint.h>
#include <wayland-server-core.h>
#include <wlr/render/wlr_texture.h>
+#include <wlr/util/box.h>
struct wlr_backend;
struct wlr_renderer_impl;
@@ -155,4 +156,71 @@ int wlr_renderer_get_drm_fd(struct wlr_renderer *r);
*/
void wlr_renderer_destroy(struct wlr_renderer *renderer);
+/**
+ * A render pass accumulates drawing operations until submitted to the GPU.
+ */
+struct wlr_render_pass;
+
+/**
+ * Begin a new render pass with the supplied destination buffer.
+ *
+ * Callers must call wlr_render_pass_submit() once they are done with the
+ * render pass.
+ */
+struct wlr_render_pass *wlr_renderer_begin_buffer_pass(
+ struct wlr_renderer *renderer, struct wlr_buffer *buffer);
+
+/**
+ * Submit the render pass.
+ *
+ * The render pass cannot be used after this function is called.
+ */
+bool wlr_render_pass_submit(struct wlr_render_pass *render_pass);
+
+struct wlr_render_texture_options {
+ /* Source texture */
+ struct wlr_texture *texture;
+ /* Source coordinates, leave empty to render the whole texture */
+ struct wlr_fbox src_box;
+ /* Destination coordinates, width/height default to the texture size */
+ struct wlr_box dst_box;
+ /* Opacity between 0 (transparent) and 1 (opaque), leave NULL for opaque */
+ const float *alpha;
+ /* Clip region, leave NULL to disable clipping */
+ const pixman_region32_t *clip;
+ /* Transform applied to the source texture */
+ enum wl_output_transform transform;
+};
+
+/**
+ * Render a texture.
+ */
+void wlr_render_pass_add_texture(struct wlr_render_pass *render_pass,
+ const struct wlr_render_texture_options *options);
+
+/**
+ * A color value.
+ *
+ * Each channel has values between 0 and 1 inclusive. The R, G, B
+ * channels need to be pre-multiplied by A.
+ */
+struct wlr_render_color {
+ float r, g, b, a;
+};
+
+struct wlr_render_rect_options {
+ /* Rectangle coordinates */
+ struct wlr_box box;
+ /* Source color */
+ struct wlr_render_color color;
+ /* Clip region, leave NULL to disable clipping */
+ const pixman_region32_t *clip;
+};
+
+/**
+ * Render a rectangle.
+ */
+void wlr_render_pass_add_rect(struct wlr_render_pass *render_pass,
+ const struct wlr_render_rect_options *options);
+
#endif
diff --git a/render/meson.build b/render/meson.build
index 4c3d4522..f09905c7 100644
--- a/render/meson.build
+++ b/render/meson.build
@@ -8,6 +8,7 @@ endif
wlr_files += files(
'dmabuf.c',
'drm_format_set.c',
+ 'pass.c',
'pixel_format.c',
'swapchain.c',
'wlr_renderer.c',
diff --git a/render/pass.c b/render/pass.c
new file mode 100644
index 00000000..c1b88b8d
--- /dev/null
+++ b/render/pass.c
@@ -0,0 +1,25 @@
+#include <assert.h>
+#include <string.h>
+#include <wlr/render/interface.h>
+#include <wlr/render/wlr_renderer.h>
+
+void wlr_render_pass_init(struct wlr_render_pass *render_pass,
+ const struct wlr_render_pass_impl *impl) {
+ assert(impl->submit && impl->add_texture && impl->add_rect);
+ memset(render_pass, 0, sizeof(*render_pass));
+ render_pass->impl = impl;
+}
+
+bool wlr_render_pass_submit(struct wlr_render_pass *render_pass) {
+ return render_pass->impl->submit(render_pass);
+}
+
+void wlr_render_pass_add_texture(struct wlr_render_pass *render_pass,
+ const struct wlr_render_texture_options *options) {
+ render_pass->impl->add_texture(render_pass, options);
+}
+
+void wlr_render_pass_add_rect(struct wlr_render_pass *render_pass,
+ const struct wlr_render_rect_options *options) {
+ render_pass->impl->add_rect(render_pass, options);
+}
diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c
index 3b1e87e2..459016b6 100644
--- a/render/wlr_renderer.c
+++ b/render/wlr_renderer.c
@@ -33,11 +33,13 @@
void wlr_renderer_init(struct wlr_renderer *renderer,
const struct wlr_renderer_impl *impl) {
- assert(impl->begin);
- assert(impl->clear);
- assert(impl->scissor);
- assert(impl->render_subtexture_with_matrix);
- assert(impl->render_quad_with_matrix);
+ if (!impl->begin_buffer_pass) {
+ assert(impl->begin);
+ assert(impl->clear);
+ assert(impl->scissor);
+ assert(impl->render_subtexture_with_matrix);
+ assert(impl->render_quad_with_matrix);
+ }
assert(impl->get_shm_texture_formats);
assert(impl->get_render_buffer_caps);
@@ -409,3 +411,11 @@ int wlr_renderer_get_drm_fd(struct wlr_renderer *r) {
}
return r->impl->get_drm_fd(r);
}
+
+struct wlr_render_pass *wlr_renderer_begin_buffer_pass(
+ struct wlr_renderer *renderer, struct wlr_buffer *buffer) {
+ if (!renderer->impl->begin_buffer_pass) {
+ return NULL;
+ }
+ return renderer->impl->begin_buffer_pass(renderer, buffer);
+}