1 // Copyright 2012 Intel Corporation
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // - Redistributions of source code must retain the above copyright notice, this
9 // list of conditions and the following disclaimer.
10 //
11 // - Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26 #include <assert.h>
27
28 #include "wcore_error.h"
29 #include "wcore_platform.h"
30
31 #include "wegl_display.h"
32 #include "wegl_imports.h"
33 #include "wegl_util.h"
34 #include "wegl_platform.h"
35
36 static bool
get_apis(struct wegl_display * dpy)37 get_apis(struct wegl_display *dpy)
38 {
39 struct wegl_platform *plat = wegl_platform(dpy->wcore.platform);
40 const char *apis = plat->eglQueryString(dpy->egl, EGL_CLIENT_APIS);
41
42 // Our minimum requirement - EGL 1.2 ...
43 if (dpy->major_version != 1 || dpy->minor_version < 2) {
44 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
45 "EGL 1.2 or later is required");
46 return false;
47 }
48
49 // ... plus working eglQueryString(EGL_CLIENT_APIS).
50 if (!apis) {
51 wegl_emit_error(plat, "eglQueryString(EGL_CLIENT_APIS)");
52 return false;
53 }
54
55 // waffle_is_extension_in_string() resets the error state. That's ok,
56 // however, because if we've reached this point then no error should be
57 // pending emission.
58 assert(wcore_error_get_code() == 0);
59
60 if (waffle_is_extension_in_string(apis, "OpenGL_ES"))
61 dpy->api_mask |= WEGL_OPENGL_ES_API;
62
63 // Check for "OpenGL" if we're running EGL 1.4 or later.
64 if (dpy->major_version == 1 && dpy->minor_version >= 4)
65 if (waffle_is_extension_in_string(apis, "OpenGL"))
66 dpy->api_mask |= WEGL_OPENGL_API;
67
68 return true;
69 }
70
71 static bool
get_extensions(struct wegl_display * dpy)72 get_extensions(struct wegl_display *dpy)
73 {
74 struct wegl_platform *plat = wegl_platform(dpy->wcore.platform);
75 const char *extensions = plat->eglQueryString(dpy->egl, EGL_EXTENSIONS);
76
77 if (!extensions) {
78 wegl_emit_error(plat, "eglQueryString(EGL_EXTENSIONS)");
79 return false;
80 }
81
82 // waffle_is_extension_in_string() resets the error state. That's ok,
83 // however, because if we've reached this point then no error should be
84 // pending emission.
85 assert(wcore_error_get_code() == 0);
86
87 #define CHECK_EXTENSION(ext) \
88 dpy->ext = waffle_is_extension_in_string(extensions, "EGL_" #ext)
89
90 CHECK_EXTENSION(EXT_create_context_robustness);
91 CHECK_EXTENSION(KHR_create_context);
92 CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
93
94 #undef CHECK_EXTENSION
95
96 return true;
97 }
98
99 /// On Linux, according to eglplatform.h, EGLNativeDisplayType and intptr_t
100 /// have the same size regardless of platform.
101 bool
wegl_display_init(struct wegl_display * dpy,struct wcore_platform * wc_plat,void * native_display)102 wegl_display_init(struct wegl_display *dpy,
103 struct wcore_platform *wc_plat,
104 void *native_display)
105 {
106 struct wegl_platform *plat = wegl_platform(wc_plat);
107 bool ok;
108
109 ok = wcore_display_init(&dpy->wcore, wc_plat);
110 if (!ok)
111 goto fail;
112
113 if (wegl_platform_can_use_eglGetPlatformDisplay(plat)) {
114 dpy->egl = plat->eglGetPlatformDisplay(plat->egl_platform,
115 native_display, NULL);
116 if (!dpy->egl) {
117 wegl_emit_error(plat, "eglGetPlatformDisplay");
118 goto fail;
119 }
120 } else if (wegl_platform_can_use_eglGetPlatformDisplayEXT(plat)) {
121 dpy->egl = plat->eglGetPlatformDisplayEXT(plat->egl_platform,
122 native_display, NULL);
123 if (!dpy->egl) {
124 wegl_emit_error(plat, "eglGetPlatformDisplayEXT");
125 goto fail;
126 }
127 } else {
128 dpy->egl = plat->eglGetDisplay((EGLNativeDisplayType) native_display);
129 if (!dpy->egl) {
130 wegl_emit_error(plat, "eglGetDisplay");
131 goto fail;
132 }
133 }
134
135 ok = plat->eglInitialize(dpy->egl, &dpy->major_version, &dpy->minor_version);
136 if (!ok) {
137 wegl_emit_error(plat, "eglInitialize");
138 goto fail;
139 }
140
141 ok = get_apis(dpy);
142 if (!ok)
143 goto fail;
144
145 ok = get_extensions(dpy);
146 if (!ok)
147 goto fail;
148
149 return true;
150
151 fail:
152 wegl_display_teardown(dpy);
153 return false;
154 }
155
156 bool
wegl_display_teardown(struct wegl_display * dpy)157 wegl_display_teardown(struct wegl_display *dpy)
158 {
159 struct wegl_platform *plat = wegl_platform(dpy->wcore.platform);
160 bool ok = true;
161
162 if (dpy->egl) {
163 ok = plat->eglTerminate(dpy->egl);
164 if (!ok)
165 wegl_emit_error(plat, "eglTerminate");
166 }
167
168 return ok;
169 }
170
171 bool
wegl_display_supports_context_api(struct wcore_display * wc_dpy,int32_t waffle_context_api)172 wegl_display_supports_context_api(struct wcore_display *wc_dpy,
173 int32_t waffle_context_api)
174 {
175 struct wegl_display *dpy = wegl_display(wc_dpy);
176
177 switch (waffle_context_api) {
178 case WAFFLE_CONTEXT_OPENGL:
179 return !!(dpy->api_mask & WEGL_OPENGL_API);
180 case WAFFLE_CONTEXT_OPENGL_ES1:
181 case WAFFLE_CONTEXT_OPENGL_ES2:
182 return !!(dpy->api_mask & WEGL_OPENGL_ES_API);
183 case WAFFLE_CONTEXT_OPENGL_ES3:
184 return !!(dpy->api_mask & WEGL_OPENGL_ES_API) &&
185 dpy->KHR_create_context;
186 default:
187 assert(false);
188 return false;
189 }
190 }
191