aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVersus Void <versusvoid@gmail.com>2017-10-10 11:18:38 +0300
committerVersus Void <versusvoid@gmail.com>2017-10-10 11:18:38 +0300
commita6db47196cabc12fed4824b3532c1f9b14b43c8e (patch)
treede2caae3fabe3dbcdd13ad8a774ca5c1f5ab4bcb
parentc39bfe7f84818be9d9901e30ba26db9e8f19c47e (diff)
Upload texture on surface commit
-rw-r--r--include/wlr/types/wlr_surface.h2
-rw-r--r--rootston/output.c1
-rw-r--r--types/wlr_surface.c98
3 files changed, 50 insertions, 51 deletions
diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h
index 03376788..461e593f 100644
--- a/include/wlr/types/wlr_surface.h
+++ b/include/wlr/types/wlr_surface.h
@@ -66,7 +66,6 @@ struct wlr_surface {
float buffer_to_surface_matrix[16];
float surface_to_buffer_matrix[16];
- bool reupload_buffer;
struct {
struct wl_signal commit;
@@ -89,7 +88,6 @@ struct wlr_surface {
struct wlr_renderer;
struct wlr_surface *wlr_surface_create(struct wl_resource *res,
struct wlr_renderer *renderer);
-void wlr_surface_flush_damage(struct wlr_surface *surface);
/**
* Gets a matrix you can pass into wlr_render_with_matrix to display this
* surface. `matrix` is the output matrix, `projection` is the wlr_output
diff --git a/rootston/output.c b/rootston/output.c
index 6c7fbf51..d1b2c7de 100644
--- a/rootston/output.c
+++ b/rootston/output.c
@@ -19,7 +19,6 @@ static inline int64_t timespec_to_msec(const struct timespec *a) {
static void render_surface(struct wlr_surface *surface,
struct roots_desktop *desktop, struct wlr_output *wlr_output,
struct timespec *when, double lx, double ly, float rotation) {
- wlr_surface_flush_damage(surface);
if (surface->texture->valid) {
int width = surface->current->buffer_width;
int height = surface->current->buffer_height;
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index ca7a9af5..f0cce8a7 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -345,6 +345,52 @@ static void wlr_surface_damage_subsurfaces(struct wlr_subsurface *subsurface) {
}
}
+static void wlr_surface_flush_damage(struct wlr_surface *surface,
+ bool reupload_buffer) {
+ if (!surface->current->buffer) {
+ return;
+ }
+ struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current->buffer);
+ if (!buffer) {
+ if (wlr_renderer_buffer_is_drm(surface->renderer,
+ surface->current->buffer)) {
+ wlr_texture_upload_drm(surface->texture, surface->current->buffer);
+ goto release;
+ } else {
+ wlr_log(L_INFO, "Unknown buffer handle attached");
+ return;
+ }
+ }
+
+ uint32_t format = wl_shm_buffer_get_format(buffer);
+ if (reupload_buffer) {
+ wlr_texture_upload_shm(surface->texture, format, buffer);
+ } else {
+ pixman_region32_t damage = surface->current->buffer_damage;
+ if (!pixman_region32_not_empty(&damage)) {
+ goto release;
+ }
+ int n;
+ pixman_box32_t *rects = pixman_region32_rectangles(&damage, &n);
+ for (int i = 0; i < n; ++i) {
+ pixman_box32_t rect = rects[i];
+ if (!wlr_texture_update_shm(surface->texture, format,
+ rect.x1, rect.y1,
+ rect.x2 - rect.x1,
+ rect.y2 - rect.y1,
+ buffer)) {
+ break;
+ }
+ }
+ }
+
+release:
+ pixman_region32_clear(&surface->current->surface_damage);
+ pixman_region32_clear(&surface->current->buffer_damage);
+
+ wlr_surface_state_release_buffer(surface->current);
+}
+
static void wlr_surface_commit_pending(struct wlr_surface *surface) {
int32_t oldw = surface->current->buffer_width;
int32_t oldh = surface->current->buffer_height;
@@ -359,6 +405,10 @@ static void wlr_surface_commit_pending(struct wlr_surface *surface) {
surface->texture->valid = false;
}
+ bool reupload_buffer = oldw != surface->current->buffer_width ||
+ oldh != surface->current->buffer_height;
+ wlr_surface_flush_damage(surface, reupload_buffer);
+
// commit subsurface order
struct wlr_subsurface *subsurface;
wl_list_for_each_reverse(subsurface, &surface->subsurface_pending_list,
@@ -372,9 +422,6 @@ static void wlr_surface_commit_pending(struct wlr_surface *surface) {
}
}
- surface->reupload_buffer = oldw != surface->current->buffer_width ||
- oldh != surface->current->buffer_height;
-
// TODO: add the invalid bitfield to this callback
wl_signal_emit(&surface->events.commit, surface);
}
@@ -459,51 +506,6 @@ static void surface_commit(struct wl_client *client,
}
}
-void wlr_surface_flush_damage(struct wlr_surface *surface) {
- if (!surface->current->buffer) {
- return;
- }
- struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current->buffer);
- if (!buffer) {
- if (wlr_renderer_buffer_is_drm(surface->renderer,
- surface->current->buffer)) {
- wlr_texture_upload_drm(surface->texture, surface->current->buffer);
- goto release;
- } else {
- wlr_log(L_INFO, "Unknown buffer handle attached");
- return;
- }
- }
-
- uint32_t format = wl_shm_buffer_get_format(buffer);
- if (surface->reupload_buffer) {
- wlr_texture_upload_shm(surface->texture, format, buffer);
- } else {
- pixman_region32_t damage = surface->current->buffer_damage;
- if (!pixman_region32_not_empty(&damage)) {
- goto release;
- }
- int n;
- pixman_box32_t *rects = pixman_region32_rectangles(&damage, &n);
- for (int i = 0; i < n; ++i) {
- pixman_box32_t rect = rects[i];
- if (!wlr_texture_update_shm(surface->texture, format,
- rect.x1, rect.y1,
- rect.x2 - rect.x1,
- rect.y2 - rect.y1,
- buffer)) {
- break;
- }
- }
- }
-
-release:
- pixman_region32_clear(&surface->current->surface_damage);
- pixman_region32_clear(&surface->current->buffer_damage);
-
- wlr_surface_state_release_buffer(surface->current);
-}
-
static void surface_set_buffer_transform(struct wl_client *client,
struct wl_resource *resource, int transform) {
struct wlr_surface *surface = wl_resource_get_user_data(resource);