mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Merge pull request #1642 from emersion/format-set
Introduce wlr_format_set
This commit is contained in:
		
						commit
						9faea17c73
					
				
					 11 changed files with 224 additions and 88 deletions
				
			
		
							
								
								
									
										27
									
								
								include/wlr/render/drm_format_set.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								include/wlr/render/drm_format_set.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					#ifndef WLR_RENDER_DRM_FORMAT_SET_H
 | 
				
			||||||
 | 
					#define WLR_RENDER_DRM_FORMAT_SET_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_drm_format {
 | 
				
			||||||
 | 
						uint32_t format;
 | 
				
			||||||
 | 
						size_t len, cap;
 | 
				
			||||||
 | 
						uint64_t modifiers[];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_drm_format_set {
 | 
				
			||||||
 | 
						size_t len, cap;
 | 
				
			||||||
 | 
						struct wlr_drm_format **formats;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_drm_format_set_finish(struct wlr_drm_format_set *set);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct wlr_drm_format *wlr_drm_format_set_get(
 | 
				
			||||||
 | 
						const struct wlr_drm_format_set *set, uint32_t format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool wlr_drm_format_set_add(struct wlr_drm_format_set *set, uint32_t format,
 | 
				
			||||||
 | 
						uint64_t modifier);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,7 @@
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <wayland-server.h>
 | 
					#include <wayland-server.h>
 | 
				
			||||||
#include <wlr/render/dmabuf.h>
 | 
					#include <wlr/render/dmabuf.h>
 | 
				
			||||||
 | 
					#include <wlr/render/drm_format_set.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_egl {
 | 
					struct wlr_egl {
 | 
				
			||||||
	EGLenum platform;
 | 
						EGLenum platform;
 | 
				
			||||||
| 
						 | 
					@ -42,6 +43,8 @@ struct wlr_egl {
 | 
				
			||||||
	} exts;
 | 
						} exts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_display *wl_display;
 | 
						struct wl_display *wl_display;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_drm_format_set dmabuf_formats;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: Allocate and return a wlr_egl
 | 
					// 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
 | 
					 * Get the available dmabuf formats
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl, int **formats);
 | 
					const struct wlr_drm_format_set *wlr_egl_get_dmabuf_formats(struct wlr_egl *egl);
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Get the available dmabuf modifiers for a given format
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl, int format,
 | 
					 | 
				
			||||||
	uint64_t **modifiers);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
 | 
					bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
 | 
				
			||||||
	int32_t width, int32_t height, uint32_t flags,
 | 
						int32_t width, int32_t height, uint32_t flags,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,9 +46,8 @@ struct wlr_renderer_impl {
 | 
				
			||||||
		struct wl_resource *resource);
 | 
							struct wl_resource *resource);
 | 
				
			||||||
	void (*wl_drm_buffer_get_size)(struct wlr_renderer *renderer,
 | 
						void (*wl_drm_buffer_get_size)(struct wlr_renderer *renderer,
 | 
				
			||||||
		struct wl_resource *buffer, int *width, int *height);
 | 
							struct wl_resource *buffer, int *width, int *height);
 | 
				
			||||||
	int (*get_dmabuf_formats)(struct wlr_renderer *renderer, int **formats);
 | 
						const struct wlr_drm_format_set *(*get_dmabuf_formats)(
 | 
				
			||||||
	int (*get_dmabuf_modifiers)(struct wlr_renderer *renderer, int format,
 | 
							struct wlr_renderer *renderer);
 | 
				
			||||||
		uint64_t **modifiers);
 | 
					 | 
				
			||||||
	enum wl_shm_format (*preferred_read_format)(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,
 | 
						bool (*read_pixels)(struct wlr_renderer *renderer, enum wl_shm_format fmt,
 | 
				
			||||||
		uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height,
 | 
							uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,10 @@
 | 
				
			||||||
install_headers(
 | 
					install_headers(
 | 
				
			||||||
	'dmabuf.h',
 | 
						'dmabuf.h',
 | 
				
			||||||
	'egl.h',
 | 
						'egl.h',
 | 
				
			||||||
 | 
						'drm_format_set.h',
 | 
				
			||||||
	'gles2.h',
 | 
						'gles2.h',
 | 
				
			||||||
	'interface.h',
 | 
						'interface.h',
 | 
				
			||||||
	'wlr_renderer.h',
 | 
						'wlr_renderer.h',
 | 
				
			||||||
	'wlr_texture.h',
 | 
						'wlr_texture.h',
 | 
				
			||||||
	subdir: 'wlr/render'
 | 
						subdir: 'wlr/render',
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@ enum wlr_renderer_read_pixels_flags {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_renderer_impl;
 | 
					struct wlr_renderer_impl;
 | 
				
			||||||
 | 
					struct wlr_drm_format_set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_renderer {
 | 
					struct wlr_renderer {
 | 
				
			||||||
	const struct wlr_renderer_impl *impl;
 | 
						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,
 | 
					void wlr_renderer_wl_drm_buffer_get_size(struct wlr_renderer *renderer,
 | 
				
			||||||
	struct wl_resource *buffer, int *width, int *height);
 | 
						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,
 | 
					const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_formats(
 | 
				
			||||||
	int **formats);
 | 
						struct wlr_renderer *renderer);
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Get the available dmabuf modifiers for a given format
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *renderer, int format,
 | 
					 | 
				
			||||||
	uint64_t **modifiers);
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Reads out of pixels of the currently bound surface into data. `stride` is in
 | 
					 * Reads out of pixels of the currently bound surface into data. `stride` is in
 | 
				
			||||||
 * bytes.
 | 
					 * bytes.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										105
									
								
								render/drm_format_set.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								render/drm_format_set.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,105 @@
 | 
				
			||||||
 | 
					#include <drm_fourcc.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <wlr/render/drm_format_set.h>
 | 
				
			||||||
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_drm_format_set_finish(struct wlr_drm_format_set *set) {
 | 
				
			||||||
 | 
						for (size_t i = 0; i < set->len; ++i) {
 | 
				
			||||||
 | 
							free(set->formats[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						free(set->formats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set->len = 0;
 | 
				
			||||||
 | 
						set->cap = 0;
 | 
				
			||||||
 | 
						set->formats = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct wlr_drm_format **format_set_get_ref(struct wlr_drm_format_set *set,
 | 
				
			||||||
 | 
							uint32_t format) {
 | 
				
			||||||
 | 
						for (size_t i = 0; i < set->len; ++i) {
 | 
				
			||||||
 | 
							if (set->formats[i]->format == format) {
 | 
				
			||||||
 | 
								return &set->formats[i];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct wlr_drm_format *wlr_drm_format_set_get(
 | 
				
			||||||
 | 
							const struct wlr_drm_format_set *set, uint32_t format) {
 | 
				
			||||||
 | 
						struct wlr_drm_format **ptr =
 | 
				
			||||||
 | 
							format_set_get_ref((struct wlr_drm_format_set *)set, format);
 | 
				
			||||||
 | 
						return ptr ? *ptr : NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool wlr_drm_format_set_add(struct wlr_drm_format_set *set, uint32_t format,
 | 
				
			||||||
 | 
							uint64_t modifier) {
 | 
				
			||||||
 | 
						struct wlr_drm_format **ptr = format_set_get_ref(set, format);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ptr) {
 | 
				
			||||||
 | 
							struct wlr_drm_format *fmt = *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (modifier == DRM_FORMAT_MOD_INVALID) {
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (size_t i = 0; i < fmt->len; ++i) {
 | 
				
			||||||
 | 
								if (fmt->modifiers[i] == modifier) {
 | 
				
			||||||
 | 
									return true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (fmt->len == fmt->cap) {
 | 
				
			||||||
 | 
								size_t cap = fmt->cap ? fmt->cap * 2 : 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								fmt = realloc(fmt, sizeof(*fmt) + sizeof(fmt->modifiers[0]) * cap);
 | 
				
			||||||
 | 
								if (!fmt) {
 | 
				
			||||||
 | 
									wlr_log_errno(WLR_ERROR, "Allocation failed");
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								fmt->cap = cap;
 | 
				
			||||||
 | 
								*ptr = fmt;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fmt->modifiers[fmt->len++] = modifier;
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size_t cap = modifier != DRM_FORMAT_MOD_INVALID ? 4 : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_drm_format *fmt =
 | 
				
			||||||
 | 
							calloc(1, sizeof(*fmt) + sizeof(fmt->modifiers[0]) * cap);
 | 
				
			||||||
 | 
						if (!fmt) {
 | 
				
			||||||
 | 
							wlr_log_errno(WLR_ERROR, "Allocation failed");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fmt->format = format;
 | 
				
			||||||
 | 
						if (cap) {
 | 
				
			||||||
 | 
							fmt->cap = cap;
 | 
				
			||||||
 | 
							fmt->len = 1;
 | 
				
			||||||
 | 
							fmt->modifiers[0] = modifier;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (set->len == set->cap) {
 | 
				
			||||||
 | 
							size_t new = set->cap ? set->cap * 2 : 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct wlr_drm_format **tmp = realloc(set->formats,
 | 
				
			||||||
 | 
								sizeof(*fmt) + sizeof(fmt->modifiers[0]) * new);
 | 
				
			||||||
 | 
							if (!tmp) {
 | 
				
			||||||
 | 
								wlr_log_errno(WLR_ERROR, "Allocation failed");
 | 
				
			||||||
 | 
								free(fmt);
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							set->cap = new;
 | 
				
			||||||
 | 
							set->formats = tmp;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set->formats[set->len++] = fmt;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										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/egl.h>
 | 
				
			||||||
#include <EGL/eglext.h>
 | 
					#include <EGL/eglext.h>
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <drm_fourcc.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <wlr/render/egl.h>
 | 
					#include <wlr/render/egl.h>
 | 
				
			||||||
| 
						 | 
					@ -77,24 +77,49 @@ static bool check_egl_ext(const char *exts, const char *ext) {
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void print_dmabuf_formats(struct wlr_egl *egl) {
 | 
					static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats);
 | 
				
			||||||
	/* Avoid log msg if extension is not present */
 | 
					static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
 | 
				
			||||||
	if (!egl->exts.image_dmabuf_import_modifiers_ext) {
 | 
						uint64_t **modifiers);
 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void init_dmabuf_formats(struct wlr_egl *egl) {
 | 
				
			||||||
	int *formats;
 | 
						int *formats;
 | 
				
			||||||
	int num = wlr_egl_get_dmabuf_formats(egl, &formats);
 | 
						int formats_len = get_egl_dmabuf_formats(egl, &formats);
 | 
				
			||||||
	if (num < 0) {
 | 
						if (formats_len < 0) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char str_formats[num * 5 + 1];
 | 
						for (int i = 0; i < formats_len; i++) {
 | 
				
			||||||
	for (int i = 0; i < num; i++) {
 | 
							uint32_t fmt = formats[i];
 | 
				
			||||||
		snprintf(&str_formats[i*5], (num - i) * 5 + 1, "%.4s ",
 | 
					
 | 
				
			||||||
 | 
							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]);
 | 
								(char*)&formats[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wlr_log(WLR_DEBUG, "Supported dmabuf buffer formats: %s", str_formats);
 | 
						wlr_log(WLR_DEBUG, "Supported dmabuf buffer formats: %s", str_formats);
 | 
				
			||||||
 | 
						free(str_formats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
	free(formats);
 | 
						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") &&
 | 
							check_egl_ext(egl->exts_str, "EGL_MESA_image_dma_buf_export") &&
 | 
				
			||||||
		eglExportDMABUFImageQueryMESA && eglExportDMABUFImageMESA;
 | 
							eglExportDMABUFImageQueryMESA && eglExportDMABUFImageMESA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	print_dmabuf_formats(egl);
 | 
						init_dmabuf_formats(egl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	egl->exts.bind_wayland_display_wl =
 | 
						egl->exts.bind_wayland_display_wl =
 | 
				
			||||||
		check_egl_ext(egl->exts_str, "EGL_WL_bind_wayland_display")
 | 
							check_egl_ext(egl->exts_str, "EGL_WL_bind_wayland_display")
 | 
				
			||||||
| 
						 | 
					@ -242,6 +267,8 @@ void wlr_egl_finish(struct wlr_egl *egl) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_drm_format_set_finish(&egl->dmabuf_formats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 | 
						eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 | 
				
			||||||
	if (egl->wl_display) {
 | 
						if (egl->wl_display) {
 | 
				
			||||||
		assert(egl->exts.bind_wayland_display_wl);
 | 
							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);
 | 
							EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl,
 | 
					static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) {
 | 
				
			||||||
		int **formats) {
 | 
					 | 
				
			||||||
	if (!egl->exts.image_dmabuf_import_ext) {
 | 
						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;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -518,7 +544,7 @@ int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EGLint num;
 | 
						EGLint num;
 | 
				
			||||||
	if (!eglQueryDmaBufFormatsEXT(egl->display, 0, NULL, &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;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -529,17 +555,17 @@ int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!eglQueryDmaBufFormatsEXT(egl->display, num, *formats, &num)) {
 | 
						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);
 | 
							free(*formats);
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return num;
 | 
						return num;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl,
 | 
					static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
 | 
				
			||||||
		int format, uint64_t **modifiers) {
 | 
							uint64_t **modifiers) {
 | 
				
			||||||
	if (!egl->exts.image_dmabuf_import_ext) {
 | 
						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;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -551,7 +577,7 @@ int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl,
 | 
				
			||||||
	EGLint num;
 | 
						EGLint num;
 | 
				
			||||||
	if (!eglQueryDmaBufModifiersEXT(egl->display, format, 0,
 | 
						if (!eglQueryDmaBufModifiersEXT(egl->display, format, 0,
 | 
				
			||||||
			NULL, NULL, &num)) {
 | 
								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;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -563,13 +589,17 @@ int wlr_egl_get_dmabuf_modifiers(struct wlr_egl *egl,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!eglQueryDmaBufModifiersEXT(egl->display, format, num,
 | 
						if (!eglQueryDmaBufModifiersEXT(egl->display, format, num,
 | 
				
			||||||
		*modifiers, NULL, &num)) {
 | 
							*modifiers, NULL, &num)) {
 | 
				
			||||||
		wlr_log(WLR_ERROR, "failed to query dmabuf modifiers");
 | 
							wlr_log(WLR_ERROR, "Failed to query dmabuf modifiers");
 | 
				
			||||||
		free(*modifiers);
 | 
							free(*modifiers);
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return num;
 | 
						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,
 | 
					bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
 | 
				
			||||||
		int32_t width, int32_t height, uint32_t flags,
 | 
							int32_t width, int32_t height, uint32_t flags,
 | 
				
			||||||
		struct wlr_dmabuf_attributes *attribs) {
 | 
							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);
 | 
						eglQueryWaylandBufferWL(renderer->egl->display, buffer, EGL_HEIGHT, height);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int gles2_get_dmabuf_formats(struct wlr_renderer *wlr_renderer,
 | 
					static const struct wlr_drm_format_set *gles2_get_dmabuf_formats(
 | 
				
			||||||
		int **formats) {
 | 
							struct wlr_renderer *wlr_renderer) {
 | 
				
			||||||
	struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
 | 
						struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
 | 
				
			||||||
	return wlr_egl_get_dmabuf_formats(renderer->egl, formats);
 | 
						return wlr_egl_get_dmabuf_formats(renderer->egl);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum wl_shm_format gles2_preferred_read_format(
 | 
					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,
 | 
						.resource_is_wl_drm_buffer = gles2_resource_is_wl_drm_buffer,
 | 
				
			||||||
	.wl_drm_buffer_get_size = gles2_wl_drm_buffer_get_size,
 | 
						.wl_drm_buffer_get_size = gles2_wl_drm_buffer_get_size,
 | 
				
			||||||
	.get_dmabuf_formats = gles2_get_dmabuf_formats,
 | 
						.get_dmabuf_formats = gles2_get_dmabuf_formats,
 | 
				
			||||||
	.get_dmabuf_modifiers = gles2_get_dmabuf_modifiers,
 | 
					 | 
				
			||||||
	.preferred_read_format = gles2_preferred_read_format,
 | 
						.preferred_read_format = gles2_preferred_read_format,
 | 
				
			||||||
	.read_pixels = gles2_read_pixels,
 | 
						.read_pixels = gles2_read_pixels,
 | 
				
			||||||
	.texture_from_pixels = gles2_texture_from_pixels,
 | 
						.texture_from_pixels = gles2_texture_from_pixels,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@ lib_wlr_render = static_library(
 | 
				
			||||||
	files(
 | 
						files(
 | 
				
			||||||
		'dmabuf.c',
 | 
							'dmabuf.c',
 | 
				
			||||||
		'egl.c',
 | 
							'egl.c',
 | 
				
			||||||
 | 
							'drm_format_set.c',
 | 
				
			||||||
		'gles2/pixel_format.c',
 | 
							'gles2/pixel_format.c',
 | 
				
			||||||
		'gles2/renderer.c',
 | 
							'gles2/renderer.c',
 | 
				
			||||||
		'gles2/shaders.c',
 | 
							'gles2/shaders.c',
 | 
				
			||||||
| 
						 | 
					@ -27,7 +28,7 @@ lib_wlr_render = static_library(
 | 
				
			||||||
		drm.partial_dependency(compile_args: true), # <drm_fourcc.h>
 | 
							drm.partial_dependency(compile_args: true), # <drm_fourcc.h>
 | 
				
			||||||
		glesv2,
 | 
							glesv2,
 | 
				
			||||||
		pixman,
 | 
							pixman,
 | 
				
			||||||
		wayland_server
 | 
							wayland_server,
 | 
				
			||||||
	],
 | 
						],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
						return r->impl->wl_drm_buffer_get_size(r, buffer, width, height);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int wlr_renderer_get_dmabuf_formats(struct wlr_renderer *r,
 | 
					const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_formats(
 | 
				
			||||||
		int **formats) {
 | 
							struct wlr_renderer *r) {
 | 
				
			||||||
	if (!r->impl->get_dmabuf_formats) {
 | 
						if (!r->impl->get_dmabuf_formats) {
 | 
				
			||||||
		return -1;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return r->impl->get_dmabuf_formats(r, formats);
 | 
						return r->impl->get_dmabuf_formats(r);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool wlr_renderer_read_pixels(struct wlr_renderer *r, enum wl_shm_format fmt,
 | 
					bool wlr_renderer_read_pixels(struct wlr_renderer *r, enum wl_shm_format fmt,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <wayland-server.h>
 | 
					#include <wayland-server.h>
 | 
				
			||||||
 | 
					#include <wlr/render/drm_format_set.h>
 | 
				
			||||||
#include <wlr/render/wlr_renderer.h>
 | 
					#include <wlr/render/wlr_renderer.h>
 | 
				
			||||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
 | 
					#include <wlr/types/wlr_linux_dmabuf_v1.h>
 | 
				
			||||||
#include <wlr/util/log.h>
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
| 
						 | 
					@ -386,45 +387,39 @@ struct wlr_linux_dmabuf_v1 *wlr_linux_dmabuf_v1_from_resource(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void linux_dmabuf_send_formats(struct wlr_linux_dmabuf_v1 *linux_dmabuf,
 | 
					static void linux_dmabuf_send_formats(struct wlr_linux_dmabuf_v1 *linux_dmabuf,
 | 
				
			||||||
		struct wl_resource *resource, uint32_t version) {
 | 
							struct wl_resource *resource, uint32_t version) {
 | 
				
			||||||
	struct wlr_renderer *renderer = linux_dmabuf->renderer;
 | 
					 | 
				
			||||||
	uint64_t modifier_invalid = DRM_FORMAT_MOD_INVALID;
 | 
						uint64_t modifier_invalid = DRM_FORMAT_MOD_INVALID;
 | 
				
			||||||
	int *formats = NULL;
 | 
						const struct wlr_drm_format_set *formats =
 | 
				
			||||||
	int num_formats = wlr_renderer_get_dmabuf_formats(renderer, &formats);
 | 
							wlr_renderer_get_dmabuf_formats(linux_dmabuf->renderer);
 | 
				
			||||||
	if (num_formats < 0) {
 | 
						if (formats == NULL) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (int i = 0; i < num_formats; i++) {
 | 
						for (size_t i = 0; i < formats->len; i++) {
 | 
				
			||||||
		uint64_t *modifiers = NULL;
 | 
							struct wlr_drm_format *fmt = formats->formats[i];
 | 
				
			||||||
		int num_modifiers = wlr_renderer_get_dmabuf_modifiers(renderer,
 | 
					
 | 
				
			||||||
			formats[i], &modifiers);
 | 
							size_t modifiers_len = fmt->len;
 | 
				
			||||||
		if (num_modifiers < 0) {
 | 
							uint64_t *modifiers = fmt->modifiers;
 | 
				
			||||||
			return;
 | 
					
 | 
				
			||||||
		}
 | 
							// Send DRM_FORMAT_MOD_INVALID token when no modifiers are supported
 | 
				
			||||||
		/* send DRM_FORMAT_MOD_INVALID token when no modifiers are supported
 | 
							// for this format
 | 
				
			||||||
		 * for this format */
 | 
							if (modifiers_len == 0) {
 | 
				
			||||||
		if (num_modifiers == 0) {
 | 
								modifiers_len = 1;
 | 
				
			||||||
			num_modifiers = 1;
 | 
					 | 
				
			||||||
			modifiers = &modifier_invalid;
 | 
								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) {
 | 
								if (version >= ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) {
 | 
				
			||||||
				uint32_t modifier_lo = modifiers[j] & 0xFFFFFFFF;
 | 
									uint32_t modifier_lo = modifiers[j] & 0xFFFFFFFF;
 | 
				
			||||||
				uint32_t modifier_hi = modifiers[j] >> 32;
 | 
									uint32_t modifier_hi = modifiers[j] >> 32;
 | 
				
			||||||
				zwp_linux_dmabuf_v1_send_modifier(resource,
 | 
									zwp_linux_dmabuf_v1_send_modifier(resource,
 | 
				
			||||||
					formats[i],
 | 
										fmt->format,
 | 
				
			||||||
					modifier_hi,
 | 
										modifier_hi,
 | 
				
			||||||
					modifier_lo);
 | 
										modifier_lo);
 | 
				
			||||||
			} else if (modifiers[j] == DRM_FORMAT_MOD_LINEAR ||
 | 
								} else if (modifiers[j] == DRM_FORMAT_MOD_LINEAR ||
 | 
				
			||||||
				   modifiers == &modifier_invalid) {
 | 
										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) {
 | 
					static void linux_dmabuf_resource_destroy(struct wl_resource *resource) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue