gbm: factor out gbm_window_{init,teardown}
[mesa-waffle.git] / src / waffle / nacl / nacl_dl.c
blob79958da9403f030e1729e98845630d5ef46e2087
1 // Copyright 2012-2015 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.
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.
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.
26 #include <assert.h>
27 #include <dlfcn.h>
28 #include <stdio.h>
29 #include <string.h>
31 #include "wcore_error.h"
33 #include "nacl_container.h"
34 #include "nacl_dl.h"
35 #include "nacl_platform.h"
38 static bool
39 nacl_dl_check_enum(int32_t waffle_dl)
41 switch (waffle_dl) {
42 case WAFFLE_DL_OPENGL:
43 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
44 "NACL does not support OpenGL");
45 return false;
46 case WAFFLE_DL_OPENGL_ES1:
47 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
48 "NACL does not support OpenGL ES1");
49 return false;
50 case WAFFLE_DL_OPENGL_ES2:
51 return true;
52 case WAFFLE_DL_OPENGL_ES3:
53 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
54 "NACL does not support OpenGL ES3");
55 return false;
56 default:
57 assert(false);
58 return false;
62 static bool
63 nacl_dl_open(struct nacl_platform *plat)
65 plat->dl_gl = dlopen(NACL_GLES2_LIBRARY, RTLD_LAZY);
67 if (!plat->dl_gl) {
68 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
69 "dlopen(\"%s\") failed: %s", NACL_GLES2_LIBRARY, dlerror());
70 return false;
73 return true;
76 bool
77 nacl_dl_can_open(struct wcore_platform *wc_plat,
78 int32_t waffle_dl)
80 struct nacl_platform *plat = nacl_platform(wc_plat);
81 bool ok;
83 WCORE_ERROR_DISABLED({
84 ok = nacl_dl_check_enum(waffle_dl);
85 });
87 if (!ok)
88 return false;
90 if (plat->dl_gl != NULL)
91 return true;
93 WCORE_ERROR_DISABLED({
94 nacl_dl_open(plat);
95 });
97 return plat->dl_gl != NULL;
100 // Construct a string that maps GL function to NaCl function
101 // by concating given prefix and function name tail from 'src'.
102 static char *
103 nacl_dl_prefix(const char *src, const char *prefix)
105 if (strncmp(src, "gl", 2) != 0) {
106 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
107 "NACL symbol name does not start with \"gl\"");
108 return NULL;
111 uint32_t len = strlen(src) + strlen(prefix);
113 char *dst = wcore_calloc(len);
114 if (!dst)
115 return NULL;
117 int n = snprintf(dst, len, "%s%s", prefix, src + 2);
118 if (n < 0 || n >= len) {
119 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
120 "NACL cannot create symbol prefix");
121 free(dst);
122 return NULL;
125 return dst;
128 void*
129 nacl_dl_sym(struct wcore_platform *wc_plat,
130 int32_t waffle_dl,
131 const char *name)
133 struct nacl_platform *plat = nacl_platform(wc_plat);
135 if (!nacl_dl_check_enum(waffle_dl))
136 return NULL;
138 if (plat->dl_gl == NULL)
139 nacl_dl_open(plat);
141 if (plat->dl_gl == NULL)
142 return NULL;
144 char *nacl_name = nacl_dl_prefix(name, "GLES2");
145 if (!nacl_name)
146 return NULL;
148 // Clear any previous error.
149 dlerror();
151 void *sym = dlsym(plat->dl_gl, name);
153 if (sym) {
154 free(nacl_name);
155 return sym;
158 // dlsym returned NULL. Check if an error occured.
159 const char *error = dlerror();
160 if (error) {
161 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
162 "dlsym(libname=\"%s\", symbol=\"%s\") failed: %s",
163 NACL_GLES2_LIBRARY, nacl_name, error);
165 free(nacl_name);
167 return NULL;
170 bool
171 nacl_dl_close(struct wcore_platform *wc_plat)
173 struct nacl_platform *plat = nacl_platform(wc_plat);
175 int error_code = 0;
176 const char *error_msg = NULL;
178 if (!plat->dl_gl)
179 return true;
181 error_code = dlclose(plat->dl_gl);
183 if (!error_code)
184 return true;
186 error_msg = dlerror();
188 if (error_msg) {
189 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
190 "dlclose(libname=\"%s\") failed: %s",
191 NACL_GLES2_LIBRARY, error_msg);
193 else {
194 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
195 "dlclose(libname=\"%s\") failed",
196 NACL_GLES2_LIBRARY);
199 return false;