Skip to content
This repository has been archived by the owner on Nov 1, 2021. It is now read-only.

surface: redesign state #1076

Merged
merged 14 commits into from
Jul 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 70 additions & 44 deletions include/wlr/types/wlr_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,57 +8,32 @@
#include <wayland-server.h>
#include <wlr/types/wlr_output.h>

#define WLR_SURFACE_INVALID_BUFFER 1
#define WLR_SURFACE_INVALID_SURFACE_DAMAGE 2
#define WLR_SURFACE_INVALID_BUFFER_DAMAGE 4
#define WLR_SURFACE_INVALID_OPAQUE_REGION 8
#define WLR_SURFACE_INVALID_INPUT_REGION 16
#define WLR_SURFACE_INVALID_TRANSFORM 32
#define WLR_SURFACE_INVALID_SCALE 64
#define WLR_SURFACE_INVALID_SUBSURFACE_POSITION 128
#define WLR_SURFACE_INVALID_FRAME_CALLBACK_LIST 256
enum wlr_surface_state_field {
WLR_SURFACE_STATE_BUFFER = 1,
WLR_SURFACE_STATE_SURFACE_DAMAGE = 2,
WLR_SURFACE_STATE_BUFFER_DAMAGE = 4,
WLR_SURFACE_STATE_OPAQUE_REGION = 8,
WLR_SURFACE_STATE_INPUT_REGION = 16,
WLR_SURFACE_STATE_TRANSFORM = 32,
WLR_SURFACE_STATE_SCALE = 64,
WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 128,
};

struct wlr_surface_state {
uint32_t invalid;
struct wl_resource *buffer;
struct wl_listener buffer_destroy_listener;
int32_t sx, sy;
uint32_t committed; // enum wlr_surface_state_field

struct wl_resource *buffer_resource;
int32_t dx, dy; // relative to previous position
pixman_region32_t surface_damage, buffer_damage;
pixman_region32_t opaque, input;
enum wl_output_transform transform;
int32_t scale;
int width, height;
int buffer_width, buffer_height;

struct {
int32_t x, y;
} subsurface_position;

struct wl_list frame_callback_list; // wl_surface.frame
};

struct wlr_subsurface {
struct wl_resource *resource;
struct wlr_surface *surface;
struct wlr_surface *parent;

struct wlr_surface_state *cached;
bool has_cache;

bool synchronized;
bool reordered;

struct wl_list parent_link;
struct wl_list parent_pending_link;

struct wl_listener surface_destroy;
struct wl_listener parent_destroy;
struct wl_list frame_callback_list; // wl_resource

struct {
struct wl_signal destroy;
} events;
int width, height; // in surface-local coordinates
int buffer_width, buffer_height;

void *data;
struct wl_listener buffer_destroy;
};

struct wlr_surface {
Expand All @@ -71,7 +46,28 @@ struct wlr_surface {
* or something went wrong with uploading the buffer.
*/
struct wlr_buffer *buffer;
struct wlr_surface_state *current, *pending;
/**
* The buffer position, in surface-local units.
*/
int sx, sy;
/**
* The last commit's buffer damage, in buffer-local coordinates. This
* contains both the damage accumulated by the client via
* `wlr_surface_state.surface_damage` and `wlr_surface_state.buffer_damage`.
* If the buffer has changed its size or moved, the whole buffer is
* damaged.
*
* This region needs to be scaled and transformed into output coordinates,
* just like the buffer's texture.
*/
pixman_region32_t buffer_damage;
/**
* `current` contains the current, committed surface state. `pending`
* accumulates state changes from the client between commits and shouldn't
* be accessed by the compositor directly. `previous` contains the state of
* the previous commit.
*/
struct wlr_surface_state current, pending, previous;
const char *role; // the lifetime-bound role or null

struct {
Expand All @@ -94,6 +90,36 @@ struct wlr_surface {
void *data;
};

struct wlr_subsurface_state {
int32_t x, y;
};

struct wlr_subsurface {
struct wl_resource *resource;
struct wlr_surface *surface;
struct wlr_surface *parent;

struct wlr_subsurface_state current, pending;

struct wlr_surface_state cached;
bool has_cache;

bool synchronized;
bool reordered;

struct wl_list parent_link;
struct wl_list parent_pending_link;

struct wl_listener surface_destroy;
struct wl_listener parent_destroy;

struct {
struct wl_signal destroy;
} events;

void *data;
};

typedef void (*wlr_surface_iterator_func_t)(struct wlr_surface *surface,
int sx, int sy, void *data);

Expand Down
8 changes: 4 additions & 4 deletions rootston/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ static void roots_cursor_update_position(
case ROOTS_CURSOR_ROTATE:
view = roots_seat_get_focus(seat);
if (view != NULL) {
int ox = view->x + view->wlr_surface->current->width/2,
oy = view->y + view->wlr_surface->current->height/2;
int ox = view->x + view->wlr_surface->current.width/2,
oy = view->y + view->wlr_surface->current.height/2;
int ux = cursor->offs_x - ox,
uy = cursor->offs_y - oy;
int vx = cursor->cursor->x - ox,
Expand Down Expand Up @@ -239,12 +239,12 @@ static void roots_cursor_press_button(struct roots_cursor *cursor,
break;
case BTN_RIGHT:
edges = 0;
if (sx < view->wlr_surface->current->width/2) {
if (sx < view->wlr_surface->current.width/2) {
edges |= WLR_EDGE_LEFT;
} else {
edges |= WLR_EDGE_RIGHT;
}
if (sy < view->wlr_surface->current->height/2) {
if (sy < view->wlr_surface->current.height/2) {
edges |= WLR_EDGE_TOP;
} else {
edges |= WLR_EDGE_BOTTOM;
Expand Down
6 changes: 3 additions & 3 deletions rootston/desktop.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ enum roots_deco_part view_get_deco_part(struct roots_view *view, double sx,
return ROOTS_DECO_PART_NONE;
}

int sw = view->wlr_surface->current->width;
int sh = view->wlr_surface->current->height;
int sw = view->wlr_surface->current.width;
int sh = view->wlr_surface->current.height;
int bw = view->border_width;
int titlebar_h = view->titlebar_height;

Expand Down Expand Up @@ -558,7 +558,7 @@ static bool view_at(struct roots_view *view, double lx, double ly,
double view_sx = lx - view->x;
double view_sy = ly - view->y;

struct wlr_surface_state *state = view->wlr_surface->current;
struct wlr_surface_state *state = &view->wlr_surface->current;
struct wlr_box box = {
.x = 0, .y = 0,
.width = state->width, .height = state->height,
Expand Down
41 changes: 25 additions & 16 deletions rootston/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ struct layout_data {
static void get_layout_position(struct layout_data *data, double *lx, double *ly,
const struct wlr_surface *surface, int sx, int sy) {
double _sx = sx, _sy = sy;
rotate_child_position(&_sx, &_sy, surface->current->width,
surface->current->height, data->width, data->height, data->rotation);
rotate_child_position(&_sx, &_sy, surface->current.width,
surface->current.height, data->width, data->height, data->rotation);
*lx = data->x + _sx;
*ly = data->y + _sy;
}
Expand All @@ -55,8 +55,8 @@ static void surface_for_each_surface(struct wlr_surface *surface,
wlr_surface_iterator_func_t iterator, void *user_data) {
layout_data->x = lx;
layout_data->y = ly;
layout_data->width = surface->current->width;
layout_data->height = surface->current->height;
layout_data->width = surface->current.width;
layout_data->height = surface->current.height;
layout_data->rotation = rotation;

wlr_surface_for_each_surface(surface, iterator, user_data);
Expand All @@ -67,8 +67,8 @@ static void view_for_each_surface(struct roots_view *view,
void *user_data) {
layout_data->x = view->x;
layout_data->y = view->y;
layout_data->width = view->wlr_surface->current->width;
layout_data->height = view->wlr_surface->current->height;
layout_data->width = view->wlr_surface->current.width;
layout_data->height = view->wlr_surface->current.height;
layout_data->rotation = view->rotation;

switch (view->type) {
Expand Down Expand Up @@ -146,16 +146,19 @@ static bool surface_intersect_output(struct wlr_surface *surface,
double ox = lx, oy = ly;
wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy);

ox += surface->sx;
oy += surface->sy;

if (box != NULL) {
box->x = ox * wlr_output->scale;
box->y = oy * wlr_output->scale;
box->width = surface->current->width * wlr_output->scale;
box->height = surface->current->height * wlr_output->scale;
box->width = surface->current.width * wlr_output->scale;
box->height = surface->current.height * wlr_output->scale;
}

struct wlr_box layout_box = {
.x = lx, .y = ly,
.width = surface->current->width, .height = surface->current->height,
.width = surface->current.width, .height = surface->current.height,
};
wlr_box_rotated_bounds(&layout_box, rotation, &layout_box);
return wlr_output_layout_intersects(output_layout, wlr_output, &layout_box);
Expand Down Expand Up @@ -223,7 +226,7 @@ static void render_surface(struct wlr_surface *surface, int sx, int sy,

float matrix[9];
enum wl_output_transform transform =
wlr_output_transform_invert(surface->current->transform);
wlr_output_transform_invert(surface->current.transform);
wlr_matrix_project_box(matrix, &box, transform, rotation,
output->wlr_output->transform_matrix);

Expand All @@ -247,8 +250,8 @@ static void get_decoration_box(struct roots_view *view,
double sx = deco_box.x - view->x;
double sy = deco_box.y - view->y;
rotate_child_position(&sx, &sy, deco_box.width, deco_box.height,
view->wlr_surface->current->width,
view->wlr_surface->current->height, view->rotation);
view->wlr_surface->current.width,
view->wlr_surface->current.height, view->rotation);
double x = sx + view->x;
double y = sy + view->y;

Expand Down Expand Up @@ -692,15 +695,21 @@ static void damage_from_surface(struct wlr_surface *surface, int sx, int sy,
int center_x = box.x + box.width/2;
int center_y = box.y + box.height/2;

enum wl_output_transform transform =
wlr_output_transform_invert(surface->current.transform);

pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_copy(&damage, &surface->current->surface_damage);
wlr_region_scale(&damage, &damage, wlr_output->scale);
if (ceil(wlr_output->scale) > surface->current->scale) {
pixman_region32_copy(&damage, &surface->buffer_damage);
wlr_region_transform(&damage, &damage, transform,
surface->current.buffer_width, surface->current.buffer_height);
wlr_region_scale(&damage, &damage,
wlr_output->scale / (float)surface->current.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);
ceil(wlr_output->scale) - surface->current.scale);
}
pixman_region32_translate(&damage, box.x, box.y);
wlr_region_rotated_bounds(&damage, &damage, rotation, center_x, center_y);
Expand Down
8 changes: 4 additions & 4 deletions rootston/wl_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) {

view_apply_damage(view);

int width = wlr_surface->current->width;
int height = wlr_surface->current->height;
int width = wlr_surface->current.width;
int height = wlr_surface->current.height;
view_update_size(view, width, height);

double x = view->x;
Expand Down Expand Up @@ -236,8 +236,8 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
return;
}
view->type = ROOTS_WL_SHELL_VIEW;
view->width = surface->surface->current->width;
view->height = surface->surface->current->height;
view->width = surface->surface->current.width;
view->height = surface->surface->current.height;

view->wl_shell_surface = surface;
view->roots_wl_shell_surface = roots_surface;
Expand Down
8 changes: 4 additions & 4 deletions rootston/xwayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) {

view_apply_damage(view);

int width = wlr_surface->current->width;
int height = wlr_surface->current->height;
int width = wlr_surface->current.width;
int height = wlr_surface->current.height;
view_update_size(view, width, height);

double x = view->x;
Expand All @@ -233,8 +233,8 @@ static void handle_map(struct wl_listener *listener, void *data) {

view->x = surface->x;
view->y = surface->y;
view->width = surface->surface->current->width;
view->height = surface->surface->current->height;
view->width = surface->surface->current.width;
view->height = surface->surface->current.height;

roots_surface->surface_commit.notify = handle_surface_commit;
wl_signal_add(&surface->surface->events.commit,
Expand Down
4 changes: 2 additions & 2 deletions types/data_device/wlr_drag.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,8 @@ static void drag_icon_handle_surface_destroy(struct wl_listener *listener,
static void drag_icon_handle_surface_commit(struct wlr_surface *surface,
void *role_data) {
struct wlr_drag_icon *icon = role_data;
icon->sx += icon->surface->current->sx;
icon->sy += icon->surface->current->sy;
icon->sx += icon->surface->current.dx;
icon->sy += icon->surface->current.dy;

drag_icon_set_mapped(icon, wlr_surface_has_buffer(surface));
}
Expand Down
Loading