aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_surface.h31
-rw-r--r--types/wlr_surface.c66
2 files changed, 74 insertions, 23 deletions
diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h
index 2bfd5d36..b80b1de4 100644
--- a/include/wlr/types/wlr_surface.h
+++ b/include/wlr/types/wlr_surface.h
@@ -1,21 +1,40 @@
#ifndef _WLR_TYPES_WLR_SURFACE_H
#define _WLR_TYPES_WLR_SURFACE_H
-
#include <wayland-server.h>
+#include <pixman.h>
+#include <stdint.h>
struct wlr_frame_callback {
struct wl_resource *resource;
struct wl_list link;
};
-struct wlr_surface {
- struct wl_resource *pending_buffer;
- bool pending_attached;
- bool attached; // whether the surface currently has a buffer attached
+#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 16
+#define WLR_SURFACE_INVALID_SCALE 16
+
+struct wlr_surface_state {
+ uint32_t invalid;
+ struct wl_resource *buffer;
+ int32_t sx, sy;
+ pixman_region32_t surface_damage, buffer_damage;
+ pixman_region32_t opaque, input;
+ uint32_t transform;
+ int32_t scale;
+};
+struct wlr_surface {
+ struct wl_resource *resource;
struct wlr_texture *texture;
+ struct wlr_surface_state current, pending;
const char *role; // the lifetime-bound role or null
- struct wl_resource *resource;
+
+ float buffer_to_surface_matrix[16];
+ float surface_to_buffer_matrix[16];
struct {
struct wl_signal destroy;
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 90f22a17..ee57a05d 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -13,19 +13,25 @@ static void surface_attach(struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *buffer, int32_t sx, int32_t sy) {
struct wlr_surface *surface = wl_resource_get_user_data(resource);
- surface->pending_buffer = buffer;
- surface->pending_attached = true;
+ surface->pending.invalid |= WLR_SURFACE_INVALID_BUFFER;
+ surface->pending.buffer = buffer;
}
static void surface_damage(struct wl_client *client,
struct wl_resource *resource,
int32_t x, int32_t y, int32_t width, int32_t height) {
- wlr_log(L_DEBUG, "damage: %dx%d@%d,%d", width, height, x, y);
+ struct wlr_surface *surface = wl_resource_get_user_data(resource);
+ if (width < 0 || height < 0) {
+ return;
+ }
+ surface->pending.invalid |= WLR_SURFACE_INVALID_SURFACE_DAMAGE;
+ pixman_region32_union_rect(&surface->pending.surface_damage,
+ &surface->pending.surface_damage,
+ x, y, width, height);
}
static void destroy_frame_callback(struct wl_resource *resource) {
struct wlr_frame_callback *cb = wl_resource_get_user_data(resource);
-
wl_list_remove(&cb->link);
free(cb);
}
@@ -58,38 +64,65 @@ static void surface_frame(struct wl_client *client,
static void surface_set_opaque_region(struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *region_resource) {
- wlr_log(L_DEBUG, "TODO: surface opaque region");
+ struct wlr_surface *surface = wl_resource_get_user_data(resource);
+ surface->pending.invalid |= WLR_SURFACE_INVALID_OPAQUE_REGION;
+ if (region_resource) {
+ pixman_region32_t *region = wl_resource_get_user_data(region_resource);
+ pixman_region32_copy(&surface->pending.opaque, region);
+ } else {
+ pixman_region32_clear(&surface->pending.opaque);
+ }
}
static void surface_set_input_region(struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *region_resource) {
- wlr_log(L_DEBUG, "TODO: surface input region");
+ struct wlr_surface *surface = wl_resource_get_user_data(resource);
+ surface->pending.invalid |= WLR_SURFACE_INVALID_INPUT_REGION;
+ if (region_resource) {
+ pixman_region32_t *region = wl_resource_get_user_data(region_resource);
+ pixman_region32_copy(&surface->pending.input, region);
+ } else {
+ pixman_region32_fini(&surface->pending.input);
+ pixman_region32_init_rect(&surface->pending.input,
+ INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
+ }
}
static void surface_commit(struct wl_client *client,
struct wl_resource *resource) {
struct wlr_surface *surface = wl_resource_get_user_data(resource);
- // apply pending state
- if (surface->pending_attached) {
- surface->attached = surface->pending_buffer;
- if (surface->pending_buffer) {
- struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->pending_buffer);
+ if ((surface->pending.invalid & WLR_SURFACE_INVALID_BUFFER)) {
+ surface->current.buffer = surface->pending.buffer;
+ // TODO: Move to wlr_surface_flush_damage and call from output frame
+ // callbacks instead of immediately here
+ if (surface->current.buffer) {
+ struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current.buffer);
if (!buffer) {
wlr_log(L_INFO, "Unknown buffer handle attached");
} else {
uint32_t format = wl_shm_buffer_get_format(buffer);
wlr_texture_upload_shm(surface->texture, format, buffer);
- wl_resource_queue_event(surface->pending_buffer, WL_BUFFER_RELEASE);
+ wl_resource_queue_event(surface->current.buffer, WL_BUFFER_RELEASE);
}
}
}
+ if ((surface->pending.invalid & WLR_SURFACE_INVALID_SURFACE_DAMAGE)) {
+ // TODO: Sort out buffer damage too
+ pixman_region32_union(&surface->current.surface_damage,
+ &surface->current.surface_damage,
+ &surface->pending.surface_damage);
+ // TODO: Surface sizing is complicated
+ //pixman_region32_intersect_rect(&surface->current.surface_damage,
+ // &surface->current.surface_damage,
+ // 0, 0, surface->width, surface->height);
+ pixman_region32_clear(&surface->pending.surface_damage);
+ }
+ // TODO: Commit other changes
- // reset pending state
- surface->pending_buffer = NULL;
- surface->pending_attached = false;
-
+ surface->pending.invalid = 0;
+ // TODO: add the invalid bitfield to this callback
wl_signal_emit(&surface->signals.commit, surface);
}
@@ -104,7 +137,6 @@ static void surface_set_buffer_scale(struct wl_client *client,
wlr_log(L_DEBUG, "TODO: surface set buffer scale");
}
-
static void surface_damage_buffer(struct wl_client *client,
struct wl_resource *resource,
int32_t x, int32_t y, int32_t width,