4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
7 * Stanislav Vorobiov <s.vorobiov@samsung.com>
8 * Jinhyung Jo <jinhyung.jo@samsung.com>
9 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
34 #include "yagl_egl_state.h"
35 #include "yagl_context.h"
36 #include "yagl_surface.h"
38 #include "yagl_malloc.h"
39 #include "yagl_client_interface.h"
40 #include "yagl_client_context.h"
50 struct yagl_context *ctx;
51 struct yagl_surface *draw_sfc;
52 struct yagl_surface *read_sfc;
54 struct yagl_client_interface *gles1_iface;
55 struct yagl_client_interface *gles2_iface;
58 static pthread_key_t g_state_key;
59 static pthread_once_t g_state_key_init = PTHREAD_ONCE_INIT;
61 void *yagl_get_gles1_sym(const char *name)
64 void *sym = dlsym(NULL, name);
70 handle = dlopen("libGLESv1_CM.so.1", RTLD_NOW|RTLD_GLOBAL);
72 handle = dlopen("libGLESv1_CM.so", RTLD_NOW|RTLD_GLOBAL);
76 return dlsym(handle, name);
82 void *yagl_get_gles2_sym(const char *name)
87 handle = dlopen("libGLESv2.so.1", RTLD_NOW|RTLD_GLOBAL);
89 handle = dlopen("libGLESv2.so", RTLD_NOW|RTLD_GLOBAL);
93 sym = dlsym(handle, name);
97 sym = dlsym(NULL, name);
103 static void yagl_egl_state_free(void* ptr)
105 struct yagl_egl_state *state = ptr;
107 YAGL_LOG_FUNC_ENTER(yagl_egl_state_free, "%p", ptr);
113 yagl_surface_release(state->read_sfc);
114 yagl_surface_release(state->draw_sfc);
115 yagl_context_release(state->ctx);
119 YAGL_LOG_FUNC_EXIT(NULL);
122 static void yagl_egl_state_key_init()
124 pthread_key_create(&g_state_key, yagl_egl_state_free);
127 static void yagl_egl_state_atfork()
129 struct yagl_egl_state *state;
132 * See yagl_state.c:yagl_state_atfork.
135 pthread_once(&g_state_key_init, yagl_egl_state_key_init);
137 state = (struct yagl_egl_state*)pthread_getspecific(g_state_key);
143 pthread_setspecific(g_state_key, NULL);
146 static void yagl_egl_state_init()
148 struct yagl_egl_state *state;
150 pthread_once(&g_state_key_init, yagl_egl_state_key_init);
152 if (pthread_getspecific(g_state_key)) {
156 YAGL_LOG_FUNC_ENTER(yagl_egl_state_init, NULL);
158 state = yagl_malloc0(sizeof(struct yagl_egl_state));
160 state->error = EGL_SUCCESS;
161 state->api = EGL_OPENGL_ES_API;
163 pthread_setspecific(g_state_key, state);
165 pthread_atfork(NULL, NULL, &yagl_egl_state_atfork);
167 YAGL_LOG_FUNC_EXIT("%p", state);
170 static struct yagl_egl_state *yagl_egl_get_state()
172 yagl_egl_state_init();
174 return (struct yagl_egl_state*)pthread_getspecific(g_state_key);
177 EGLint yagl_get_error()
179 struct yagl_egl_state *state = yagl_egl_get_state();
181 EGLint error = state->error;
183 state->error = EGL_SUCCESS;
188 void yagl_set_error(EGLint error)
190 struct yagl_egl_state *state = yagl_egl_get_state();
192 if (state->error == EGL_SUCCESS) {
193 state->error = error;
197 EGLenum yagl_get_api()
199 struct yagl_egl_state *state = yagl_egl_get_state();
204 void yagl_set_api(EGLenum api)
206 struct yagl_egl_state *state = yagl_egl_get_state();
211 struct yagl_context *yagl_get_context()
213 struct yagl_egl_state *state = yagl_egl_get_state();
218 struct yagl_surface *yagl_get_draw_surface()
220 struct yagl_egl_state *state = yagl_egl_get_state();
222 return state->draw_sfc;
225 struct yagl_surface *yagl_get_read_surface()
227 struct yagl_egl_state *state = yagl_egl_get_state();
229 return state->read_sfc;
232 int yagl_set_context(struct yagl_context *ctx,
233 struct yagl_surface *draw_sfc,
234 struct yagl_surface *read_sfc)
236 struct yagl_egl_state *state = yagl_egl_get_state();
237 int ctx_marked = 0, draw_sfc_marked = 0;
239 if (ctx && (state->ctx != ctx)) {
240 if (!yagl_context_mark_current(ctx, 1)) {
246 if (draw_sfc && (state->draw_sfc != draw_sfc)) {
247 if (!yagl_surface_mark_current(draw_sfc, 1)) {
254 (state->read_sfc != read_sfc) &&
255 (read_sfc != draw_sfc) &&
256 !yagl_surface_mark_current(read_sfc, 1)) {
260 if (state->ctx && (state->ctx != ctx)) {
261 yagl_context_mark_current(state->ctx, 0);
264 if (state->draw_sfc && (state->draw_sfc != draw_sfc)) {
265 yagl_surface_mark_current(state->draw_sfc, 0);
268 if (state->read_sfc &&
269 (state->read_sfc != read_sfc) &&
270 (state->read_sfc != state->draw_sfc)) {
271 yagl_surface_mark_current(state->read_sfc, 0);
274 yagl_context_acquire(ctx);
275 yagl_surface_acquire(draw_sfc);
276 yagl_surface_acquire(read_sfc);
278 yagl_surface_release(state->read_sfc);
279 yagl_surface_release(state->draw_sfc);
280 yagl_context_release(state->ctx);
283 state->read_sfc = read_sfc;
284 state->draw_sfc = draw_sfc;
290 yagl_context_mark_current(ctx, 0);
292 if (draw_sfc_marked) {
293 yagl_surface_mark_current(draw_sfc, 0);
299 void yagl_reset_state()
301 struct yagl_egl_state *state = yagl_egl_get_state();
303 yagl_set_context(NULL, NULL, NULL);
305 state->error = EGL_SUCCESS;
306 state->api = EGL_OPENGL_ES_API;
309 struct yagl_client_context *yagl_get_client_context(void)
311 struct yagl_egl_state *state = yagl_egl_get_state();
313 return state->ctx ? state->ctx->client_ctx : NULL;
316 struct yagl_client_interface *yagl_get_client_interface(yagl_client_api client_api)
318 struct yagl_egl_state *state = yagl_egl_get_state();
320 switch (client_api) {
321 case yagl_client_api_gles1:
322 if (!state->gles1_iface) {
323 state->gles1_iface = yagl_get_gles1_sym("yagl_gles1_interface");
325 return state->gles1_iface;
326 case yagl_client_api_gles2:
327 case yagl_client_api_gles3:
328 if (!state->gles2_iface) {
329 state->gles2_iface = yagl_get_gles1_sym("yagl_gles2_interface");
331 return state->gles2_iface;
337 struct yagl_client_interface *yagl_get_any_client_interface()
339 struct yagl_client_interface *iface;
341 iface = yagl_get_client_interface(yagl_client_api_gles2);
343 iface = yagl_get_client_interface(yagl_client_api_gles1);