|  |  | @ -62,7 +62,9 @@ static void backend_destroy(struct wlr_backend *wlr_backend) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_signal_emit_safe(&wlr_backend->events.destroy, backend); |  |  |  | 	wlr_signal_emit_safe(&wlr_backend->events.destroy, backend); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_renderer_destroy(backend->renderer); |  |  |  | 	wlr_renderer_destroy(backend->renderer); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_egl_finish(&backend->egl); |  |  |  | 	if (backend->egl == &backend->priv_egl) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_egl_finish(&backend->priv_egl); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	free(backend); |  |  |  | 	free(backend); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -85,6 +87,34 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	backend_destroy(&backend->backend); |  |  |  | 	backend_destroy(&backend->backend); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static bool backend_init(struct wlr_headless_backend *backend, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		struct wl_display *display, struct wlr_renderer *renderer) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	wlr_backend_init(&backend->backend, &backend_impl); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	backend->display = display; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	wl_list_init(&backend->outputs); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	wl_list_init(&backend->input_devices); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	backend->renderer = renderer; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	backend->egl = wlr_gles2_renderer_get_egl(renderer); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (wlr_gles2_renderer_check_ext(backend->renderer, "GL_OES_rgb8_rgba8") || | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			wlr_gles2_renderer_check_ext(backend->renderer, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				"GL_OES_required_internalformat") || | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			wlr_gles2_renderer_check_ext(backend->renderer, "GL_ARM_rgba8")) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		backend->internal_format = GL_RGBA8_OES; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_log(WLR_INFO, "GL_RGBA8_OES not supported, " | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			"falling back to GL_RGBA4 internal format " | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			"(performance may be affected)"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		backend->internal_format = GL_RGBA4; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	backend->display_destroy.notify = handle_display_destroy; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	wl_display_add_destroy_listener(display, &backend->display_destroy); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | struct wlr_backend *wlr_headless_backend_create(struct wl_display *display, |  |  |  | struct wlr_backend *wlr_headless_backend_create(struct wl_display *display, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wlr_renderer_create_func_t create_renderer_func) { |  |  |  | 		wlr_renderer_create_func_t create_renderer_func) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_log(WLR_INFO, "Creating headless backend"); |  |  |  | 	wlr_log(WLR_INFO, "Creating headless backend"); | 
			
		
	
	
		
		
			
				
					|  |  | @ -95,10 +125,6 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_display *display, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wlr_log(WLR_ERROR, "Failed to allocate wlr_headless_backend"); |  |  |  | 		wlr_log(WLR_ERROR, "Failed to allocate wlr_headless_backend"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return NULL; |  |  |  | 		return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_backend_init(&backend->backend, &backend_impl); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	backend->display = display; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_list_init(&backend->outputs); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_list_init(&backend->input_devices); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	static const EGLint config_attribs[] = { |  |  |  | 	static const EGLint config_attribs[] = { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		EGL_SURFACE_TYPE, 0, |  |  |  | 		EGL_SURFACE_TYPE, 0, | 
			
		
	
	
		
		
			
				
					|  |  | @ -113,36 +139,41 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_display *display, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		create_renderer_func = wlr_renderer_autocreate; |  |  |  | 		create_renderer_func = wlr_renderer_autocreate; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	backend->renderer = create_renderer_func(&backend->egl, |  |  |  | 	struct wlr_renderer *renderer = create_renderer_func(&backend->priv_egl, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, |  |  |  | 		EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		(EGLint*)config_attribs, 0); |  |  |  | 		(EGLint*)config_attribs, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (!backend->renderer) { |  |  |  | 	if (!renderer) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 		wlr_log(WLR_ERROR, "Failed to create renderer"); |  |  |  | 		wlr_log(WLR_ERROR, "Failed to create renderer"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		goto error_backend; |  |  |  | 		free(backend); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (wlr_gles2_renderer_check_ext(backend->renderer, "GL_OES_rgb8_rgba8") || |  |  |  | 	if (!backend_init(backend, display, renderer)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_gles2_renderer_check_ext(backend->renderer, |  |  |  | 		wlr_renderer_destroy(backend->renderer); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				"GL_OES_required_internalformat") || |  |  |  | 		free(backend); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_gles2_renderer_check_ext(backend->renderer, "GL_ARM_rgba8")) { |  |  |  | 		return NULL; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 		backend->internal_format = GL_RGBA8_OES; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} else { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wlr_log(WLR_INFO, "GL_RGBA8_OES not supported, " |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			"falling back to GL_RGBA4 internal format " |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			"(performance may be affected)"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		backend->internal_format = GL_RGBA4; |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	backend->display_destroy.notify = handle_display_destroy; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_display_add_destroy_listener(display, &backend->display_destroy); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	return &backend->backend; |  |  |  | 	return &backend->backend; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | error_renderer: |  |  |  | struct wlr_backend *wlr_headless_backend_create_with_renderer( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_renderer_destroy(backend->renderer); |  |  |  | 		struct wl_display *display, struct wlr_renderer *renderer) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | error_backend: |  |  |  | 	wlr_log(WLR_INFO, "Creating headless backend"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	free(backend); |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	return NULL; |  |  |  | 	struct wlr_headless_backend *backend = | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		calloc(1, sizeof(struct wlr_headless_backend)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!backend) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_log(WLR_ERROR, "Failed to allocate wlr_headless_backend"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!backend_init(backend, display, renderer)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		free(backend); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	return &backend->backend; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | bool wlr_backend_is_headless(struct wlr_backend *backend) { |  |  |  | bool wlr_backend_is_headless(struct wlr_backend *backend) { | 
			
		
	
	
		
		
			
				
					|  |  | 
 |