render: pass rendering state together in a struct

This lets us easily add rendering state that we need in the future
This commit is contained in:
Alexander Orzechowski 2023-04-27 11:19:58 +02:00 committed by Simon Ser
parent 33cfdbe886
commit d5cc474aef
6 changed files with 156 additions and 159 deletions

View file

@ -12,6 +12,7 @@
#include "sway/input/text_input.h" #include "sway/input/text_input.h"
struct sway_seat; struct sway_seat;
struct render_context;
struct sway_seatop_impl { struct sway_seatop_impl {
void (*button)(struct sway_seat *seat, uint32_t time_msec, void (*button)(struct sway_seat *seat, uint32_t time_msec,
@ -49,8 +50,7 @@ struct sway_seatop_impl {
uint32_t time_msec, enum wlr_tablet_tool_tip_state state); uint32_t time_msec, enum wlr_tablet_tool_tip_state state);
void (*end)(struct sway_seat *seat); void (*end)(struct sway_seat *seat);
void (*unref)(struct sway_seat *seat, struct sway_container *con); void (*unref)(struct sway_seat *seat, struct sway_container *con);
void (*render)(struct sway_seat *seat, struct sway_output *output, void (*render)(struct sway_seat *seat, struct render_context *ctx);
const pixman_region32_t *damage);
bool allow_set_cursor; bool allow_set_cursor;
}; };
@ -356,8 +356,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con);
* Instructs a seatop to render anything that it needs to render * Instructs a seatop to render anything that it needs to render
* (eg. dropzone for move-tiling) * (eg. dropzone for move-tiling)
*/ */
void seatop_render(struct sway_seat *seat, struct sway_output *output, void seatop_render(struct sway_seat *seat, struct render_context *ctx);
const pixman_region32_t *damage);
bool seatop_allows_set_cursor(struct sway_seat *seat); bool seatop_allows_set_cursor(struct sway_seat *seat);

View file

