Refactor EGL handling
This commit is contained in:
		
							parent
							
								
									4aaf76cb66
								
							
						
					
					
						commit
						c24351681f
					
				|  | @ -39,6 +39,13 @@ void wlr_backend_destroy(struct wlr_backend *backend) { | |||
| 	free(backend); | ||||
| } | ||||
| 
 | ||||
| struct wlr_egl *wlr_backend_get_egl(struct wlr_backend *backend) { | ||||
| 	if (!backend->impl->get_egl) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return backend->impl->get_egl(backend->state); | ||||
| } | ||||
| 
 | ||||
| static struct wlr_backend *attempt_wl_backend(struct wl_display *display) { | ||||
| 	struct wlr_backend *backend = wlr_wl_backend_create(display); | ||||
| 	if (backend) { | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ | |||
| #include <wlr/interfaces/wlr_output.h> | ||||
| #include <wlr/util/list.h> | ||||
| #include <wlr/util/log.h> | ||||
| #include <wlr/egl.h> | ||||
| #include "backend/udev.h" | ||||
| #include "backend/drm.h" | ||||
| 
 | ||||
|  | @ -38,9 +39,14 @@ static void wlr_drm_backend_destroy(struct wlr_backend_state *drm) { | |||
| 	free(drm); | ||||
| } | ||||
| 
 | ||||
| static struct wlr_egl *wlr_drm_backend_get_egl(struct wlr_backend_state *drm) { | ||||
| 	return &drm->renderer.egl; | ||||
| } | ||||
| 
 | ||||
| static struct wlr_backend_impl backend_impl = { | ||||
| 	.init = wlr_drm_backend_init, | ||||
| 	.destroy = wlr_drm_backend_destroy | ||||
| 	.destroy = wlr_drm_backend_destroy, | ||||
| 	.get_egl = wlr_drm_backend_get_egl | ||||
| }; | ||||
| 
 | ||||
| static void session_signal(struct wl_listener *listener, void *data) { | ||||
|  |  | |||
|  | @ -579,7 +579,7 @@ static bool wlr_drm_output_set_cursor(struct wlr_output_state *output, | |||
| 		wlr_matrix_texture(plane->matrix, plane->width, plane->height, | ||||
| 			output->base->transform ^ WL_OUTPUT_TRANSFORM_FLIPPED_180); | ||||
| 
 | ||||
| 		plane->wlr_rend = wlr_gles2_renderer_init(&output->renderer->egl); | ||||
| 		plane->wlr_rend = wlr_gles2_renderer_init(drm->base); | ||||
| 		if (!plane->wlr_rend) { | ||||
| 			return false; | ||||
| 		} | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| wlr_files += files( | ||||
|     'backend.c', | ||||
|     'egl.c', | ||||
|     'udev.c', | ||||
|     'session/direct-ipc.c', | ||||
|     'session/direct.c', | ||||
|  |  | |||
|  | @ -38,9 +38,21 @@ static void multi_backend_destroy(struct wlr_backend_state *state) { | |||
| 	free(state); | ||||
| } | ||||
| 
 | ||||
| static struct wlr_egl *multi_backend_get_egl(struct wlr_backend_state *state) { | ||||
| 	for (size_t i = 0; i < state->backends->length; ++i) { | ||||
| 		struct subbackend_state *sub = state->backends->items[i]; | ||||
| 		struct wlr_egl *egl = wlr_backend_get_egl(sub->backend); | ||||
| 		if (egl) { | ||||
| 			return egl; | ||||
| 		} | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| struct wlr_backend_impl backend_impl = { | ||||
| 	.init = multi_backend_init, | ||||
| 	.destroy = multi_backend_destroy | ||||
| 	.destroy = multi_backend_destroy, | ||||
| 	.get_egl = multi_backend_get_egl | ||||
| }; | ||||
| 
 | ||||
| struct wlr_backend *wlr_multi_backend_create(struct wlr_session *session, | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include <EGL/egl.h> | ||||
| #include <EGL/eglext.h> | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/egl.h> | ||||
| #include <wlr/backend/interface.h> | ||||
| #include <wlr/interfaces/wlr_output.h> | ||||
| #include <wlr/interfaces/wlr_input_device.h> | ||||
|  | @ -95,9 +96,14 @@ static void wlr_wl_backend_destroy(struct wlr_backend_state *state) { | |||
| 	free(state); | ||||
| } | ||||
| 
 | ||||
| static struct wlr_egl *wlr_wl_backend_get_egl(struct wlr_backend_state *state) { | ||||
| 	return &state->egl; | ||||
| } | ||||
| 
 | ||||
| static struct wlr_backend_impl backend_impl = { | ||||
| 	.init = wlr_wl_backend_init, | ||||
| 	.destroy = wlr_wl_backend_destroy | ||||
| 	.destroy = wlr_wl_backend_destroy, | ||||
| 	.get_egl = wlr_wl_backend_get_egl | ||||
| }; | ||||
| 
 | ||||
| bool wlr_backend_is_wl(struct wlr_backend *b) { | ||||
|  |  | |||
|  | @ -68,7 +68,7 @@ int main() { | |||
| 	}; | ||||
| 	compositor_init(&compositor); | ||||
| 
 | ||||
| 	state.renderer = wlr_gles2_renderer_init(); | ||||
| 	state.renderer = wlr_gles2_renderer_init(compositor.backend); | ||||
| 	wl_display_init_shm(compositor.display); | ||||
| 	wl_compositor_init(compositor.display, &state.compositor, state.renderer); | ||||
| 	wl_shell_init(compositor.display, &state.shell); | ||||
|  |  | |||
|  | @ -204,7 +204,7 @@ int main(int argc, char *argv[]) { | |||
| 	compositor.keyboard_key_cb = handle_keyboard_key; | ||||
| 	compositor_init(&compositor); | ||||
| 
 | ||||
| 	state.renderer = wlr_gles2_renderer_init(); | ||||
| 	state.renderer = wlr_gles2_renderer_init(compositor.backend); | ||||
| 	state.cat_texture = wlr_render_texture_init(state.renderer); | ||||
| 	wlr_texture_upload_pixels(state.cat_texture, WL_SHM_FORMAT_ABGR8888, | ||||
| 		cat_tex.width, cat_tex.width, cat_tex.height, cat_tex.pixel_data); | ||||
|  |  | |||
|  | @ -152,7 +152,7 @@ int main(int argc, char *argv[]) { | |||
| 	}; | ||||
| 	compositor_init(&compositor); | ||||
| 
 | ||||
| 	state.renderer = wlr_gles2_renderer_init(); | ||||
| 	state.renderer = wlr_gles2_renderer_init(compositor.backend); | ||||
| 	compositor_run(&compositor); | ||||
| 
 | ||||
| 	wlr_renderer_destroy(state.renderer); | ||||
|  |  | |||
|  | @ -104,7 +104,7 @@ int main(int argc, char *argv[]) { | |||
| 	}; | ||||
| 	compositor_init(&compositor); | ||||
| 
 | ||||
| 	state.renderer = wlr_gles2_renderer_init(); | ||||
| 	state.renderer = wlr_gles2_renderer_init(compositor.backend); | ||||
| 	state.cat_texture = wlr_render_texture_init(state.renderer); | ||||
| 	wlr_texture_upload_pixels(state.cat_texture, WL_SHM_FORMAT_ARGB8888, | ||||
| 		cat_tex.width, cat_tex.width, cat_tex.height, cat_tex.pixel_data); | ||||
|  |  | |||
|  | @ -12,9 +12,9 @@ | |||
| 
 | ||||
| #include <wlr/backend/session.h> | ||||
| #include <wlr/backend/drm.h> | ||||
| #include <wlr/egl.h> | ||||
| #include <wlr/util/list.h> | ||||
| 
 | ||||
| #include <backend/egl.h> | ||||
| #include <backend/udev.h> | ||||
| #include "drm-properties.h" | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,10 +4,10 @@ | |||
| #include <wayland-client.h> | ||||
| #include <wayland-server.h> | ||||
| #include <wayland-egl.h> | ||||
| #include <wlr/egl.h> | ||||
| #include <wlr/backend/wayland.h> | ||||
| #include <wlr/types/wlr_input_device.h> | ||||
| #include <wlr/util/list.h> | ||||
| #include "backend/egl.h" | ||||
| 
 | ||||
| struct wlr_backend_state { | ||||
| 	/* local state */ | ||||
|  |  | |||
|  | @ -7,6 +7,8 @@ | |||
| #include <GLES2/gl2ext.h> | ||||
| #include <EGL/egl.h> | ||||
| #include <EGL/eglext.h> | ||||
| #include <wlr/egl.h> | ||||
| #include <wlr/backend.h> | ||||
| #include <wlr/render.h> | ||||
| #include <wlr/util/log.h> | ||||
| 
 | ||||
|  | @ -19,8 +21,14 @@ struct pixel_format { | |||
| 	GLuint *shader; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_renderer_state { | ||||
| 	struct wlr_renderer *renderer; | ||||
| 	struct wlr_egl *egl; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_texture_state { | ||||
| 	struct wlr_texture *wlr_texture; | ||||
| 	struct wlr_egl *egl; | ||||
| 	GLuint tex_id; | ||||
| 	const struct pixel_format *pixel_format; | ||||
| 	EGLImageKHR image; | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| 
 | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/backend/session.h> | ||||
| #include <wlr/egl.h> | ||||
| 
 | ||||
| struct wlr_backend_impl; | ||||
| struct wlr_backend_state; | ||||
|  | @ -22,5 +23,6 @@ struct wlr_backend { | |||
| struct wlr_backend *wlr_backend_autocreate(struct wl_display *display); | ||||
| bool wlr_backend_init(struct wlr_backend *backend); | ||||
| void wlr_backend_destroy(struct wlr_backend *backend); | ||||
| struct wlr_egl *wlr_backend_get_egl(struct wlr_backend *backend); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -3,12 +3,14 @@ | |||
| 
 | ||||
| #include <stdbool.h> | ||||
| #include <wlr/backend.h> | ||||
| #include <wlr/egl.h> | ||||
| 
 | ||||
| struct wlr_backend_state; | ||||
| 
 | ||||
| struct wlr_backend_impl { | ||||
| 	bool (*init)(struct wlr_backend_state *state); | ||||
| 	void (*destroy)(struct wlr_backend_state *state); | ||||
| 	struct wlr_egl *(*get_egl)(struct wlr_backend_state *state); | ||||
| }; | ||||
| 
 | ||||
| struct wlr_backend *wlr_backend_create(const struct wlr_backend_impl *impl, | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| #ifndef WLR_BACKEND_EGL_H | ||||
| #define WLR_BACKEND_EGL_H | ||||
| #ifndef WLR_EGL_H | ||||
| #define WLR_EGL_H | ||||
| 
 | ||||
| #include <EGL/egl.h> | ||||
| #include <EGL/eglext.h> | ||||
|  | @ -10,12 +10,22 @@ struct wlr_egl { | |||
| 	EGLConfig config; | ||||
| 	EGLContext context; | ||||
| 
 | ||||
| 	PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display; | ||||
| 	PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC create_platform_window_surface; | ||||
| 
 | ||||
| 	PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; | ||||
| 	PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; | ||||
| 	PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL; | ||||
| 	PFNEGLBINDWAYLANDDISPLAYWL eglBindWaylandDisplayWL; | ||||
| 	PFNEGLUNBINDWAYLANDDISPLAYWL eglUnbindWaylandDisplayWL; | ||||
| 
 | ||||
| 	const char *egl_exts; | ||||
| 	const char *gl_exts; | ||||
| 
 | ||||
| 	struct wl_display *wl_display; | ||||
| }; | ||||
| 
 | ||||
| // TODO: Allocate and return a wlr_egl
 | ||||
| /**
 | ||||
|  *  Initializes an egl context for the given platform and remote display. | ||||
|  * Will attempt to load all possibly required api functions. | ||||
|  | @ -35,15 +45,9 @@ void wlr_egl_free(struct wlr_egl *egl); | |||
| bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display); | ||||
| 
 | ||||
| /**
 | ||||
|  * Queries information about the given (potential egl/drm) buffer, returns | ||||
|  * the information in value. | ||||
|  * Refer to eglQueryWaylandBufferWL for more information about attrib and value. | ||||
|  * Makes only sense when a wl_display was bound to it since otherwise there | ||||
|  * cannot be any egl/drm buffers. | ||||
|  * Will only work after a wlr_egl objct was initialized and if the needed egl extension | ||||
|  * is present. | ||||
|  * Refer to the eglQueryWaylandBufferWL extension function. | ||||
|  */ | ||||
| bool wlr_egl_query_buffer(struct wl_resource *buf, | ||||
| bool wlr_egl_query_buffer(struct wlr_egl *egl, struct wl_resource *buf, | ||||
| 	EGLint attrib, EGLint *value); | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -54,16 +58,14 @@ EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window); | |||
| 
 | ||||
| /**
 | ||||
|  * Creates an egl image from the given client buffer and attributes. | ||||
|  * Will only work after a wlr_egl objct was initialized and if the needed egl extension | ||||
|  * is present. | ||||
|  */ | ||||
| EGLImageKHR wlr_egl_create_image(EGLenum target, EGLClientBuffer buffer, | ||||
| 	const EGLint *attribs); | ||||
| EGLImageKHR wlr_egl_create_image(struct wlr_egl *egl, | ||||
| 		EGLenum target, EGLClientBuffer buffer, const EGLint *attribs); | ||||
| 
 | ||||
| /**
 | ||||
|  * Destroys an egl image created with the given wlr_egl. | ||||
|  */ | ||||
| bool wlr_egl_destroy_image(EGLImageKHR image); | ||||
| bool wlr_egl_destroy_image(struct wlr_egl *egl, EGLImageKHR image); | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns a string for the last error ocurred with egl. | ||||
|  | @ -43,6 +43,11 @@ void wlr_render_colored_ellipse(struct wlr_renderer *r, | |||
|  */ | ||||
| const enum wl_shm_format *wlr_renderer_get_formats( | ||||
| 		struct wlr_renderer *r, size_t *len); | ||||
| /**
 | ||||
|  * Returns true if this wl_buffer is a DRM buffer. | ||||
|  */ | ||||
| bool wlr_renderer_buffer_is_drm(struct wlr_renderer *renderer, | ||||
| 		struct wl_resource *buffer); | ||||
| /**
 | ||||
|  * Destroys this wlr_renderer. Textures must be destroyed separately. | ||||
|  */ | ||||
|  |  | |||
|  | @ -1,8 +1,9 @@ | |||
| #ifndef _WLR_GLES2_RENDERER_H | ||||
| #define _WLR_GLES2_RENDERER_H | ||||
| #include <wlr/render.h> | ||||
| #include <wlr/backend.h> | ||||
| 
 | ||||
| struct wlr_egl; | ||||
| struct wlr_renderer *wlr_gles2_renderer_init(); | ||||
| struct wlr_renderer *wlr_gles2_renderer_init(struct wlr_backend *backend); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -25,6 +25,8 @@ struct wlr_renderer_impl { | |||
| 		const float (*color)[4], const float (*matrix)[16]); | ||||
| 	const enum wl_shm_format *(*formats)( | ||||
| 		struct wlr_renderer_state *state, size_t *len); | ||||
| 	bool (*buffer_is_drm)(struct wlr_renderer_state *state, | ||||
| 		struct wl_resource *buffer); | ||||
| 	void (*destroy)(struct wlr_renderer_state *state); | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ struct wlr_surface_state { | |||
| 
 | ||||
| struct wlr_surface { | ||||
| 	struct wl_resource *resource; | ||||
| 	struct wlr_renderer *renderer; | ||||
| 	struct wlr_texture *texture; | ||||
| 	struct wlr_surface_state current, pending; | ||||
| 	const char *role; // the lifetime-bound role or null
 | ||||
|  |  | |||
|  | @ -4,14 +4,12 @@ | |||
| #include <gbm.h> // GBM_FORMAT_XRGB8888 | ||||
| #include <stdlib.h> | ||||
| #include <wlr/util/log.h> | ||||
| #include "backend/egl.h" | ||||
| #include <wlr/egl.h> | ||||
| 
 | ||||
| // Extension documentation
 | ||||
| // https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_image_base.txt.
 | ||||
| // https://cgit.freedesktop.org/mesa/mesa/tree/docs/specs/WL_bind_wayland_display.spec
 | ||||
| 
 | ||||
| struct wlr_egl *egl_global; | ||||
| 
 | ||||
| const char *egl_error(void) { | ||||
| 	switch (eglGetError()) { | ||||
| 	case EGL_SUCCESS: | ||||
|  | @ -49,29 +47,19 @@ const char *egl_error(void) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // EGL extensions
 | ||||
| PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display; | ||||
| PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC create_platform_window_surface; | ||||
| 
 | ||||
| PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; | ||||
| PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; | ||||
| PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL; | ||||
| PFNEGLBINDWAYLANDDISPLAYWL eglBindWaylandDisplayWL; | ||||
| PFNEGLUNBINDWAYLANDDISPLAYWL eglUnbindWaylandDisplayWL; | ||||
| 
 | ||||
| static bool egl_exts() { | ||||
| 	get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC) | ||||
| static bool egl_exts(struct wlr_egl *egl) { | ||||
| 	egl->get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC) | ||||
| 		eglGetProcAddress("eglGetPlatformDisplayEXT"); | ||||
| 
 | ||||
| 	if (!get_platform_display) { | ||||
| 	if (!egl->get_platform_display) { | ||||
| 		wlr_log(L_ERROR, "Failed to load EGL extension 'eglGetPlatformDisplayEXT'"); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	create_platform_window_surface = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) | ||||
| 	egl->create_platform_window_surface = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) | ||||
| 		eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); | ||||
| 
 | ||||
| 	if (!get_platform_display) { | ||||
| 	if (!egl->get_platform_display) { | ||||
| 		wlr_log(L_ERROR, | ||||
| 			"Failed to load EGL extension 'eglCreatePlatformWindowSurfaceEXT'"); | ||||
| 		return false; | ||||
|  | @ -124,7 +112,7 @@ static bool egl_get_config(EGLDisplay disp, EGLConfig *out, EGLenum platform) { | |||
| 
 | ||||
| bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, | ||||
| 		void *remote_display) { | ||||
| 	if (!egl_exts()) { | ||||
| 	if (!egl_exts(egl)) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -133,7 +121,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, | |||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	egl->display = get_platform_display(platform, remote_display, NULL); | ||||
| 	egl->display = egl->get_platform_display(platform, remote_display, NULL); | ||||
| 	if (egl->display == EGL_NO_DISPLAY) { | ||||
| 		wlr_log(L_ERROR, "Failed to create EGL display: %s", egl_error()); | ||||
| 		goto error; | ||||
|  | @ -168,19 +156,17 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, | |||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) | ||||
| 	egl->eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) | ||||
| 		eglGetProcAddress("eglCreateImageKHR"); | ||||
| 	eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) | ||||
| 	egl->eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) | ||||
| 		eglGetProcAddress("eglDestroyImageKHR"); | ||||
| 	eglQueryWaylandBufferWL = (PFNEGLQUERYWAYLANDBUFFERWL) | ||||
| 	egl->eglQueryWaylandBufferWL = (PFNEGLQUERYWAYLANDBUFFERWL) | ||||
| 		(void*) eglGetProcAddress("eglQueryWaylandBufferWL"); | ||||
| 	eglBindWaylandDisplayWL = (PFNEGLBINDWAYLANDDISPLAYWL) | ||||
| 	egl->eglBindWaylandDisplayWL = (PFNEGLBINDWAYLANDDISPLAYWL) | ||||
| 		(void*) eglGetProcAddress("eglBindWaylandDisplayWL"); | ||||
| 	eglUnbindWaylandDisplayWL = (PFNEGLUNBINDWAYLANDDISPLAYWL) | ||||
| 	egl->eglUnbindWaylandDisplayWL = (PFNEGLUNBINDWAYLANDDISPLAYWL) | ||||
| 		(void*) eglGetProcAddress("eglUnbindWaylandDisplayWL"); | ||||
| 
 | ||||
| 	egl_global = egl; | ||||
| 
 | ||||
| 	egl->gl_exts = (const char*) glGetString(GL_EXTENSIONS); | ||||
| 	wlr_log(L_INFO, "Using EGL %d.%d", (int)major, (int)minor); | ||||
| 	wlr_log(L_INFO, "Supported EGL extensions: %s", egl->egl_exts); | ||||
|  | @ -196,25 +182,22 @@ error: | |||
| } | ||||
| 
 | ||||
| void wlr_egl_free(struct wlr_egl *egl) { | ||||
| 	if (egl->wl_display && eglUnbindWaylandDisplayWL) { | ||||
| 		eglUnbindWaylandDisplayWL(egl->display, egl->wl_display); | ||||
| 	if (egl->wl_display && egl->eglUnbindWaylandDisplayWL) { | ||||
| 		egl->eglUnbindWaylandDisplayWL(egl->display, egl->wl_display); | ||||
| 	} | ||||
| 
 | ||||
| 	eglDestroyContext(egl->display, egl->context); | ||||
| 	eglTerminate(egl->display); | ||||
| 	eglReleaseThread(); | ||||
| 	eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | ||||
| 
 | ||||
| 	if (egl_global == egl) | ||||
| 		egl_global = NULL; | ||||
| } | ||||
| 
 | ||||
| bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display) { | ||||
| 	if (!eglBindWaylandDisplayWL) { | ||||
| 	if (!egl->eglBindWaylandDisplayWL) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (eglBindWaylandDisplayWL(egl->display, local_display)) { | ||||
| 	if (egl->eglBindWaylandDisplayWL(egl->display, local_display)) { | ||||
| 		egl->wl_display = local_display; | ||||
| 		return true; | ||||
| 	} | ||||
|  | @ -222,35 +205,35 @@ bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display) | |||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool wlr_egl_query_buffer(struct wl_resource *buf, int attrib, int *value) { | ||||
| 	if (!egl_global || !eglQueryWaylandBufferWL) { | ||||
| bool wlr_egl_query_buffer(struct wlr_egl *egl, struct wl_resource *buf, | ||||
| 		int attrib, int *value) { | ||||
| 	if (!egl->eglQueryWaylandBufferWL) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	return eglQueryWaylandBufferWL(egl_global->display, buf, attrib, value); | ||||
| 	return egl->eglQueryWaylandBufferWL(egl->display, buf, attrib, value); | ||||
| } | ||||
| 
 | ||||
| EGLImage wlr_egl_create_image(EGLenum target, | ||||
| EGLImage wlr_egl_create_image(struct wlr_egl *egl, EGLenum target, | ||||
| 		EGLClientBuffer buffer, const EGLint *attribs) { | ||||
| 	if (!egl_global || !eglCreateImageKHR) { | ||||
| 	if (!egl->eglCreateImageKHR) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	return eglCreateImageKHR(egl_global->display, egl_global->context, target, | ||||
| 	return egl->eglCreateImageKHR(egl->display, egl->context, target, | ||||
| 		buffer, attribs); | ||||
| } | ||||
| 
 | ||||
| bool wlr_egl_destroy_image(EGLImage image) { | ||||
| 	if (!egl_global || !eglDestroyImageKHR) { | ||||
| bool wlr_egl_destroy_image(struct wlr_egl *egl, EGLImage image) { | ||||
| 	if (!egl->eglDestroyImageKHR) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	eglDestroyImageKHR(egl_global->display, image); | ||||
| 	egl->eglDestroyImageKHR(egl->display, image); | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window) { | ||||
| 	EGLSurface surf = create_platform_window_surface(egl->display, egl->config, | ||||
| 	EGLSurface surf = egl->create_platform_window_surface(egl->display, egl->config, | ||||
| 		window, NULL); | ||||
| 	if (surf == EGL_NO_SURFACE) { | ||||
| 		wlr_log(L_ERROR, "Failed to create EGL surface: %s", egl_error()); | ||||
|  | @ -5,11 +5,12 @@ | |||
| #include <GLES2/gl2ext.h> | ||||
| #include <wayland-util.h> | ||||
| #include <wayland-server-protocol.h> | ||||
| #include <wlr/egl.h> | ||||
| #include <wlr/backend.h> | ||||
| #include <wlr/render.h> | ||||
| #include <wlr/render/interface.h> | ||||
| #include <wlr/render/matrix.h> | ||||
| #include <wlr/util/log.h> | ||||
| #include "backend/egl.h" | ||||
| #include "render/gles2.h" | ||||
| 
 | ||||
| PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = NULL; | ||||
|  | @ -123,7 +124,7 @@ static void wlr_gles2_end(struct wlr_renderer_state *state) { | |||
| } | ||||
| 
 | ||||
| static struct wlr_texture *wlr_gles2_texture_init(struct wlr_renderer_state *state) { | ||||
| 	return gles2_texture_init(); | ||||
| 	return gles2_texture_init(state->egl); | ||||
| } | ||||
| 
 | ||||
| static void draw_quad() { | ||||
|  | @ -195,8 +196,14 @@ static const enum wl_shm_format *wlr_gles2_formats( | |||
| 	return formats; | ||||
| } | ||||
| 
 | ||||
| static bool wlr_gles2_buffer_is_drm(struct wlr_renderer_state *state, | ||||
| 		struct wl_resource *buffer) { | ||||
| 	EGLint format; | ||||
| 	return wlr_egl_query_buffer(state->egl, buffer, EGL_TEXTURE_FORMAT, &format); | ||||
| } | ||||
| 
 | ||||
| static void wlr_gles2_destroy(struct wlr_renderer_state *state) { | ||||
| 	// no-op
 | ||||
| 	free(state); | ||||
| } | ||||
| 
 | ||||
| static struct wlr_renderer_impl wlr_renderer_impl = { | ||||
|  | @ -207,10 +214,16 @@ static struct wlr_renderer_impl wlr_renderer_impl = { | |||
| 	.render_quad = wlr_gles2_render_quad, | ||||
| 	.render_ellipse = wlr_gles2_render_ellipse, | ||||
| 	.formats = wlr_gles2_formats, | ||||
| 	.buffer_is_drm = wlr_gles2_buffer_is_drm, | ||||
| 	.destroy = wlr_gles2_destroy | ||||
| }; | ||||
| 
 | ||||
| struct wlr_renderer *wlr_gles2_renderer_init(struct wlr_egl *egl) { | ||||
| struct wlr_renderer *wlr_gles2_renderer_init(struct wlr_backend *backend) { | ||||
| 	init_globals(); | ||||
| 	return wlr_renderer_init(NULL, &wlr_renderer_impl); | ||||
| 	struct wlr_egl *egl = wlr_backend_get_egl(backend); | ||||
| 	struct wlr_renderer_state *state = calloc(1, sizeof(struct wlr_renderer_state)); | ||||
| 	struct wlr_renderer *renderer = wlr_renderer_init(state, &wlr_renderer_impl); | ||||
| 	state->renderer = renderer; | ||||
| 	state->egl = egl; | ||||
| 	return renderer; | ||||
| } | ||||
|  |  | |||
|  | @ -5,12 +5,12 @@ | |||
| #include <GLES2/gl2ext.h> | ||||
| #include <wayland-util.h> | ||||
| #include <wayland-server-protocol.h> | ||||
| #include <wlr/egl.h> | ||||
| #include <wlr/render.h> | ||||
| #include <wlr/render/interface.h> | ||||
| #include <wlr/render/matrix.h> | ||||
| #include <wlr/util/log.h> | ||||
| #include "render/gles2.h" | ||||
| #include "backend/egl.h" | ||||
| 
 | ||||
| static struct pixel_format external_pixel_format = { | ||||
| 	.wl_format = 0, | ||||
|  | @ -139,23 +139,25 @@ static bool gles2_texture_update_shm(struct wlr_texture_state *texture, | |||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| static bool gles2_texture_upload_drm(struct wlr_texture_state *texture, | ||||
| 		struct wl_resource* buf) { | ||||
| static bool gles2_texture_upload_drm(struct wlr_texture_state *tex, | ||||
| 		struct wl_resource *buf) { | ||||
| 	if (!glEGLImageTargetTexture2DOES) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	EGLint format; | ||||
| 	if (!wlr_egl_query_buffer(buf, EGL_TEXTURE_FORMAT, &format)) { | ||||
| 	if (!wlr_egl_query_buffer(tex->egl, buf, EGL_TEXTURE_FORMAT, &format)) { | ||||
| 		wlr_log(L_INFO, "upload_drm called with no drm buffer"); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	wlr_egl_query_buffer(buf, EGL_WIDTH, (EGLint*) &texture->wlr_texture->width); | ||||
| 	wlr_egl_query_buffer(buf, EGL_HEIGHT, (EGLint*) &texture->wlr_texture->height); | ||||
| 	wlr_egl_query_buffer(tex->egl, buf, EGL_WIDTH, | ||||
| 			(EGLint*)&tex->wlr_texture->width); | ||||
| 	wlr_egl_query_buffer(tex->egl, buf, EGL_HEIGHT, | ||||
| 			(EGLint*)&tex->wlr_texture->height); | ||||
| 
 | ||||
| 	EGLint inverted_y; | ||||
| 	wlr_egl_query_buffer(buf, EGL_WAYLAND_Y_INVERTED_WL, &inverted_y); | ||||
| 	wlr_egl_query_buffer(tex->egl, buf, EGL_WAYLAND_Y_INVERTED_WL, &inverted_y); | ||||
| 
 | ||||
| 	GLenum target; | ||||
| 	const struct pixel_format *pf; | ||||
|  | @ -174,22 +176,22 @@ static bool gles2_texture_upload_drm(struct wlr_texture_state *texture, | |||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	gles2_texture_gen_texture(texture); | ||||
| 	GL_CALL(glBindTexture(GL_TEXTURE_2D, texture->tex_id)); | ||||
| 	gles2_texture_gen_texture(tex); | ||||
| 	GL_CALL(glBindTexture(GL_TEXTURE_2D, tex->tex_id)); | ||||
| 
 | ||||
| 	EGLint attribs[] = { EGL_WAYLAND_PLANE_WL, 0, EGL_NONE }; | ||||
| 	texture->image = wlr_egl_create_image(EGL_WAYLAND_BUFFER_WL, | ||||
| 	tex->image = wlr_egl_create_image(tex->egl, EGL_WAYLAND_BUFFER_WL, | ||||
| 		(EGLClientBuffer*) buf, attribs); | ||||
| 	if (!texture->image) { | ||||
| 	if (!tex->image) { | ||||
| 		wlr_log(L_ERROR, "failed to create egl image: %s", egl_error()); | ||||
|  		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	GL_CALL(glActiveTexture(GL_TEXTURE0)); | ||||
| 	GL_CALL(glBindTexture(target, texture->tex_id)); | ||||
| 	GL_CALL(glEGLImageTargetTexture2DOES(target, texture->image)); | ||||
| 	texture->wlr_texture->valid = true; | ||||
| 	texture->pixel_format = pf; | ||||
| 	GL_CALL(glBindTexture(target, tex->tex_id)); | ||||
| 	GL_CALL(glEGLImageTargetTexture2DOES(target, tex->image)); | ||||
| 	tex->wlr_texture->valid = true; | ||||
| 	tex->pixel_format = pf; | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
|  | @ -230,10 +232,11 @@ static struct wlr_texture_impl wlr_texture_impl = { | |||
| 	.destroy = gles2_texture_destroy, | ||||
| }; | ||||
| 
 | ||||
| struct wlr_texture *gles2_texture_init() { | ||||
| struct wlr_texture *gles2_texture_init(struct wlr_egl *egl) { | ||||
| 	struct wlr_texture_state *state = calloc(sizeof(struct wlr_texture_state), 1); | ||||
| 	struct wlr_texture *texture = wlr_texture_init(state, &wlr_texture_impl); | ||||
| 	state->wlr_texture = texture; | ||||
| 	state->egl = egl; | ||||
| 	wl_signal_init(&texture->destroy_signal); | ||||
| 	return texture; | ||||
| } | ||||
|  |  | |||
|  | @ -1,10 +1,11 @@ | |||
| wlr_files += files( | ||||
|     'egl.c', | ||||
|     'matrix.c', | ||||
|     'wlr_renderer.c', | ||||
|     'wlr_texture.c', | ||||
|     'gles2/pixel_format.c', | ||||
|     'gles2/renderer.c', | ||||
|     'gles2/shaders.c', | ||||
|     'gles2/texture.c', | ||||
|     'gles2/util.c', | ||||
|     'wlr_renderer.c', | ||||
|     'wlr_texture.c', | ||||
| ) | ||||
|  |  | |||
|  | @ -46,3 +46,8 @@ const enum wl_shm_format *wlr_renderer_get_formats( | |||
| 		struct wlr_renderer *r, size_t *len) { | ||||
| 	return r->impl->formats(r->state, len); | ||||
| } | ||||
| 
 | ||||
| bool wlr_renderer_buffer_is_drm(struct wlr_renderer *r, | ||||
| 		struct wl_resource *buffer) { | ||||
| 	return r->impl->buffer_is_drm(r->state, buffer); | ||||
| } | ||||
|  |  | |||
|  | @ -2,9 +2,9 @@ | |||
| #include <stdlib.h> | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/util/log.h> | ||||
| #include <wlr/egl.h> | ||||
| #include <wlr/render/interface.h> | ||||
| #include <wlr/types/wlr_surface.h> | ||||
| #include "backend/egl.h" | ||||
| 
 | ||||
| static void surface_destroy(struct wl_client *client, struct wl_resource *resource) { | ||||
| 	wl_resource_destroy(resource); | ||||
|  | @ -124,8 +124,7 @@ void wlr_surface_flush_damage(struct wlr_surface *surface) { | |||
| 	} | ||||
| 	struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current.buffer); | ||||
| 	if (!buffer) { | ||||
| 		EGLint format; | ||||
| 		if (wlr_egl_query_buffer(surface->current.buffer, EGL_TEXTURE_FORMAT, &format)) { | ||||
| 		if (wlr_renderer_buffer_is_drm(surface->renderer, surface->pending.buffer)) { | ||||
| 			wlr_texture_upload_drm(surface->texture, surface->pending.buffer); | ||||
| 			goto release; | ||||
| 		} else { | ||||
|  | @ -202,6 +201,7 @@ static void destroy_surface(struct wl_resource *resource) { | |||
| struct wlr_surface *wlr_surface_create(struct wl_resource *res, | ||||
| 		struct wlr_renderer *renderer) { | ||||
| 	struct wlr_surface *surface = calloc(1, sizeof(struct wlr_surface)); | ||||
| 	surface->renderer = renderer; | ||||
| 	surface->texture = wlr_render_texture_init(renderer); | ||||
| 	surface->resource = res; | ||||
| 	wl_signal_init(&surface->signals.commit); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue