[PATCH weston 3/8] gl-renderer: Add optional support for desktop OpenGL.

John Kåre Alsaker john.kare.alsaker at gmail.com
Thu Feb 21 10:19:29 PST 2013


This adds support for desktop OpenGL which can be enabled by with
./configure --enable-opengl.

Most of the differences in API between OpenGL and OpenGL ES is hidden by
the new gl_renderer fields.

It also accesses GLES2 extensions by including GLES2/gl2platform.h directly.
---
 configure.ac         | 11 ++++++++-
 src/compositor-rpi.c |  2 +-
 src/compositor.h     |  1 +
 src/gl-internal.h    |  6 ++---
 src/gl-renderer.c    | 65 +++++++++++++++++++++++++++++++++++-----------------
 src/gl-renderer.h    | 19 +++++++++++++++
 src/gl-shaders.c     |  5 ++--
 7 files changed, 81 insertions(+), 28 deletions(-)

diff --git a/configure.ac b/configure.ac
index 74eb892..6351f8e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -48,9 +48,18 @@ COMPOSITOR_MODULES="wayland-server xkbcommon pixman-1"
 AC_ARG_ENABLE(egl, [  --disable-egl],,
               enable_egl=yes)
 AM_CONDITIONAL(ENABLE_EGL, test x$enable_egl = xyes)
+AC_ARG_ENABLE(opengl, [  --enable-opengl],,
+		  enable_opengl=no)
+AM_CONDITIONAL(ENABLE_OPENGL, test x$enable_opengl = xyes)
 if test x$enable_egl = xyes; then
 	AC_DEFINE([ENABLE_EGL], [1], [Build Weston with EGL support])
-	COMPOSITOR_MODULES="$COMPOSITOR_MODULES egl >= 7.10 glesv2"
+	COMPOSITOR_MODULES="$COMPOSITOR_MODULES egl >= 7.10"
+	if test x$enable_opengl = xyes; then
+		AC_DEFINE([BUILD_DESKTOP_OPENGL], [1], [Build using desktop OpenGL])
+		COMPOSITOR_MODULES="$COMPOSITOR_MODULES gl"
+	else
+		COMPOSITOR_MODULES="$COMPOSITOR_MODULES glesv2"
+	fi
 fi
 
 PKG_CHECK_MODULES(COMPOSITOR, [$COMPOSITOR_MODULES])
diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c
index d3767b9..1de85ec 100644
--- a/src/compositor-rpi.c
+++ b/src/compositor-rpi.c
@@ -1436,7 +1436,7 @@ rpi_compositor_create(struct wl_display *display, int *argc, char *argv[],
 		EGL_GREEN_SIZE, 1,
 		EGL_BLUE_SIZE, 1,
 		EGL_ALPHA_SIZE, 0,
-		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+		EGL_RENDERABLE_TYPE, GL_RENDERER_EGL_OPENGL_BIT,
 		EGL_NONE
 	};
 
diff --git a/src/compositor.h b/src/compositor.h
index a45fdf6..8842372 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -24,6 +24,7 @@
 #ifndef _WAYLAND_SYSTEM_COMPOSITOR_H_
 #define _WAYLAND_SYSTEM_COMPOSITOR_H_
 
+#include <config.h>
 #include <pixman.h>
 #include <xkbcommon/xkbcommon.h>
 #include <wayland-server.h>
diff --git a/src/gl-internal.h b/src/gl-internal.h
index 2f61299..f27b221 100644
--- a/src/gl-internal.h
+++ b/src/gl-internal.h
@@ -24,9 +24,6 @@
 #ifndef _GL_INTERNAL_H_
 #define _GL_INTERNAL_H_
 
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -112,6 +109,9 @@ struct gl_renderer {
 		int32_t width, height;
 	} border;
 
