mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	wlr_scene: Add a function to also specify damage when applying a buffer to wlr_scene_buffer
This commit is contained in:
		
							parent
							
								
									34be5da072
								
							
						
					
					
						commit
						73a656e8ac
					
				
					 2 changed files with 91 additions and 15 deletions
				
			
		| 
						 | 
					@ -303,6 +303,15 @@ struct wlr_scene_buffer *wlr_scene_buffer_create(struct wlr_scene_node *parent,
 | 
				
			||||||
void wlr_scene_buffer_set_buffer(struct wlr_scene_buffer *scene_buffer,
 | 
					void wlr_scene_buffer_set_buffer(struct wlr_scene_buffer *scene_buffer,
 | 
				
			||||||
	struct wlr_buffer *buffer);
 | 
						struct wlr_buffer *buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Sets the buffer's backing buffer with a custom damage region.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The damage region is in buffer-local coordinates. If the region is NULL,
 | 
				
			||||||
 | 
					 * the whole buffer node will be damaged.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_scene_buffer_set_buffer_with_damage(struct wlr_scene_buffer *scene_buffer,
 | 
				
			||||||
 | 
						struct wlr_buffer *buffer, pixman_region32_t *region);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Set the source rectangle describing the region of the buffer which will be
 | 
					 * Set the source rectangle describing the region of the buffer which will be
 | 
				
			||||||
 * sampled to render this node. This allows cropping the buffer.
 | 
					 * sampled to render this node. This allows cropping the buffer.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -420,27 +420,94 @@ struct wlr_scene_buffer *wlr_scene_buffer_create(struct wlr_scene_node *parent,
 | 
				
			||||||
	return scene_buffer;
 | 
						return scene_buffer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_scene_buffer_set_buffer(struct wlr_scene_buffer *scene_buffer,
 | 
					void wlr_scene_buffer_set_buffer_with_damage(struct wlr_scene_buffer *scene_buffer,
 | 
				
			||||||
		struct wlr_buffer *buffer)  {
 | 
							struct wlr_buffer *buffer, pixman_region32_t *damage) {
 | 
				
			||||||
	if (buffer == scene_buffer->buffer) {
 | 
						// specifying a region for a NULL buffer doesn't make sense. We need to know
 | 
				
			||||||
 | 
						// about the buffer to scale the buffer local coordinates down to scene
 | 
				
			||||||
 | 
						// coordinates. 
 | 
				
			||||||
 | 
						assert(buffer || !damage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (buffer != scene_buffer->buffer) {
 | 
				
			||||||
 | 
							if (!damage) {
 | 
				
			||||||
 | 
								scene_node_damage_whole(&scene_buffer->node);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wlr_texture_destroy(scene_buffer->texture);
 | 
				
			||||||
 | 
							scene_buffer->texture = NULL;
 | 
				
			||||||
 | 
							wlr_buffer_unlock(scene_buffer->buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (buffer) {
 | 
				
			||||||
 | 
								scene_buffer->buffer = wlr_buffer_lock(buffer);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								scene_buffer->buffer = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							scene_node_update_outputs(&scene_buffer->node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!damage) {
 | 
				
			||||||
 | 
								scene_node_damage_whole(&scene_buffer->node);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!damage) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	scene_node_damage_whole(&scene_buffer->node);
 | 
						int lx, ly;
 | 
				
			||||||
 | 
						if (!wlr_scene_node_coords(&scene_buffer->node, &lx, &ly)) {
 | 
				
			||||||
	wlr_texture_destroy(scene_buffer->texture);
 | 
							return;
 | 
				
			||||||
	scene_buffer->texture = NULL;
 | 
					 | 
				
			||||||
	wlr_buffer_unlock(scene_buffer->buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (buffer) {
 | 
					 | 
				
			||||||
		scene_buffer->buffer = wlr_buffer_lock(buffer);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		scene_buffer->buffer = NULL;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	scene_node_damage_whole(&scene_buffer->node);
 | 
						struct wlr_fbox box = scene_buffer->src_box;
 | 
				
			||||||
 | 
						if (wlr_fbox_empty(&box)) {
 | 
				
			||||||
 | 
							box.x = 0;
 | 
				
			||||||
 | 
							box.y = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	scene_node_update_outputs(&scene_buffer->node);
 | 
							if (scene_buffer->transform & WL_OUTPUT_TRANSFORM_90) {
 | 
				
			||||||
 | 
								box.width = buffer->height;
 | 
				
			||||||
 | 
								box.height = buffer->width;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								box.width = buffer->width;
 | 
				
			||||||
 | 
								box.height = buffer->height;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						double scale_x, scale_y;
 | 
				
			||||||
 | 
						if (scene_buffer->dst_width || scene_buffer->dst_height) {
 | 
				
			||||||
 | 
							scale_x = scene_buffer->dst_width / box.width;
 | 
				
			||||||
 | 
							scale_y = scene_buffer->dst_height / box.height;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							scale_x = buffer->width / box.width;
 | 
				
			||||||
 | 
							scale_y = buffer->height / box.height;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pixman_region32_t trans_damage;
 | 
				
			||||||
 | 
						pixman_region32_init(&trans_damage);
 | 
				
			||||||
 | 
						wlr_region_transform(&trans_damage, damage,
 | 
				
			||||||
 | 
							scene_buffer->transform, buffer->width, buffer->height);
 | 
				
			||||||
 | 
						pixman_region32_intersect_rect(&trans_damage, &trans_damage,
 | 
				
			||||||
 | 
							box.x, box.y, box.width, box.height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_scene *scene = scene_node_get_root(&scene_buffer->node);
 | 
				
			||||||
 | 
						struct wlr_scene_output *scene_output;
 | 
				
			||||||
 | 
						wl_list_for_each(scene_output, &scene->outputs, link) {
 | 
				
			||||||
 | 
							float output_scale = scene_output->output->scale;
 | 
				
			||||||
 | 
							pixman_region32_t output_damage;
 | 
				
			||||||
 | 
							pixman_region32_init(&output_damage);
 | 
				
			||||||
 | 
							wlr_region_scale_xy(&output_damage, &trans_damage,
 | 
				
			||||||
 | 
								output_scale * scale_x, output_scale * scale_y);
 | 
				
			||||||
 | 
							pixman_region32_translate(&output_damage,
 | 
				
			||||||
 | 
								(lx - scene_output->x) * output_scale, (ly - scene_output->y) * output_scale);
 | 
				
			||||||
 | 
							wlr_output_damage_add(scene_output->damage, &output_damage);
 | 
				
			||||||
 | 
							pixman_region32_fini(&output_damage);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pixman_region32_fini(&trans_damage);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_scene_buffer_set_buffer(struct wlr_scene_buffer *scene_buffer,
 | 
				
			||||||
 | 
							struct wlr_buffer *buffer)  {
 | 
				
			||||||
 | 
						wlr_scene_buffer_set_buffer_with_damage(scene_buffer, buffer, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_scene_buffer_set_source_box(struct wlr_scene_buffer *scene_buffer,
 | 
					void wlr_scene_buffer_set_source_box(struct wlr_scene_buffer *scene_buffer,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue