diff options
author | Alexander Orzechowski <alex@ozal.ski> | 2023-05-02 11:43:44 -0400 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2023-05-02 18:31:55 +0200 |
commit | 029b99b4829148ef3e899f21bba4fe2a1d4d0db9 (patch) | |
tree | c1211ce46f432ebe3fe84e95608d62a35e51dcbc /sway/desktop/render.c | |
parent | render: Don't pass matrix into render_texture (diff) | |
download | sway-029b99b4829148ef3e899f21bba4fe2a1d4d0db9.tar.gz sway-029b99b4829148ef3e899f21bba4fe2a1d4d0db9.tar.zst sway-029b99b4829148ef3e899f21bba4fe2a1d4d0db9.zip |
render: Use wlr_render_pass
Diffstat (limited to 'sway/desktop/render.c')
-rw-r--r-- | sway/desktop/render.c | 171 |
1 files changed, 83 insertions, 88 deletions
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index a3ae5efc..37e84647 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -38,6 +38,23 @@ struct render_data { | |||
38 | struct wlr_box *clip_box; | 38 | struct wlr_box *clip_box; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static void transform_output_damage(pixman_region32_t *damage, struct wlr_output *output) { | ||
42 | int ow, oh; | ||
43 | wlr_output_transformed_resolution(output, &ow, &oh); | ||
44 | enum wl_output_transform transform = | ||
45 | wlr_output_transform_invert(output->transform); | ||
46 | wlr_region_transform(damage, damage, transform, ow, oh); | ||
47 | } | ||
48 | |||
49 | static void transform_output_box(struct wlr_box *box, struct wlr_output *output) { | ||
50 | int ow, oh; | ||
51 | wlr_output_transformed_resolution(output, &ow, &oh); | ||
52 | enum wl_output_transform transform = | ||
53 | wlr_output_transform_invert(output->transform); | ||
54 | wlr_box_transform(box, box, transform, ow, oh); | ||
55 | } | ||
56 | |||
57 | |||
41 | /** | 58 | /** |
42 | * Apply scale to a width or height. | 59 | * Apply scale to a width or height. |
43 | * | 60 | * |
@@ -54,28 +71,6 @@ static int scale_length(int length, int offset, float scale) { | |||
54 | return roundf((offset + length) * scale) - roundf(offset * scale); | 71 | return roundf((offset + length) * scale) - roundf(offset * scale); |
55 | } | 72 | } |
56 | 73 | ||
57 | static void scissor_output(struct wlr_output *wlr_output, | ||
58 | pixman_box32_t *rect) { | ||
59 | struct wlr_renderer *renderer = wlr_output->renderer; | ||
60 | assert(renderer); | ||
61 | |||
62 | struct wlr_box box = { | ||
63 | .x = rect->x1, | ||
64 | .y = rect->y1, | ||
65 | .width = rect->x2 - rect->x1, | ||
66 | .height = rect->y2 - rect->y1, | ||
67 | }; | ||
68 | |||
69 | int ow, oh; | ||
70 | wlr_output_transformed_resolution(wlr_output, &ow, &oh); | ||
71 | |||
72 | enum wl_output_transform transform = | ||
73 | wlr_output_transform_invert(wlr_output->transform); | ||
74 | wlr_box_transform(&box, &box, transform, ow, oh); | ||
75 | |||
76 | wlr_renderer_scissor(renderer, &box); | ||
77 | } | ||
78 | |||
79 | static void set_scale_filter(struct wlr_output *wlr_output, | 74 | static void set_scale_filter(struct wlr_output *wlr_output, |
80 | struct wlr_texture *texture, enum scale_filter_mode scale_filter) { | 75 | struct wlr_texture *texture, enum scale_filter_mode scale_filter) { |
81 | #if WLR_HAS_GLES2_RENDERER | 76 | #if WLR_HAS_GLES2_RENDERER |
@@ -103,40 +98,39 @@ static void set_scale_filter(struct wlr_output *wlr_output, | |||
103 | } | 98 | } |
104 | 99 | ||
105 | static void render_texture(struct render_context *ctx, struct wlr_texture *texture, | 100 | static void render_texture(struct render_context *ctx, struct wlr_texture *texture, |
106 | const struct wlr_fbox *src_box, const struct wlr_box *dst_box, | 101 | const struct wlr_fbox *_src_box, const struct wlr_box *dst_box, |
107 | enum wl_output_transform transform, float alpha) { | 102 | enum wl_output_transform transform, float alpha) { |
108 | struct wlr_renderer *renderer = ctx->renderer; | ||
109 | struct sway_output *output = ctx->output; | 103 | struct sway_output *output = ctx->output; |
110 | 104 | ||
111 | struct wlr_box proj_box = *dst_box; | 105 | struct wlr_box proj_box = *dst_box; |
112 | scale_box(&proj_box, output->wlr_output->scale); | ||
113 | 106 | ||
114 | float matrix[9]; | 107 | struct wlr_fbox src_box = {0}; |
115 | enum wl_output_transform inv_transform = wlr_output_transform_invert(transform); | 108 | if (_src_box) { |
116 | wlr_matrix_project_box(matrix, &proj_box, inv_transform, 0, | 109 | src_box = *_src_box; |
117 | output->wlr_output->transform_matrix); | 110 | } |
118 | 111 | ||
119 | pixman_region32_t damage; | 112 | pixman_region32_t damage; |
120 | pixman_region32_init(&damage); | 113 | pixman_region32_init_rect(&damage, proj_box.x, proj_box.y, |
121 | pixman_region32_union_rect(&damage, &damage, dst_box->x, dst_box->y, | 114 | proj_box.width, proj_box.height); |
122 | dst_box->width, dst_box->height); | ||
123 | pixman_region32_intersect(&damage, &damage, ctx->output_damage); | 115 | pixman_region32_intersect(&damage, &damage, ctx->output_damage); |
124 | bool damaged = pixman_region32_not_empty(&damage); | 116 | bool damaged = pixman_region32_not_empty(&damage); |
125 | if (!damaged) { | 117 | if (!damaged) { |
126 | goto damage_finish; | 118 | goto damage_finish; |
127 | } | 119 | } |
128 | 120 | ||
129 | int nrects; | 121 | transform_output_box(&proj_box, output->wlr_output); |
130 | pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); | 122 | transform_output_damage(&damage, output->wlr_output); |
131 | for (int i = 0; i < nrects; ++i) { | 123 | transform = wlr_output_transform_compose(transform, output->wlr_output->transform); |
132 | scissor_output(output->wlr_output, &rects[i]); | 124 | |
133 | set_scale_filter(output->wlr_output, texture, output->scale_filter); | 125 | set_scale_filter(output->wlr_output, texture, output->scale_filter); |
134 | if (src_box != NULL) { | 126 | wlr_render_pass_add_texture(ctx->pass, &(struct wlr_render_texture_options) { |
135 | wlr_render_subtexture_with_matrix(renderer, texture, src_box, matrix, alpha); | 127 | .texture = texture, |
136 | } else { | 128 | .src_box = src_box, |
137 | wlr_render_texture_with_matrix(renderer, texture, matrix, alpha); | 129 | .dst_box = proj_box, |
138 | } | 130 | .transform = transform, |
139 | } | 131 | .alpha = &alpha, |
132 | .clip = &damage, | ||
133 | }); | ||
140 | 134 | ||
141 | damage_finish: | 135 | damage_finish: |
142 | pixman_region32_fini(&damage); | 136 | pixman_region32_fini(&damage); |
@@ -218,16 +212,13 @@ static void render_drag_icons(struct render_context *ctx, struct wl_list *drag_i | |||
218 | void render_rect(struct render_context *ctx, const struct wlr_box *_box, | 212 | void render_rect(struct render_context *ctx, const struct wlr_box *_box, |
219 | float color[static 4]) { | 213 | float color[static 4]) { |
220 | struct wlr_output *wlr_output = ctx->output->wlr_output; | 214 | struct wlr_output *wlr_output = ctx->output->wlr_output; |
221 | struct wlr_renderer *renderer = ctx->renderer; | ||
222 | 215 | ||
223 | struct wlr_box box; | 216 | struct wlr_box box = *_box; |
224 | memcpy(&box, _box, sizeof(struct wlr_box)); | ||
225 | box.x -= ctx->output->lx * wlr_output->scale; | 217 | box.x -= ctx->output->lx * wlr_output->scale; |
226 | box.y -= ctx->output->ly * wlr_output->scale; | 218 | box.y -= ctx->output->ly * wlr_output->scale; |
227 | 219 | ||
228 | pixman_region32_t damage; | 220 | pixman_region32_t damage; |
229 | pixman_region32_init(&damage); | 221 | pixman_region32_init_rect(&damage, box.x, box.y, |
230 | pixman_region32_union_rect(&damage, &damage, box.x, box.y, | ||
231 | box.width, box.height); | 222 | box.width, box.height); |
232 | pixman_region32_intersect(&damage, &damage, ctx->output_damage); | 223 | pixman_region32_intersect(&damage, &damage, ctx->output_damage); |
233 | bool damaged = pixman_region32_not_empty(&damage); | 224 | bool damaged = pixman_region32_not_empty(&damage); |
@@ -235,13 +226,19 @@ void render_rect(struct render_context *ctx, const struct wlr_box *_box, | |||
235 | goto damage_finish; | 226 | goto damage_finish; |
236 | } | 227 | } |
237 | 228 | ||
238 | int nrects; | 229 | transform_output_damage(&damage, wlr_output); |
239 | pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); | 230 | transform_output_box(&box, wlr_output); |
240 | for (int i = 0; i < nrects; ++i) { | 231 | |
241 | scissor_output(wlr_output, &rects[i]); | 232 | wlr_render_pass_add_rect(ctx->pass, &(struct wlr_render_rect_options){ |
242 | wlr_render_rect(renderer, &box, color, | 233 | .box = box, |
243 | wlr_output->transform_matrix); | 234 | .color = { |
244 | } | 235 | .r = color[0], |
236 | .g = color[1], | ||
237 | .b = color[2], | ||
238 | .a = color[3], | ||
239 | }, | ||
240 | .clip = &damage, | ||
241 | }); | ||
245 | 242 | ||
246 | damage_finish: | 243 | damage_finish: |
247 | pixman_region32_fini(&damage); | 244 | pixman_region32_fini(&damage); |
@@ -1006,7 +1003,6 @@ static void render_seatops(struct render_context *ctx) { | |||
1006 | 1003 | ||
1007 | void output_render(struct render_context *ctx) { | 1004 | void output_render(struct render_context *ctx) { |
1008 | struct wlr_output *wlr_output = ctx->output->wlr_output; | 1005 | struct wlr_output *wlr_output = ctx->output->wlr_output; |
1009 | struct wlr_renderer *renderer = ctx->renderer; | ||
1010 | struct sway_output *output = ctx->output; | 1006 | struct sway_output *output = ctx->output; |
1011 | const pixman_region32_t *damage = ctx->output_damage; | 1007 | const pixman_region32_t *damage = ctx->output_damage; |
1012 | 1008 | ||
@@ -1020,32 +1016,38 @@ void output_render(struct render_context *ctx) { | |||
1020 | fullscreen_con = workspace->current.fullscreen; | 1016 | fullscreen_con = workspace->current.fullscreen; |
1021 | } | 1017 | } |
1022 | 1018 | ||
1023 | if (!wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height)) { | ||
1024 | return; | ||
1025 | } | ||
1026 | |||
1027 | if (!pixman_region32_not_empty(damage)) { | 1019 | if (!pixman_region32_not_empty(damage)) { |
1028 | // Output isn't damaged but needs buffer swap | 1020 | // Output isn't damaged but needs buffer swap |
1029 | goto renderer_end; | 1021 | goto renderer_end; |
1030 | } | 1022 | } |
1031 | 1023 | ||
1032 | if (debug.damage == DAMAGE_HIGHLIGHT) { | 1024 | if (debug.damage == DAMAGE_HIGHLIGHT) { |
1033 | wlr_renderer_clear(renderer, (float[]){1, 1, 0, 1}); | 1025 | wlr_render_pass_add_rect(ctx->pass, &(struct wlr_render_rect_options){ |
1026 | .box = { .width = output->width, .height = output->height }, | ||
1027 | .color = { .r = 1, .g = 1, .b = 0, .a = 1 }, | ||
1028 | }); | ||
1034 | } | 1029 | } |
1035 | 1030 | ||
1031 | pixman_region32_t transformed_damage; | ||
1032 | pixman_region32_init(&transformed_damage); | ||
1033 | pixman_region32_copy(&transformed_damage, damage); | ||
1034 | transform_output_damage(&transformed_damage, wlr_output); | ||
1035 | |||
1036 | if (server.session_lock.locked) { | 1036 | if (server.session_lock.locked) { |
1037 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; | 1037 | struct wlr_render_color clear_color = { |
1038 | .a = 1.0f | ||
1039 | }; | ||
1038 | if (server.session_lock.lock == NULL) { | 1040 | if (server.session_lock.lock == NULL) { |
1039 | // abandoned lock -> red BG | 1041 | // abandoned lock -> red BG |
1040 | clear_color[0] = 1.f; | 1042 | clear_color.r = 1.f; |
1041 | } | ||
1042 | int nrects; | ||
1043 | pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects); | ||
1044 | for (int i = 0; i < nrects; ++i) { | ||
1045 | scissor_output(wlr_output, &rects[i]); | ||
1046 | wlr_renderer_clear(renderer, clear_color); | ||
1047 | } | 1043 | } |
1048 | 1044 | ||
1045 | wlr_render_pass_add_rect(ctx->pass, &(struct wlr_render_rect_options){ | ||
1046 | .box = { .width = output->width, .height = output->height }, | ||
1047 | .color = clear_color, | ||
1048 | .clip = &transformed_damage, | ||
1049 | }); | ||
1050 | |||
1049 | if (server.session_lock.lock != NULL) { | 1051 | if (server.session_lock.lock != NULL) { |
1050 | struct render_data data = { | 1052 | struct render_data data = { |
1051 | .alpha = 1.0f, | 1053 | .alpha = 1.0f, |
@@ -1073,14 +1075,11 @@ void output_render(struct render_context *ctx) { | |||
1073 | } | 1075 | } |
1074 | 1076 | ||
1075 | if (fullscreen_con) { | 1077 | if (fullscreen_con) { |
1076 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; | 1078 | wlr_render_pass_add_rect(ctx->pass, &(struct wlr_render_rect_options){ |
1077 | 1079 | .box = { .width = output->width, .height = output->height }, | |
1078 | int nrects; | 1080 | .color = { .r = 0, .g = 0, .b = 0, .a = 1 }, |
1079 | pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects); | 1081 | .clip = &transformed_damage, |
1080 | for (int i = 0; i < nrects; ++i) { | 1082 | }); |
1081 | scissor_output(wlr_output, &rects[i]); | ||
1082 | wlr_renderer_clear(renderer, clear_color); | ||
1083 | } | ||
1084 | 1083 | ||
1085 | if (fullscreen_con->view) { | 1084 | if (fullscreen_con->view) { |
1086 | if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) { | 1085 | if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) { |
@@ -1104,14 +1103,11 @@ void output_render(struct render_context *ctx) { | |||
1104 | render_unmanaged(ctx, &root->xwayland_unmanaged); | 1103 | render_unmanaged(ctx, &root->xwayland_unmanaged); |
1105 | #endif | 1104 | #endif |
1106 | } else { | 1105 | } else { |
1107 | float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; | 1106 | wlr_render_pass_add_rect(ctx->pass, &(struct wlr_render_rect_options){ |
1108 | 1107 | .box = { .width = output->width, .height = output->height }, | |
1109 | int nrects; | 1108 | .color = { .r = 0.25f, .g = 0.25f, .b = 0.25f, .a = 1 }, |
1110 | pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects); | 1109 | .clip = &transformed_damage, |
1111 | for (int i = 0; i < nrects; ++i) { | 1110 | }); |
1112 | scissor_output(wlr_output, &rects[i]); | ||
1113 | wlr_renderer_clear(renderer, clear_color); | ||
1114 | } | ||
1115 | 1111 | ||
1116 | render_layer_toplevel(ctx, | 1112 | render_layer_toplevel(ctx, |
1117 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); | 1113 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); |
@@ -1150,7 +1146,6 @@ render_overlay: | |||
1150 | render_drag_icons(ctx, &root->drag_icons); | 1146 | render_drag_icons(ctx, &root->drag_icons); |
1151 | 1147 | ||
1152 | renderer_end: | 1148 | renderer_end: |
1153 | wlr_renderer_scissor(renderer, NULL); | 1149 | pixman_region32_fini(&transformed_damage); |
1154 | wlr_output_render_software_cursors(wlr_output, damage); | 1150 | wlr_output_add_software_cursors_to_render_pass(wlr_output, ctx->pass, damage); |
1155 | wlr_renderer_end(renderer); | ||
1156 | } | 1151 | } |