@ -65,6 +65,12 @@ struct sway_output_non_desktop {
struct wl_listener destroy; struct wl_listener destroy;
}; };
struct render_context {
struct sway_output *output;
struct wlr_renderer *renderer;
const pixman_region32_t *output_damage;
};
struct sway_output *output_create(struct wlr_output *wlr_output); struct sway_output *output_create(struct wlr_output *wlr_output);
void output_destroy(struct sway_output *output); void output_destroy(struct sway_output *output);
@ -115,7 +121,7 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output);
struct sway_workspace *output_get_active_workspace(struct sway_output *output); struct sway_workspace *output_get_active_workspace(struct sway_output *output);
void output_render(struct sway_output *output, pixman_region32_t *damage); void output_render(struct render_context *ctx);
void output_surface_for_each_surface(struct sway_output *output, void output_surface_for_each_surface(struct sway_output *output,
struct wlr_surface *surface, double ox, double oy, struct wlr_surface *surface, double ox, double oy,
@ -168,8 +174,7 @@ void output_get_box(struct sway_output *output, struct wlr_box *box);
enum sway_container_layout output_get_default_layout( enum sway_container_layout output_get_default_layout(
struct sway_output *output); struct sway_output *output);
void render_rect(struct sway_output *output, void render_rect(struct render_context *ctx, const struct wlr_box *_box,
const pixman_region32_t *output_damage, const struct wlr_box *_box,
float color[static 4]); float color[static 4]);
void premultiply_alpha(float color[4], float opacity); void premultiply_alpha(float color[4], float opacity);

View file

@ -613,10 +613,22 @@ static int output_repaint_timer_handler(void *data) {
pixman_region32_init(&damage); pixman_region32_init(&damage);
wlr_damage_ring_get_buffer_damage(&output->damage_ring, buffer_age, &damage); wlr_damage_ring_get_buffer_damage(&output->damage_ring, buffer_age, &damage);
if (debug.damage == DAMAGE_RERENDER) {
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
pixman_region32_union_rect(&damage, &damage, 0, 0, width, height);
}
struct render_context ctx = {
.output_damage = &damage,
.renderer = wlr_output->renderer,
.output = output,
};
struct timespec now; struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
output_render(output, &damage); output_render(&ctx);
pixman_region32_fini(&damage); pixman_region32_fini(&damage);

View file

@ -32,6 +32,7 @@
#endif #endif
struct render_data { struct render_data {
struct render_context *ctx;
const pixman_region32_t *damage; const pixman_region32_t *damage;
float alpha; float alpha;
struct wlr_box *clip_box; struct wlr_box *clip_box;
@ -101,18 +102,17 @@ static void set_scale_filter(struct wlr_output *wlr_output,
#endif #endif
} }
static void render_texture(struct wlr_output *wlr_output, static void render_texture(struct render_context *ctx, struct wlr_texture *texture,
const pixman_region32_t *output_damage, struct wlr_texture *texture,
const struct wlr_fbox *src_box, const struct wlr_box *dst_box, const struct wlr_fbox *src_box, const struct wlr_box *dst_box,
const float matrix[static 9], float alpha) { const float matrix[static 9], float alpha) {
struct wlr_renderer *renderer = wlr_output->renderer; struct wlr_renderer *renderer = ctx->renderer;
struct sway_output *output = wlr_output->data; struct sway_output *output = ctx->output;
pixman_region32_t damage; pixman_region32_t damage;
pixman_region32_init(&damage); pixman_region32_init(&damage);
pixman_region32_union_rect(&damage, &damage, dst_box->x, dst_box->y, pixman_region32_union_rect(&damage, &damage, dst_box->x, dst_box->y,
dst_box->width, dst_box->height); dst_box->width, dst_box->height);
pixman_region32_intersect(&damage, &damage, output_damage); pixman_region32_intersect(&damage, &damage, ctx->output_damage);
bool damaged = pixman_region32_not_empty(&damage); bool damaged = pixman_region32_not_empty(&damage);
if (!damaged) { if (!damaged) {
goto damage_finish; goto damage_finish;
@ -121,8 +121,8 @@ static void render_texture(struct wlr_output *wlr_output,
int nrects; int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) { for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]); scissor_output(output->wlr_output, &rects[i]);
set_scale_filter(wlr_output, texture, output->scale_filter); set_scale_filter(output->wlr_output, texture, output->scale_filter);
if (src_box != NULL) { if (src_box != NULL) {
wlr_render_subtexture_with_matrix(renderer, texture, src_box, matrix, alpha); wlr_render_subtexture_with_matrix(renderer, texture, src_box, matrix, alpha);
} else { } else {
@ -139,7 +139,6 @@ static void render_surface_iterator(struct sway_output *output,
struct wlr_box *_box, void *_data) { struct wlr_box *_box, void *_data) {
struct render_data *data = _data; struct render_data *data = _data;
struct wlr_output *wlr_output = output->wlr_output; struct wlr_output *wlr_output = output->wlr_output;
const pixman_region32_t *output_damage = data->damage;
float alpha = data->alpha; float alpha = data->alpha;
struct wlr_texture *texture = wlr_surface_get_texture(surface); struct wlr_texture *texture = wlr_surface_get_texture(surface);
@ -167,73 +166,68 @@ static void render_surface_iterator(struct sway_output *output,
} }
scale_box(&dst_box, wlr_output->scale); scale_box(&dst_box, wlr_output->scale);
render_texture(wlr_output, output_damage, texture, render_texture(data->ctx, texture,
&src_box, &dst_box, matrix, alpha); &src_box, &dst_box, matrix, alpha);
wlr_presentation_surface_sampled_on_output(server.presentation, surface, wlr_presentation_surface_sampled_on_output(server.presentation, surface,
wlr_output); wlr_output);
} }
static void render_layer_toplevel(struct sway_output *output, static void render_layer_toplevel(struct render_context *ctx, struct wl_list *layer_surfaces) {
const pixman_region32_t *damage, struct wl_list *layer_surfaces) {
struct render_data data = { struct render_data data = {
.damage = damage,
.alpha = 1.0f, .alpha = 1.0f,
.ctx = ctx,
}; };
output_layer_for_each_toplevel_surface(output, layer_surfaces, output_layer_for_each_toplevel_surface(ctx->output, layer_surfaces,
render_surface_iterator, &data); render_surface_iterator, &data);
} }
static void render_layer_popups(struct sway_output *output, static void render_layer_popups(struct render_context *ctx, struct wl_list *layer_surfaces) {
const pixman_region32_t *damage, struct wl_list *layer_surfaces) {
struct render_data data = { struct render_data data = {
.damage = damage,
.alpha = 1.0f, .alpha = 1.0f,
.ctx = ctx,
}; };
output_layer_for_each_popup_surface(output, layer_surfaces, output_layer_for_each_popup_surface(ctx->output, layer_surfaces,
render_surface_iterator, &data); render_surface_iterator, &data);
} }
#if HAVE_XWAYLAND #if HAVE_XWAYLAND
static void render_unmanaged(struct sway_output *output, static void render_unmanaged(struct render_context *ctx, struct wl_list *unmanaged) {
const pixman_region32_t *damage, struct wl_list *unmanaged) {
struct render_data data = { struct render_data data = {
.damage = damage,
.alpha = 1.0f, .alpha = 1.0f,
.ctx = ctx,
}; };
output_unmanaged_for_each_surface(output, unmanaged, output_unmanaged_for_each_surface(ctx->output, unmanaged,
render_surface_iterator, &data); render_surface_iterator, &data);
} }
#endif #endif
static void render_drag_icons(struct sway_output *output, static void render_drag_icons(struct render_context *ctx, struct wl_list *drag_icons) {
const pixman_region32_t *damage, struct wl_list *drag_icons) {
struct render_data data = { struct render_data data = {
.damage = damage,
.alpha = 1.0f, .alpha = 1.0f,
.ctx = ctx,
}; };
output_drag_icons_for_each_surface(output, drag_icons, output_drag_icons_for_each_surface(ctx->output, drag_icons,
render_surface_iterator, &data); render_surface_iterator, &data);
} }
// _box.x and .y are expected to be layout-local // _box.x and .y are expected to be layout-local
// _box.width and .height are expected to be output-buffer-local // _box.width and .height are expected to be output-buffer-local
void render_rect(struct sway_output *output, void render_rect(struct render_context *ctx, const struct wlr_box *_box,
const pixman_region32_t *output_damage, const struct wlr_box *_box,
float color[static 4]) { float color[static 4]) {
struct wlr_output *wlr_output = output->wlr_output; struct wlr_output *wlr_output = ctx->output->wlr_output;
struct wlr_renderer *renderer = wlr_output->renderer; struct wlr_renderer *renderer = ctx->renderer;
struct wlr_box box; struct wlr_box box;
memcpy(&box, _box, sizeof(struct wlr_box)); memcpy(&box, _box, sizeof(struct wlr_box));
box.x -= output->lx * wlr_output->scale; box.x -= ctx->output->lx * wlr_output->scale;
box.y -= output->ly * wlr_output->scale; box.y -= ctx->output->ly * wlr_output->scale;
pixman_region32_t damage; pixman_region32_t damage;
pixman_region32_init(&damage); pixman_region32_init(&damage);
pixman_region32_union_rect(&damage, &damage, box.x, box.y, pixman_region32_union_rect(&damage, &damage, box.x, box.y,
box.width, box.height); box.width, box.height);
pixman_region32_intersect(&damage, &damage, output_damage); pixman_region32_intersect(&damage, &damage, ctx->output_damage);
bool damaged = pixman_region32_not_empty(&damage); bool damaged = pixman_region32_not_empty(&damage);
if (!damaged) { if (!damaged) {
goto damage_finish; goto damage_finish;
@ -258,11 +252,11 @@ void premultiply_alpha(float color[4], float opacity) {
color[2] *= color[3]; color[2] *= color[3];
} }
static void render_view_toplevels(struct sway_view *view, static void render_view_toplevels(struct render_context *ctx,
struct sway_output *output, const pixman_region32_t *damage, float alpha) { struct sway_view *view, float alpha) {
struct render_data data = { struct render_data data = {
.damage = damage,
.alpha = alpha, .alpha = alpha,
.ctx = ctx,
}; };
struct wlr_box clip_box; struct wlr_box clip_box;
if (!container_is_current_floating(view->container)) { if (!container_is_current_floating(view->container)) {
@ -274,25 +268,26 @@ static void render_view_toplevels(struct sway_view *view,
} }
// Render all toplevels without descending into popups // Render all toplevels without descending into popups
double ox = view->container->surface_x - double ox = view->container->surface_x -
output->lx - view->geometry.x; ctx->output->lx - view->geometry.x;
double oy = view->container->surface_y - double oy = view->container->surface_y -
output->ly - view->geometry.y; ctx->output->ly - view->geometry.y;
output_surface_for_each_surface(output, view->surface, ox, oy, output_surface_for_each_surface(ctx->output, view->surface, ox, oy,
render_surface_iterator, &data); render_surface_iterator, &data);
} }
static void render_view_popups(struct sway_view *view, static void render_view_popups(struct render_context *ctx, struct sway_view *view,
struct sway_output *output, const pixman_region32_t *damage, float alpha) { float alpha) {
struct render_data data = { struct render_data data = {
.damage = damage,
.alpha = alpha, .alpha = alpha,
.ctx = ctx,
}; };
output_view_for_each_popup_surface(output, view, output_view_for_each_popup_surface(ctx->output, view,
render_surface_iterator, &data); render_surface_iterator, &data);
} }
static void render_saved_view(struct sway_view *view, static void render_saved_view(struct render_context *ctx, struct sway_view *view,
struct sway_output *output, const pixman_region32_t *damage, float alpha) { float alpha) {
struct sway_output *output = ctx->output;
struct wlr_output *wlr_output = output->wlr_output; struct wlr_output *wlr_output = output->wlr_output;
if (wl_list_empty(&view->saved_buffers)) { if (wl_list_empty(&view->saved_buffers)) {
@ -343,7 +338,7 @@ static void render_saved_view(struct sway_view *view,
} }
scale_box(&dst_box, wlr_output->scale); scale_box(&dst_box, wlr_output->scale);
render_texture(wlr_output, damage, saved_buf->buffer->texture, render_texture(ctx, saved_buf->buffer->texture,
&saved_buf->source_box, &dst_box, matrix, alpha); &saved_buf->source_box, &dst_box, matrix, alpha);
} }
@ -355,13 +350,13 @@ static void render_saved_view(struct sway_view *view,
/** /**
* Render a view's surface and left/bottom/right borders. * Render a view's surface and left/bottom/right borders.
*/ */
static void render_view(struct sway_output *output, const pixman_region32_t *damage, static void render_view(struct render_context *ctx,
struct sway_container *con, struct border_colors *colors) { struct sway_container *con, struct border_colors *colors) {
struct sway_view *view = con->view; struct sway_view *view = con->view;
if (!wl_list_empty(&view->saved_buffers)) { if (!wl_list_empty(&view->saved_buffers)) {
render_saved_view(view, output, damage, view->container->alpha); render_saved_view(ctx, view, view->container->alpha);
} else if (view->surface) { } else if (view->surface) {
render_view_toplevels(view, output, damage, view->container->alpha); render_view_toplevels(ctx, view, view->container->alpha);
} }
if (con->current.border == B_NONE || con->current.border == B_CSD) { if (con->current.border == B_NONE || con->current.border == B_CSD) {
@ -369,7 +364,7 @@ static void render_view(struct sway_output *output, const pixman_region32_t *dam
} }
struct wlr_box box; struct wlr_box box;
float output_scale = output->wlr_output->scale; float output_scale = ctx->output->wlr_output->scale;
float color[4]; float color[4];
struct sway_container_state *state = &con->current; struct sway_container_state *state = &con->current;
@ -381,7 +376,7 @@ static void render_view(struct sway_output *output, const pixman_region32_t *dam
box.width = state->border_thickness; box.width = state->border_thickness;
box.height = state->content_height; box.height = state->content_height;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, damage, &box, color); render_rect(ctx, &box, color);
} }
list_t *siblings = container_get_current_siblings(con); list_t *siblings = container_get_current_siblings(con);
@ -400,7 +395,7 @@ static void render_view(struct sway_output *output, const pixman_region32_t *dam
box.width = state->border_thickness; box.width = state->border_thickness;
box.height = state->content_height; box.height = state->content_height;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, damage, &box, color); render_rect(ctx, &box, color);
} }
if (state->border_bottom) { if (state->border_bottom) {
@ -415,7 +410,7 @@ static void render_view(struct sway_output *output, const pixman_region32_t *dam
box.width = state->width; box.width = state->width;
box.height = state->border_thickness; box.height = state->border_thickness;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, damage, &box, color); render_rect(ctx, &box, color);
} }
} }
@ -428,13 +423,13 @@ static void render_view(struct sway_output *output, const pixman_region32_t *dam
* The height is: 1px border, 3px padding, font height, 3px padding, 1px border * The height is: 1px border, 3px padding, font height, 3px padding, 1px border
* The left side is: 1px border, 2px padding, title * The left side is: 1px border, 2px padding, title
*/ */
static void render_titlebar(struct sway_output *output, static void render_titlebar(struct render_context *ctx, struct sway_container *con,
const pixman_region32_t *output_damage, struct sway_container *con,
int x, int y, int width, int x, int y, int width,
struct border_colors *colors, struct wlr_texture *title_texture, struct border_colors *colors, struct wlr_texture *title_texture,
struct wlr_texture *marks_texture) { struct wlr_texture *marks_texture) {
struct wlr_box box; struct wlr_box box;
float color[4]; float color[4];
struct sway_output *output = ctx->output;
float output_scale = output->wlr_output->scale; float output_scale = output->wlr_output->scale;
double output_x = output->lx; double output_x = output->lx;
double output_y = output->ly; double output_y = output->ly;
@ -451,7 +446,7 @@ static void render_titlebar(struct sway_output *output,
box.width = width; box.width = width;
box.height = titlebar_border_thickness; box.height = titlebar_border_thickness;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
// Single pixel bar below title // Single pixel bar below title
box.x = x; box.x = x;
@ -459,7 +454,7 @@ static void render_titlebar(struct sway_output *output,
box.width = width; box.width = width;
box.height = titlebar_border_thickness; box.height = titlebar_border_thickness;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
// Single pixel left edge // Single pixel left edge
box.x = x; box.x = x;
@ -467,7 +462,7 @@ static void render_titlebar(struct sway_output *output,
box.width = titlebar_border_thickness; box.width = titlebar_border_thickness;
box.height = container_titlebar_height() - titlebar_border_thickness * 2; box.height = container_titlebar_height() - titlebar_border_thickness * 2;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
// Single pixel right edge // Single pixel right edge
box.x = x + width - titlebar_border_thickness; box.x = x + width - titlebar_border_thickness;
@ -475,7 +470,7 @@ static void render_titlebar(struct sway_output *output,
box.width = titlebar_border_thickness; box.width = titlebar_border_thickness;
box.height = container_titlebar_height() - titlebar_border_thickness * 2; box.height = container_titlebar_height() - titlebar_border_thickness * 2;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
int inner_x = x - output_x + titlebar_h_padding; int inner_x = x - output_x + titlebar_h_padding;
int bg_y = y + titlebar_border_thickness; int bg_y = y + titlebar_border_thickness;
@ -524,7 +519,7 @@ static void render_titlebar(struct sway_output *output,
if (ob_inner_width < texture_box.width) { if (ob_inner_width < texture_box.width) {
texture_box.width = ob_inner_width; texture_box.width = ob_inner_width;
} }
render_texture(output->wlr_output, output_damage, marks_texture, render_texture(ctx, marks_texture,
NULL, &texture_box, matrix, con->alpha); NULL, &texture_box, matrix, con->alpha);
// Padding above // Padding above
@ -534,12 +529,12 @@ static void render_titlebar(struct sway_output *output,
box.y = roundf((y + titlebar_border_thickness) * output_scale); box.y = roundf((y + titlebar_border_thickness) * output_scale);
box.width = texture_box.width; box.width = texture_box.width;
box.height = ob_padding_above; box.height = ob_padding_above;
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
// Padding below // Padding below
box.y += ob_padding_above + texture_box.height; box.y += ob_padding_above + texture_box.height;
box.height = ob_padding_below; box.height = ob_padding_below;
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
} }
// Title text // Title text
@ -600,7 +595,7 @@ static void render_titlebar(struct sway_output *output,
texture_box.width = ob_inner_width - ob_marks_width; texture_box.width = ob_inner_width - ob_marks_width;
} }
render_texture(output->wlr_output, output_damage, title_texture, render_texture(ctx, title_texture,
NULL, &texture_box, matrix, con->alpha); NULL, &texture_box, matrix, con->alpha);
// Padding above // Padding above
@ -610,12 +605,12 @@ static void render_titlebar(struct sway_output *output,
box.y = roundf((y + titlebar_border_thickness) * output_scale); box.y = roundf((y + titlebar_border_thickness) * output_scale);
box.width = texture_box.width; box.width = texture_box.width;
box.height = ob_padding_above; box.height = ob_padding_above;
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
// Padding below // Padding below
box.y += ob_padding_above + texture_box.height; box.y += ob_padding_above + texture_box.height;
box.height = ob_padding_below; box.height = ob_padding_below;
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
} }
// Determine the left + right extends of the textures (output-buffer local) // Determine the left + right extends of the textures (output-buffer local)
@ -649,7 +644,7 @@ static void render_titlebar(struct sway_output *output,
box.x = ob_left_x + ob_left_width + round(output_x * output_scale); box.x = ob_left_x + ob_left_width + round(output_x * output_scale);
box.y = roundf(bg_y * output_scale); box.y = roundf(bg_y * output_scale);
box.height = ob_bg_height; box.height = ob_bg_height;
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
} }
// Padding on left side // Padding on left side
@ -663,7 +658,7 @@ static void render_titlebar(struct sway_output *output,
if (box.x + box.width < left_x) { if (box.x + box.width < left_x) {
box.width += left_x - box.x - box.width; box.width += left_x - box.x - box.width;
} }
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
// Padding on right side // Padding on right side
box.x = x + width - titlebar_h_padding; box.x = x + width - titlebar_h_padding;
@ -677,14 +672,13 @@ static void render_titlebar(struct sway_output *output,
box.width += box.x - right_rx; box.width += box.x - right_rx;
box.x = right_rx; box.x = right_rx;
} }
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
} }
/** /**
* Render the top border line for a view using "border pixel". * Render the top border line for a view using "border pixel".
*/ */
static void render_top_border(struct sway_output *output, static void render_top_border(struct render_context *ctx, struct sway_container *con,
const pixman_region32_t *output_damage, struct sway_container *con,
struct border_colors *colors) { struct border_colors *colors) {
struct sway_container_state *state = &con->current; struct sway_container_state *state = &con->current;
if (!state->border_top) { if (!state->border_top) {
@ -692,7 +686,7 @@ static void render_top_border(struct sway_output *output,
} }
struct wlr_box box; struct wlr_box box;
float color[4]; float color[4];
float output_scale = output->wlr_output->scale; float output_scale = ctx->output->wlr_output->scale;
// Child border - top edge // Child border - top edge
memcpy(&color, colors->child_border, sizeof(float) * 4); memcpy(&color, colors->child_border, sizeof(float) * 4);
@ -702,7 +696,7 @@ static void render_top_border(struct sway_output *output,
box.width = state->width; box.width = state->width;
box.height = state->border_thickness; box.height = state->border_thickness;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, output_damage, &box, color); render_rect(ctx, &box, color);
} }
struct parent_data { struct parent_data {
@ -713,8 +707,8 @@ struct parent_data {
struct sway_container *active_child; struct sway_container *active_child;
}; };
static void render_container(struct sway_output *output, static void render_container(struct render_context *ctx,
const pixman_region32_t *damage, struct sway_container *con, bool parent_focused); struct sway_container *con, bool parent_focused);
/** /**
* Render a container's children using a L_HORIZ or L_VERT layout. * Render a container's children using a L_HORIZ or L_VERT layout.
@ -722,8 +716,7 @@ static void render_container(struct sway_output *output,
* Wrap child views in borders and leave child containers borderless because * Wrap child views in borders and leave child containers borderless because
* they'll apply their own borders to their children. * they'll apply their own borders to their children.
*/ */
static void render_containers_linear(struct sway_output *output, static void render_containers_linear(struct render_context *ctx, struct parent_data *parent) {
const pixman_region32_t *damage, struct parent_data *parent) {
for (int i = 0; i < parent->children->length; ++i) { for (int i = 0; i < parent->children->length; ++i) {
struct sway_container *child = parent->children->items[i]; struct sway_container *child = parent->children->items[i];
@ -753,15 +746,15 @@ static void render_containers_linear(struct sway_output *output,
} }
if (state->border == B_NORMAL) { if (state->border == B_NORMAL) {
render_titlebar(output, damage, child, floor(state->x), render_titlebar(ctx, child, floor(state->x),
floor(state->y), state->width, colors, floor(state->y), state->width, colors,
title_texture, marks_texture); title_texture, marks_texture);
} else if (state->border == B_PIXEL) { } else if (state->border == B_PIXEL) {
render_top_border(output, damage, child, colors); render_top_border(ctx, child, colors);
} }
render_view(output, damage, child, colors); render_view(ctx, child, colors);
} else { } else {
render_container(output, damage, child, render_container(ctx, child,
parent->focused || child->current.focused); parent->focused || child->current.focused);
} }
} }
@ -778,8 +771,7 @@ static bool container_has_focused_child(struct sway_container *con) {
/** /**
* Render a container's children using the L_TABBED layout. * Render a container's children using the L_TABBED layout.
*/ */
static void render_containers_tabbed(struct sway_output *output, static void render_containers_tabbed(struct render_context *ctx, struct parent_data *parent) {
const pixman_region32_t *damage, struct parent_data *parent) {
if (!parent->children->length) { if (!parent->children->length) {
return; return;
} }
@ -827,7 +819,7 @@ static void render_containers_tabbed(struct sway_output *output,
tab_width = parent->box.width - tab_width * i; tab_width = parent->box.width - tab_width * i;
} }
render_titlebar(output, damage, child, x, parent->box.y, tab_width, render_titlebar(ctx, child, x, parent->box.y, tab_width,
colors, title_texture, marks_texture); colors, title_texture, marks_texture);
if (child == current) { if (child == current) {
@ -837,9 +829,9 @@ static void render_containers_tabbed(struct sway_output *output,
// Render surface and left/right/bottom borders // Render surface and left/right/bottom borders
if (current->view) { if (current->view) {
render_view(output, damage, current, current_colors); render_view(ctx, current, current_colors);
} else { } else {
render_container(output, damage, current, render_container(ctx, current,
parent->focused || current->current.focused); parent->focused || current->current.focused);
} }
} }
@ -847,8 +839,7 @@ static void render_containers_tabbed(struct sway_output *output,
/** /**
* Render a container's children using the L_STACKED layout. * Render a container's children using the L_STACKED layout.
*/ */
static void render_containers_stacked(struct sway_output *output, static void render_containers_stacked(struct render_context *ctx, struct parent_data *parent) {
const pixman_region32_t *damage, struct parent_data *parent) {
if (!parent->children->length) { if (!parent->children->length) {
return; return;
} }
@ -890,7 +881,7 @@ static void render_containers_stacked(struct sway_output *output,
} }
int y = parent->box.y + titlebar_height * i; int y = parent->box.y + titlebar_height * i;
render_titlebar(output, damage, child, parent->box.x, y, render_titlebar(ctx, child, parent->box.x, y,
parent->box.width, colors, title_texture, marks_texture); parent->box.width, colors, title_texture, marks_texture);
if (child == current) { if (child == current) {
@ -900,19 +891,18 @@ static void render_containers_stacked(struct sway_output *output,
// Render surface and left/right/bottom borders // Render surface and left/right/bottom borders
if (current->view) { if (current->view) {
render_view(output, damage, current, current_colors); render_view(ctx, current, current_colors);
} else { } else {
render_container(output, damage, current, render_container(ctx, current,
parent->focused || current->current.focused); parent->focused || current->current.focused);
} }
} }
static void render_containers(struct sway_output *output, static void render_containers(struct render_context *ctx, struct parent_data *parent) {
const pixman_region32_t *damage, struct parent_data *parent) {
if (config->hide_lone_tab && parent->children->length == 1) { if (config->hide_lone_tab && parent->children->length == 1) {
struct sway_container *child = parent->children->items[0]; struct sway_container *child = parent->children->items[0];
if (child->view) { if (child->view) {
render_containers_linear(output,damage, parent); render_containers_linear(ctx, parent);
return; return;
} }
} }
@ -921,19 +911,19 @@ static void render_containers(struct sway_output *output,
case L_NONE: case L_NONE:
case L_HORIZ: case L_HORIZ:
case L_VERT: case L_VERT:
render_containers_linear(output, damage, parent); render_containers_linear(ctx, parent);
break; break;
case L_STACKED: case L_STACKED:
render_containers_stacked(output, damage, parent); render_containers_stacked(ctx, parent);
break; break;
case L_TABBED: case L_TABBED:
render_containers_tabbed(output, damage, parent); render_containers_tabbed(ctx, parent);
break; break;
} }
} }
static void render_container(struct sway_output *output, static void render_container(struct render_context *ctx,
const pixman_region32_t *damage, struct sway_container *con, bool focused) { struct sway_container *con, bool focused) {
struct parent_data data = { struct parent_data data = {
.layout = con->current.layout, .layout = con->current.layout,
.box = { .box = {
@ -946,11 +936,11 @@ static void render_container(struct sway_output *output,
.focused = focused, .focused = focused,
.active_child = con->current.focused_inactive_child, .active_child = con->current.focused_inactive_child,
}; };
render_containers(output, damage, &data); render_containers(ctx, &data);
} }
static void render_workspace(struct sway_output *output, static void render_workspace(struct render_context *ctx,
const pixman_region32_t *damage, struct sway_workspace *ws, bool focused) { struct sway_workspace *ws, bool focused) {
struct parent_data data = { struct parent_data data = {
.layout = ws->current.layout, .layout = ws->current.layout,
.box = { .box = {
@ -963,11 +953,11 @@ static void render_workspace(struct sway_output *output,
.focused = focused, .focused = focused,
.active_child = ws->current.focused_inactive_child, .active_child = ws->current.focused_inactive_child,
}; };
render_containers(output, damage, &data); render_containers(ctx, &data);
} }
static void render_floating_container(struct sway_output *soutput, static void render_floating_container(struct render_context *ctx,
const pixman_region32_t *damage, struct sway_container *con) { struct sway_container *con) {
if (con->view) { if (con->view) {
struct sway_view *view = con->view; struct sway_view *view = con->view;
struct border_colors *colors; struct border_colors *colors;
@ -989,20 +979,19 @@ static void render_floating_container(struct sway_output *soutput,
} }
if (con->current.border == B_NORMAL) { if (con->current.border == B_NORMAL) {
render_titlebar(soutput, damage, con, floor(con->current.x), render_titlebar(ctx, con, floor(con->current.x),
floor(con->current.y), con->current.width, colors, floor(con->current.y), con->current.width, colors,
title_texture, marks_texture); title_texture, marks_texture);
} else if (con->current.border == B_PIXEL) { } else if (con->current.border == B_PIXEL) {
render_top_border(soutput, damage, con, colors); render_top_border(ctx, con, colors);
} }
render_view(soutput, damage, con, colors); render_view(ctx, con, colors);
} else { } else {
render_container(soutput, damage, con, con->current.focused); render_container(ctx, con, con->current.focused);
} }
} }
static void render_floating(struct sway_output *soutput, static void render_floating(struct render_context *ctx) {
const pixman_region32_t *damage) {
for (int i = 0; i < root->outputs->length; ++i) { for (int i = 0; i < root->outputs->length; ++i) {
struct sway_output *output = root->outputs->items[i]; struct sway_output *output = root->outputs->items[i];
for (int j = 0; j < output->current.workspaces->length; ++j) { for (int j = 0; j < output->current.workspaces->length; ++j) {
@ -1015,23 +1004,24 @@ static void render_floating(struct sway_output *soutput,
if (floater->current.fullscreen_mode != FULLSCREEN_NONE) { if (floater->current.fullscreen_mode != FULLSCREEN_NONE) {
continue; continue;
} }
render_floating_container(soutput, damage, floater); render_floating_container(ctx, floater);
} }
} }
} }
} }
static void render_seatops(struct sway_output *output, static void render_seatops(struct render_context *ctx) {
const pixman_region32_t *damage) {
struct sway_seat *seat; struct sway_seat *seat;
wl_list_for_each(seat, &server.input->seats, link) { wl_list_for_each(seat, &server.input->seats, link) {
seatop_render(seat, output, damage); seatop_render(seat, ctx);
} }
} }
void output_render(struct sway_output *output, pixman_region32_t *damage) { void output_render(struct render_context *ctx) {
struct wlr_output *wlr_output = output->wlr_output; struct wlr_output *wlr_output = ctx->output->wlr_output;
struct wlr_renderer *renderer = output->server->renderer; struct wlr_renderer *renderer = ctx->renderer;
struct sway_output *output = ctx->output;
const pixman_region32_t *damage = ctx->output_damage;
struct sway_workspace *workspace = output->current.active_workspace; struct sway_workspace *workspace = output->current.active_workspace;
if (workspace == NULL) { if (workspace == NULL) {
@ -1047,12 +1037,6 @@ void output_render(struct sway_output *output, pixman_region32_t *damage) {
return; return;
} }
if (debug.damage == DAMAGE_RERENDER) {
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
pixman_region32_union_rect(damage, damage, 0, 0, width, height);
}
if (!pixman_region32_not_empty(damage)) { if (!pixman_region32_not_empty(damage)) {
// Output isn't damaged but needs buffer swap // Output isn't damaged but needs buffer swap
goto renderer_end; goto renderer_end;
@ -1077,8 +1061,8 @@ void output_render(struct sway_output *output, pixman_region32_t *damage) {
if (server.session_lock.lock != NULL) { if (server.session_lock.lock != NULL) {
struct render_data data = { struct render_data data = {
.damage = damage,
.alpha = 1.0f, .alpha = 1.0f,
.ctx = ctx,
}; };
struct wlr_session_lock_surface_v1 *lock_surface; struct wlr_session_lock_surface_v1 *lock_surface;
@ -1113,13 +1097,12 @@ void output_render(struct sway_output *output, pixman_region32_t *damage) {
if (fullscreen_con->view) { if (fullscreen_con->view) {
if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) { if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) {
render_saved_view(fullscreen_con->view, output, damage, 1.0f); render_saved_view(ctx, fullscreen_con->view, 1.0f);
} else if (fullscreen_con->view->surface) { } else if (fullscreen_con->view->surface) {
render_view_toplevels(fullscreen_con->view, render_view_toplevels(ctx, fullscreen_con->view, 1.0f);
output, damage, 1.0f);
} }
} else { } else {
render_container(output, damage, fullscreen_con, render_container(ctx, fullscreen_con,
fullscreen_con->current.focused); fullscreen_con->current.focused);
} }
@ -1127,11 +1110,11 @@ void output_render(struct sway_output *output, pixman_region32_t *damage) {
struct sway_container *floater = struct sway_container *floater =
workspace->current.floating->items[i]; workspace->current.floating->items[i];
if (container_is_transient_for(floater, fullscreen_con)) { if (container_is_transient_for(floater, fullscreen_con)) {
render_floating_container(output, damage, floater); render_floating_container(ctx, floater);
} }
} }
#if HAVE_XWAYLAND #if HAVE_XWAYLAND
render_unmanaged(output, damage, &root->xwayland_unmanaged); render_unmanaged(ctx, &root->xwayland_unmanaged);
#endif #endif
} else { } else {
float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
@ -1143,41 +1126,41 @@ void output_render(struct sway_output *output, pixman_region32_t *damage) {
wlr_renderer_clear(renderer, clear_color); wlr_renderer_clear(renderer, clear_color);
} }
render_layer_toplevel(output, damage, render_layer_toplevel(ctx,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
render_layer_toplevel(output, damage, render_layer_toplevel(ctx,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
render_workspace(output, damage, workspace, workspace->current.focused); render_workspace(ctx, workspace, workspace->current.focused);
render_floating(output, damage); render_floating(ctx);
#if HAVE_XWAYLAND #if HAVE_XWAYLAND
render_unmanaged(output, damage, &root->xwayland_unmanaged); render_unmanaged(ctx, &root->xwayland_unmanaged);
#endif #endif
render_layer_toplevel(output, damage, render_layer_toplevel(ctx,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
render_layer_popups(output, damage, render_layer_popups(ctx,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
render_layer_popups(output, damage, render_layer_popups(ctx,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
render_layer_popups(output, damage, render_layer_popups(ctx,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
} }
render_seatops(output, damage); render_seatops(ctx);
struct sway_seat *seat = input_manager_current_seat(); struct sway_seat *seat = input_manager_current_seat();
struct sway_container *focus = seat_get_focused_container(seat); struct sway_container *focus = seat_get_focused_container(seat);
if (focus && focus->view) { if (focus && focus->view) {
render_view_popups(focus->view, output, damage, focus->alpha); render_view_popups(ctx, focus->view, focus->alpha);
} }
render_overlay: render_overlay:
render_layer_toplevel(output, damage, render_layer_toplevel(ctx,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
render_layer_popups(output, damage, render_layer_popups(ctx,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
render_drag_icons(output, damage, &root->drag_icons); render_drag_icons(ctx, &root->drag_icons);
renderer_end: renderer_end:
wlr_renderer_scissor(renderer, NULL); wlr_renderer_scissor(renderer, NULL);

View file

@ -1726,10 +1726,9 @@ void seatop_end(struct sway_seat *seat) {
seat->seatop_impl = NULL; seat->seatop_impl = NULL;
} }
void seatop_render(struct sway_seat *seat, struct sway_output *output, void seatop_render(struct sway_seat *seat, struct render_context *ctx) {
const pixman_region32_t *damage) {
if (seat->seatop_impl->render) { if (seat->seatop_impl->render) {
seat->seatop_impl->render(seat, output, damage); seat->seatop_impl->render(seat, ctx);
} }
} }

View file

@ -31,21 +31,20 @@ struct seatop_move_tiling_event {
bool insert_after_target; bool insert_after_target;
}; };
static void handle_render(struct sway_seat *seat, static void handle_render(struct sway_seat *seat, struct render_context *ctx) {
struct sway_output *output, const pixman_region32_t *damage) {
struct seatop_move_tiling_event *e = seat->seatop_data; struct seatop_move_tiling_event *e = seat->seatop_data;
if (!e->threshold_reached) { if (!e->threshold_reached) {
return; return;
} }
if (e->target_node && node_get_output(e->target_node) == output) { if (e->target_node && node_get_output(e->target_node) == ctx->output) {
float color[4]; float color[4];
memcpy(&color, config->border_colors.focused.indicator, memcpy(&color, config->border_colors.focused.indicator,
sizeof(float) * 4); sizeof(float) * 4);
premultiply_alpha(color, 0.5); premultiply_alpha(color, 0.5);
struct wlr_box box; struct wlr_box box;
memcpy(&box, &e->drop_box, sizeof(struct wlr_box)); memcpy(&box, &e->drop_box, sizeof(struct wlr_box));
scale_box(&box, output->wlr_output->scale); scale_box(&box, ctx->output->wlr_output->scale);
render_rect(output, damage, &box, color); render_rect(ctx, &box, color);
} }
} }