aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-04-06 14:17:58 -0400
committerLibravatar emersion <contact@emersion.fr>2018-04-06 14:17:58 -0400
commit58914822aa70d69a61794c52aa2113dbe7fcc7af (patch)
treeba1de3856366da1883247fe49d463c6ba35b9b57
parentRefactor rendering code (diff)
downloadsway-58914822aa70d69a61794c52aa2113dbe7fcc7af.tar.gz
sway-58914822aa70d69a61794c52aa2113dbe7fcc7af.tar.zst
sway-58914822aa70d69a61794c52aa2113dbe7fcc7af.zip
Don't damage the whole output
-rw-r--r--sway/desktop/output.c103
-rw-r--r--sway/desktop/xdg_shell_v6.c24
2 files changed, 104 insertions, 23 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 90ec3c77..0f25cff1 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -1,8 +1,8 @@
1#define _POSIX_C_SOURCE 200809L 1#define _POSIX_C_SOURCE 200809L
2#include <assert.h> 2#include <assert.h>
3#include <stdlib.h> 3#include <stdlib.h>
4#include <time.h>
5#include <strings.h> 4#include <strings.h>
5#include <time.h>
6#include <wayland-server.h> 6#include <wayland-server.h>
7#include <wlr/render/wlr_renderer.h> 7#include <wlr/render/wlr_renderer.h>
8#include <wlr/types/wlr_box.h> 8#include <wlr/types/wlr_box.h>
@@ -12,6 +12,7 @@
12#include <wlr/types/wlr_output.h> 12#include <wlr/types/wlr_output.h>
13#include <wlr/types/wlr_surface.h> 13#include <wlr/types/wlr_surface.h>
14#include <wlr/types/wlr_wl_shell.h> 14#include <wlr/types/wlr_wl_shell.h>
15#include <wlr/util/region.h>
15#include "log.h" 16#include "log.h"
16#include "sway/input/input-manager.h" 17#include "sway/input/input-manager.h"
17#include "sway/input/seat.h" 18#include "sway/input/seat.h"
@@ -95,13 +96,13 @@ static bool get_surface_box(struct root_geometry *geo,
95} 96}
96 97
97static void output_surface_for_each_surface(struct wlr_surface *surface, 98static void output_surface_for_each_surface(struct wlr_surface *surface,
98 double ox, double oy, float rotation, struct root_geometry *geo, 99 double ox, double oy, struct root_geometry *geo,
99 wlr_surface_iterator_func_t iterator, void *user_data) { 100 wlr_surface_iterator_func_t iterator, void *user_data) {
100 geo->x = ox; 101 geo->x = ox;
101 geo->y = oy; 102 geo->y = oy;
102 geo->width = surface->current->width; 103 geo->width = surface->current->width;
103 geo->height = surface->current->height; 104 geo->height = surface->current->height;
104 geo->rotation = rotation; 105 geo->rotation = 0;
105 106
106 wlr_surface_for_each_surface(surface, iterator, user_data); 107 wlr_surface_for_each_surface(surface, iterator, user_data);
107} 108}
@@ -174,14 +175,14 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy,
174} 175}
175 176
176static void render_surface(struct sway_output *output, struct timespec *when, 177static void render_surface(struct sway_output *output, struct timespec *when,
177 struct wlr_surface *surface, double ox, double oy, float rotation) { 178 struct wlr_surface *surface, double ox, double oy) {
178 struct render_data data = { 179 struct render_data data = {
179 .output = output, 180 .output = output,
180 .when = when, 181 .when = when,
181 .alpha = 1.0f, 182 .alpha = 1.0f,
182 }; 183 };
183 184
184 output_surface_for_each_surface(surface, ox, oy, rotation, &data.root_geo, 185 output_surface_for_each_surface(surface, ox, oy, &data.root_geo,
185 render_surface_iterator, &data); 186 render_surface_iterator, &data);
186} 187}
187 188
@@ -204,7 +205,7 @@ static void render_layer(struct sway_output *output, struct timespec *when,
204 struct wlr_layer_surface *wlr_layer_surface = 205 struct wlr_layer_surface *wlr_layer_surface =
205 layer_surface->layer_surface; 206 layer_surface->layer_surface;
206 render_surface(output, when, wlr_layer_surface->surface, 207 render_surface(output, when, wlr_layer_surface->surface,
207 layer_surface->geo.x, layer_surface->geo.y, 0); 208 layer_surface->geo.x, layer_surface->geo.y);
208 } 209 }
209} 210}
210 211
@@ -241,6 +242,11 @@ static void render_output(struct sway_output *output, struct timespec *when,
241 goto renderer_end; 242 goto renderer_end;
242 } 243 }
243 244
245 // TODO: don't damage the whole output
246 int width, height;
247 wlr_output_transformed_resolution(wlr_output, &width, &height);
248 pixman_region32_union_rect(damage, damage, 0, 0, width, height);
249
244 float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; 250 float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
245 wlr_renderer_clear(renderer, clear_color); 251 wlr_renderer_clear(renderer, clear_color);
246 252
@@ -270,7 +276,7 @@ static void render_output(struct sway_output *output, struct timespec *when,
270 unmanaged_surface->wlr_xwayland_surface; 276 unmanaged_surface->wlr_xwayland_surface;
271 double ox = unmanaged_surface->lx - output->swayc->x; 277 double ox = unmanaged_surface->lx - output->swayc->x;
272 double oy = unmanaged_surface->ly - output->swayc->y; 278 double oy = unmanaged_surface->ly - output->swayc->y;
273 render_surface(output, when, xsurface->surface, ox, oy, 0); 279 render_surface(output, when, xsurface->surface, ox, oy);
274 } 280 }
275 281
276 // TODO: consider revising this when fullscreen windows are supported 282 // TODO: consider revising this when fullscreen windows are supported
@@ -318,22 +324,93 @@ void output_damage_whole(struct sway_output *output) {
318 wlr_output_damage_add_whole(output->damage); 324 wlr_output_damage_add_whole(output->damage);
319} 325}
320 326
327struct damage_data {
328 struct root_geometry root_geo;
329 struct sway_output *output;
330 bool whole;
331};
332
333static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy,
334 void *_data) {
335 struct damage_data *data = _data;
336 struct sway_output *output = data->output;
337 float rotation = data->root_geo.rotation;
338 bool whole = data->whole;
339
340 if (!wlr_surface_has_buffer(surface)) {
341 return;
342 }
343
344 struct wlr_box box;
345 bool intersects = get_surface_box(&data->root_geo, data->output, surface,
346 sx, sy, &box);
347 if (!intersects) {
348 return;
349 }
350
351 scale_box(&box, output->wlr_output->scale);
352
353 if (whole) {
354 wlr_box_rotated_bounds(&box, rotation, &box);
355 wlr_output_damage_add_box(output->damage, &box);
356 } else {
357 int center_x = box.x + box.width/2;
358 int center_y = box.y + box.height/2;
359
360 pixman_region32_t damage;
361 pixman_region32_init(&damage);
362 pixman_region32_copy(&damage, &surface->current->surface_damage);
363 wlr_region_scale(&damage, &damage, output->wlr_output->scale);
364 if (ceil(output->wlr_output->scale) > surface->current->scale) {
365 // When scaling up a surface, it'll become blurry so we need to
366 // expand the damage region
367 wlr_region_expand(&damage, &damage,
368 ceil(output->wlr_output->scale) - surface->current->scale);
369 }
370 pixman_region32_translate(&damage, box.x, box.y);
371 wlr_region_rotated_bounds(&damage, &damage, rotation,
372 center_x, center_y);
373 wlr_output_damage_add(output->damage, &damage);
374 pixman_region32_fini(&damage);
375 }
376}
377
321void output_damage_surface(struct sway_output *output, double ox, double oy, 378void output_damage_surface(struct sway_output *output, double ox, double oy,
322 struct wlr_surface *surface, bool whole) { 379 struct wlr_surface *surface, bool whole) {
323 // TODO 380 struct damage_data data = {
324 output_damage_whole(output); 381 .output = output,
382 .whole = whole,
383 };
384
385 output_surface_for_each_surface(surface, ox, oy, &data.root_geo,
386 damage_surface_iterator, &data);
325} 387}
326 388
327void output_damage_view(struct sway_output *output, struct sway_view *view, 389void output_damage_view(struct sway_output *output, struct sway_view *view,
328 bool whole) { 390 bool whole) {
329 // TODO 391 if (!sway_assert(view->swayc != NULL, "expected a view in the tree")) {
330 output_damage_whole(output); 392 return;
393 }
394
395 struct damage_data data = {
396 .output = output,
397 .whole = whole,
398 };
399
400 output_view_for_each_surface(view, &data.root_geo,
401 damage_surface_iterator, &data);
331} 402}
332 403
333void output_damage_whole_container(struct sway_output *output, 404void output_damage_whole_container(struct sway_output *output,
334 struct sway_container *con) { 405 struct sway_container *con) {
335 // TODO 406 float scale = output->wlr_output->scale;
336 output_damage_whole(output); 407 struct wlr_box box = {
408 .x = con->x * scale,
409 .y = con->y * scale,
410 .width = con->width * scale,
411 .height = con->height * scale,
412 };
413 wlr_output_damage_add_box(output->damage, &box);
337} 414}
338 415
339static void damage_handle_destroy(struct wl_listener *listener, void *data) { 416static void damage_handle_destroy(struct wl_listener *listener, void *data) {
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index b82eec8f..e4703040 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -143,9 +143,7 @@ static void destroy(struct sway_view *view) {
143 if (xdg_shell_v6_view == NULL) { 143 if (xdg_shell_v6_view == NULL) {
144 return; 144 return;
145 } 145 }
146 wl_list_remove(&xdg_shell_v6_view->commit.link);
147 wl_list_remove(&xdg_shell_v6_view->destroy.link); 146 wl_list_remove(&xdg_shell_v6_view->destroy.link);
148 wl_list_remove(&xdg_shell_v6_view->new_popup.link);
149 wl_list_remove(&xdg_shell_v6_view->map.link); 147 wl_list_remove(&xdg_shell_v6_view->map.link);
150 wl_list_remove(&xdg_shell_v6_view->unmap.link); 148 wl_list_remove(&xdg_shell_v6_view->unmap.link);
151 free(xdg_shell_v6_view); 149 free(xdg_shell_v6_view);
@@ -182,14 +180,28 @@ static void handle_new_popup(struct wl_listener *listener, void *data) {
182static void handle_unmap(struct wl_listener *listener, void *data) { 180static void handle_unmap(struct wl_listener *listener, void *data) {
183 struct sway_xdg_shell_v6_view *xdg_shell_v6_view = 181 struct sway_xdg_shell_v6_view *xdg_shell_v6_view =
184 wl_container_of(listener, xdg_shell_v6_view, unmap); 182 wl_container_of(listener, xdg_shell_v6_view, unmap);
183
185 view_unmap(&xdg_shell_v6_view->view); 184 view_unmap(&xdg_shell_v6_view->view);
185
186 wl_list_remove(&xdg_shell_v6_view->commit.link);
187 wl_list_remove(&xdg_shell_v6_view->new_popup.link);
186} 188}
187 189
188static void handle_map(struct wl_listener *listener, void *data) { 190static void handle_map(struct wl_listener *listener, void *data) {
189 struct sway_xdg_shell_v6_view *xdg_shell_v6_view = 191 struct sway_xdg_shell_v6_view *xdg_shell_v6_view =
190 wl_container_of(listener, xdg_shell_v6_view, map); 192 wl_container_of(listener, xdg_shell_v6_view, map);
191 struct sway_view *view = &xdg_shell_v6_view->view; 193 struct sway_view *view = &xdg_shell_v6_view->view;
194 struct wlr_xdg_surface_v6 *xdg_surface = view->wlr_xdg_surface_v6;
195
192 view_map(view, view->wlr_xdg_surface_v6->surface); 196 view_map(view, view->wlr_xdg_surface_v6->surface);
197
198 xdg_shell_v6_view->commit.notify = handle_commit;
199 wl_signal_add(&xdg_surface->surface->events.commit,
200 &xdg_shell_v6_view->commit);
201
202 xdg_shell_v6_view->new_popup.notify = handle_new_popup;
203 wl_signal_add(&xdg_surface->events.new_popup,
204 &xdg_shell_v6_view->new_popup);
193} 205}
194 206
195static void handle_destroy(struct wl_listener *listener, void *data) { 207static void handle_destroy(struct wl_listener *listener, void *data) {
@@ -226,14 +238,6 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {
226 // - Look up pid and open on appropriate workspace 238 // - Look up pid and open on appropriate workspace
227 // - Criteria 239 // - Criteria
228 240
229 xdg_shell_v6_view->commit.notify = handle_commit;
230 wl_signal_add(&xdg_surface->surface->events.commit,
231 &xdg_shell_v6_view->commit);
232
233 xdg_shell_v6_view->new_popup.notify = handle_new_popup;
234 wl_signal_add(&xdg_surface->events.new_popup,
235 &xdg_shell_v6_view->new_popup);
236
237 xdg_shell_v6_view->map.notify = handle_map; 241 xdg_shell_v6_view->map.notify = handle_map;
238 wl_signal_add(&xdg_surface->events.map, &xdg_shell_v6_view->map); 242 wl_signal_add(&xdg_surface->events.map, &xdg_shell_v6_view->map);
239 243