view: add view damage tracking

This commit is contained in:
Jente Hidskes 2020-07-03 22:27:34 +02:00
parent 79b81263f4
commit 5feeb33505
No known key found for this signature in database
GPG key ID: 04BE5A29F32D91EA
3 changed files with 58 additions and 0 deletions

View file

@ -12,8 +12,10 @@
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <wlr/types/wlr_surface.h> #include <wlr/types/wlr_surface.h>
#include <wlr/util/region.h>
#include "output.h" #include "output.h"
#include "util.h"
#include "view.h" #include "view.h"
static bool static bool
@ -64,6 +66,31 @@ cage_view_position(struct cg_view *view)
} }
} }
static void
damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, void *user_data)
{
struct cg_view *view = (struct cg_view *) surface->data;
struct cg_output *output = view->output;
struct wlr_output *wlr_output = output->wlr_output;
if (pixman_region32_not_empty(&surface->buffer_damage)) {
pixman_region32_t damage;
pixman_region32_init(&damage);
wlr_surface_get_effective_damage(surface, &damage);
wlr_region_scale(&damage, &damage, wlr_output->scale);
if (ceil(wlr_output->scale) > surface->current.scale) {
/* When scaling up a surface it'll become
blurry, so we need to expand the damage
region. */
wlr_region_expand(&damage, &damage, ceil(wlr_output->scale) - surface->current.scale);
}
pixman_region32_translate(&damage, sx, sy);
wlr_output_damage_add(output->damage, &damage);
pixman_region32_fini(&damage);
}
}
void void
cage_view_for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *user_data) cage_view_for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *user_data)
{ {
@ -85,6 +112,27 @@ cage_view_get_title(struct cg_view *view)
return strndup(title, strlen(title)); return strndup(title, strlen(title));
} }
void
cage_view_damage_whole(struct cg_view *view)
{
assert(view != NULL);
assert(view->impl->get_geometry != NULL);
struct cg_output *output = view->output;
struct wlr_box box = {0};
view->impl->get_geometry(view, &box.width, &box.height);
scale_box(&box, output->wlr_output->scale);
cage_output_damage_region(output, &box);
}
void
cage_view_damage_part(struct cg_view *view)
{
assert(view != NULL);
cage_view_for_each_surface(view, damage_surface_iterator, NULL);
}
void void
cage_view_activate(struct cg_view *view, bool activate) cage_view_activate(struct cg_view *view, bool activate)
{ {
@ -111,6 +159,7 @@ cage_view_unmap(struct cg_view *view)
wl_list_remove(&view->link); wl_list_remove(&view->link);
wl_list_init(&view->link); wl_list_init(&view->link);
view->wlr_surface->data = NULL;
view->wlr_surface = NULL; view->wlr_surface = NULL;
assert(!cage_view_is_mapped(view)); assert(!cage_view_is_mapped(view));
@ -124,6 +173,7 @@ cage_view_map(struct cg_view *view, struct wlr_surface *surface)
assert(!cage_view_is_mapped(view)); assert(!cage_view_is_mapped(view));
view->wlr_surface = surface; view->wlr_surface = surface;
surface->data = view;
wl_list_insert(&view->output->views, &view->link); wl_list_insert(&view->output->views, &view->link);
cage_view_position(view); cage_view_position(view);

View file

@ -80,6 +80,8 @@ bool cage_view_is_primary(struct cg_view *view);
void cage_view_position(struct cg_view *view); void cage_view_position(struct cg_view *view);
void cage_view_for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *user_data); void cage_view_for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *user_data);
char *cage_view_get_title(struct cg_view *view); char *cage_view_get_title(struct cg_view *view);
void cage_view_damage_whole(struct cg_view *view);
void cage_view_damage_part(struct cg_view *view);
void cage_view_activate(struct cg_view *view, bool activate); void cage_view_activate(struct cg_view *view, bool activate);
bool cage_view_is_mapped(struct cg_view *view); bool cage_view_is_mapped(struct cg_view *view);
void cage_view_unmap(struct cg_view *view); void cage_view_unmap(struct cg_view *view);

View file

@ -81,6 +81,8 @@ handle_xdg_shell_surface_unmap(struct wl_listener *listener, void *user_data)
assert(cage_view_is_mapped(view)); assert(cage_view_is_mapped(view));
cage_view_damage_whole(view);
wl_list_remove(&xdg_shell_view->commit.link); wl_list_remove(&xdg_shell_view->commit.link);
wl_list_remove(&xdg_shell_view->request_fullscreen.link); wl_list_remove(&xdg_shell_view->request_fullscreen.link);
@ -100,6 +102,9 @@ handle_xdg_shell_surface_request_fullscreen(struct wl_listener *listener, void *
static void static void
handle_xdg_shell_surface_commit(struct wl_listener *listener, void *user_data) handle_xdg_shell_surface_commit(struct wl_listener *listener, void *user_data)
{ {
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, commit);
struct cg_view *view = &xdg_shell_view->view;
cage_view_damage_part(view);
} }
static void static void
@ -137,6 +142,7 @@ handle_xdg_shell_surface_map(struct wl_listener *listener, void *user_data)
cage_view_map(view, xdg_shell_view->xdg_surface->surface); cage_view_map(view, xdg_shell_view->xdg_surface->surface);
cage_view_damage_whole(view);
assert(cage_view_is_mapped(view)); assert(cage_view_is_mapped(view));
} }