Skip to content

render: Add region of interest to wlr_texture_read_pixels_options

Andri Yngvason requested to merge andri/wlroots:read-pixels-roi into master

This adds a region of interest option, outside of which data need not be copied.

Something like this is needed to fully implement damage tracking in ext-screencopy-v1.

This could also be implemented in ext-screencopy-v1 using the source region option, but because different renderer implementations have different limitations in this regard, it's best to implement this specifically for each renderer for optimal performance.

Tested by patching !4545 as follows:

diff --cc types/wlr_ext_screencopy_v1.c
index ca70038a,ca70038a..1e253697
--- a/types/wlr_ext_screencopy_v1.c
+++ b/types/wlr_ext_screencopy_v1.c
@@@ -131,18 -131,18 +131,19 @@@ out
  }
  
  static bool copy_shm(void *data, uint32_t format, size_t stride,
--		struct wlr_buffer *src, struct wlr_renderer *renderer) {
++		struct wlr_buffer *src, struct wlr_renderer *renderer,
++		struct pixman_region32 *roi) {
  	// TODO: bypass renderer if source buffer supports data ptr access
  	struct wlr_texture *texture = wlr_texture_from_buffer(renderer, src);
  	if (!texture) {
  		return false;
  	}
  
--	// TODO: only copy damaged region
  	bool ok = wlr_texture_read_pixels(texture, &(struct wlr_texture_read_pixels_options){
  		.data = data,
  		.format = format,
  		.stride = stride,
++		.roi = roi,
  	});
  
  	wlr_texture_destroy(texture);
@@@ -180,7 -180,7 +181,8 @@@ bool wlr_ext_screencopy_frame_v1_copy_b
  			ok = false;
  			failure_reason = EXT_SCREENCOPY_FRAME_V1_FAILURE_REASON_BUFFER_CONSTRAINTS;
  		} else {
--			ok = copy_shm(data, format, stride, src, renderer);
++			ok = copy_shm(data, format, stride, src, renderer,
++					&frame->buffer_damage);
  		}
  		wlr_buffer_end_data_ptr_access(dst);
  	}

Merge request reports