mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	render/egl: add support for explicit sync extensions
This commit is contained in:
		
							parent
							
								
									2a1d7d40f4
								
							
						
					
					
						commit
						989301a89b
					
				
					 2 changed files with 86 additions and 0 deletions
				
			
		| 
						 | 
					@ -37,6 +37,10 @@ struct wlr_egl {
 | 
				
			||||||
		PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT;
 | 
							PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT;
 | 
				
			||||||
		PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT;
 | 
							PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT;
 | 
				
			||||||
		PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT;
 | 
							PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT;
 | 
				
			||||||
 | 
							PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR;
 | 
				
			||||||
 | 
							PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR;
 | 
				
			||||||
 | 
							PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID;
 | 
				
			||||||
 | 
							PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR;
 | 
				
			||||||
	} procs;
 | 
						} procs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool has_modifiers;
 | 
						bool has_modifiers;
 | 
				
			||||||
| 
						 | 
					@ -113,4 +117,12 @@ bool wlr_egl_unset_current(struct wlr_egl *egl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool wlr_egl_is_current(struct wlr_egl *egl);
 | 
					bool wlr_egl_is_current(struct wlr_egl *egl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EGLSyncKHR wlr_egl_create_sync(struct wlr_egl *egl, int fence_fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_egl_destroy_sync(struct wlr_egl *egl, EGLSyncKHR sync);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int wlr_egl_dup_fence_fd(struct wlr_egl *egl, EGLSyncKHR sync);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool wlr_egl_wait_sync(struct wlr_egl *egl, EGLSyncKHR sync);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										74
									
								
								render/egl.c
									
										
									
									
									
								
							
							
						
						
									
										74
									
								
								render/egl.c
									
										
									
									
									
								
							| 
						 | 
					@ -323,6 +323,18 @@ static bool egl_init_display(struct wlr_egl *egl, EGLDisplay *display) {
 | 
				
			||||||
	egl->exts.IMG_context_priority =
 | 
						egl->exts.IMG_context_priority =
 | 
				
			||||||
		check_egl_ext(display_exts_str, "EGL_IMG_context_priority");
 | 
							check_egl_ext(display_exts_str, "EGL_IMG_context_priority");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (check_egl_ext(display_exts_str, "EGL_KHR_fence_sync") &&
 | 
				
			||||||
 | 
								check_egl_ext(display_exts_str, "EGL_ANDROID_native_fence_sync")) {
 | 
				
			||||||
 | 
							load_egl_proc(&egl->procs.eglCreateSyncKHR, "eglCreateSyncKHR");
 | 
				
			||||||
 | 
							load_egl_proc(&egl->procs.eglDestroySyncKHR, "eglDestroySyncKHR");
 | 
				
			||||||
 | 
							load_egl_proc(&egl->procs.eglDupNativeFenceFDANDROID,
 | 
				
			||||||
 | 
								"eglDupNativeFenceFDANDROID");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (check_egl_ext(display_exts_str, "EGL_KHR_wait_sync")) {
 | 
				
			||||||
 | 
							load_egl_proc(&egl->procs.eglWaitSyncKHR, "eglWaitSyncKHR");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_log(WLR_INFO, "Using EGL %d.%d", (int)major, (int)minor);
 | 
						wlr_log(WLR_INFO, "Using EGL %d.%d", (int)major, (int)minor);
 | 
				
			||||||
	wlr_log(WLR_INFO, "Supported EGL display extensions: %s", display_exts_str);
 | 
						wlr_log(WLR_INFO, "Supported EGL display extensions: %s", display_exts_str);
 | 
				
			||||||
	if (device_exts_str != NULL) {
 | 
						if (device_exts_str != NULL) {
 | 
				
			||||||
| 
						 | 
					@ -954,3 +966,65 @@ int wlr_egl_dup_drm_fd(struct wlr_egl *egl) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return render_fd;
 | 
						return render_fd;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EGLSyncKHR wlr_egl_create_sync(struct wlr_egl *egl, int fence_fd) {
 | 
				
			||||||
 | 
						if (!egl->procs.eglCreateSyncKHR) {
 | 
				
			||||||
 | 
							return EGL_NO_SYNC_KHR;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EGLint attribs[3] = { EGL_NONE };
 | 
				
			||||||
 | 
						int dup_fd = -1;
 | 
				
			||||||
 | 
						if (fence_fd >= 0) {
 | 
				
			||||||
 | 
							dup_fd = fcntl(fence_fd, F_DUPFD_CLOEXEC, 0);
 | 
				
			||||||
 | 
							if (dup_fd < 0) {
 | 
				
			||||||
 | 
								wlr_log_errno(WLR_ERROR, "dup failed");
 | 
				
			||||||
 | 
								return EGL_NO_SYNC_KHR;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							attribs[0] = EGL_SYNC_NATIVE_FENCE_FD_ANDROID;
 | 
				
			||||||
 | 
							attribs[1] = dup_fd;
 | 
				
			||||||
 | 
							attribs[2] = EGL_NONE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EGLSyncKHR sync = egl->procs.eglCreateSyncKHR(egl->display,
 | 
				
			||||||
 | 
							EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
 | 
				
			||||||
 | 
						if (sync == EGL_NO_SYNC_KHR) {
 | 
				
			||||||
 | 
							wlr_log(WLR_ERROR, "eglCreateSyncKHR failed");
 | 
				
			||||||
 | 
							if (dup_fd >= 0) {
 | 
				
			||||||
 | 
								close(dup_fd);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return sync;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_egl_destroy_sync(struct wlr_egl *egl, EGLSyncKHR sync) {
 | 
				
			||||||
 | 
						if (sync == EGL_NO_SYNC_KHR) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						assert(egl->procs.eglDestroySyncKHR);
 | 
				
			||||||
 | 
						if (egl->procs.eglDestroySyncKHR(egl->display, sync) != EGL_TRUE) {
 | 
				
			||||||
 | 
							wlr_log(WLR_ERROR, "eglDestroySyncKHR failed");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int wlr_egl_dup_fence_fd(struct wlr_egl *egl, EGLSyncKHR sync) {
 | 
				
			||||||
 | 
						if (!egl->procs.eglDupNativeFenceFDANDROID) {
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int fd = egl->procs.eglDupNativeFenceFDANDROID(egl->display, sync);
 | 
				
			||||||
 | 
						if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
 | 
				
			||||||
 | 
							wlr_log(WLR_ERROR, "eglDupNativeFenceFDANDROID failed");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool wlr_egl_wait_sync(struct wlr_egl *egl, EGLSyncKHR sync) {
 | 
				
			||||||
 | 
						if (egl->procs.eglWaitSyncKHR(egl->display, sync, 0) != EGL_TRUE) {
 | 
				
			||||||
 | 
							wlr_log(WLR_ERROR, "eglWaitSyncKHR failed");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue