From patchwork Wed May 20 15:19:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 474521 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 838501402A1 for ; Thu, 21 May 2015 01:20:40 +1000 (AEST) Received: from localhost ([::1]:52747 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yv5nS-000529-LZ for incoming@patchwork.ozlabs.org; Wed, 20 May 2015 11:20:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47493) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yv5mm-0003pZ-GG for qemu-devel@nongnu.org; Wed, 20 May 2015 11:19:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yv5mh-0003dg-Eb for qemu-devel@nongnu.org; Wed, 20 May 2015 11:19:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41792) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yv5mh-0003dI-6z for qemu-devel@nongnu.org; Wed, 20 May 2015 11:19:51 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id C43E0BBB20 for ; Wed, 20 May 2015 15:19:50 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-43.ams2.redhat.com [10.36.116.43]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t4KFJn27020023; Wed, 20 May 2015 11:19:49 -0400 Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 0339581D6C; Wed, 20 May 2015 17:19:46 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 20 May 2015 17:19:40 +0200 Message-Id: <1432135182-29676-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1432135182-29676-1-git-send-email-kraxel@redhat.com> References: <1432135182-29676-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH v2 3/5] ui: add egl-helpers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add helper functions to initialize OpenGL using egl. Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- configure | 2 +- include/ui/egl-helpers.h | 16 +++++ ui/Makefile.objs | 3 + ui/egl-helpers.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 include/ui/egl-helpers.h create mode 100644 ui/egl-helpers.c diff --git a/configure b/configure index ec67ee8..d713385 100755 --- a/configure +++ b/configure @@ -3153,7 +3153,7 @@ else fi if test "$opengl" != "no" ; then - opengl_pkgs="gl glesv2 epoxy" + opengl_pkgs="gl glesv2 epoxy egl" if $pkg_config $opengl_pkgs x11 && test "$have_glx" = "yes"; then opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags" opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs" diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h new file mode 100644 index 0000000..5ad5dc3 --- /dev/null +++ b/include/ui/egl-helpers.h @@ -0,0 +1,16 @@ +#ifndef EGL_HELPERS_H +#define EGL_HELPERS_H + +#include +#include + +extern EGLDisplay *qemu_egl_display; +extern EGLConfig qemu_egl_config; + +EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win); + +int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug); +EGLContext qemu_egl_init_ctx(void); +bool qemu_egl_has_ext(const char *haystack, const char *needle); + +#endif /* EGL_HELPERS_H */ diff --git a/ui/Makefile.objs b/ui/Makefile.objs index 029a42a..5c46870 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -30,11 +30,14 @@ sdl.mo-cflags := $(SDL_CFLAGS) ifeq ($(CONFIG_OPENGL),y) common-obj-y += shader.o common-obj-y += console-gl.o +common-obj-y += egl-helpers.o endif gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) shader.o-cflags += $(OPENGL_CFLAGS) console-gl.o-cflags += $(OPENGL_CFLAGS) +egl-helpers.o-cflags += $(OPENGL_CFLAGS) shader.o-libs += $(OPENGL_LIBS) console-gl.o-libs += $(OPENGL_LIBS) +egl-helpers.o-libs += $(OPENGL_LIBS) diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c new file mode 100644 index 0000000..87d77af --- /dev/null +++ b/ui/egl-helpers.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ui/egl-helpers.h" + +EGLDisplay *qemu_egl_display; +EGLConfig qemu_egl_config; + +/* ---------------------------------------------------------------------- */ + +static bool egl_gles; +static int egl_debug; + +#define egl_dbg(_x ...) \ + do { \ + if (egl_debug) { \ + fprintf(stderr, "egl: " _x); \ + } \ + } while (0); + +/* ---------------------------------------------------------------------- */ + +EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win) +{ + EGLSurface esurface; + EGLBoolean b; + + egl_dbg("eglCreateWindowSurface (x11 win id 0x%lx) ...\n", + (unsigned long) win); + esurface = eglCreateWindowSurface(qemu_egl_display, + qemu_egl_config, + (EGLNativeWindowType)win, NULL); + if (esurface == EGL_NO_SURFACE) { + fprintf(stderr, "egl: eglCreateWindowSurface failed\n"); + return NULL; + } + + b = eglMakeCurrent(qemu_egl_display, esurface, esurface, ectx); + if (b == EGL_FALSE) { + fprintf(stderr, "egl: eglMakeCurrent failed\n"); + return NULL; + } + + return esurface; +} + +/* ---------------------------------------------------------------------- */ + +int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug) +{ + static const EGLint conf_att_gl[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + EGL_RED_SIZE, 5, + EGL_GREEN_SIZE, 5, + EGL_BLUE_SIZE, 5, + EGL_ALPHA_SIZE, 0, + EGL_NONE, + }; + static const EGLint conf_att_gles[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RED_SIZE, 5, + EGL_GREEN_SIZE, 5, + EGL_BLUE_SIZE, 5, + EGL_ALPHA_SIZE, 0, + EGL_NONE, + }; + EGLint major, minor; + EGLBoolean b; + EGLint n; + + if (debug) { + egl_debug = 1; + setenv("EGL_LOG_LEVEL", "debug", true); + setenv("LIBGL_DEBUG", "verbose", true); + } + + egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy); + qemu_egl_display = eglGetDisplay(dpy); + if (qemu_egl_display == EGL_NO_DISPLAY) { + fprintf(stderr, "egl: eglGetDisplay failed\n"); + return -1; + } + + egl_dbg("eglInitialize ...\n"); + b = eglInitialize(qemu_egl_display, &major, &minor); + if (b == EGL_FALSE) { + fprintf(stderr, "egl: eglInitialize failed\n"); + return -1; + } + + egl_dbg("eglBindAPI ...\n"); + b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API); + if (b == EGL_FALSE) { + fprintf(stderr, "egl: eglBindAPI failed\n"); + return -1; + } + + egl_dbg("eglChooseConfig ...\n"); + b = eglChooseConfig(qemu_egl_display, + gles ? conf_att_gles : conf_att_gl, + &qemu_egl_config, 1, &n); + if (b == EGL_FALSE || n != 1) { + fprintf(stderr, "egl: eglChooseConfig failed\n"); + return -1; + } + + egl_gles = gles; + return 0; +} + +EGLContext qemu_egl_init_ctx(void) +{ + static const EGLint ctx_att_gl[] = { + EGL_NONE + }; + static const EGLint ctx_att_gles[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + EGLContext ectx; + EGLBoolean b; + + egl_dbg("eglCreateContext ...\n"); + ectx = eglCreateContext(qemu_egl_display, qemu_egl_config, EGL_NO_CONTEXT, + egl_gles ? ctx_att_gles : ctx_att_gl); + if (ectx == EGL_NO_CONTEXT) { + fprintf(stderr, "egl: eglCreateContext failed\n"); + return NULL; + } + + b = eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ectx); + if (b == EGL_FALSE) { + fprintf(stderr, "egl: eglMakeCurrent failed\n"); + return NULL; + } + + return ectx; +}