1 /*
2  * This an unstable interface of wlroots. No guarantees are made regarding the
3  * future consistency of this API.
4  */
5 #ifndef WLR_USE_UNSTABLE
6 #error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
7 #endif
8 
9 #ifndef WLR_RENDER_EGL_H
10 #define WLR_RENDER_EGL_H
11 
12 #ifndef MESA_EGL_NO_X11_HEADERS
13 #define MESA_EGL_NO_X11_HEADERS
14 #endif
15 #ifndef EGL_NO_X11
16 #define EGL_NO_X11
17 #endif
18 #ifndef EGL_NO_PLATFORM_SPECIFIC_TYPES
19 #define EGL_NO_PLATFORM_SPECIFIC_TYPES
20 #endif
21 
22 #include <wlr/config.h>
23 
24 #include <EGL/egl.h>
25 #include <EGL/eglext.h>
26 #if WLR_HAS_EGLMESAEXT_H
27 // TODO: remove eglmesaext.h
28 #include <EGL/eglmesaext.h>
29 #endif
30 #include <pixman.h>
31 #include <stdbool.h>
32 #include <wayland-server-core.h>
33 #include <wlr/render/dmabuf.h>
34 #include <wlr/render/drm_format_set.h>
35 
36 struct wlr_egl_context {
37 	EGLDisplay display;
38 	EGLContext context;
39 	EGLSurface draw_surface;
40 	EGLSurface read_surface;
41 };
42 
43 struct wlr_egl {
44 	EGLenum platform;
45 	EGLDisplay display;
46 	EGLConfig config;
47 	EGLContext context;
48 
49 	struct {
50 		bool bind_wayland_display_wl;
51 		bool buffer_age_ext;
52 		bool image_base_khr;
53 		bool image_dma_buf_export_mesa;
54 		bool image_dmabuf_import_ext;
55 		bool image_dmabuf_import_modifiers_ext;
56 		bool swap_buffers_with_damage;
57 	} exts;
58 
59 	struct {
60 		PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
61 		PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT;
62 		PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
63 		PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
64 		PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL;
65 		PFNEGLBINDWAYLANDDISPLAYWL eglBindWaylandDisplayWL;
66 		PFNEGLUNBINDWAYLANDDISPLAYWL eglUnbindWaylandDisplayWL;
67 		PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC eglSwapBuffersWithDamage; // KHR or EXT
68 		PFNEGLQUERYDMABUFFORMATSEXTPROC eglQueryDmaBufFormatsEXT;
69 		PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT;
70 		PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC eglExportDMABUFImageQueryMESA;
71 		PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImageMESA;
72 		PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR;
73 	} procs;
74 
75 	struct wl_display *wl_display;
76 
77 	struct wlr_drm_format_set dmabuf_formats;
78 	EGLBoolean **external_only_dmabuf_formats;
79 };
80 
81 // TODO: Allocate and return a wlr_egl
82 /**
83  * Initializes an EGL context for the given platform and remote display.
84  * Will attempt to load all possibly required api functions.
85  */
86 bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
87 	const EGLint *config_attribs, EGLint visual_id);
88 
89 /**
90  * Frees all related EGL resources, makes the context not-current and
91  * unbinds a bound wayland display.
92  */
93 void wlr_egl_finish(struct wlr_egl *egl);
94 
95 /**
96  * Binds the given display to the EGL instance.
97  * This will allow clients to create EGL surfaces from wayland ones and render
98  * to it.
99  */
100 bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display);
101 
102 /**
103  * Returns a surface for the given native window
104  * The window must match the remote display the wlr_egl was created with.
105  */
106 EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window);
107 
108 /**
109  * Creates an EGL image from the given wl_drm buffer resource.
110  */
111 EGLImageKHR wlr_egl_create_image_from_wl_drm(struct wlr_egl *egl,
112 	struct wl_resource *data, EGLint *fmt, int *width, int *height,
113 	bool *inverted_y);
114 
115 /**
116  * Creates an EGL image from the given dmabuf attributes. Check usability
117  * of the dmabuf with wlr_egl_check_import_dmabuf once first.
118  */
119 EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
120 	struct wlr_dmabuf_attributes *attributes, bool *external_only);
121 
122 /**
123  * Get the available dmabuf formats
124  */
125 const struct wlr_drm_format_set *wlr_egl_get_dmabuf_formats(struct wlr_egl *egl);
126 
127 bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
128 	int32_t width, int32_t height, uint32_t flags,
129 	struct wlr_dmabuf_attributes *attribs);
130 
131 /**
132  * Destroys an EGL image created with the given wlr_egl.
133  */
134 bool wlr_egl_destroy_image(struct wlr_egl *egl, EGLImageKHR image);
135 
136 /**
137  * Make the EGL context current. The provided surface will be made current
138  * unless EGL_NO_SURFACE.
139  *
140  * Callers are expected to clear the current context when they are done by
141  * calling wlr_egl_unset_current.
142  */
143 bool wlr_egl_make_current(struct wlr_egl *egl, EGLSurface surface,
144 	int *buffer_age);
145 
146 bool wlr_egl_unset_current(struct wlr_egl *egl);
147 
148 bool wlr_egl_is_current(struct wlr_egl *egl);
149 
150 /**
151  * Save the current EGL context to the structure provided in the argument.
152  *
153  * This includes display, context, draw surface and read surface.
154  */
155 void wlr_egl_save_context(struct wlr_egl_context *context);
156 
157 /**
158  * Restore EGL context that was previously saved using wlr_egl_save_current().
159  */
160 bool wlr_egl_restore_context(struct wlr_egl_context *context);
161 
162 bool wlr_egl_swap_buffers(struct wlr_egl *egl, EGLSurface surface,
163 	pixman_region32_t *damage);
164 
165 bool wlr_egl_destroy_surface(struct wlr_egl *egl, EGLSurface surface);
166 
167 #endif
168