aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dwyer <ryandwyer1@gmail.com>2018-06-18 20:42:12 +1000
committerRyan Dwyer <ryandwyer1@gmail.com>2018-06-18 20:42:12 +1000
commit1c89f32533534f6e78c81c95578f40df45bb9016 (patch)
tree98ba154e1cbd5148e9b7178037c26a3dadcec839
parent645bf446fab8db581b04babb1a34aa3c40428058 (diff)
Preserve buffers during transactions
* Also fix parts of the rendering where it was rendering the pending state instead of current.
-rw-r--r--include/sway/tree/view.h9
-rw-r--r--sway/desktop/output.c101
-rw-r--r--sway/desktop/transaction.c28
-rw-r--r--sway/desktop/xwayland.c2
-rw-r--r--sway/tree/container.c3
5 files changed, 76 insertions, 67 deletions
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index d0093db5..fc4c8df9 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -72,10 +72,11 @@ struct sway_view {
list_t *marks; // char *
list_t *instructions; // struct sway_transaction_instruction *
- // If saved_texture is set, the main surface of the view will render this
- // texture instead of its own. This is used while waiting for transactions
- // to complete.
- struct wlr_texture *saved_texture;
+ // If saved_buffer is set, the main surface of the view will render this
+ // buffer/texture instead of its own. This is used while waiting for
+ // transactions to complete.
+ struct wlr_buffer *saved_buffer;
+ int saved_surface_width, saved_surface_height;
struct wlr_texture *marks_focused;
struct wlr_texture *marks_focused_inactive;
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 37528cac..a485cb10 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -6,6 +6,7 @@
#include <wayland-server.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_box.h>
+#include <wlr/types/wlr_buffer.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_output_layout.h>
@@ -112,8 +113,8 @@ static bool get_surface_box(struct root_geometry *geo,
static bool get_view_box(struct root_geometry *geo,
struct sway_output *output, struct sway_view *view, int sx, int sy,
struct wlr_box *surface_box) {
- int sw = view->width;
- int sh = view->height;
+ int sw = view->saved_surface_width;
+ int sh = view->saved_surface_height;
double _sx = sx, _sy = sy;
rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height,
@@ -157,10 +158,10 @@ static void output_view_for_each_surface(struct sway_view *view,
struct root_geometry *geo, wlr_surface_iterator_func_t iterator,
void *user_data) {
struct render_data *data = user_data;
- geo->x = view->x - data->output->swayc->x;
- geo->y = view->y - data->output->swayc->y;
- geo->width = view->surface->current->width;
- geo->height = view->surface->current->height;
+ geo->x = view->swayc->current.view_x - data->output->swayc->x;
+ geo->y = view->swayc->current.view_y - data->output->swayc->y;
+ geo->width = view->swayc->current.view_width;
+ geo->height = view->swayc->current.view_height;
geo->rotation = 0; // TODO
view_for_each_surface(view, iterator, user_data);
@@ -277,11 +278,11 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy,
struct wlr_box box;
bool intersects;
- // If this is the main surface of a view, render the saved_texture instead
+ // If this is the main surface of a view, render the saved_buffer instead
// if it exists. It exists when we are mid-transaction.
- if (data->view && data->view->saved_texture &&
+ if (data->view && data->view->saved_buffer &&
data->view->surface == surface) {
- texture = data->view->saved_texture;
+ texture = data->view->saved_buffer->texture;
intersects = get_view_box(&data->root_geo, data->output, data->view,
sx, sy, &box);
} else {
@@ -405,46 +406,46 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
float output_scale = output->wlr_output->scale;
float color[4];
- if (view->border != B_NONE) {
- if (view->border_left) {
+ if (con->current.border != B_NONE) {
+ if (con->current.border_left) {
memcpy(&color, colors->child_border, sizeof(float) * 4);
premultiply_alpha(color, con->alpha);
- box.x = con->x;
- box.y = view->y;
- box.width = view->border_thickness;
- box.height = view->height;
+ box.x = con->current.swayc_x;
+ box.y = con->current.view_y;
+ box.width = con->current.border_thickness;
+ box.height = con->current.view_height;
scale_box(&box, output_scale);
render_rect(output->wlr_output, damage, &box, color);
}
- if (view->border_right) {
+ if (con->current.border_right) {
if (con->parent->children->length == 1
- && con->parent->layout == L_HORIZ) {
+ && con->parent->current.layout == L_HORIZ) {
memcpy(&color, colors->indicator, sizeof(float) * 4);
} else {
memcpy(&color, colors->child_border, sizeof(float) * 4);
}
premultiply_alpha(color, con->alpha);
- box.x = view->x + view->width;
- box.y = view->y;
- box.width = view->border_thickness;
- box.height = view->height;
+ box.x = con->current.view_x + con->current.view_width;
+ box.y = con->current.view_y;
+ box.width = con->current.border_thickness;
+ box.height = con->current.view_height;
scale_box(&box, output_scale);
render_rect(output->wlr_output, damage, &box, color);
}
- if (view->border_bottom) {
+ if (con->current.border_bottom) {
if (con->parent->children->length == 1
- && con->parent->layout == L_VERT) {
+ && con->parent->current.layout == L_VERT) {
memcpy(&color, colors->indicator, sizeof(float) * 4);
} else {
memcpy(&color, colors->child_border, sizeof(float) * 4);
}
premultiply_alpha(color, con->alpha);
- box.x = con->x;
- box.y = view->y + view->height;
- box.width = con->width;
- box.height = view->border_thickness;
+ box.x = con->current.swayc_x;
+ box.y = con->current.view_y + con->current.view_height;
+ box.width = con->current.swayc_width;
+ box.height = con->current.border_thickness;
scale_box(&box, output_scale);
render_rect(output->wlr_output, damage, &box, color);
}
@@ -468,9 +469,8 @@ static void render_titlebar(struct sway_output *output,
struct wlr_texture *marks_texture) {
struct wlr_box box;
float color[4];
- struct sway_view *view = con->type == C_VIEW ? con->sway_view : NULL;
float output_scale = output->wlr_output->scale;
- enum sway_container_layout layout = con->parent->layout;
+ enum sway_container_layout layout = con->parent->current.layout;
bool is_last_child =
con->parent->children->items[con->parent->children->length - 1] == con;
@@ -489,9 +489,11 @@ static void render_titlebar(struct sway_output *output,
bool connects_sides = false;
if (layout == L_HORIZ || layout == L_VERT ||
(layout == L_STACKED && is_last_child)) {
- if (view) {
- left_offset = view->border_left * view->border_thickness;
- right_offset = view->border_right * view->border_thickness;
+ if (con->type == C_VIEW) {
+ left_offset =
+ con->current.border_left * con->current.border_thickness;
+ right_offset =
+ con->current.border_right * con->current.border_thickness;
connects_sides = true;
}
}
@@ -612,15 +614,16 @@ static void render_titlebar(struct sway_output *output,
// Left pixel in line with bottom bar
box.x = x;
box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS;
- box.width = view->border_thickness * view->border_left;
+ box.width = con->current.border_thickness * con->current.border_left;
box.height = TITLEBAR_BORDER_THICKNESS;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
// Right pixel in line with bottom bar
- box.x = x + width - view->border_thickness * view->border_right;
+ box.x = x + width -
+ con->current.border_thickness * con->current.border_right;
box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS;
- box.width = view->border_thickness * view->border_right;
+ box.width = con->current.border_thickness * con->current.border_right;
box.height = TITLEBAR_BORDER_THICKNESS;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
@@ -633,8 +636,7 @@ static void render_titlebar(struct sway_output *output,
static void render_top_border(struct sway_output *output,
pixman_region32_t *output_damage, struct sway_container *con,
struct border_colors *colors) {
- struct sway_view *view = con->sway_view;
- if (!view->border_top) {
+ if (!con->current.border_top) {
return;
}
struct wlr_box box;
@@ -644,10 +646,10 @@ static void render_top_border(struct sway_output *output,
// Child border - top edge
memcpy(&color, colors->child_border, sizeof(float) * 4);
premultiply_alpha(color, con->alpha);
- box.x = con->x;
- box.y = con->y;
- box.width = con->width;
- box.height = view->border_thickness;
+ box.x = con->current.swayc_x;
+ box.y = con->current.swayc_y;
+ box.width = con->current.swayc_width;
+ box.height = con->current.border_thickness;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
}
@@ -688,9 +690,10 @@ static void render_container_simple(struct sway_output *output,
marks_texture = child->sway_view->marks_unfocused;
}
- if (child->sway_view->border == B_NORMAL) {
- render_titlebar(output, damage, child, child->x, child->y,
- child->width, colors, title_texture, marks_texture);
+ if (child->current.border == B_NORMAL) {
+ render_titlebar(output, damage, child, child->current.swayc_x,
+ child->current.swayc_y, child->current.swayc_width,
+ colors, title_texture, marks_texture);
} else {
render_top_border(output, damage, child, colors);
}
@@ -739,15 +742,15 @@ static void render_container_tabbed(struct sway_output *output,
marks_texture = view ? view->marks_unfocused : NULL;
}
- int tab_width = con->width / con->children->length;
- int x = con->x + tab_width * i;
+ int tab_width = con->current.swayc_width / con->children->length;
+ int x = con->current.swayc_x + tab_width * i;
// Make last tab use the remaining width of the parent
if (i == con->children->length - 1) {
- tab_width = con->width - tab_width * i;
+ tab_width = con->current.swayc_width - tab_width * i;
}
- render_titlebar(output, damage, child, x, child->y, tab_width, colors,
- title_texture, marks_texture);
+ render_titlebar(output, damage, child, x, child->current.swayc_y,
+ tab_width, colors, title_texture, marks_texture);
if (child == current) {
current_colors = colors;
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index 07bfbf7a..77377a18 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -2,6 +2,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
+#include <wlr/types/wlr_buffer.h>
#include <wlr/types/wlr_linux_dmabuf.h>
#include "sway/debug.h"
#include "sway/desktop/transaction.h"
@@ -112,16 +113,23 @@ void transaction_add_damage(struct sway_transaction *transaction,
list_add(transaction->damage, box);
}
-static void save_view_texture(struct sway_view *view) {
- wlr_texture_destroy(view->saved_texture);
- view->saved_texture = NULL;
-
- // TODO: Copy the texture and store it in view->saved_texture.
+static void save_view_buffer(struct sway_view *view) {
+ if (view->saved_buffer) {
+ wlr_buffer_unref(view->saved_buffer);
+ }
+ wlr_buffer_ref(view->surface->buffer);
+ view->saved_buffer = view->surface->buffer;
+ view->saved_surface_width = view->surface->current->width;
+ view->saved_surface_height = view->surface->current->height;
}
-static void remove_saved_view_texture(struct sway_view *view) {
- wlr_texture_destroy(view->saved_texture);
- view->saved_texture = NULL;
+static void remove_saved_view_buffer(struct sway_view *view) {
+ if (view->saved_buffer) {
+ wlr_buffer_unref(view->saved_buffer);
+ view->saved_buffer = NULL;
+ view->saved_surface_width = 0;
+ view->saved_surface_height = 0;
+ }
}
/**
@@ -141,7 +149,7 @@ static void transaction_apply(struct sway_transaction *transaction) {
sizeof(struct sway_container_state));
if (container->type == C_VIEW) {
- remove_saved_view_texture(container->sway_view);
+ remove_saved_view_buffer(container->sway_view);
}
}
@@ -183,7 +191,7 @@ void transaction_commit(struct sway_transaction *transaction) {
instruction->state.view_width,
instruction->state.view_height);
if (instruction->serial) {
- save_view_texture(con->sway_view);
+ save_view_buffer(con->sway_view);
list_add(con->sway_view->instructions, instruction);
++transaction->num_waiting;
}
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 70929d48..55917bf6 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -261,8 +261,8 @@ static void handle_commit(struct wl_listener *listener, void *data) {
view_update_size(view, view->swayc->width, view->swayc->height);
}
view_update_position(view, view->x, view->y);
- view_damage_from(view);
}
+ view_damage_from(view);
}
static void handle_unmap(struct wl_listener *listener, void *data) {
diff --git a/sway/tree/container.c b/sway/tree/container.c
index f8620b72..b071f394 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -766,9 +766,6 @@ static void update_title_texture(struct sway_container *con,
"Unexpected type %s", container_type_to_str(con->type))) {
return;
}
- if (!con->width) {
- return;
- }
struct sway_container *output = container_parent(con, C_OUTPUT);
if (!output) {
return;