mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-10-29 05:40:12 -04:00 
			
		
		
		
	render: switch wlr_renderer to wlr_drm_format_set
This commit is contained in:
		
							parent
							
								
									c01b81c99c
								
							
						
					
					
						commit
						e42178d03f
					
				
					 7 changed files with 88 additions and 86 deletions
				
			
		|  | @ -21,6 +21,7 @@ | |||
| #include <stdbool.h> | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/render/dmabuf.h> | ||||
| #include <wlr/render/drm_format_set.h> | ||||
| 
 | ||||
| struct wlr_egl { | ||||
| 	EGLenum platform; | ||||
|  | @ -42,6 +43,8 @@ struct wlr_egl { | |||
| 	} exts; | ||||
| 
 | ||||
| 	struct wl_display *wl_display; | ||||
| 
 | ||||
| 	struct wlr_drm_format_set dmabuf_formats; | ||||
| }; | ||||
| 
 | ||||
| // TODO: Allocate and return a wlr_egl
 | ||||
|  | @ -88,13 +91,7 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl, | |||
| /**
 | ||||
|  * Get the available dmabuf formats | ||||
|  */ | ||||
| int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl, int **formats); | ||||
| 
 | ||||
| /**
 | ||||
|  * Get the available dmabuf modifiers for a given format | ||||
|  */ | ||||
| int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl, int format, | ||||
| 	uint64_t **modifiers); | ||||
| const struct wlr_drm_format_set *wlr_egl_get_dmabuf_formats(struct wlr_egl *egl); | ||||
| 
 | ||||
| bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image, | ||||
| 	int32_t width, int32_t height, uint32_t flags, | ||||
|  |  | |||
|  | @ -46,9 +46,8 @@ struct wlr_renderer_impl { | |||
| 		struct wl_resource *resource); | ||||
| 	void (*wl_drm_buffer_get_size)(struct wlr_renderer *renderer, | ||||
| 		struct wl_resource *buffer, int *width, int *height); | ||||
| 	int (*get_dmabuf_formats)(struct wlr_renderer *renderer, int **formats); | ||||
| 	int (*get_dmabuf_modifiers)(struct wlr_renderer *renderer, int format, | ||||
| 		uint64_t **modifiers); | ||||
| 	const struct wlr_drm_format_set *(*get_dmabuf_formats)( | ||||
| 		struct wlr_renderer *renderer); | ||||
| 	enum wl_shm_format (*preferred_read_format)(struct wlr_renderer *renderer); | ||||
| 	bool (*read_pixels)(struct wlr_renderer *renderer, enum wl_shm_format fmt, | ||||
| 		uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height, | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ enum wlr_renderer_read_pixels_flags { | |||
| }; | ||||
| 
 | ||||
| struct wlr_renderer_impl; | ||||
| struct wlr_drm_format_set; | ||||
| 
 | ||||
| struct wlr_renderer { | ||||
| 	const struct wlr_renderer_impl *impl; | ||||
|  | @ -87,15 +88,10 @@ bool wlr_renderer_resource_is_wl_drm_buffer(struct wlr_renderer *renderer, | |||
| void wlr_renderer_wl_drm_buffer_get_size(struct wlr_renderer *renderer, | ||||
| 	struct wl_resource *buffer, int *width, int *height); | ||||
| /**
 | ||||
|  * Get the available dmabuf formats | ||||
|  * Get the available DMA-BUF formats. | ||||
|  */ | ||||
| int wlr_renderer_get_dmabuf_formats(struct wlr_renderer *renderer, | ||||
| 	int **formats); | ||||
| /**
 | ||||
|  * Get the available dmabuf modifiers for a given format | ||||
|  */ | ||||
| int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *renderer, int format, | ||||
| 	uint64_t **modifiers); | ||||
| const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_formats( | ||||
| 	struct wlr_renderer *renderer); | ||||
| /**
 | ||||
|  * Reads out of pixels of the currently bound surface into data. `stride` is in | ||||
|  * bytes. | ||||
|  |  | |||
							
								
								
									
										76
									
								
								render/egl.c
									
										
									
									
									
								
							
							
						
						
									
										76
									
								
								render/egl.c
									
										
									
									
									
								
							|  | @ -1,7 +1,7 @@ | |||
| #include <assert.h> | ||||
| #include <drm_fourcc.h> | ||||
| #include <EGL/egl.h> | ||||
| #include <EGL/eglext.h> | ||||
| #include <assert.h> | ||||
| #include <drm_fourcc.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <wlr/render/egl.h> | ||||
|  | @ -77,24 +77,49 @@ static bool check_egl_ext(const char *exts, const char *ext) { | |||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static void print_dmabuf_formats(struct wlr_egl *egl) { | ||||
| 	/* Avoid log msg if extension is not present */ | ||||
| 	if (!egl->exts.image_dmabuf_import_modifiers_ext) { | ||||
| 		return; | ||||
| 	} | ||||
| static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats); | ||||
| static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format, | ||||
| 	uint64_t **modifiers); | ||||
| 
 | ||||
