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());
722 EGLenum newapi = _orig_fastpath_eglQueryAPI();
723 if (tstate->binded_api != EGL_OPENGL_ES_API)
725 tstate->binded_api = newapi;
732 _COREGL_FASTPATH_FUNC_END();
737 fastpath_eglQueryAPI(void)
740 MY_MODULE_TSTATE *tstate = NULL;
742 _COREGL_FASTPATH_FUNC_BEGIN();
743 if (fp_opt == FP_UNKNOWN_PATH)
745 COREGL_ERR("\E[40;31;1mInvalid library link! (CoreGL path option is invalid)\E[0m\n");
749 ret = _orig_fastpath_eglQueryAPI();
751 GET_MY_TSTATE(tstate, get_current_thread_state());
754 AST(tstate->binded_api == ret);
760 _COREGL_FASTPATH_FUNC_END();
765 fastpath_eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list)
767 GLGlueContext *gctx = NULL, *newgctx = NULL;
768 GLGlueContext_List *gctx_list_new = NULL;
769 MY_MODULE_TSTATE *tstate = NULL;
770 GLContextState *cstate = NULL;
771 GLContextState *cstate_new = NULL;
772 GL_Shared_Object_State *sostate_new = NULL;
773 GLContext ctx = NULL;
775 EGL_packed_option *real_ctx_option = NULL;
776 EGL_packed_sharable_option *real_ctx_sharable_option = NULL;
778 // Special eject condition for binding API
779 GET_MY_TSTATE(tstate, get_current_thread_state());
780 if (tstate != NULL && tstate->binded_api != EGL_OPENGL_ES_API)
782 return _orig_fastpath_eglCreateContext(dpy, config, share_context, attrib_list);
785 _COREGL_FASTPATH_FUNC_BEGIN();
787 real_ctx_option = (EGL_packed_option *)calloc(1, sizeof(EGL_packed_option));
788 if (real_ctx_option == NULL)
790 COREGL_ERR("\E[40;31;1mError creating a new GLGlueContext(Memory full 1)\E[0m\n");
793 cstate = _egl_create_context(real_ctx_option, &cstate_new, &ctx, dpy, config, attrib_list);
796 // Pack shared context options
797 real_ctx_sharable_option = (EGL_packed_sharable_option *)calloc(1, sizeof(EGL_packed_sharable_option));
798 if (real_ctx_sharable_option == NULL)
800 COREGL_ERR("\E[40;31;1mError creating a new GLGlueContext(Memory full 2)\E[0m\n");
803 AST(_pack_egl_context_sharable_option(real_ctx_sharable_option, share_context) == 1);
805 // Allocate a new context
806 newgctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
809 COREGL_ERR("\E[40;31;1mError creating a new GLGlueContext(Memory full 3)\E[0m\n");
813 newgctx->magic = MAGIC_GLFAST;
814 newgctx->initialized = 0;
816 newgctx->thread_id = get_current_thread();
818 fastpath_ostate_init(&newgctx->ostate);
820 if (share_context != EGL_NO_CONTEXT)
822 GLGlueContext *shared_gctx = (GLGlueContext *)share_context;
823 AST(shared_gctx->magic == MAGIC_GLFAST);
824 AST(shared_gctx->ostate.shared != NULL);
825 newgctx->ostate.shared = shared_gctx->ostate.shared;
829 sostate_new = (GL_Shared_Object_State *)calloc(1, sizeof(GL_Shared_Object_State));
830 if (sostate_new == NULL)
832 COREGL_ERR("\E[40;31;1mError creating a new GLGlueContext(Memory full 4)\E[0m\n");
835 fastpath_sostate_init(sostate_new);
836 newgctx->ostate.shared = sostate_new;
838 _add_shared_obj_state_ref(newgctx, newgctx->ostate.shared);
839 newgctx->real_ctx_option = real_ctx_option;
840 newgctx->real_ctx_option_len = sizeof(EGL_packed_option);
841 newgctx->real_ctx_sharable_option = real_ctx_sharable_option;
842 newgctx->real_ctx_sharable_option_len = sizeof(EGL_packed_sharable_option);
844 _link_context_state(newgctx, cstate);
845 _add_context_ref(newgctx);
847 newgctx->cstate = cstate;
849 { // Add glue context to list
850 gctx_list_new = (GLGlueContext_List *)calloc(1, sizeof(GLGlueContext_List));
851 if (gctx_list_new == NULL)
853 COREGL_ERR("\E[40;31;1mError creating a new GlGlueContext(Memory full 5)\E[0m\n");
857 AST(mutex_lock(&ctx_list_access_mutex) == 1);
859 gctx_list_new->gctx = newgctx;
861 gctx_list_new->prev = NULL;
862 gctx_list_new->next = gctx_list;
863 if (gctx_list != NULL)
864 gctx_list->prev = gctx_list_new;
866 gctx_list = gctx_list_new;
868 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
873 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
874 if (unlikely(trace_ctx_flag == 1))
877 add_to_general_trace_list(&glue_ctx_trace_list, newgctx);
879 sprintf(ment, "eglCreateContext completed (GlueCTX=[%12p])", newgctx);
880 _dump_context_info(ment, 1);
882 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
891 _orig_fastpath_eglDestroyContext(dpy, ctx);
894 if (sostate_new != NULL)
899 if (real_ctx_option != NULL)
901 free(real_ctx_option);
902 real_ctx_option = NULL;
904 if (real_ctx_sharable_option != NULL)
906 free(real_ctx_sharable_option);
907 real_ctx_sharable_option = NULL;
909 if (cstate_new != NULL)
911 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
912 if (unlikely(trace_ctx_flag == 1))
913 remove_from_general_trace_list(&context_state_trace_list, cstate_new);
914 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
916 fastpath_remove_context_states_from_list(cstate_new, &ctx_list_access_mutex);
920 if (gctx_list_new != NULL)
922 AST(mutex_lock(&ctx_list_access_mutex) == 1);
924 if (gctx_list_new->next != NULL)
925 gctx_list_new->next->prev = gctx_list_new->prev;
927 if (gctx_list_new->prev != NULL)
928 gctx_list_new->prev->next = gctx_list_new->next;
930 gctx_list = gctx_list_new->next;
932 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
938 _remove_context_ref(newgctx, &ctx_list_access_mutex);
944 _COREGL_FASTPATH_FUNC_END();
945 return (EGLContext)gctx;
949 fastpath_eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
951 EGLBoolean ret = EGL_FALSE;
952 GLGlueContext *gctx = NULL;
954 _COREGL_FASTPATH_FUNC_BEGIN();
956 gctx = (GLGlueContext *)ctx;
958 if (gctx != NULL && gctx != EGL_NO_CONTEXT)
960 GLContextState *cstate = NULL;
962 if (gctx->magic != MAGIC_GLFAST)
964 ret = _orig_fastpath_eglDestroyContext(dpy, ctx);
968 cstate = gctx->cstate;
971 if (gctx->is_destroyed != 1)
973 gctx->is_destroyed = 1;
974 _remove_context_ref(gctx, &ctx_list_access_mutex);
979 COREGL_WRN("\E[40;31;1mInvalid destroying context. (no exists)\E[0m\n");
988 _COREGL_FASTPATH_FUNC_END();
990 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
991 if (unlikely(trace_ctx_flag == 1))
994 sprintf(ment, "eglDestroyContext completed (GlueCTX=[%12p])", ctx);
995 _dump_context_info(ment, 1);
997 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
1003 fastpath_eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
1005 EGLBoolean ret = EGL_FALSE;
1006 EGLContext real_ctx = EGL_NO_CONTEXT;
1008 _COREGL_FASTPATH_FUNC_BEGIN();
1010 if (ctx != EGL_NO_CONTEXT)
1012 GLGlueContext *gctx = NULL;
1013 gctx = (GLGlueContext *)ctx;
1015 if (gctx->magic != MAGIC_GLFAST)
1021 AST(gctx->cstate != NULL);
1022 real_ctx = gctx->cstate->rctx;
1026 ret = _orig_fastpath_eglQueryContext(dpy, real_ctx, attribute, value);
1030 _COREGL_FASTPATH_FUNC_END();
1037 fastpath_eglReleaseThread(void)
1039 EGLBoolean ret = EGL_FALSE;
1040 EGLDisplay dpy = EGL_NO_DISPLAY;
1041 MY_MODULE_TSTATE *tstate = NULL;
1043 GET_MY_TSTATE(tstate, get_current_thread_state());
1045 // Special eject condition for binding API
1046 if (tstate != NULL && tstate->binded_api != EGL_OPENGL_ES_API)
1048 return _orig_fastpath_eglReleaseThread();
1051 _COREGL_FASTPATH_FUNC_BEGIN();
1053 dpy = _orig_fastpath_eglGetCurrentDisplay();
1054 AST(dpy != EGL_NO_DISPLAY);
1055 fastpath_eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1056 ret = _orig_fastpath_eglReleaseThread();
1060 _COREGL_FASTPATH_FUNC_END();
1065 fastpath_eglGetCurrentDisplay(void)
1067 MY_MODULE_TSTATE *tstate = NULL;
1068 EGLDisplay dpy = EGL_NO_DISPLAY;
1070 GET_MY_TSTATE(tstate, get_current_thread_state());
1074 // Special eject condition for binding API
1075 if(tstate->binded_api != EGL_OPENGL_ES_API)
1077 return _orig_fastpath_eglGetCurrentDisplay();
1080 _COREGL_FASTPATH_FUNC_BEGIN();
1082 if (tstate->cstate != NULL)
1084 dpy = tstate->cstate->rdpy;
1088 _COREGL_FASTPATH_FUNC_END();
1100 fastpath_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
1102 EGLBoolean ret = EGL_FALSE;
1103 EGLBoolean need_mc = EGL_FALSE;
1104 GLGlueContext *gctx = NULL;
1106 MY_MODULE_TSTATE *tstate = NULL;
1108 GET_MY_TSTATE(tstate, get_current_thread_state());
1110 // Special eject condition for binding API
1111 if (tstate != NULL && tstate->binded_api != EGL_OPENGL_ES_API)
1113 return _orig_fastpath_eglMakeCurrent(dpy, draw, read, ctx);
1116 _COREGL_FASTPATH_FUNC_BEGIN();
1118 gctx = (GLGlueContext *)ctx;
1122 AST(init_new_thread_state() == 1);
1124 GET_MY_TSTATE(tstate, get_current_thread_state());
1125 AST(tstate != NULL);
1128 // Special path for context deletion
1129 if (ctx == EGL_NO_CONTEXT)
1133 if (tstate->cstate != NULL)
1135 if (_bind_context_state(NULL, tstate->cstate, &ctx_list_access_mutex) != 1)
1137 COREGL_WRN("\E[40;31;1mError soft-makecurrent for context deletion\E[0m\n");
1139 tstate->cstate = NULL;
1141 if (_orig_fastpath_eglMakeCurrent(dpy, draw, read, ctx) != EGL_TRUE)
1143 COREGL_WRN("Error making context [%p] current. (invalid EGL display [%p] or EGL surface [D:%p/R:%p])\n", ctx, dpy, draw, read);
1148 tstate->rsurf_draw = draw;
1149 tstate->rsurf_read = read;
1156 AST(gctx->cstate != NULL);
1158 if (gctx->rdpy != dpy)
1160 COREGL_WRN("\E[40;31;1mInvalid context (or invalid EGL display)\E[0m\n");
1165 AST(gctx->real_ctx_option != NULL);
1166 AST(gctx->real_ctx_sharable_option != NULL);
1168 // Handle cross threading of context (when used by two or more gctx)
1169 if (gctx->thread_id != get_current_thread() && gctx->cstate->ref_count > 1)
1171 #define ATTRIB_LIST_BUFFER_SIZE 8
1173 GLContextState *cstate_new = NULL;
1174 EGLContext new_real_ctx = EGL_NO_CONTEXT;
1176 EGLDisplay dpy = EGL_NO_DISPLAY;
1177 EGLConfig config = NULL;
1178 int attrib_list[ATTRIB_LIST_BUFFER_SIZE];
1180 AST(_unpack_egl_context_option(gctx->real_ctx_option, &dpy, &config, NULL, attrib_list, ATTRIB_LIST_BUFFER_SIZE) == 1);
1181 AST(dpy == gctx->rdpy);
1183 _egl_create_context(gctx->real_ctx_option, &cstate_new, &new_real_ctx, dpy, config, attrib_list);
1185 AST(cstate_new != NULL);
1187 if (_bind_context_state(gctx, cstate_new, &ctx_list_access_mutex) != 1)
1189 COREGL_WRN("\E[40;31;1mError soft-makecurrent in Cross-thread usage!\E[0m\n");
1191 _orig_fastpath_eglDestroyContext(dpy, new_real_ctx);
1196 // TODO : Setup context state for new real ctx
1197 COREGL_WRN("\E[40;31;1mCross-thread usage(makecurrent) can cause a state-broken situation!\E[0m\n");
1199 _unlink_context_state(gctx, &ctx_list_access_mutex);
1200 _link_context_state(gctx, cstate_new);
1202 // Apply to new thread
1203 gctx->thread_id = get_current_thread();
1207 // Check if the object is correct
1208 if (gctx->magic != MAGIC_GLFAST)
1210 COREGL_ERR("\E[40;31;1mGlue-CTX Magic Check Failed!!! (Memory broken?)\E[0m\n");
1216 // If drawable changed, do a make current
1217 if ((tstate->rsurf_draw != draw) ||
1218 (tstate->rsurf_read != read))
1221 AST(gctx->cstate != NULL);
1223 // If binded real context changed, do a make current
1224 if (tstate->cstate == NULL || tstate->cstate != gctx->cstate)
1227 if (need_mc == EGL_TRUE)
1229 AST(dpy == gctx->cstate->rdpy);
1231 // BB : full makecurrent
1232 if (_orig_fastpath_eglMakeCurrent(dpy, draw, read, gctx->cstate->rctx) != EGL_TRUE)
1234 COREGL_WRN("\E[40;31;1mError making context current with the drawable. (Bad match?)\E[0m\n");
1239 // Update references only when the contexts are different
1240 if(tstate->cstate != gctx->cstate) {
1241 if (tstate->cstate != NULL && tstate->cstate->data != NULL)
1242 _remove_context_ref((GLGlueContext *)tstate->cstate->data, &ctx_list_access_mutex);
1244 tstate->cstate = gctx->cstate;
1246 if (tstate->cstate->data != NULL)
1247 _add_context_ref((GLGlueContext *)tstate->cstate->data);
1250 tstate->rsurf_draw = draw;
1251 tstate->rsurf_read = read;
1254 // Initialize context states
1255 if (gctx->initialized == 0)
1257 if (fastpath_init_context_states(gctx) != 1)
1259 COREGL_ERR("\E[40;31;1mError intializing context. (Check driver specification)\E[0m\n");
1264 // Setup initial Viewport & Scissor
1265 if (gctx->surface_attached == 0 && draw != EGL_NO_SURFACE)
1267 EGLint box_buffer[4];
1271 _orig_fastpath_glGetIntegerv(GL_VIEWPORT, box_buffer);
1272 width = box_buffer[2];
1273 height = box_buffer[3];
1275 gctx->_clear_flag1 |= _CLEAR_FLAG1_BIT_gl_viewport;
1276 gctx->gl_viewport[0] = 0;
1277 gctx->gl_viewport[1] = 0;
1278 gctx->gl_viewport[2] = width;
1279 gctx->gl_viewport[3] = height;
1281 _orig_fastpath_glGetIntegerv(GL_SCISSOR_BOX, box_buffer);
1282 width = box_buffer[2];
1283 height = box_buffer[3];
1285 gctx->_misc_flag2 |= _MISC_FLAG2_BIT_gl_scissor_box;
1286 gctx->gl_scissor_box[0] = 0;
1287 gctx->gl_scissor_box[1] = 0;
1288 gctx->gl_scissor_box[2] = width;
1289 gctx->gl_scissor_box[3] = height;
1291 gctx->surface_attached = 1;
1294 if (_bind_context_state(gctx, tstate->cstate, &ctx_list_access_mutex) != 1)
1306 _COREGL_FASTPATH_FUNC_END();
1308 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
1309 if (unlikely(trace_ctx_flag == 1))
1312 sprintf(ment, "eglMakeCurrent finished (GlueCTX=[%12p] Surf=[D:%12p R:%12p])", ctx, draw, read);
1313 _dump_context_info(ment, 0);
1315 #endif // COREGL_FASTPATH_TRACE_CONTEXT_INFO
1322 fastpath_eglGetCurrentContext(void)
1324 GLGlueContext *ret = NULL;
1325 MY_MODULE_TSTATE *tstate = NULL;
1327 GET_MY_TSTATE(tstate, get_current_thread_state());
1329 // Special eject condition for binding API
1330 if (tstate != NULL && tstate->binded_api != EGL_OPENGL_ES_API)
1332 return _orig_fastpath_eglGetCurrentContext();
1335 _COREGL_FASTPATH_FUNC_BEGIN();
1339 if (tstate->cstate != NULL)
1341 ret = (GLGlueContext *)tstate->cstate->data;
1342 AST(ret->magic == MAGIC_GLFAST);
1348 _COREGL_FASTPATH_FUNC_END();
1349 return (EGLContext)ret;
1354 fastpath_eglGetCurrentSurface(EGLint readdraw)
1356 EGLSurface ret = EGL_NO_SURFACE;
1357 MY_MODULE_TSTATE *tstate = NULL;
1359 GET_MY_TSTATE(tstate, get_current_thread_state());
1361 // Special eject condition for binding API
1362 if (tstate != NULL && tstate->binded_api != EGL_OPENGL_ES_API)
1364 return _orig_fastpath_eglGetCurrentSurface(readdraw);
1367 _COREGL_FASTPATH_FUNC_BEGIN();
1374 ret = (GLGlueContext *)tstate->rsurf_draw;
1377 ret = (GLGlueContext *)tstate->rsurf_read;
1384 _COREGL_FASTPATH_FUNC_END();
1389 fastpath_eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
1392 EGLContext real_ctx = EGL_NO_CONTEXT;
1393 GLuint real_obj = 0;
1395 _COREGL_FASTPATH_FUNC_BEGIN();
1397 if (ctx != NULL && ctx != EGL_NO_CONTEXT)
1399 GLGlueContext *gctx = (GLGlueContext *)ctx;
1401 if (gctx->magic != MAGIC_GLFAST)
1407 AST(gctx->cstate != NULL);
1408 real_ctx = gctx->cstate->rctx;
1413 case EGL_GL_TEXTURE_2D_KHR:
1414 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
1415 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
1416 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
1417 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
1418 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
1419 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
1420 case EGL_GL_TEXTURE_3D_KHR:
1421 case EGL_GL_RENDERBUFFER_KHR:
1422 if((GLuint )buffer == 0)
1424 COREGL_ERR("\E[40;31;1m fastpath_eglCreateImageKHR buffer object NULL \E[0m\n");
1427 real_obj = fastpath_ostate_get_object(&gctx->ostate, GL_OBJECT_TYPE_TEXTURE, (GLuint )buffer);
1431 COREGL_ERR("\E[40;31;1mError Not supported target NULL client buffer\E[0m\n");
1436 real_obj = (GLuint )buffer;
1439 ret = _orig_fastpath_eglCreateImageKHR(dpy, real_ctx, target, (EGLClientBuffer)real_obj, attrib_list);
1445 _COREGL_FASTPATH_FUNC_END();
1450 fastpath_eglGetProcAddress(const char* procname)
1454 _COREGL_FASTPATH_FUNC_BEGIN();
1456 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST) \
1457 if (strcmp(procname, #FUNC_NAME) == 0) \
1459 _eng_fn ret_orig = NULL; \
1460 ret_orig = _orig_fastpath_eglGetProcAddress(procname); \
1461 if (ret_orig != NULL) \
1462 ret = (_eng_fn)ovr_##FUNC_NAME; \
1466 #define _COREGL_EXT_SYMBOL_ALIAS(ALIAS_NAME, FUNC_NAME) \
1467 if (strcmp(procname, #ALIAS_NAME) == 0) \
1469 _eng_fn ret_orig = NULL; \
1470 ret_orig = _orig_fastpath_eglGetProcAddress(#ALIAS_NAME); \
1471 if (ret_orig != NULL) \
1472 ret = (_eng_fn)ovr_##FUNC_NAME; \
1476 #include "../../headers/sym_egl.h"
1477 #include "../../headers/sym_gl.h"
1478 #undef _COREGL_SYMBOL
1479 #undef _COREGL_EXT_SYMBOL_ALIAS
1481 ret = _orig_fastpath_eglGetProcAddress(procname);
1485 #define _COREGL_EXT_SYMBOL_FASTPATH_PASS(FUNC_NAME) \
1486 if (strcmp(procname, #FUNC_NAME) == 0) \
1489 #define _COREGL_EXT_SYMBOL_FASTPATH_BLOCK(FUNC_NAME) \
1490 if (strcmp(procname, #FUNC_NAME) == 0) \
1496 #include "../../headers/sym_egl.h"
1497 #include "../../headers/sym_gl.h"
1498 #undef _COREGL_EXT_SYMBOL_FASTPATH_PASS
1499 #undef _COREGL_EXT_SYMBOL_FASTPATH_BLOCK
1501 COREGL_ERR("\E[40;31;1mFASTPATH can't support '%s' (will be terminated with Illegal instruction!)\E[0m\n", procname);
1508 _COREGL_FASTPATH_FUNC_END();
1513 fastpath_eglTerminate(EGLDisplay dpy)
1515 EGLBoolean ret = EGL_FALSE;
1516 GLGlueContext_List *current = NULL;
1517 GLGlueContext_List *remove_list = NULL;
1519 _COREGL_FASTPATH_FUNC_BEGIN();
1521 AST(mutex_lock(&ctx_list_access_mutex) == 1);
1522 current = gctx_list;
1523 while (current != NULL)
1525 if (current->gctx->cstate->rdpy == dpy)
1527 GLGlueContext_List *rm_newitm = NULL;
1528 rm_newitm = (GLGlueContext_List *)calloc(1, sizeof(GLGlueContext_List));
1529 rm_newitm->gctx = current->gctx;
1531 rm_newitm->next = remove_list;
1532 remove_list = rm_newitm;
1534 current = current->next;
1536 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
1538 current = remove_list;
1539 while (current != NULL)
1541 fastpath_eglDestroyContext(dpy, current->gctx);
1542 remove_list = current->next;
1544 current = remove_list;
1547 ret = _orig_fastpath_eglTerminate(dpy);
1551 _COREGL_FASTPATH_FUNC_END();