wip - import hostgl from abi v0 and adapt to abi v1/GL.library ABI
[AROS.git] / arch / all-hosted / libs / hostgl / hostgl_ctx_manager.c
blob5afb985ce43da3c1f7a23a3b51c0b972b7b66e44
1 /*
2 Copyright 2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/symbolsets.h>
7 #include <proto/exec.h>
8 #include "hostgl_ctx_manager.h"
9 #include "tls.h"
10 #include <aros/debug.h>
12 #include LC_LIBDEFS_FILE
14 /* AROS is just one process to host, thus it can only have
15 one current GLX context. On the other hand, there can
16 be many GL apps running under AROS at the same time, each
17 with it's own GL context. To solve this, calls to HostGL
18 functions are serialized and at each call, it is checked
19 if current HostGL GLX context matches current AROS task
20 GL context. If no, change is made before executing the call.
21 Constant switching of GLX contexts is bad for performance,
22 but solves the problem. */
24 static struct SignalSemaphore global_glx_context_sem;
25 static volatile GLXContext global_glx_context;
26 static Display * global_x11_display = NULL;
28 static struct TaskLocalStorage * ctxtls = NULL;
31 /* Note: only one AROS task at a time may send commands via the display. Code
32 acquiring display must guarantee this. Opening display in the task itself
33 won't help - just use the this pointer and serialize calls */
34 Display * HostGL_GetGlobalX11Display()
36 return global_x11_display;
39 GLAContext HostGL_GetCurrentContext()
41 return GetFromTLS(ctxtls);
44 VOID HostGL_SetCurrentContext(GLAContext ctx)
46 InsertIntoTLS(ctxtls, ctx);
49 /* Note: This lock needs to be obtained before doing ANY X11 or GLX call - remember AROS is one
50 process to Linux and different AROS tasks cannot inter-mingle their X11/GLX calls */
51 VOID HostGL_Lock()
53 ObtainSemaphore(&global_glx_context_sem);
56 VOID HostGL_UnLock()
58 ReleaseSemaphore(&global_glx_context_sem);
61 /* This funtion needs to be called while holding the semaphore */
62 VOID HostGL_UpdateGlobalGLXContext()
64 struct hostgl_context *cur_ctx = HostGL_GetCurrentContext();
65 Display * dsp = HostGL_GetGlobalX11Display();
67 if (cur_ctx)
69 if (cur_ctx->glXctx != global_glx_context)
71 global_glx_context = cur_ctx->glXctx;
72 D(bug("[HostGL] TASK: 0x%x, GLX: 0x%x\n",FindTask(NULL), global_glx_context));
74 #if defined(RENDERER_SEPARATE_X_WINDOW)
75 GLXCALL(glXMakeContextCurrent, dsp, cur_ctx->glXWindow, cur_ctx->glXWindow, cur_ctx->glXctx);
76 #endif
77 #if defined(RENDERER_PBUFFER_WPA)
78 GLXCALL(glXMakeContextCurrent, dsp, cur_ctx->glXPbuffer, cur_ctx->glXPbuffer, cur_ctx->glXctx);
79 #endif
80 #if defined(RENDERER_PIXMAP_BLIT)
81 GLXCALL(glXMakeContextCurrent, dsp, cur_ctx->glXPixmap, cur_ctx->glXPixmap, cur_ctx->glXctx);
82 #endif
85 else
87 global_glx_context = NULL;
88 D(bug("[HostGL] TASK: 0x%x, GLX: 0x%x\n",FindTask(NULL), global_glx_context));
90 GLXCALL(glXMakeContextCurrent, dsp, None, None, NULL);
94 static int HostGL_Ctx_Manager_Init(LIBBASETYPEPTR LIBBASE)
96 InitSemaphore(&global_glx_context_sem);
97 global_glx_context = NULL;
98 global_x11_display = XCALL(XOpenDisplay, NULL);
99 ctxtls = CreateTLS();
100 return 1;
103 static int HostGL_Ctx_Manager_Expunge(LIBBASETYPEPTR LIBBASE)
105 if (ctxtls) DestroyTLS(ctxtls);
106 if (global_x11_display) XCALL(XCloseDisplay, global_x11_display);
107 //TODO: destroy global glx context if not null
108 return 1;
111 /* These functions need to be at priority 1, so that XCALL/GLXCALL/GLCALL are made workable bofore them */
112 ADD2INITLIB(HostGL_Ctx_Manager_Init, 1)
113 ADD2EXPUNGELIB(HostGL_Ctx_Manager_Expunge, 1)