mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-05 04:06:11 -05:00
render: add support for clearing render passes
introduces a new `wlr_render_pass_clear` function, allowing render passes to be cleared with a solid color.
This commit is contained in:
parent
7cb4e30bfd
commit
eeecb382cc
8 changed files with 120 additions and 8 deletions
|
|
@ -62,6 +62,8 @@ struct wlr_render_pass_impl {
|
|||
/* Implementers are also guaranteed that options->box is nonempty */
|
||||
void (*add_rect)(struct wlr_render_pass *pass,
|
||||
const struct wlr_render_rect_options *options);
|
||||
void (*clear)(struct wlr_render_pass *pass,
|
||||
const struct wlr_render_clear_options *options);
|
||||
};
|
||||
|
||||
struct wlr_render_timer {
|
||||
|
|
|
|||
|
|
@ -157,4 +157,20 @@ struct wlr_render_rect_options {
|
|||
void wlr_render_pass_add_rect(struct wlr_render_pass *render_pass,
|
||||
const struct wlr_render_rect_options *options);
|
||||
|
||||
struct wlr_render_clear_options {
|
||||
/* Clear color */
|
||||
struct wlr_render_color color;
|
||||
/* Clip region, leave NULL to disable clipping */
|
||||
const pixman_region32_t *clip;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the render target with a solid color.
|
||||
*
|
||||
* This is optimized for GPU hardware (e.g., glClear + glScissor) and is more
|
||||
* efficient than drawing a rectangle.
|
||||
*/
|
||||
void wlr_render_pass_clear(struct wlr_render_pass *render_pass,
|
||||
const struct wlr_render_clear_options *options);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -275,10 +275,41 @@ static void render_pass_add_rect(struct wlr_render_pass *wlr_pass,
|
|||
pop_gles2_debug(renderer);
|
||||
}
|
||||
|
||||
static void render_pass_clear(struct wlr_render_pass *wlr_pass,
|
||||
const struct wlr_render_clear_options *options) {
|
||||
struct wlr_gles2_render_pass *pass = get_render_pass(wlr_pass);
|
||||
struct wlr_gles2_renderer *renderer = pass->buffer->renderer;
|
||||
|
||||
push_gles2_debug(renderer);
|
||||
|
||||
const struct wlr_render_color *color = &options->color;
|
||||
glClearColor(color->r, color->g, color->b, color->a);
|
||||
|
||||
if (options->clip) {
|
||||
int rects_len;
|
||||
const pixman_box32_t *rects = pixman_region32_rectangles(options->clip, &rects_len);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
for (int i = 0; i < rects_len; i++) {
|
||||
const pixman_box32_t *rect = &rects[i];
|
||||
int height = pass->buffer->buffer->height;
|
||||
glScissor(rect->x1, height - rect->y2,
|
||||
rect->x2 - rect->x1, rect->y2 - rect->y1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
} else {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
pop_gles2_debug(renderer);
|
||||
}
|
||||
|
||||
static const struct wlr_render_pass_impl render_pass_impl = {
|
||||
.submit = render_pass_submit,
|
||||
.add_texture = render_pass_add_texture,
|
||||
.add_rect = render_pass_add_rect,
|
||||
.clear = render_pass_clear,
|
||||
};
|
||||
|
||||
static const char *reset_status_str(GLenum status) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
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);
|
||||
assert(impl->submit && impl->add_texture && impl->add_rect && impl->clear);
|
||||
*render_pass = (struct wlr_render_pass){
|
||||
.impl = impl,
|
||||
};
|
||||
|
|
@ -34,6 +34,11 @@ void wlr_render_pass_add_rect(struct wlr_render_pass *render_pass,
|
|||
render_pass->impl->add_rect(render_pass, options);
|
||||
}
|
||||
|
||||
void wlr_render_pass_clear(struct wlr_render_pass *render_pass,
|
||||
const struct wlr_render_clear_options *options) {
|
||||
render_pass->impl->clear(render_pass, options);
|
||||
}
|
||||
|
||||
void wlr_render_texture_options_get_src_box(const struct wlr_render_texture_options *options,
|
||||
struct wlr_fbox *box) {
|
||||
*box = options->src_box;
|
||||
|
|
|
|||
|
|
@ -225,10 +225,23 @@ static void render_pass_add_rect(struct wlr_render_pass *wlr_pass,
|
|||
pixman_image_unref(fill);
|
||||
}
|
||||
|
||||
static void render_pass_clear(struct wlr_render_pass *wlr_pass,
|
||||
const struct wlr_render_clear_options *options) {
|
||||
struct wlr_pixman_render_pass *pass = get_render_pass(wlr_pass);
|
||||
|
||||
render_pass_add_rect(wlr_pass, &(struct wlr_render_rect_options){
|
||||
.box = { .width = pass->buffer->buffer->width, .height = pass->buffer->buffer->height },
|
||||
.color = options->color,
|
||||
.clip = options->clip,
|
||||
.blend_mode = WLR_RENDER_BLEND_MODE_NONE,
|
||||
});
|
||||
}
|
||||
|
||||
static const struct wlr_render_pass_impl render_pass_impl = {
|
||||
.submit = render_pass_submit,
|
||||
.add_texture = render_pass_add_texture,
|
||||
.add_rect = render_pass_add_rect,
|
||||
.clear = render_pass_clear,
|
||||
};
|
||||
|
||||
struct wlr_pixman_render_pass *begin_pixman_render_pass(
|
||||
|
|
|
|||
|
|
@ -943,13 +943,60 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass,
|
|||
}
|
||||
}
|
||||
|
||||
static void render_pass_clear(struct wlr_render_pass *wlr_pass,
|
||||
const struct wlr_render_clear_options *options) {
|
||||
struct wlr_vk_render_pass *pass = get_render_pass(wlr_pass);
|
||||
VkCommandBuffer cb = pass->command_buffer->vk;
|
||||
|
||||
float linear_color[] = {
|
||||
color_to_linear_premult(options->color.r, options->color.a),
|
||||
color_to_linear_premult(options->color.g, options->color.a),
|
||||
color_to_linear_premult(options->color.b, options->color.a),
|
||||
options->color.a,
|
||||
};
|
||||
|
||||
VkClearAttachment clear_att = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.colorAttachment = 0,
|
||||
.clearValue.color.float32 = {
|
||||
linear_color[0],
|
||||
linear_color[1],
|
||||
linear_color[2],
|
||||
linear_color[3],
|
||||
},
|
||||
};
|
||||
|
||||
pixman_region32_t clip;
|
||||
get_clip_region(pass, options->clip, &clip);
|
||||
|
||||
int clip_rects_len;
|
||||
const pixman_box32_t *clip_rects = pixman_region32_rectangles(&clip, &clip_rects_len);
|
||||
|
||||
VkClearRect clear_rect = {
|
||||
.layerCount = 1,
|
||||
};
|
||||
for (int i = 0; i < clip_rects_len; i++) {
|
||||
convert_pixman_box_to_vk_rect(&clip_rects[i], &clear_rect.rect);
|
||||
vkCmdClearAttachments(cb, 1, &clear_att, 1, &clear_rect);
|
||||
struct wlr_box box = {
|
||||
.x = clip_rects[i].x1,
|
||||
.y = clip_rects[i].y1,
|
||||
.width = clip_rects[i].x2 - clip_rects[i].x1,
|
||||
.height = clip_rects[i].y2 - clip_rects[i].y1,
|
||||
};
|
||||
render_pass_mark_box_updated(pass, &box);
|
||||
}
|
||||
|
||||
pixman_region32_fini(&clip);
|
||||
}
|
||||
|
||||
static const struct wlr_render_pass_impl render_pass_impl = {
|
||||
.submit = render_pass_submit,
|
||||
.add_rect = render_pass_add_rect,
|
||||
.add_texture = render_pass_add_texture,
|
||||
.clear = render_pass_clear,
|
||||
};
|
||||
|
||||
|
||||
void vk_color_transform_destroy(struct wlr_addon *addon) {
|
||||
struct wlr_vk_renderer *renderer = (struct wlr_vk_renderer *)addon->owner;
|
||||
struct wlr_vk_color_transform *transform = wl_container_of(addon, transform, addon);
|
||||
|
|
|
|||
|
|
@ -268,9 +268,8 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor)
|
|||
enum wl_output_transform transform = wlr_output_transform_invert(cursor->transform);
|
||||
transform = wlr_output_transform_compose(transform, output->transform);
|
||||
|
||||
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
||||
.box = { .width = buffer->width, .height = buffer->height },
|
||||
.blend_mode = WLR_RENDER_BLEND_MODE_NONE,
|
||||
wlr_render_pass_clear(pass, &(struct wlr_render_clear_options){
|
||||
.color = { 0, 0, 0, 0 },
|
||||
});
|
||||
wlr_render_pass_add_texture(pass, &(struct wlr_render_texture_options){
|
||||
.texture = texture,
|
||||
|
|
@ -535,4 +534,4 @@ bool output_cursor_refresh_color_transform(struct wlr_output_cursor *output_curs
|
|||
wlr_color_transform_unref(transforms[0]);
|
||||
wlr_color_transform_unref(transforms[1]);
|
||||
return output_cursor->color_transform != NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,9 +63,8 @@ static struct wlr_buffer *output_acquire_empty_buffer(struct wlr_output *output,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
||||
wlr_render_pass_clear(pass, &(struct wlr_render_clear_options){
|
||||
.color = { 0, 0, 0, 0 },
|
||||
.blend_mode = WLR_RENDER_BLEND_MODE_NONE,
|
||||
});
|
||||
|
||||
if (!wlr_render_pass_submit(pass)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue