1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
/*
* Copyright 2014 © Samsung Research America, Silicon Valley
*
* Use of this source code is governed by the 3-Clause BSD license
* specified in the COPYING file included with this source code.
*/
#include <config.h>
#include <err.h>
#include <stdlib.h>
#include <unistd.h>
#include <EGL/egl.h>
#if HAVE_GLES3_H
#include <GLES3/gl3.h>
#elif HAVE_GLES2_H
#include <GLES2/gl2.h>
#endif
#include "egl.h"
#include "device_config.h"
bool
createEGLContextAndWindow(egl_state_t *state, const device_config_t& device_config)
{
EGLint attr[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_ALPHA_SIZE, 1,
EGL_STENCIL_SIZE, 1,
EGL_SAMPLES, 0,
EGL_SAMPLE_BUFFERS, 0,
EGL_DEPTH_SIZE, 0,
EGL_LUMINANCE_SIZE, 0,
EGL_MIN_SWAP_INTERVAL, EGL_DONT_CARE,
EGL_MAX_SWAP_INTERVAL, EGL_DONT_CARE,
EGL_MATCH_NATIVE_PIXMAP, EGL_NONE,
EGL_NONE
};
EGLint ctx_attr[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLConfig egl_config;
EGLint num;
EGLint major, minor;
// TODO: Hack
// User configuration settings
for (int i=0; i<28; i+=2) {
switch (attr[i]) {
case EGL_SAMPLES:
attr[i+1] = device_config.egl_samples;
break;
case EGL_SAMPLE_BUFFERS:
attr[i+1] = device_config.egl_sample_buffers;
break;
case EGL_DEPTH_SIZE:
attr[i+1] = device_config.egl_depth_size;
break;
case EGL_LUMINANCE_SIZE:
attr[i+1] = device_config.egl_luminance_size;
break;
case EGL_MIN_SWAP_INTERVAL:
attr[i+1] = device_config.egl_min_swap_interval;
break;
case EGL_MAX_SWAP_INTERVAL:
attr[i+1] = device_config.egl_max_swap_interval;
break;
case EGL_MATCH_NATIVE_PIXMAP:
attr[i+1] = device_config.egl_match_native_pixmap;
break;
}
}
if(device_config.egl_gles_version) {
ctx_attr[1] = device_config.egl_gles_version;
}
state->dpy = XOpenDisplay (NULL);
if (!state->dpy) {
warnx ("Failed to open display: %s\n", XDisplayName (0));
return false;
}
state->window = XCreateSimpleWindow (state->dpy, DefaultRootWindow (state->dpy),
200, 200,
device_config.width, device_config.height,
0,
BlackPixel (state->dpy, DefaultRootWindow (state->dpy)),
BlackPixel (state->dpy, DefaultRootWindow (state->dpy)));
XMapWindow (state->dpy, state->window);
state->egl_display = eglGetDisplay ((EGLNativeDisplayType) state->dpy);
if (state->egl_display == EGL_NO_DISPLAY) {
warnx ("Cannot get egl display\n");
return false;
}
if (!eglInitialize(state->egl_display, &major, &minor)) {
warnx ("Cannot initialize EGL\n");
return false;
}
if (!eglBindAPI(EGL_OPENGL_ES_API)) {
warnx ("Cannot bind EGL to GLES API\n");
return false;
}
if (! eglChooseConfig (state->egl_display, attr, &egl_config, 1, &num)) {
warnx ("Cannot choose EGL configuration\n");
return false;
}
if (!egl_config or num < 1) {
warnx ("No valid EGL configuration could be found\n");
return false;
}
state->egl_context = eglCreateContext (state->egl_display, egl_config, NULL, ctx_attr);
if (state->egl_context == EGL_NO_CONTEXT) {
warnx ("Cannot create EGL context\n");
return false;
}
state->egl_surface = eglCreateWindowSurface (state->egl_display, egl_config, (EGLNativeWindowType)state->window, NULL);
if (state->egl_surface == EGL_NO_SURFACE) {
warnx ("Cannot create EGL window surface\n");
return false;
}
return true;
}
void
destroyEGLContextAndWindow (egl_state_t *state)
{
if (state->egl_display) {
eglMakeCurrent (state->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext (state->egl_display, state->egl_context);
eglDestroySurface (state->egl_display, state->egl_surface);
state->egl_context = EGL_NO_CONTEXT;
state->egl_surface = EGL_NO_SURFACE;
eglTerminate (state->egl_display);
}
if (state->dpy) {
XUnmapWindow (state->dpy, state->window);
XDestroyWindow (state->dpy, state->window);
XCloseDisplay (state->dpy);
}
}
void
cleanup_state_egl(void *data)
{
egl_state_t *state = (egl_state_t*)data;
destroyEGLContextAndWindow(state);
free(state);
}
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
|