| static void init_dmabuf_formats(struct wlr_egl *egl) { | ||||
| 	int *formats; | ||||
| 	int num = wlr_egl_get_dmabuf_formats(egl, &formats); | ||||
| 	if (num < 0) { | ||||
| 	int formats_len = get_egl_dmabuf_formats(egl, &formats); | ||||
| 	if (formats_len < 0) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	char str_formats[num * 5 + 1]; | ||||
| 	for (int i = 0; i < num; i++) { | ||||
| 		snprintf(&str_formats[i*5], (num - i) * 5 + 1, "%.4s ", | ||||
| 	for (int i = 0; i < formats_len; i++) { | ||||
| 		uint32_t fmt = formats[i]; | ||||
| 
 | ||||
| 		uint64_t *modifiers; | ||||
| 		int modifiers_len = get_egl_dmabuf_modifiers(egl, fmt, &modifiers); | ||||
| 		if (modifiers_len < 0) { | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if (modifiers_len == 0) { | ||||
| 			wlr_drm_format_set_add(&egl->dmabuf_formats, fmt, DRM_FORMAT_MOD_INVALID); | ||||
| 		} | ||||
| 
 | ||||
| 		for (int j = 0; j < modifiers_len; j++) { | ||||
| 			wlr_drm_format_set_add(&egl->dmabuf_formats, fmt, modifiers[j]); | ||||
| 		} | ||||
| 
 | ||||
| 		free(modifiers); | ||||
| 	} | ||||
| 
 | ||||
| 	char *str_formats = malloc(formats_len * 5 + 1); | ||||
| 	if (str_formats == NULL) { | ||||
| 		goto out; | ||||
| 	} | ||||
| 	for (int i = 0; i < formats_len; i++) { | ||||
| 		snprintf(&str_formats[i*5], (formats_len - i) * 5 + 1, "%.4s ", | ||||
| 			(char*)&formats[i]); | ||||
| 	} | ||||
| 	wlr_log(WLR_DEBUG, "Supported dmabuf buffer formats: %s", str_formats); | ||||
| 	free(str_formats); | ||||
| 
 | ||||
| out: | ||||
| 	free(formats); | ||||
| } | ||||
| 
 | ||||
|  | @ -173,7 +198,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, | |||
| 		check_egl_ext(egl->exts_str, "EGL_MESA_image_dma_buf_export") && | ||||
| 		eglExportDMABUFImageQueryMESA && eglExportDMABUFImageMESA; | ||||
| 
 | ||||
| 	print_dmabuf_formats(egl); | ||||
| 	init_dmabuf_formats(egl); | ||||
| 
 | ||||
| 	egl->exts.bind_wayland_display_wl = | ||||
| 		check_egl_ext(egl->exts_str, "EGL_WL_bind_wayland_display") | ||||
|  | @ -242,6 +267,8 @@ void wlr_egl_finish(struct wlr_egl *egl) { | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	wlr_drm_format_set_finish(&egl->dmabuf_formats); | ||||
| 
 | ||||
| 	eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | ||||
| 	if (egl->wl_display) { | ||||
| 		assert(egl->exts.bind_wayland_display_wl); | ||||
|  | @ -486,10 +513,9 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl, | |||
| 		EGL_LINUX_DMA_BUF_EXT, NULL, attribs); | ||||
| } | ||||
| 
 | ||||
| int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl, | ||||
| 		int **formats) { | ||||
| static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) { | ||||
| 	if (!egl->exts.image_dmabuf_import_ext) { | ||||
| 		wlr_log(WLR_DEBUG, "dmabuf import extension not present"); | ||||
| 		wlr_log(WLR_DEBUG, "DMA-BUF import extension not present"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -518,7 +544,7 @@ int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl, | |||
| 
 | ||||
| 	EGLint num; | ||||
| 	if (!eglQueryDmaBufFormatsEXT(egl->display, 0, NULL, &num)) { | ||||
| 		wlr_log(WLR_ERROR, "failed to query number of dmabuf formats"); | ||||
| 		wlr_log(WLR_ERROR, "Failed to query number of dmabuf formats"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -529,17 +555,17 @@ int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl, | |||
| 	} | ||||
| 
 | ||||
| 	if (!eglQueryDmaBufFormatsEXT(egl->display, num, *formats, &num)) { | ||||
| 		wlr_log(WLR_ERROR, "failed to query dmabuf format"); | ||||
| 		wlr_log(WLR_ERROR, "Failed to query dmabuf format"); | ||||
| 		free(*formats); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return num; | ||||
| } | ||||
| 
 | ||||
| int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl, | ||||
| 		int format, uint64_t **modifiers) { | ||||
| static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format, | ||||
| 		uint64_t **modifiers) { | ||||
| 	if (!egl->exts.image_dmabuf_import_ext) { | ||||
| 		wlr_log(WLR_DEBUG, "dmabuf extension not present"); | ||||
| 		wlr_log(WLR_DEBUG, "DMA-BUF extension not present"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -551,7 +577,7 @@ int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl, | |||
| 	EGLint num; | ||||
| 	if (!eglQueryDmaBufModifiersEXT(egl->display, format, 0, | ||||
| 			NULL, NULL, &num)) { | ||||
| 		wlr_log(WLR_ERROR, "failed to query dmabuf number of modifiers"); | ||||
| 		wlr_log(WLR_ERROR, "Failed to query dmabuf number of modifiers"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -563,13 +589,17 @@ int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl, | |||
| 
 | ||||
| 	if (!eglQueryDmaBufModifiersEXT(egl->display, format, num, | ||||
| 		*modifiers, NULL, &num)) { | ||||
| 		wlr_log(WLR_ERROR, "failed to query dmabuf modifiers"); | ||||
| 		wlr_log(WLR_ERROR, "Failed to query dmabuf modifiers"); | ||||
| 		free(*modifiers); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return num; | ||||
| } | ||||
| 
 | ||||
| const struct wlr_drm_format_set *wlr_egl_get_dmabuf_formats(struct wlr_egl *egl) { | ||||
| 	return &egl->dmabuf_formats; | ||||
| } | ||||
| 
 | ||||
| bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image, | ||||
| 		int32_t width, int32_t height, uint32_t flags, | ||||
| 		struct wlr_dmabuf_attributes *attribs) { | ||||
|  |  | |||
|  | @ -247,16 +247,10 @@ static void gles2_wl_drm_buffer_get_size(struct wlr_renderer *wlr_renderer, | |||
| 	eglQueryWaylandBufferWL(renderer->egl->display, buffer, EGL_HEIGHT, height); | ||||
| } | ||||
| 
 | ||||
| static int gles2_get_dmabuf_formats(struct wlr_renderer *wlr_renderer, | ||||
| 		int **formats) { | ||||
| static const struct wlr_drm_format_set *gles2_get_dmabuf_formats( | ||||
| 		struct wlr_renderer *wlr_renderer) { | ||||
| 	struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer); | ||||
| 	return wlr_egl_get_dmabuf_formats(renderer->egl, formats); | ||||
| } | ||||
| 
 | ||||
| static int gles2_get_dmabuf_modifiers(struct wlr_renderer *wlr_renderer, | ||||
| 		int format, uint64_t **modifiers) { | ||||
| 	struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer); | ||||
| 	return wlr_egl_get_dmabuf_modifiers(renderer->egl, format, modifiers); | ||||
| 	return wlr_egl_get_dmabuf_formats(renderer->egl); | ||||
| } | ||||
| 
 | ||||
| static enum wl_shm_format gles2_preferred_read_format( | ||||
|  | @ -402,7 +396,6 @@ static const struct wlr_renderer_impl renderer_impl = { | |||
| 	.resource_is_wl_drm_buffer = gles2_resource_is_wl_drm_buffer, | ||||
| 	.wl_drm_buffer_get_size = gles2_wl_drm_buffer_get_size, | ||||
| 	.get_dmabuf_formats = gles2_get_dmabuf_formats, | ||||
| 	.get_dmabuf_modifiers = gles2_get_dmabuf_modifiers, | ||||
| 	.preferred_read_format = gles2_preferred_read_format, | ||||
| 	.read_pixels = gles2_read_pixels, | ||||
| 	.texture_from_pixels = gles2_texture_from_pixels, | ||||
|  |  | |||
|  | @ -123,20 +123,12 @@ void wlr_renderer_wl_drm_buffer_get_size(struct wlr_renderer *r, | |||
| 	return r->impl->wl_drm_buffer_get_size(r, buffer, width, height); | ||||
| } | ||||
| 
 | ||||
| int wlr_renderer_get_dmabuf_formats(struct wlr_renderer *r, | ||||
| 		int **formats) { | ||||
| const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_formats( | ||||
| 		struct wlr_renderer *r) { | ||||
| 	if (!r->impl->get_dmabuf_formats) { | ||||
| 		return -1; | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return r->impl->get_dmabuf_formats(r, formats); | ||||
| } | ||||
| 
 | ||||
| int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *r, int format, | ||||
| 		uint64_t **modifiers) { | ||||
| 	if (!r->impl->get_dmabuf_modifiers) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return r->impl->get_dmabuf_modifiers(r, format, modifiers); | ||||
| 	return r->impl->get_dmabuf_formats(r); | ||||
| } | ||||
| 
 | ||||
| bool wlr_renderer_read_pixels(struct wlr_renderer *r, enum wl_shm_format fmt, | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/render/drm_format_set.h> | ||||
| #include <wlr/render/wlr_renderer.h> | ||||
| #include <wlr/types/wlr_linux_dmabuf_v1.h> | ||||
| #include <wlr/util/log.h> | ||||
|  | @ -386,46 +387,40 @@ struct wlr_linux_dmabuf_v1 *wlr_linux_dmabuf_v1_from_resource( | |||
| 
 | ||||
| static void linux_dmabuf_send_formats(struct wlr_linux_dmabuf_v1 *linux_dmabuf, | ||||
| 		struct wl_resource *resource, uint32_t version) { | ||||
| 	struct wlr_renderer *renderer = linux_dmabuf->renderer; | ||||
| 	uint64_t modifier_invalid = DRM_FORMAT_MOD_INVALID; | ||||
| 	int *formats = NULL; | ||||
| 	int num_formats = wlr_renderer_get_dmabuf_formats(renderer, &formats); | ||||
| 	if (num_formats < 0) { | ||||
| 	const struct wlr_drm_format_set *formats = | ||||
| 		wlr_renderer_get_dmabuf_formats(linux_dmabuf->renderer); | ||||
| 	if (formats == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	for (int i = 0; i < num_formats; i++) { | ||||
| 		uint64_t *modifiers = NULL; | ||||
| 		int num_modifiers = wlr_renderer_get_dmabuf_modifiers(renderer, | ||||
| 			formats[i], &modifiers); | ||||
| 		if (num_modifiers < 0) { | ||||
| 			return; | ||||
| 		} | ||||
| 		/* send DRM_FORMAT_MOD_INVALID token when no modifiers are supported
 | ||||
| 		 * for this format */ | ||||
| 		if (num_modifiers == 0) { | ||||
| 			num_modifiers = 1; | ||||
| 	for (size_t i = 0; i < formats->len; i++) { | ||||
| 		struct wlr_drm_format *fmt = formats->formats[i]; | ||||
| 
 | ||||
| 		size_t modifiers_len = fmt->len; | ||||
| 		uint64_t *modifiers = fmt->modifiers; | ||||
| 
 | ||||
| 		// Send DRM_FORMAT_MOD_INVALID token when no modifiers are supported
 | ||||
| 		// for this format
 | ||||
| 		if (modifiers_len == 0) { | ||||
| 			modifiers_len = 1; | ||||
| 			modifiers = &modifier_invalid; | ||||
| 		} | ||||
| 		for (int j = 0; j < num_modifiers; j++) { | ||||
| 		for (size_t j = 0; j < modifiers_len; j++) { | ||||
| 			if (version >= ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) { | ||||
| 				uint32_t modifier_lo = modifiers[j] & 0xFFFFFFFF; | ||||
| 				uint32_t modifier_hi = modifiers[j] >> 32; | ||||
| 				zwp_linux_dmabuf_v1_send_modifier(resource, | ||||
| 					formats[i], | ||||
| 					fmt->format, | ||||
| 					modifier_hi, | ||||
| 					modifier_lo); | ||||
| 			} else if (modifiers[j] == DRM_FORMAT_MOD_LINEAR || | ||||
| 					modifiers == &modifier_invalid) { | ||||
| 				zwp_linux_dmabuf_v1_send_format(resource, formats[i]); | ||||
| 				zwp_linux_dmabuf_v1_send_format(resource, fmt->format); | ||||
| 			} | ||||
| 		} | ||||
| 		if (modifiers != &modifier_invalid) { | ||||
| 			free(modifiers); | ||||
| 	} | ||||
| } | ||||
| 	free(formats); | ||||
| } | ||||
| 
 | ||||
| static void linux_dmabuf_resource_destroy(struct wl_resource *resource) { | ||||
| 	wl_list_remove(wl_resource_get_link(resource)); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 emersion
						emersion