|  |  | @ -87,7 +87,7 @@ static void load_egl_proc(void *proc_ptr, const char *name) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats); |  |  |  | static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats); | 
			
		
	
		
		
			
				
					
					|  |  |  | static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format, |  |  |  | static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	uint64_t **modifiers); |  |  |  | 	uint64_t **modifiers, EGLBoolean **external_only); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void init_dmabuf_formats(struct wlr_egl *egl) { |  |  |  | static void init_dmabuf_formats(struct wlr_egl *egl) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int *formats; |  |  |  | 	int *formats; | 
			
		
	
	
		
		
			
				
					|  |  | @ -96,11 +96,20 @@ static void init_dmabuf_formats(struct wlr_egl *egl) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return; |  |  |  | 		return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	egl->external_only_dmabuf_formats = calloc(formats_len, sizeof(EGLBoolean *)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (egl->external_only_dmabuf_formats == NULL) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_log_errno(WLR_ERROR, "Allocation failed"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		goto out; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	size_t external_formats_len = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	for (int i = 0; i < formats_len; i++) { |  |  |  | 	for (int i = 0; i < formats_len; i++) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t fmt = formats[i]; |  |  |  | 		uint32_t fmt = formats[i]; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint64_t *modifiers; |  |  |  | 		uint64_t *modifiers; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		int modifiers_len = get_egl_dmabuf_modifiers(egl, fmt, &modifiers); |  |  |  | 		EGLBoolean *external_only; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		int modifiers_len = | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			get_egl_dmabuf_modifiers(egl, fmt, &modifiers, &external_only); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (modifiers_len < 0) { |  |  |  | 		if (modifiers_len < 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			continue; |  |  |  | 			continue; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
	
		
		
			
				
					|  |  | @ -114,6 +123,9 @@ static void init_dmabuf_formats(struct wlr_egl *egl) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		free(modifiers); |  |  |  | 		free(modifiers); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		egl->external_only_dmabuf_formats[external_formats_len] = external_only; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		external_formats_len++; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *str_formats = malloc(formats_len * 5 + 1); |  |  |  | 	char *str_formats = malloc(formats_len * 5 + 1); | 
			
		
	
	
		
		
			
				
					|  |  | @ -305,6 +317,11 @@ void wlr_egl_finish(struct wlr_egl *egl) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return; |  |  |  | 		return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	for (size_t i = 0; i < egl->dmabuf_formats.len; i++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		free(egl->external_only_dmabuf_formats[i]); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	free(egl->external_only_dmabuf_formats); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_drm_format_set_finish(&egl->dmabuf_formats); |  |  |  | 	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); | 
			
		
	
	
		
		
			
				
					|  |  | @ -479,8 +496,29 @@ EGLImageKHR wlr_egl_create_image_from_wl_drm(struct wlr_egl *egl, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		EGL_WAYLAND_BUFFER_WL, data, attribs); |  |  |  | 		EGL_WAYLAND_BUFFER_WL, data, attribs); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static bool dmabuf_format_is_external_only(struct wlr_egl *egl, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		uint32_t format, uint64_t modifier) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	for (size_t i = 0; i < egl->dmabuf_formats.len; i++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		struct wlr_drm_format *fmt = egl->dmabuf_formats.formats[i]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (fmt->format == format) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if (egl->external_only_dmabuf_formats[i] == NULL) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			for (size_t j = 0; j < fmt->len; j++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				if (fmt->modifiers[j] == modifier) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					return egl->external_only_dmabuf_formats[i][j]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	// No info, we're doomed. Choose GL_TEXTURE_EXTERNAL_OES and hope for the
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	// best.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl, |  |  |  | EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		struct wlr_dmabuf_attributes *attributes) { |  |  |  | 		struct wlr_dmabuf_attributes *attributes, bool *external_only) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	if (!egl->exts.image_base_khr || !egl->exts.image_dmabuf_import_ext) { |  |  |  | 	if (!egl->exts.image_base_khr || !egl->exts.image_dmabuf_import_ext) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wlr_log(WLR_ERROR, "dmabuf import extension not present"); |  |  |  | 		wlr_log(WLR_ERROR, "dmabuf import extension not present"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return NULL; |  |  |  | 		return NULL; | 
			
		
	
	
		
		
			
				
					|  |  | @ -561,8 +599,16 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	attribs[atti++] = EGL_NONE; |  |  |  | 	attribs[atti++] = EGL_NONE; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	assert(atti < sizeof(attribs)/sizeof(attribs[0])); |  |  |  | 	assert(atti < sizeof(attribs)/sizeof(attribs[0])); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	return egl->procs.eglCreateImageKHR(egl->display, EGL_NO_CONTEXT, |  |  |  | 	EGLImageKHR image = egl->procs.eglCreateImageKHR(egl->display, EGL_NO_CONTEXT, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		EGL_LINUX_DMA_BUF_EXT, NULL, attribs); |  |  |  | 		EGL_LINUX_DMA_BUF_EXT, NULL, attribs); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (image == EGL_NO_IMAGE_KHR) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_log(WLR_ERROR, "eglCreateImageKHR failed"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return EGL_NO_IMAGE_KHR; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	*external_only = dmabuf_format_is_external_only(egl, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		attributes->format, attributes->modifier); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	return image; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) { |  |  |  | static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -615,13 +661,15 @@ static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format, |  |  |  | static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint64_t **modifiers) { |  |  |  | 		uint64_t **modifiers, EGLBoolean **external_only) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	*modifiers = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	*external_only = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (!egl->exts.image_dmabuf_import_ext) { |  |  |  | 	if (!egl->exts.image_dmabuf_import_ext) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wlr_log(WLR_DEBUG, "DMA-BUF extension not present"); |  |  |  | 		wlr_log(WLR_DEBUG, "DMA-BUF extension not present"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return -1; |  |  |  | 		return -1; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (!egl->exts.image_dmabuf_import_modifiers_ext) { |  |  |  | 	if (!egl->exts.image_dmabuf_import_modifiers_ext) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		*modifiers = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return 0; |  |  |  | 		return 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -632,18 +680,24 @@ static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return -1; |  |  |  | 		return -1; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (num == 0) { |  |  |  | 	if (num == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		*modifiers = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return 0; |  |  |  | 		return 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	*modifiers = calloc(num, sizeof(uint64_t)); |  |  |  | 	*modifiers = calloc(num, sizeof(uint64_t)); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (*modifiers == NULL) { |  |  |  | 	if (*modifiers == NULL) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wlr_log(WLR_ERROR, "Allocation failed: %s", strerror(errno)); |  |  |  | 		wlr_log_errno(WLR_ERROR, "Allocation failed"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	*external_only = calloc(num, sizeof(EGLBoolean)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (*external_only == NULL) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_log_errno(WLR_ERROR, "Allocation failed"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		free(*modifiers); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		*modifiers = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return -1; |  |  |  | 		return -1; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (!egl->procs.eglQueryDmaBufModifiersEXT(egl->display, format, num, |  |  |  | 	if (!egl->procs.eglQueryDmaBufModifiersEXT(egl->display, format, num, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		*modifiers, NULL, &num)) { |  |  |  | 			*modifiers, *external_only, &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; | 
			
		
	
	
		
		
			
				
					|  |  | 
 |