1 #include "coregl_fastpath.h"
13 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
15 General_Trace_List *glue_ctx_trace_list = NULL;
16 General_Trace_List *context_state_trace_list = NULL;
19 _dump_context_info(const char *ment, int force_output)
21 MY_MODULE_TSTATE *tstate = NULL;
22 static struct timeval tv_last = { 0, 0 };
24 if (trace_ctx_flag != 1) return;
26 AST(mutex_lock(&ctx_list_access_mutex) == 1);
27 AST(mutex_lock(&general_trace_lists_access_mutex) == 1);
29 if (!force_output && !trace_ctx_force_flag)
31 struct timeval tv_now = { 0, 0 };
32 AST(gettimeofday(&tv_now, NULL) == 0);
33 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC)
40 GET_MY_TSTATE(tstate, get_current_thread_state());
43 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
44 TRACE("\E[40;32;1m Context info \E[1;37;1m: <PID = %d> %s\E[0m\n", getpid(), ment);
45 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
50 General_Trace_List *current = NULL;
51 current = thread_trace_list;
53 while (current != NULL)
55 GLThreadState *cur_tstate = (GLThreadState *)current->value;
56 MY_MODULE_TSTATE *cur_tstate_tm = NULL;
58 GET_MY_TSTATE(cur_tstate_tm, cur_tstate);
59 AST(cur_tstate_tm != NULL);
61 TRACE(" %c Thread [0x%12x] : Surf <D=[%12p] R=[%12p]>",
62 (tstate == cur_tstate_tm) ? '*' : ' ',
63 cur_tstate->thread_id,
64 cur_tstate_tm->rsurf_draw,
65 cur_tstate_tm->rsurf_read);
67 if (cur_tstate_tm->cstate != NULL)
69 TRACE(" GlueCTX=[%12p] RealCTX=[%12p]\E[0m\n",
70 cur_tstate_tm->cstate->data,
71 cur_tstate_tm->cstate);
75 TRACE(" (NOT BINDED TO THREAD)\E[0m\n");
78 // Binded Context State List
80 General_Trace_List *current = NULL;
81 current = context_state_trace_list;
83 while (current != NULL)
85 GLContextState *cur_cstate = (GLContextState *)current->value;
86 MY_MODULE_TSTATE *cur_tstate_tm = NULL;
88 GET_MY_TSTATE(cur_tstate_tm, cur_tstate);
89 AST(cur_tstate_tm != NULL);
91 if (cur_tstate_tm->cstate == cur_cstate)
93 TRACE(" -> RealCTX [%12p] : EGLDPY=[%12p] EGLCTX=[%12p] <[%2d] GlueCTXs>\E[0m\n",
97 cur_cstate->ref_count);
99 // Binded Glue Context List
101 General_Trace_List *current = NULL;
102 current = glue_ctx_trace_list;
104 while (current != NULL)
106 GLGlueContext *cur_gctx = (GLGlueContext *)current->value;
108 if (cur_gctx->cstate == cur_cstate)
110 TRACE(" -%c GlueCTX [%12p] : EGLDPY=[%12p] TID=[%12d] <MC count [%10d]>",
111 (cur_cstate->data == cur_gctx) ? '>' : '-',
115 cur_gctx->used_count);
117 TRACE(" <Ref [%2d]>\E[0m\n", cur_gctx->ref_count);
120 current = current->next;
125 current = current->next;
131 current = current->next;
135 TRACE("\E[40;33m........................................................................................................................\E[0m\n");
137 // Not-binded Context State List
139 General_Trace_List *current = NULL;
140 current = context_state_trace_list;
142 while (current != NULL)
144 GLContextState *cur_cstate = (GLContextState *)current->value;
148 if (cur_cstate->data != NULL)
150 General_Trace_List *current_t = NULL;
151 current_t = thread_trace_list;
153 while (current_t != NULL)
155 GLThreadState *cur_tstate = (GLThreadState *)current_t->value;
156 MY_MODULE_TSTATE *cur_tstate_tm = NULL;
158 GET_MY_TSTATE(cur_tstate_tm, cur_tstate);
159 AST(cur_tstate_tm != NULL);
161 if (cur_tstate->thread_id == ((GLGlueContext *)cur_cstate->data)->thread_id)
163 if (cur_tstate_tm->cstate == cur_cstate)
167 current_t = current_t->next;
173 TRACE(" RealCTX [%12p] : EGLDPY=[%12p] EGLCTX=[%12p] <[%2d] GlueCTXs>\E[0m\n",
177 cur_cstate->ref_count);
179 // Binded Glue Context List
181 General_Trace_List *current = NULL;
182 current = glue_ctx_trace_list;
184 while (current != NULL)
186 GLGlueContext *cur_gctx = (GLGlueContext *)current->value;
188 if (cur_gctx->cstate == cur_cstate)
190 TRACE(" -%c GlueCTX [%12p] : EGLDPY=[%12p] TID=[%12d] <MC count [%10d]>",
191 (cur_cstate->data == cur_gctx) ? '>' : '-',
195 cur_gctx->used_count);
197 TRACE(" <Ref [%2d]>\E[0m\n", cur_gctx->ref_count);
200 current = current->next;
205 current = current->next;
210 TRACE("\E[40;33m........................................................................................................................\E[0m\n");
212 // Not-binded Glue Context List
214 General_Trace_List *current = NULL;
215 current = glue_ctx_trace_list;
217 while (current != NULL)
219 GLGlueContext *cur_gctx = (GLGlueContext *)current->value;
221 if (cur_gctx->cstate == NULL)
223 TRACE(" GlueCTX [%12p] : EGLDPY=[%12p] TID=[%12d] <MC count [%10d]>",
227 cur_gctx->used_count);
229 TRACE(" <Ref [%2d]>\E[0m\n", cur_gctx->ref_count);
232 current = current->next;
236 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
245 AST(mutex_unlock(&general_trace_lists_access_mutex) == 1);
246 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
250 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
255 EGLint context_major_version;
256 EGLint context_minor_version;
257 EGLint context_flags;
258 EGLint context_opengl_profile_mask;
259 EGLint opengl_reset_notification_strategy;
260 } EGL_packed_attrib_list;
266 EGL_packed_attrib_list attrib_list;
272 EGLContext share_context;
273 } EGL_packed_sharable_option;
277 _pack_egl_context_option(EGL_packed_option *pack_data, EGLDisplay dpy, EGLConfig cfg, EGLint force_unique, const EGLint *attrib_list)
279 static int force_unique_free_id = 0;
282 pack_data->dpy = dpy;
283 pack_data->cfg = cfg;
284 if (force_unique != 0)
285 pack_data->force_unique = force_unique_free_id++;
287 // Default context attributes
288 pack_data->attrib_list.context_major_version = EGL_DONT_CARE;
289 pack_data->attrib_list.context_minor_version = EGL_DONT_CARE;
290 pack_data->attrib_list.context_flags = EGL_DONT_CARE;
291 pack_data->attrib_list.context_opengl_profile_mask = EGL_DONT_CARE;
292 pack_data->attrib_list.opengl_reset_notification_strategy = EGL_DONT_CARE;
294 // Apply specified attributes
295 EGLint *attrib = (EGLint *)attrib_list;
296 while(attrib[0] != EGL_NONE)
300 case EGL_CONTEXT_MAJOR_VERSION_KHR: // EGL_CONTEXT_CLIENT_VERSION
301 pack_data->attrib_list.context_major_version = attrib[1];
303 case EGL_CONTEXT_MINOR_VERSION_KHR:
304 pack_data->attrib_list.context_minor_version = attrib[1];
306 case EGL_CONTEXT_FLAGS_KHR:
307 pack_data->attrib_list.context_flags = attrib[1];
309 case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
310 pack_data->attrib_list.context_opengl_profile_mask = attrib[1];
312 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
313 pack_data->attrib_list.opengl_reset_notification_strategy = attrib[1];
316 COREGL_WRN("\E[40;31;1mInvalid context attribute.\E[0m\n");
322 // Eject condition for context version
323 if (pack_data->attrib_list.context_major_version != 2)
325 pack_data->force_unique = force_unique_free_id;
336 _unpack_egl_context_option(EGL_packed_option *pack_data, EGLDisplay *dpy, EGLConfig *cfg, EGLint *force_unique, EGLint *attrib_list, const int attrib_list_size)
340 if (dpy != NULL) *dpy = pack_data->dpy;
341 if (cfg != NULL) *cfg = pack_data->cfg;
342 if (force_unique != NULL) *force_unique = pack_data->force_unique;
344 if (attrib_list != NULL && attrib_list_size > 0)
346 int attrib_list_index = 0;
348 memset(attrib_list, 0x00, sizeof(int) * attrib_list_size);
350 if (pack_data->attrib_list.context_major_version != EGL_DONT_CARE)
352 AST(attrib_list_index + 2 < attrib_list_size);
353 attrib_list[attrib_list_index] = EGL_CONTEXT_MAJOR_VERSION_KHR;
354 attrib_list[attrib_list_index + 1] = pack_data->attrib_list.context_major_version;
355 attrib_list_index += 2;
357 if (pack_data->attrib_list.context_minor_version != EGL_DONT_CARE)
359 AST(attrib_list_index + 2 < attrib_list_size);
360 attrib_list[attrib_list_index] = EGL_CONTEXT_MINOR_VERSION_KHR;
361 attrib_list[attrib_list_index + 1] = pack_data->attrib_list.context_minor_version;
362 attrib_list_index += 2;
364 if (pack_data->attrib_list.context_flags != EGL_DONT_CARE)
366 AST(attrib_list_index + 2 < attrib_list_size);
367 attrib_list[attrib_list_index] = EGL_CONTEXT_FLAGS_KHR;
368 attrib_list[attrib_list_index + 1] = pack_data->attrib_list.context_flags;
369 attrib_list_index += 2;
371 if (pack_data->attrib_list.context_opengl_profile_mask != EGL_DONT_CARE)
373 AST(attrib_list_index + 2 < attrib_list_size);
374 attrib_list[attrib_list_index] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
375 attrib_list[attrib_list_index + 1] = pack_data->attrib_list.context_opengl_profile_mask;
376 attrib_list_index += 2;
378 if (pack_data->attrib_list.opengl_reset_notification_strategy != EGL_DONT_CARE)
380 AST(attrib_list_index + 2 < attrib_list_size);
381 attrib_list[attrib_list_index] = EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR;
382 attrib_list[attrib_list_index + 1] = pack_data->attrib_list.opengl_reset_notification_strategy;
383 attrib_list_index += 2;
386 attrib_list[attrib_list_index] = EGL_NONE;
396 _pack_egl_context_sharable_option(EGL_packed_sharable_option *pack_data, EGLContext share_context)
400 pack_data->share_context = share_context;
411 _unpack_egl_context_sharable_option(EGL_packed_sharable_option *pack_data, EGLContext *share_context)
415 if (share_context != NULL) *share_context = pack_data->share_context;
426 _link_context_state(GLGlueContext *gctx, GLContextState *cstate)
428 AST(gctx->cstate == NULL);
430 gctx->cstate = cstate;
434 _unlink_context_state(GLGlueContext *gctx, Mutex *ctx_list_mtx)
436 GLContextState *cstate = NULL;
438 cstate = gctx->cstate;
442 AST(cstate->ref_count >= 0);
444 if (cstate->ref_count == 0)
446 MY_MODULE_TSTATE *tstate = NULL;
448 AST(cstate->data == NULL || cstate->data == initial_ctx);
450 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
451 if (unlikely(trace_ctx_flag == 1))
452 remove_from_general_trace_list(&context_state_trace_list, cstate);
453 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
455 AST(fastpath_remove_context_states_from_list(cstate, ctx_list_mtx) == 1);
457 GET_MY_TSTATE(tstate, get_current_thread_state());
460 if (tstate->cstate == cstate)
462 _orig_fastpath_eglMakeCurrent(cstate->rdpy, tstate->rsurf_draw, tstate->rsurf_read, EGL_NO_CONTEXT);
463 tstate->cstate = NULL;
466 _orig_fastpath_eglDestroyContext(cstate->rdpy, cstate->rctx);
473 _add_shared_obj_state_ref(GLGlueContext *gctx, GL_Shared_Object_State *sostate)
475 AST(sostate->ref_count >= 0);
476 sostate->ref_count++;
477 add_to_general_trace_list(&sostate->using_gctxs, gctx);
481 _remove_shared_obj_state_ref(GLGlueContext *gctx, GL_Shared_Object_State *sostate)
483 remove_from_general_trace_list(&sostate->using_gctxs, gctx);
485 // Restore attached states
486 fastpath_release_gl_context(gctx);
488 AST(sostate->ref_count > 0);
489 sostate->ref_count--;
490 if (sostate->ref_count == 0)
492 fastpath_sostate_deinit(sostate);
498 _add_context_ref(GLGlueContext *gctx)
500 if (gctx == initial_ctx) return;
502 AST(gctx->ref_count >= 0);
507 _remove_context_ref(GLGlueContext *gctx, Mutex *ctx_list_mtx)
509 if (gctx == initial_ctx) return;
511 AST(gctx->ref_count > 0);
513 if (gctx->ref_count == 0)
515 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
516 if (unlikely(trace_ctx_flag == 1))
517 remove_from_general_trace_list(&glue_ctx_trace_list, gctx);
518 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
520 AST(gctx->cstate != NULL);
521 if (gctx->cstate->data == gctx)
522 gctx->cstate->data = NULL;
524 _unlink_context_state(gctx, ctx_list_mtx);
526 AST(gctx->ostate.shared != NULL);
527 _remove_shared_obj_state_ref(gctx, gctx->ostate.shared);
528 gctx->ostate.shared = NULL;
530 fastpath_ostate_deinit(&gctx->ostate);
532 if (gctx->real_ctx_option != NULL)
534 free(gctx->real_ctx_option);
535 gctx->real_ctx_option = NULL;
537 if (gctx->real_ctx_sharable_option != NULL)
539 free(gctx->real_ctx_sharable_option);
540 gctx->real_ctx_sharable_option = NULL;
545 GLGlueContext_List *current = NULL;
547 AST(mutex_lock(&ctx_list_access_mutex) == 1);
551 while (current != NULL)
553 if (current->gctx == gctx)
555 if (current->next != NULL)
556 current->next->prev = current->prev;
558 if (current->prev != NULL)
559 current->prev->next = current->next;
561 gctx_list = current->next;
567 current = current->next;
570 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
576 _bind_context_state(GLGlueContext *gctx, GLContextState *cstate, Mutex *ctx_list_mtx)
580 AST(gctx->cstate == cstate);
583 if (cstate->data != gctx)
585 GLGlueContext *curctx = (GLGlueContext *)cstate->data;
586 GLGlueContext *newctx = gctx;
589 newctx = initial_ctx;
592 curctx = initial_ctx;
597 if (!fastpath_make_context_current(curctx, newctx))
600 cstate->data = (void *)newctx;
601 _remove_context_ref(curctx, ctx_list_mtx);
602 _add_context_ref(newctx);
610 _egl_create_context(EGL_packed_option *real_ctx_option, GLContextState **cstate_new, EGLContext *ctx,
611 EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list)
613 GLContextState *cstate = NULL;
615 AST(real_ctx_option != NULL);
616 AST(cstate_new != NULL);
619 // Pack context option
620 AST(_pack_egl_context_option(real_ctx_option, dpy, config, 0, attrib_list) == 1);
624 AST(_pack_egl_context_option(real_ctx_option, dpy, config, 1, attrib_list) == 1);
627 // Find context state
628 if (real_ctx_option->force_unique == 0)
630 cstate = fastpath_get_context_state_from_list(real_ctx_option, sizeof(EGL_packed_option), &ctx_list_access_mutex);
633 // Create a real context if it hasn't been created
636 EGLContext *real_share_context = EGL_NO_CONTEXT;
638 AST(mutex_lock(&ctx_list_access_mutex) == 1);
640 GLContext_List *current = NULL;
642 current = glctx_list;
643 while (current != NULL)
645 EGLDisplay cur_dpy = EGL_NO_DISPLAY;
646 AST(_unpack_egl_context_option(current->option, &cur_dpy, NULL, NULL, NULL, 0) == 1);
649 AST(current->cstate != NULL);
650 real_share_context = current->cstate->rctx;
653 current = current->next;
656 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
658 *ctx = _orig_fastpath_eglCreateContext(dpy, config, real_share_context, attrib_list);
660 if (*ctx == EGL_NO_CONTEXT)
662 COREGL_WRN("\E[40;31;1mFailed creating a egl real context for Fastpath. (Invalid config?)\E[0m\n");
666 *cstate_new = (GLContextState *)calloc(1, sizeof(GLContextState));
667 if (*cstate_new == NULL)
669 COREGL_ERR("\E[40;31;1mError creating a new context state. (Memory full)\E[0m\n");
672 (*cstate_new)->rctx = *ctx;
673 (*cstate_new)->rdpy = dpy;
674 (*cstate_new)->data = NULL;
676 AST(fastpath_add_context_state_to_list(real_ctx_option, sizeof(EGL_packed_option), *cstate_new, &ctx_list_access_mutex) == 1);
678 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
679 if (unlikely(trace_ctx_flag == 1))
680 add_to_general_trace_list(&context_state_trace_list, *cstate_new);
681 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
683 cstate = *cstate_new;
694 extern EGLBoolean (*ovr_eglBindAPI)(EGLenum api);
695 extern EGLenum (*ovr_eglQueryAPI)(void);
698 fastpath_eglBindAPI(EGLenum api)
700 EGLBoolean ret = EGL_FALSE;
701 MY_MODULE_TSTATE *tstate = NULL;
703 _COREGL_FASTPATH_FUNC_BEGIN();
704 if (fp_opt == FP_UNKNOWN_PATH)
706 COREGL_ERR("\E[40;31;1mInvalid library link! (CoreGL path option is invalid)\E[0m\n");
710 ret = _orig_fastpath_eglBindAPI(api);
712 GET_MY_TSTATE(tstate, get_current_thread_state());
715 AST(init_new_thread_state() == 1);
717 GET_MY_TSTATE(tstate, get_current_thread_state());
721 /* Prevent CID : 403951 */
724 EGLenum newapi = _orig_fastpath_eglQueryAPI();
725 if (tstate->binded_api != EGL_OPENGL_ES_API)
727 tstate->binded_api = newapi;
734 _COREGL_FASTPATH_FUNC_END();
739 fastpath_eglQueryAPI(void)
742 MY_MODULE_TSTATE *tstate = NULL;
744 _COREGL_FASTPATH_FUNC_BEGIN();
745 if (fp_opt == FP_UNKNOWN_PATH)
747 COREGL_ERR("\E[40;31;1mInvalid library link! (CoreGL path option is invalid)\E[0m\n");
751 ret = _orig_fastpath_eglQueryAPI();
753 GET_MY_TSTATE(tstate, get_current_thread_state());
756 AST(tstate->binded_api == ret);
762 _COREGL_FASTPATH_FUNC_END();
767 fastpath_eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list)
769 GLGlueContext *gctx = NULL, *newgctx = NULL;
770 GLGlueContext_List *gctx_list_new = NULL;
771 MY_MODULE_TSTATE *tstate = NULL;
772 GLContextState *cstate = NULL;
773 GLContextState *cstate_new = NULL;
774 GL_Shared_Object_State *sostate_new = NULL;
775 GLContext ctx = NULL;
777 EGL_packed_option *real_ctx_option = NULL;
778 EGL_packed_sharable_option *real_ctx_sharable_option = NULL;
780 // Special eject condition for binding API
781 GET_MY_TSTATE(tstate, get_current_thread_state());
782 if (tstate != NULL && tstate->binded_api != EGL_OPENGL_ES_API)
784 return _orig_fastpath_eglCreateContext(dpy, config, share_context, attrib_list);
787 _COREGL_FASTPATH_FUNC_BEGIN();
789 real_ctx_option = (EGL_packed_option *)calloc(1, sizeof(EGL_packed_option));
790 if (real_ctx_option == NULL)
792 COREGL_ERR("\E[40;31;1mError creating a new GLGlueContext(Memory full 1)\E[0m\n");
795 cstate = _egl_create_context(real_ctx_option, &cstate_new, &ctx, dpy, config, attrib_list);
798 // Pack shared context options
799 real_ctx_sharable_option = (EGL_packed_sharable_option *)calloc(1, sizeof(EGL_packed_sharable_option));
800 if (real_ctx_sharable_option == NULL)
802 COREGL_ERR("\E[40;31;1mError creating a new GLGlueContext(Memory full 2)\E[0m\n");
805 AST(_pack_egl_context_sharable_option(real_ctx_sharable_option, share_context) == 1);
807 // Allocate a new context
808 newgctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
811 COREGL_ERR("\E[40;31;1mError creating a new GLGlueContext(Memory full 3)\E[0m\n");
815 newgctx->magic = MAGIC_GLFAST;
816 newgctx->initialized = 0;
818 newgctx->thread_id = get_current_thread();
820 fastpath_ostate_init(&newgctx->ostate);
822 if (share_context != EGL_NO_CONTEXT)
824 GLGlueContext *shared_gctx = (GLGlueContext *)share_context;
825 AST(shared_gctx->magic == MAGIC_GLFAST);
826 AST(shared_gctx->ostate.shared != NULL);
827 newgctx->ostate.shared = shared_gctx->ostate.shared;
831 sostate_new = (GL_Shared_Object_State *)calloc(1, sizeof(GL_Shared_Object_State));
832 if (sostate_new == NULL)
834 COREGL_ERR("\E[40;31;1mError creating a new GLGlueContext(Memory full 4)\E[0m\n");
837 fastpath_sostate_init(sostate_new);
838 newgctx->ostate.shared = sostate_new;
840 _add_shared_obj_state_ref(newgctx, newgctx->ostate.shared);
841 newgctx->real_ctx_option = real_ctx_option;
842 newgctx->real_ctx_option_len = sizeof(EGL_packed_option);
843 newgctx->real_ctx_sharable_option = real_ctx_sharable_option;
844 newgctx->real_ctx_sharable_option_len = sizeof(EGL_packed_sharable_option);
846 _link_context_state(newgctx, cstate);
847 _add_context_ref(newgctx);
849 newgctx->cstate = cstate;
851 { // Add glue context to list
852 gctx_list_new = (GLGlueContext_List *)calloc(1, sizeof(GLGlueContext_List));
853 if (gctx_list_new == NULL)
855 COREGL_ERR("\E[40;31;1mError creating a new GlGlueContext(Memory full 5)\E[0m\n");
859 AST(mutex_lock(&ctx_list_access_mutex) == 1);
861 gctx_list_new->gctx = newgctx;
863 gctx_list_new->prev = NULL;
864 gctx_list_new->next = gctx_list;
865 if (gctx_list != NULL)
866 gctx_list->prev = gctx_list_new;
868 gctx_list = gctx_list_new;
870 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
875 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
876 if (unlikely(trace_ctx_flag == 1))
879 add_to_general_trace_list(&glue_ctx_trace_list, newgctx);
881 snprintf(ment,sizeof(ment), "eglCreateContext completed (GlueCTX=[%12p])", newgctx);
882 _dump_context_info(ment, 1);
884 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
893 _orig_fastpath_eglDestroyContext(dpy, ctx);
896 if (sostate_new != NULL)
901 if (real_ctx_option != NULL)
903 free(real_ctx_option);
904 real_ctx_option = NULL;
906 if (real_ctx_sharable_option != NULL)
908 free(real_ctx_sharable_option);
909 real_ctx_sharable_option = NULL;
911 if (cstate_new != NULL)
913 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
914 if (unlikely(trace_ctx_flag == 1))
915 remove_from_general_trace_list(&context_state_trace_list, cstate_new);
916 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
918 fastpath_remove_context_states_from_list(cstate_new, &ctx_list_access_mutex);
922 if (gctx_list_new != NULL)
924 AST(mutex_lock(&ctx_list_access_mutex) == 1);
926 if (gctx_list_new->next != NULL)
927 gctx_list_new->next->prev = gctx_list_new->prev;
929 if (gctx_list_new->prev != NULL)
930 gctx_list_new->prev->next = gctx_list_new->next;
932 gctx_list = gctx_list_new->next;
934 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
940 _remove_context_ref(newgctx, &ctx_list_access_mutex);
946 _COREGL_FASTPATH_FUNC_END();
947 return (EGLContext)gctx;
951 fastpath_eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
953 EGLBoolean ret = EGL_FALSE;
954 GLGlueContext *gctx = NULL;
956 _COREGL_FASTPATH_FUNC_BEGIN();
958 gctx = (GLGlueContext *)ctx;
960 if (gctx != NULL && gctx != EGL_NO_CONTEXT)
962 GLContextState *cstate = NULL;
964 if (gctx->magic != MAGIC_GLFAST)
966 ret = _orig_fastpath_eglDestroyContext(dpy, ctx);
970 cstate = gctx->cstate;
973 if (gctx->is_destroyed != 1)
975 gctx->is_destroyed = 1;
976 _remove_context_ref(gctx, &ctx_list_access_mutex);
981 COREGL_WRN("\E[40;31;1mInvalid destroying context. (no exists)\E[0m\n");
990 _COREGL_FASTPATH_FUNC_END();
992 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
993 if (unlikely(trace_ctx_flag == 1))
996 snprintf(ment,sizeof(ment), "eglDestroyContext completed (GlueCTX=[%12p])", ctx);
997 _dump_context_info(ment, 1);
999 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
1005 fastpath_eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
1007 EGLBoolean ret = EGL_FALSE;
1008 EGLContext real_ctx = EGL_NO_CONTEXT;
1010 _COREGL_FASTPATH_FUNC_BEGIN();
1012 if (ctx != EGL_NO_CONTEXT)
1014 GLGlueContext *gctx = NULL;
1015 gctx = (GLGlueContext *)ctx;
1017 if (gctx->magic != MAGIC_GLFAST)
1023 AST(gctx->cstate != NULL);
1024 real_ctx = gctx->cstate->rctx;
1028 ret = _orig_fastpath_eglQueryContext(dpy, real_ctx, attribute, value);
1032 _COREGL_FASTPATH_FUNC_END();
1039 fastpath_eglReleaseThread(void)
1041 EGLBoolean ret = EGL_FALSE;
1042 EGLDisplay dpy = EGL_NO_DISPLAY;
1043 MY_MODULE_TSTATE *tstate = NULL;
1045 GET_MY_TSTATE(tstate, get_current_thread_state());
1047 // Special eject condition for binding API
1048 if (tstate != NULL && tstate->binded_api != EGL_OPENGL_ES_API)
1050 return _orig_fastpath_eglReleaseThread();
1053 _COREGL_FASTPATH_FUNC_BEGIN();
1055 dpy = _orig_fastpath_eglGetCurrentDisplay();
1056 AST(dpy != EGL_NO_DISPLAY);
1057 fastpath_eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1058 ret = _orig_fastpath_eglReleaseThread();
1062 _COREGL_FASTPATH_FUNC_END();
1067 fastpath_eglGetCurrentDisplay(void)
1069 MY_MODULE_TSTATE *tstate = NULL;
1070 EGLDisplay dpy = EGL_NO_DISPLAY;
1072 GET_MY_TSTATE(tstate, get_current_thread_state());
1076 // Special eject condition for binding API
1077 if(tstate->binded_api != EGL_OPENGL_ES_API)
1079 return _orig_fastpath_eglGetCurrentDisplay();
1082 _COREGL_FASTPATH_FUNC_BEGIN();
1084 if (tstate->cstate != NULL)
1086 dpy = tstate->cstate->rdpy;
1090 _COREGL_FASTPATH_FUNC_END();
1102 fastpath_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
1104 EGLBoolean ret = EGL_FALSE;
1105 EGLBoolean need_mc = EGL_FALSE;
1106 GLGlueContext *gctx = NULL;
1108 MY_MODULE_TSTATE *tstate = NULL;
1110 GET_MY_TSTATE(tstate, get_current_thread_state());
1112 // Special eject condition for binding API
1113 if (tstate != NULL && tstate->binded_api != EGL_OPENGL_ES_API)
1115 return _orig_fastpath_eglMakeCurrent(dpy, draw, read, ctx);
1118 _COREGL_FASTPATH_FUNC_BEGIN();
1120 gctx = (GLGlueContext *)ctx;
1124 AST(init_new_thread_state() == 1);
1126 GET_MY_TSTATE(tstate, get_current_thread_state());
1127 AST(tstate != NULL);
1128 /* Prevent CID : 395199 */
1129 if (tstate == NULL) goto finish;
1132 // Special path for context deletion
1133 if (ctx == EGL_NO_CONTEXT)
1137 if (tstate->cstate != NULL)
1139 if (_bind_context_state(NULL, tstate->cstate, &ctx_list_access_mutex) != 1)
1141 COREGL_WRN("\E[40;31;1mError soft-makecurrent for context deletion\E[0m\n");
1143 tstate->cstate = NULL;
1145 if (_orig_fastpath_eglMakeCurrent(dpy, draw, read, ctx) != EGL_TRUE)
1147 COREGL_WRN("Error making context [%p] current. (invalid EGL display [%p] or EGL surface [D:%p/R:%p])\n", ctx, dpy, draw, read);
1152 tstate->rsurf_draw = draw;
1153 tstate->rsurf_read = read;
1160 AST(gctx->cstate != NULL);
1162 if (gctx->rdpy != dpy)
1164 COREGL_WRN("\E[40;31;1mInvalid context (or invalid EGL display)\E[0m\n");
1169 AST(gctx->real_ctx_option != NULL);
1170 AST(gctx->real_ctx_sharable_option != NULL);
1172 // Handle cross threading of context (when used by two or more gctx)
1173 if (gctx->thread_id != get_current_thread() && gctx->cstate->ref_count > 1)
1175 #define ATTRIB_LIST_BUFFER_SIZE 8
1177 GLContextState *cstate_new = NULL;
1178 EGLContext new_real_ctx = EGL_NO_CONTEXT;
1180 EGLDisplay dpy = EGL_NO_DISPLAY;
1181 EGLConfig config = NULL;
1182 int attrib_list[ATTRIB_LIST_BUFFER_SIZE];
1184 AST(_unpack_egl_context_option(gctx->real_ctx_option, &dpy, &config, NULL, attrib_list, ATTRIB_LIST_BUFFER_SIZE) == 1);
1185 AST(dpy == gctx->rdpy);
1187 _egl_create_context(gctx->real_ctx_option, &cstate_new, &new_real_ctx, dpy, config, attrib_list);
1189 AST(cstate_new != NULL);
1191 if (_bind_context_state(gctx, cstate_new, &ctx_list_access_mutex) != 1)
1193 COREGL_WRN("\E[40;31;1mError soft-makecurrent in Cross-thread usage!\E[0m\n");
1195 _orig_fastpath_eglDestroyContext(dpy, new_real_ctx);
1200 // TODO : Setup context state for new real ctx
1201 COREGL_WRN("\E[40;31;1mCross-thread usage(makecurrent) can cause a state-broken situation!\E[0m\n");
1203 _unlink_context_state(gctx, &ctx_list_access_mutex);
1204 _link_context_state(gctx, cstate_new);
1206 // Apply to new thread
1207 gctx->thread_id = get_current_thread();
1211 // Check if the object is correct
1212 if (gctx->magic != MAGIC_GLFAST)
1214 COREGL_ERR("\E[40;31;1mGlue-CTX Magic Check Failed!!! (Memory broken?)\E[0m\n");
1220 // If drawable changed, do a make current
1221 if ((tstate->rsurf_draw != draw) ||
1222 (tstate->rsurf_read != read))
1225 AST(gctx->cstate != NULL);
1227 // If binded real context changed, do a make current
1228 if (tstate->cstate == NULL || tstate->cstate != gctx->cstate)
1231 if (need_mc == EGL_TRUE)
1233 AST(dpy == gctx->cstate->rdpy);
1235 // BB : full makecurrent
1236 if (_orig_fastpath_eglMakeCurrent(dpy, draw, read, gctx->cstate->rctx) != EGL_TRUE)
1238 COREGL_WRN("\E[40;31;1mError making context current with the drawable. (Bad match?)\E[0m\n");
1243 // Update references only when the contexts are different
1244 if(tstate->cstate != gctx->cstate) {
1245 if (tstate->cstate != NULL && tstate->cstate->data != NULL)
1246 _remove_context_ref((GLGlueContext *)tstate->cstate->data, &ctx_list_access_mutex);
1248 tstate->cstate = gctx->cstate;
1250 if (tstate->cstate->data != NULL)
1251 _add_context_ref((GLGlueContext *)tstate->cstate->data);
1254 tstate->rsurf_draw = draw;
1255 tstate->rsurf_read = read;
1258 // Initialize context states
1259 if (gctx->initialized == 0)
1261 if (fastpath_init_context_states(gctx) != 1)
1263 COREGL_ERR("\E[40;31;1mError intializing context. (Check driver specification)\E[0m\n");
1268 // Setup initial Viewport & Scissor
1269 if (gctx->surface_attached == 0 && draw != EGL_NO_SURFACE)
1271 EGLint box_buffer[4];
1275 _orig_fastpath_glGetIntegerv(GL_VIEWPORT, box_buffer);
1276 width = box_buffer[2];
1277 height = box_buffer[3];
1279 gctx->_clear_flag1 |= _CLEAR_FLAG1_BIT_gl_viewport;
1280 gctx->gl_viewport[0] = 0;
1281 gctx->gl_viewport[1] = 0;
1282 gctx->gl_viewport[2] = width;
1283 gctx->gl_viewport[3] = height;
1285 _orig_fastpath_glGetIntegerv(GL_SCISSOR_BOX, box_buffer);
1286 width = box_buffer[2];
1287 height = box_buffer[3];
1289 gctx->_misc_flag2 |= _MISC_FLAG2_BIT_gl_scissor_box;
1290 gctx->gl_scissor_box[0] = 0;
1291 gctx->gl_scissor_box[1] = 0;
1292 gctx->gl_scissor_box[2] = width;
1293 gctx->gl_scissor_box[3] = height;
1295 gctx->surface_attached = 1;
1298 if (_bind_context_state(gctx, tstate->cstate, &ctx_list_access_mutex) != 1)
1310 _COREGL_FASTPATH_FUNC_END();
1312 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
1313 if (unlikely(trace_ctx_flag == 1))
1316 snprintf(ment,sizeof(ment), "eglMakeCurrent finished (GlueCTX=[%12p] Surf=[D:%12p R:%12p])", ctx, draw, read);
1317 _dump_context_info(ment, 0);
1319 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
1326 fastpath_eglGetCurrentContext(void)
1328 GLGlueContext *ret = NULL;
1329 MY_MODULE_TSTATE *tstate = NULL;
1331 GET_MY_TSTATE(tstate, get_current_thread_state());
1333 // Special eject condition for binding API
1334 if (tstate != NULL && tstate->binded_api != EGL_OPENGL_ES_API)
1336 return _orig_fastpath_eglGetCurrentContext();
1339 _COREGL_FASTPATH_FUNC_BEGIN();
1343 if (tstate->cstate != NULL)
1345 ret = (GLGlueContext *)tstate->cstate->data;
1346 AST(ret->magic == MAGIC_GLFAST);
1352 _COREGL_FASTPATH_FUNC_END();
1353 return (EGLContext)ret;
1358 fastpath_eglGetCurrentSurface(EGLint readdraw)
1360 EGLSurface ret = EGL_NO_SURFACE;
1361 MY_MODULE_TSTATE *tstate = NULL;
1363 GET_MY_TSTATE(tstate, get_current_thread_state());
1365 // Special eject condition for binding API
1366 if (tstate != NULL && tstate->binded_api != EGL_OPENGL_ES_API)
1368 return _orig_fastpath_eglGetCurrentSurface(readdraw);
1371 _COREGL_FASTPATH_FUNC_BEGIN();
1378 ret = (GLGlueContext *)tstate->rsurf_draw;
1381 ret = (GLGlueContext *)tstate->rsurf_read;
1388 _COREGL_FASTPATH_FUNC_END();
1393 fastpath_eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
1396 EGLContext real_ctx = EGL_NO_CONTEXT;
1397 GLuint real_obj = 0;
1399 _COREGL_FASTPATH_FUNC_BEGIN();
1401 if (ctx != NULL && ctx != EGL_NO_CONTEXT)
1403 GLGlueContext *gctx = (GLGlueContext *)ctx;
1405 if (gctx->magic != MAGIC_GLFAST)
1411 AST(gctx->cstate != NULL);
1412 real_ctx = gctx->cstate->rctx;
1417 case EGL_GL_TEXTURE_2D_KHR:
1418 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
1419 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
1420 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
1421 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
1422 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
1423 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
1424 case EGL_GL_TEXTURE_3D_KHR:
1425 case EGL_GL_RENDERBUFFER_KHR:
1426 if((GLuint )buffer == 0)
1428 COREGL_ERR("\E[40;31;1m fastpath_eglCreateImageKHR buffer object NULL \E[0m\n");
1431 real_obj = fastpath_ostate_get_object(&gctx->ostate, GL_OBJECT_TYPE_TEXTURE, (GLuint )buffer);
1435 COREGL_ERR("\E[40;31;1mError Not supported target NULL client buffer\E[0m\n");
1440 real_obj = (GLuint )buffer;
1443 ret = _orig_fastpath_eglCreateImageKHR(dpy, real_ctx, target, (EGLClientBuffer)real_obj, attrib_list);
1449 _COREGL_FASTPATH_FUNC_END();
1454 fastpath_eglGetProcAddress(const char* procname)
1458 _COREGL_FASTPATH_FUNC_BEGIN();
1460 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST) \
1461 if (strcmp(procname, #FUNC_NAME) == 0) \
1463 _eng_fn ret_orig = NULL; \
1464 ret_orig = _orig_fastpath_eglGetProcAddress(procname); \
1465 if (ret_orig != NULL) \
1466 ret = (_eng_fn)ovr_##FUNC_NAME; \
1470 #define _COREGL_EXT_SYMBOL_ALIAS(ALIAS_NAME, FUNC_NAME) \
1471 if (strcmp(procname, #ALIAS_NAME) == 0) \
1473 _eng_fn ret_orig = NULL; \
1474 ret_orig = _orig_fastpath_eglGetProcAddress(#ALIAS_NAME); \
1475 if (ret_orig != NULL) \
1476 ret = (_eng_fn)ovr_##FUNC_NAME; \
1480 #include "../../headers/sym_egl.h"
1481 #include "../../headers/sym_gl.h"
1482 #undef _COREGL_SYMBOL
1483 #undef _COREGL_EXT_SYMBOL_ALIAS
1485 ret = _orig_fastpath_eglGetProcAddress(procname);
1489 #define _COREGL_EXT_SYMBOL_FASTPATH_PASS(FUNC_NAME) \
1490 if (strcmp(procname, #FUNC_NAME) == 0) \
1493 #define _COREGL_EXT_SYMBOL_FASTPATH_BLOCK(FUNC_NAME) \
1494 if (strcmp(procname, #FUNC_NAME) == 0) \
1500 #include "../../headers/sym_egl.h"
1501 #include "../../headers/sym_gl.h"
1502 #undef _COREGL_EXT_SYMBOL_FASTPATH_PASS
1503 #undef _COREGL_EXT_SYMBOL_FASTPATH_BLOCK
1505 COREGL_ERR("\E[40;31;1mFASTPATH does NOT support '%s'!! Returning NULL...\E[0m\n", procname);
1512 _COREGL_FASTPATH_FUNC_END();
1517 fastpath_eglTerminate(EGLDisplay dpy)
1519 EGLBoolean ret = EGL_FALSE;
1520 GLGlueContext_List *current = NULL;
1521 GLGlueContext_List *remove_list = NULL;
1523 _COREGL_FASTPATH_FUNC_BEGIN();
1525 AST(mutex_lock(&ctx_list_access_mutex) == 1);
1526 current = gctx_list;
1527 while (current != NULL)
1529 if (current->gctx->cstate->rdpy == dpy)
1531 GLGlueContext_List *rm_newitm = NULL;
1532 rm_newitm = (GLGlueContext_List *)calloc(1, sizeof(GLGlueContext_List));
1534 /* Prevent CID : 390950 */
1535 /* Prevent CID : 451104 */
1536 if (rm_newitm != NULL)
1538 rm_newitm->gctx = current->gctx;
1540 /* insert at HEAD of dbl. linked list (ignoring upwards link) */
1541 rm_newitm->next = remove_list;
1542 remove_list = rm_newitm;
1545 current = current->next;
1547 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
1549 current = remove_list;
1550 while (current != NULL)
1552 fastpath_eglDestroyContext(dpy, current->gctx);
1553 remove_list = current->next;
1555 current = remove_list;
1558 ret = _orig_fastpath_eglTerminate(dpy);
1562 _COREGL_FASTPATH_FUNC_END();