From cbe099dcc7fab1b70f3225e52cc5e340a368dd61 Mon Sep 17 00:00:00 2001
From: Simon Ser <contact@emersion.fr>
Date: Wed, 11 Aug 2021 17:18:41 +0200
Subject: [PATCH] buffer: take a wlr_buffer in wlr_client_buffer_apply_damage

Instead of taking a wl_resource as argument, take a wlr_buffer.
---
 include/wlr/types/wlr_buffer.h |  2 +-
 types/wlr_buffer.c             | 41 +++++++++++++++-------------------
 types/wlr_surface.c            |  4 ++--
 3 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/include/wlr/types/wlr_buffer.h b/include/wlr/types/wlr_buffer.h
index b4be3226..4d9640d8 100644
--- a/include/wlr/types/wlr_buffer.h
+++ b/include/wlr/types/wlr_buffer.h
@@ -186,7 +186,7 @@ bool wlr_resource_is_buffer(struct wl_resource *resource);
  * isn't mutable.
  */
 struct wlr_client_buffer *wlr_client_buffer_apply_damage(
-	struct wlr_client_buffer *buffer, struct wl_resource *resource,
+	struct wlr_client_buffer *buffer, struct wlr_buffer *next,
 	pixman_region32_t *damage);
 
 #endif
diff --git a/types/wlr_buffer.c b/types/wlr_buffer.c
index 21c274c0..86b138d9 100644
--- a/types/wlr_buffer.c
+++ b/types/wlr_buffer.c
@@ -272,42 +272,37 @@ struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer,
 }
 
 struct wlr_client_buffer *wlr_client_buffer_apply_damage(
-		struct wlr_client_buffer *client_buffer, struct wl_resource *resource,
+		struct wlr_client_buffer *client_buffer, struct wlr_buffer *next,
 		pixman_region32_t *damage) {
-	assert(wlr_resource_is_buffer(resource));
-
 	if (client_buffer->base.n_locks > 1) {
 		// Someone else still has a reference to the buffer
 		return NULL;
 	}
 
-	struct wl_shm_buffer *shm_buf = wl_shm_buffer_get(resource);
-	if (shm_buf == NULL ||
-			client_buffer->shm_source_format == DRM_FORMAT_INVALID) {
+	if ((uint32_t)next->width != client_buffer->texture->width ||
+			(uint32_t)next->height != client_buffer->texture->height) {
+		return NULL;
+	}
+
+	if (client_buffer->shm_source_format == DRM_FORMAT_INVALID) {
 		// Uploading only damaged regions only works for wl_shm buffers and
 		// mutable textures (created from wl_shm buffer)
 		return NULL;
 	}
 
-	enum wl_shm_format new_shm_fmt = wl_shm_buffer_get_format(shm_buf);
-	if (convert_wl_shm_format_to_drm(new_shm_fmt) !=
-			client_buffer->shm_source_format) {
+	void *data;
+	uint32_t format;
+	size_t stride;
+	if (!buffer_begin_data_ptr_access(next, &data, &format, &stride)) {
+		return NULL;
+	}
+
+	if (format != client_buffer->shm_source_format) {
 		// Uploading to textures can't change the format
+		buffer_end_data_ptr_access(next);
 		return NULL;
 	}
 
-	int32_t stride = wl_shm_buffer_get_stride(shm_buf);
-	int32_t width = wl_shm_buffer_get_width(shm_buf);
-	int32_t height = wl_shm_buffer_get_height(shm_buf);
-
-	if ((uint32_t)width != client_buffer->texture->width ||
-			(uint32_t)height != client_buffer->texture->height) {
-		return NULL;
-	}
-
-	wl_shm_buffer_begin_access(shm_buf);
-	void *data = wl_shm_buffer_get_data(shm_buf);
-
 	int n;
 	pixman_box32_t *rects = pixman_region32_rectangles(damage, &n);
 	for (int i = 0; i < n; ++i) {
@@ -315,12 +310,12 @@ struct wlr_client_buffer *wlr_client_buffer_apply_damage(
 		if (!wlr_texture_write_pixels(client_buffer->texture, stride,
 				r->x2 - r->x1, r->y2 - r->y1, r->x1, r->y1,
 				r->x1, r->y1, data)) {
-			wl_shm_buffer_end_access(shm_buf);
+			buffer_end_data_ptr_access(next);
 			return NULL;
 		}
 	}
 
-	wl_shm_buffer_end_access(shm_buf);
+	buffer_end_data_ptr_access(next);
 
 	return client_buffer;
 }
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 15001c5c..a82fc5bf 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -365,8 +365,8 @@ static void surface_apply_damage(struct wlr_surface *surface) {
 
 	if (surface->buffer != NULL) {
 		struct wlr_client_buffer *updated_buffer =
-			wlr_client_buffer_apply_damage(surface->buffer, resource,
-			&surface->buffer_damage);
+			wlr_client_buffer_apply_damage(surface->buffer,
+			surface->current.buffer, &surface->buffer_damage);
 		if (updated_buffer != NULL) {
 			wlr_buffer_unlock(surface->current.buffer);
 			surface->current.buffer = NULL;