-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add helper functions to initialize OpenGL using egl. Signed-off-by: Gerd Hoffmann <[email protected]> Reviewed-by: Max Reitz <[email protected]>
- Loading branch information
Showing
4 changed files
with
168 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#ifndef EGL_HELPERS_H | ||
#define EGL_HELPERS_H | ||
|
||
#include <epoxy/gl.h> | ||
#include <epoxy/egl.h> | ||
|
||
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 */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include <unistd.h> | ||
#include <string.h> | ||
#include <errno.h> | ||
#include <fcntl.h> | ||
#include <glob.h> | ||
|
||
#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; | ||
} |