+	GLenum bgra_internal_format, bgra_format;
+	GLenum short_type;
+
 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;
 	PFNEGLCREATEIMAGEKHRPROC create_image;
 	PFNEGLDESTROYIMAGEKHRPROC destroy_image;
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index 6e0bfa5..97bcfc8 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -893,11 +893,12 @@ gl_renderer_read_pixels(struct weston_output *output,
 			       uint32_t x, uint32_t y,
 			       uint32_t width, uint32_t height)
 {
+	struct gl_renderer *gr = get_renderer(output->compositor);
 	GLenum gl_format;
 
 	switch (format) {
 	case PIXMAN_a8r8g8b8:
-		gl_format = GL_BGRA_EXT;
+		gl_format = gr->bgra_format;
 		break;
 	case PIXMAN_a8b8g8r8:
 		gl_format = GL_RGBA;
@@ -949,9 +950,9 @@ gl_renderer_flush_damage(struct weston_surface *surface)
 	glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
 
 	if (!gr->has_unpack_subimage) {
-		glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
+		glTexImage2D(GL_TEXTURE_2D, 0, gr->bgra_internal_format,
 			     gs->pitch, buffer->height, 0,
-			     GL_BGRA_EXT, GL_UNSIGNED_BYTE,
+			     gr->bgra_format, GL_UNSIGNED_BYTE,
 			     wl_shm_buffer_get_data(buffer));
 
 		goto done;
@@ -971,7 +972,7 @@ gl_renderer_flush_damage(struct weston_surface *surface)
 		glPixelStorei(GL_UNPACK_SKIP_ROWS, r.y1);
 		glTexSubImage2D(GL_TEXTURE_2D, 0, r.x1, r.y1,
 				r.x2 - r.x1, r.y2 - r.y1,
-				GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
+				gr->bgra_format, GL_UNSIGNED_BYTE, data);
 	}
 #endif
 
@@ -1030,9 +1031,9 @@ gl_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer)
 
 		ensure_textures(gs, 1);
 		glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
-		glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
+		glTexImage2D(GL_TEXTURE_2D, 0, gr->bgra_internal_format,
 			     gs->pitch, buffer->height, 0,
-			     GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
+			     gr->bgra_format, GL_UNSIGNED_BYTE, NULL);
 		if (wl_shm_buffer_get_format(buffer) == WL_SHM_FORMAT_XRGB8888)
 			gs->input = INPUT_RGBX;
 		else
@@ -1265,10 +1266,10 @@ gl_renderer_set_border(struct weston_compositor *ec, int32_t width, int32_t heig
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
+	glTexImage2D(GL_TEXTURE_2D, 0, gr->bgra_internal_format,
 		     width,
 		     height,
-		     0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
+		     0, gr->bgra_format, GL_UNSIGNED_BYTE,
 		     data);
 
 	wl_list_for_each(output, &ec->output_list, link)
@@ -1411,7 +1412,7 @@ WL_EXPORT const EGLint gl_renderer_opaque_attribs[] = {
 	EGL_GREEN_SIZE, 1,
 	EGL_BLUE_SIZE, 1,
 	EGL_ALPHA_SIZE, 0,
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+	EGL_RENDERABLE_TYPE, GL_RENDERER_EGL_OPENGL_BIT,
 	EGL_NONE
 };
 
@@ -1421,7 +1422,7 @@ WL_EXPORT const EGLint gl_renderer_alpha_attribs[] = {
 	EGL_GREEN_SIZE, 1,
 	EGL_BLUE_SIZE, 1,
 	EGL_ALPHA_SIZE, 1,
-	EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+	EGL_RENDERABLE_TYPE, GL_RENDERER_EGL_OPENGL_BIT,
 	EGL_NONE
 };
 
@@ -1499,12 +1500,28 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
 	const char *extensions;
 	EGLBoolean ret;
 
+#ifdef BUILD_OPENGL
+	static const EGLint context_attribs[] = {
+		EGL_CONTEXT_MAJOR_VERSION_KHR, 2,
+		EGL_CONTEXT_MINOR_VERSION_KHR, 0,
+		EGL_NONE
+	};
+
+	gr->bgra_internal_format = GL_RGBA;
+	gr->bgra_format = GL_BGRA;
+	gr->short_type = GL_UNSIGNED_SHORT;
+#else
 	static const EGLint context_attribs[] = {
 		EGL_CONTEXT_CLIENT_VERSION, 2,
 		EGL_NONE
 	};
 
-	if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+	gr->bgra_internal_format = GL_BGRA_EXT;
+	gr->bgra_format = GL_BGRA_EXT;
+	gr->short_type = GL_UNSIGNED_BYTE;
+#endif
+
+	if (!eglBindAPI(OPENGL_ES_VER ? EGL_OPENGL_ES_API : EGL_OPENGL_API)) {
 		weston_log("failed to bind EGL_OPENGL_ES_API\n");
 		gl_renderer_print_egl_error_state();
 		return -1;
@@ -1512,6 +1529,18 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
 
 	log_egl_config_info(gr->egl_display, gr->egl_config);
 
+	extensions =
+		(const char *) eglQueryString(gr->egl_display, EGL_EXTENSIONS);
+	if (!extensions) {
+		weston_log("Retrieving EGL extension string failed.\n");
+		return -1;
+	}
+
+	if (!OPENGL_ES_VER && !strstr(extensions, "EGL_KHR_create_context")) {
+		weston_log("EGL_KHR_create_context required to create OpenGL context\n");
+		return -1;
+	}
+
 	gr->egl_context = eglCreateContext(gr->egl_display, gr->egl_config,
 					   EGL_NO_CONTEXT, context_attribs);
 	if (gr->egl_context == NULL) {
@@ -1541,13 +1570,16 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
 	gr->query_buffer =
 		(void *) eglGetProcAddress("eglQueryWaylandBufferWL");
 
+	if (strstr(extensions, "EGL_WL_bind_wayland_display"))
+		gr->has_bind_display = 1;
+
 	extensions = (const char *) glGetString(GL_EXTENSIONS);
 	if (!extensions) {
 		weston_log("Retrieving GL extension string failed.\n");
 		return -1;
 	}
 
-	if (!strstr(extensions, "GL_EXT_texture_format_BGRA8888")) {
+	if (OPENGL_ES_VER && !strstr(extensions, "GL_EXT_texture_format_BGRA8888")) {
 		weston_log("GL_EXT_texture_format_BGRA8888 not available\n");
 		return -1;
 	}
@@ -1563,15 +1595,6 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
 	if (strstr(extensions, "GL_OES_EGL_image_external"))
 		gr->has_egl_image_external = 1;
 
-	extensions =
-		(const char *) eglQueryString(gr->egl_display, EGL_EXTENSIONS);
-	if (!extensions) {
-		weston_log("Retrieving EGL extension string failed.\n");
-		return -1;
-	}
-
-	if (strstr(extensions, "EGL_WL_bind_wayland_display"))
-		gr->has_bind_display = 1;
 	if (gr->has_bind_display) {
 		ret = gr->bind_display(gr->egl_display, ec->wl_display);
 		if (!ret)
diff --git a/src/gl-renderer.h b/src/gl-renderer.h
index a2e8690..beb05dc 100644
--- a/src/gl-renderer.h
+++ b/src/gl-renderer.h
@@ -27,6 +27,25 @@
 
 #ifdef ENABLE_EGL
 
+#ifdef BUILD_DESKTOP_OPENGL
+
+#define OPENGL_ES_VER 0
+#define GL_GLEXT_PROTOTYPES
+#define GL_RENDERER_EGL_OPENGL_BIT EGL_OPENGL_BIT
+
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include <GLES2/gl2platform.h>
+
+#else
+
+#define OPENGL_ES_VER 2
+#define GL_RENDERER_EGL_OPENGL_BIT EGL_OPENGL_ES2_BIT
+#include <GLES2/gl2.h>
+
+#endif
+
+#include <GLES2/gl2ext.h>
 #include <EGL/egl.h>
 
 extern const EGLint gl_renderer_opaque_attribs[];
diff --git a/src/gl-shaders.c b/src/gl-shaders.c
index ccbe4c6..0f6438e 100644
--- a/src/gl-shaders.c
+++ b/src/gl-shaders.c
@@ -423,8 +423,9 @@ create_shader_permutation(struct gl_renderer *renderer,
 
 	shader_builder_init(&sb);
 
-	append(&sb.global, "precision mediump float;\n" \
-		"varying vec2 texture_coord;\n" \
+	if (OPENGL_ES_VER)
+		append(&sb.global, "precision mediump float;\n");
+	append(&sb.global, "varying vec2 texture_coord;\n" \
 		"uniform float alpha;\n");
 
 	append(&sb.body, "void main()\n{\n");
-- 
1.8.1.3



More information about the wayland-devel mailing list