xref: /openbmc/qemu/ui/egl-helpers.c (revision 0b2ff2ce)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <stdbool.h>
5 #include <unistd.h>
6 #include <string.h>
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <glob.h>
10 
11 #include "ui/egl-helpers.h"
12 
13 EGLDisplay *qemu_egl_display;
14 EGLConfig qemu_egl_config;
15 
16 /* ---------------------------------------------------------------------- */
17 
18 static bool egl_gles;
19 static int egl_debug;
20 
21 #define egl_dbg(_x ...)                          \
22     do {                                         \
23         if (egl_debug) {                         \
24             fprintf(stderr, "egl: " _x);         \
25         }                                        \
26     } while (0);
27 
28 /* ---------------------------------------------------------------------- */
29 
30 EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
31 {
32     EGLSurface esurface;
33     EGLBoolean b;
34 
35     egl_dbg("eglCreateWindowSurface (x11 win id 0x%lx) ...\n",
36             (unsigned long) win);
37     esurface = eglCreateWindowSurface(qemu_egl_display,
38                                       qemu_egl_config,
39                                       (EGLNativeWindowType)win, NULL);
40     if (esurface == EGL_NO_SURFACE) {
41         fprintf(stderr, "egl: eglCreateWindowSurface failed\n");
42         return NULL;
43     }
44 
45     b = eglMakeCurrent(qemu_egl_display, esurface, esurface, ectx);
46     if (b == EGL_FALSE) {
47         fprintf(stderr, "egl: eglMakeCurrent failed\n");
48         return NULL;
49     }
50 
51     return esurface;
52 }
53 
54 /* ---------------------------------------------------------------------- */
55 
56 int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
57 {
58     static const EGLint conf_att_gl[] = {
59         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
60         EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
61         EGL_RED_SIZE,   5,
62         EGL_GREEN_SIZE, 5,
63         EGL_BLUE_SIZE,  5,
64         EGL_ALPHA_SIZE, 0,
65         EGL_NONE,
66     };
67     static const EGLint conf_att_gles[] = {
68         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
69         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
70         EGL_RED_SIZE,   5,
71         EGL_GREEN_SIZE, 5,
72         EGL_BLUE_SIZE,  5,
73         EGL_ALPHA_SIZE, 0,
74         EGL_NONE,
75     };
76     EGLint major, minor;
77     EGLBoolean b;
78     EGLint n;
79 
80     if (debug) {
81         egl_debug = 1;
82         setenv("EGL_LOG_LEVEL", "debug", true);
83         setenv("LIBGL_DEBUG", "verbose", true);
84     }
85 
86     egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy);
87     qemu_egl_display = eglGetDisplay(dpy);
88     if (qemu_egl_display == EGL_NO_DISPLAY) {
89         fprintf(stderr, "egl: eglGetDisplay failed\n");
90         return -1;
91     }
92 
93     egl_dbg("eglInitialize ...\n");
94     b = eglInitialize(qemu_egl_display, &major, &minor);
95     if (b == EGL_FALSE) {
96         fprintf(stderr, "egl: eglInitialize failed\n");
97         return -1;
98     }
99 
100     egl_dbg("eglBindAPI ...\n");
101     b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
102     if (b == EGL_FALSE) {
103         fprintf(stderr, "egl: eglBindAPI failed\n");
104         return -1;
105     }
106 
107     egl_dbg("eglChooseConfig ...\n");
108     b = eglChooseConfig(qemu_egl_display,
109                         gles ? conf_att_gles : conf_att_gl,
110                         &qemu_egl_config, 1, &n);
111     if (b == EGL_FALSE || n != 1) {
112         fprintf(stderr, "egl: eglChooseConfig failed\n");
113         return -1;
114     }
115 
116     egl_gles = gles;
117     return 0;
118 }
119 
120 EGLContext qemu_egl_init_ctx(void)
121 {
122     static const EGLint ctx_att_gl[] = {
123         EGL_NONE
124     };
125     static const EGLint ctx_att_gles[] = {
126         EGL_CONTEXT_CLIENT_VERSION, 2,
127         EGL_NONE
128     };
129 
130     EGLContext ectx;
131     EGLBoolean b;
132 
133     egl_dbg("eglCreateContext ...\n");
134     ectx = eglCreateContext(qemu_egl_display, qemu_egl_config, EGL_NO_CONTEXT,
135                             egl_gles ? ctx_att_gles : ctx_att_gl);
136     if (ectx == EGL_NO_CONTEXT) {
137         fprintf(stderr, "egl: eglCreateContext failed\n");
138         return NULL;
139     }
140 
141     b = eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ectx);
142     if (b == EGL_FALSE) {
143         fprintf(stderr, "egl: eglMakeCurrent failed\n");
144         return NULL;
145     }
146 
147     return ectx;
148 }
149