diff options
Diffstat (limited to 'render')
| -rw-r--r-- | render/egl.c | 61 | ||||
| -rw-r--r-- | render/glapi.txt | 8 | ||||
| -rw-r--r-- | render/gles2/renderer.c | 39 | ||||
| -rw-r--r-- | render/meson.build | 20 | ||||
| -rw-r--r-- | render/wlr_renderer.c | 5 | 
5 files changed, 67 insertions, 66 deletions
diff --git a/render/egl.c b/render/egl.c index 82dea50c..9815b923 100644 --- a/render/egl.c +++ b/render/egl.c @@ -4,6 +4,7 @@  #include <stdlib.h>  #include <wlr/util/log.h>  #include <wlr/egl.h> +#include "render/glapi.h"  // Extension documentation  // https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_image_base.txt. @@ -46,27 +47,6 @@ const char *egl_error(void) {  	}  } -static bool egl_exts(struct wlr_egl *egl) { -	egl->get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC) -		eglGetProcAddress("eglGetPlatformDisplayEXT"); - -	if (!egl->get_platform_display) { -		wlr_log(L_ERROR, "Failed to load EGL extension 'eglGetPlatformDisplayEXT'"); -		return false; -	} - -	egl->create_platform_window_surface = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) -		eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); - -	if (!egl->create_platform_window_surface) { -		wlr_log(L_ERROR, -			"Failed to load EGL extension 'eglCreatePlatformWindowSurfaceEXT'"); -		return false; -	} - -	return true; -} -  static bool egl_get_config(EGLDisplay disp, EGLConfig *out, EGLint visual_id) {  	EGLint count = 0, matched = 0, ret; @@ -103,7 +83,7 @@ static bool egl_get_config(EGLDisplay disp, EGLConfig *out, EGLint visual_id) {  bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, EGLint visual_id,  		void *remote_display) { -	if (!egl_exts(egl)) { +	if (!load_glapi()) {  		return false;  	} @@ -112,7 +92,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, EGLint visual_id,  		goto error;  	} -	egl->display = egl->get_platform_display(platform, remote_display, NULL); +	egl->display = eglGetPlatformDisplayEXT(platform, remote_display, NULL);  	if (egl->display == EGL_NO_DISPLAY) {  		wlr_log(L_ERROR, "Failed to create EGL display: %s", egl_error());  		goto error; @@ -142,22 +122,11 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, EGLint visual_id,  	eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl->context);  	egl->egl_exts = eglQueryString(egl->display, EGL_EXTENSIONS);  	if (strstr(egl->egl_exts, "EGL_WL_bind_wayland_display") == NULL || -		strstr(egl->egl_exts, "EGL_KHR_image_base") == NULL) { +			strstr(egl->egl_exts, "EGL_KHR_image_base") == NULL) {  		wlr_log(L_ERROR, "Required egl extensions not supported");  		goto error;  	} -	egl->eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) -		eglGetProcAddress("eglCreateImageKHR"); -	egl->eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) -		eglGetProcAddress("eglDestroyImageKHR"); -	egl->eglQueryWaylandBufferWL = (PFNEGLQUERYWAYLANDBUFFERWL) -		(void*) eglGetProcAddress("eglQueryWaylandBufferWL"); -	egl->eglBindWaylandDisplayWL = (PFNEGLBINDWAYLANDDISPLAYWL) -		(void*) eglGetProcAddress("eglBindWaylandDisplayWL"); -	egl->eglUnbindWaylandDisplayWL = (PFNEGLUNBINDWAYLANDDISPLAYWL) -		(void*) eglGetProcAddress("eglUnbindWaylandDisplayWL"); -  	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); @@ -174,8 +143,8 @@ error:  void wlr_egl_free(struct wlr_egl *egl) {  	eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -	if (egl->wl_display && egl->eglUnbindWaylandDisplayWL) { -		egl->eglUnbindWaylandDisplayWL(egl->display, egl->wl_display); +	if (egl->wl_display && eglUnbindWaylandDisplayWL) { +		eglUnbindWaylandDisplayWL(egl->display, egl->wl_display);  	}  	eglDestroyContext(egl->display, egl->context); @@ -184,11 +153,11 @@ void wlr_egl_free(struct wlr_egl *egl) {  }  bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display) { -	if (!egl->eglBindWaylandDisplayWL) { +	if (!eglBindWaylandDisplayWL) {  		return false;  	} -	if (egl->eglBindWaylandDisplayWL(egl->display, local_display)) { +	if (eglBindWaylandDisplayWL(egl->display, local_display)) {  		egl->wl_display = local_display;  		return true;  	} @@ -198,33 +167,33 @@ bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display)  bool wlr_egl_query_buffer(struct wlr_egl *egl, struct wl_resource *buf,  		int attrib, int *value) { -	if (!egl->eglQueryWaylandBufferWL) { +	if (!eglQueryWaylandBufferWL) {  		return false;  	} -	return egl->eglQueryWaylandBufferWL(egl->display, buf, attrib, value); +	return eglQueryWaylandBufferWL(egl->display, buf, attrib, value);  }  EGLImage wlr_egl_create_image(struct wlr_egl *egl, EGLenum target,  		EGLClientBuffer buffer, const EGLint *attribs) { -	if (!egl->eglCreateImageKHR) { +	if (!eglCreateImageKHR) {  		return false;  	} -	return egl->eglCreateImageKHR(egl->display, egl->context, target, +	return eglCreateImageKHR(egl->display, egl->context, target,  		buffer, attribs);  }  bool wlr_egl_destroy_image(struct wlr_egl *egl, EGLImage image) { -	if (!egl->eglDestroyImageKHR) { +	if (!eglDestroyImageKHR) {  		return false;  	} -	egl->eglDestroyImageKHR(egl->display, image); +	eglDestroyImageKHR(egl->display, image);  	return true;  }  EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window) { -	EGLSurface surf = egl->create_platform_window_surface(egl->display, egl->config, +	EGLSurface surf = eglCreatePlatformWindowSurfaceEXT(egl->display, egl->config,  		window, NULL);  	if (surf == EGL_NO_SURFACE) {  		wlr_log(L_ERROR, "Failed to create EGL surface: %s", egl_error()); diff --git a/render/glapi.txt b/render/glapi.txt new file mode 100644 index 00000000..81791204 --- /dev/null +++ b/render/glapi.txt @@ -0,0 +1,8 @@ +eglGetPlatformDisplayEXT +eglCreatePlatformWindowSurfaceEXT +-eglCreateImageKHR +-eglDestroyImageKHR +-eglQueryWaylandBufferWL +-eglBindWaylandDisplayWL +-eglUnbindWaylandDisplayWL +-glEGLImageTargetTexture2DOES diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index d6c22ebe..94c50b9a 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -12,8 +12,8 @@  #include <wlr/render/matrix.h>  #include <wlr/util/log.h>  #include "render/gles2.h" +#include "render/glapi.h" -PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = NULL;  struct shaders shaders;  static bool compile_shader(GLuint type, const GLchar *src, GLuint *shader) { @@ -101,25 +101,7 @@ error:  	wlr_log(L_ERROR, "Failed to set up default shaders!");  } -static void init_image_ext() { -	if (glEGLImageTargetTexture2DOES) { -		return; -	} - -	const char *exts = (const char*) glGetString(GL_EXTENSIONS); -	if (strstr(exts, "GL_OES_EGL_image_external")) { - 		glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) -			eglGetProcAddress("glEGLImageTargetTexture2DOES"); -	} - -	if (!glEGLImageTargetTexture2DOES) { -		wlr_log(L_INFO, "Failed to load glEGLImageTargetTexture2DOES " -			"Will not be able to attach drm buffers"); -	} -} -  static void init_globals() { -	init_image_ext();  	init_default_shaders();  } @@ -226,7 +208,23 @@ static bool wlr_gles2_buffer_is_drm(struct wlr_renderer *_renderer,  		(struct wlr_gles2_renderer *)_renderer;  	EGLint format;  	return wlr_egl_query_buffer(renderer->egl, buffer, -			EGL_TEXTURE_FORMAT, &format); +		EGL_TEXTURE_FORMAT, &format); +} + +static void rgba_to_argb(uint32_t *data, size_t height, size_t stride) { +	size_t n = height*stride/4; +	for (size_t i = 0; i < n; ++i) { +		uint32_t v = data[i]; +		uint32_t rgb = (v & 0xffffff00) >> 8; +		uint32_t a = v & 0x000000ff; +		data[i] = rgb | (a << 24); +	} +} + +static void wlr_gles2_read_pixels(struct wlr_renderer *renderer, int x, int y, +		int width, int height, void *out_data) { +	glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, out_data); +	rgba_to_argb(out_data, height, width*4);  }  static struct wlr_renderer_impl wlr_renderer_impl = { @@ -238,6 +236,7 @@ static struct wlr_renderer_impl wlr_renderer_impl = {  	.render_ellipse = wlr_gles2_render_ellipse,  	.formats = wlr_gles2_formats,  	.buffer_is_drm = wlr_gles2_buffer_is_drm, +	.read_pixels = wlr_gles2_read_pixels,  };  struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_backend *backend) { diff --git a/render/meson.build b/render/meson.build index dc0ceeb9..749d1393 100644 --- a/render/meson.build +++ b/render/meson.build @@ -1,3 +1,16 @@ +glgen = find_program('../glgen.sh') + +glapi_c = custom_target('glapi.c', +	input: 'glapi.txt', +	output: '@BASENAME@.c', +	command: [glgen, '@INPUT@', '@OUTPUT@'], +) +glapi_h = custom_target('glapi.h', +	input: 'glapi.txt', +	output: '@BASENAME@.h', +	command: [glgen, '@INPUT@', '@OUTPUT@'], +) +  lib_wlr_render = static_library(  	'wlr_render',  	files( @@ -11,6 +24,13 @@ lib_wlr_render = static_library(  		'wlr_renderer.c',  		'wlr_texture.c',  	), +	glapi_c, +	glapi_h,  	include_directories: wlr_inc,  	dependencies: [glesv2, egl],  ) + +wlr_render = declare_dependency( +	link_with: lib_wlr_render, +	sources: glapi_h, +) diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index fec5e38a..ef0c31be 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -51,3 +51,8 @@ bool wlr_renderer_buffer_is_drm(struct wlr_renderer *r,  		struct wl_resource *buffer) {  	return r->impl->buffer_is_drm(r, buffer);  } + +void wlr_renderer_read_pixels(struct wlr_renderer *r, int x, int y, +		int width, int height, void *out_data) { +	r->impl->read_pixels(r, x, y, width, height, out_data); +}  | 
