Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / mesa / src / egl / drivers / arosmesa / egl_arosmesa.c
bloba8634e0b63ce4dfcd25595f14dca10e1ab5d21e8
1 /*
2 Copyright 2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "eglsurface.h"
7 #include "eglcontext.h"
8 #include "eglconfig.h"
9 #include "egldisplay.h"
10 #include "egldriver.h"
12 #include <stdlib.h>
14 #include <GL/gla.h>
16 extern struct Library * GLBase;
18 /* General note: due to fact that AROSMesa API is not symmetric with EGL api,
19 * AROSMesa context is not created in EGL create context, but in EGL MakeCurrent
22 struct egl_arosmesa
24 _EGLDriver base;
27 struct egl_arosmesa_context
29 _EGLContext base;
30 GLAContext amesactx;
33 static inline struct egl_arosmesa_context * egl_arosmesa_context(_EGLContext * ctx)
35 return (struct egl_arosmesa_context *)ctx;
38 struct egl_arosmesa_surface
40 _EGLSurface base;
41 struct Window * win;
44 static _EGLProc egl_arosmesa_getprocaddress(_EGLDriver *drv, const char *procname)
46 (void) drv;
48 return glAGetProcAddress(procname);
51 static EGLBoolean egl_arosmesa_terminate(_EGLDriver *drv, _EGLDisplay *disp)
53 _eglReleaseDisplayResources(drv, disp);
54 _eglCleanupDisplay(disp);
56 disp->DriverData = NULL;
58 return EGL_TRUE;
61 static EGLBoolean egl_arosmesa_destroycontext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
63 (void) drv;
65 if (_eglPutContext(ctx))
67 struct egl_arosmesa_context * eglctx = egl_arosmesa_context(ctx);
68 glAMakeCurrent(NULL);
69 if (eglctx->amesactx)
70 glADestroyContext(eglctx->amesactx);
71 free(eglctx);
74 return EGL_TRUE;
77 static EGLBoolean egl_arosmesa_destroysurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
79 (void) drv;
81 if (_eglPutSurface(surf))
83 free(surf);
86 return EGL_TRUE;
89 static EGLBoolean egl_arosmesa_swapbuffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
91 glASwapBuffers(disp->DriverData);
92 return EGL_TRUE;
95 static EGLBoolean egl_arosmesa_makecurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
96 _EGLSurface *rsurf, _EGLContext *ctx)
98 _EGLContext *old_ctx;
99 _EGLSurface *old_dsurf, *old_rsurf;
101 if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf))
102 return EGL_FALSE;
104 /* Since AROSMesa API is not symmetric with EGL, context handling needs to be performed here */
106 /* Do nothing */
107 if ((ctx == NULL) && (old_ctx == NULL))
108 return EGL_TRUE;
110 /* Unbind the current context */
111 if ((ctx == NULL) && (old_ctx != NULL))
113 glAMakeCurrent(NULL);
114 _eglPutSurface(old_dsurf);
115 _eglPutSurface(old_rsurf);
116 _eglPutContext(old_ctx);
117 disp->DriverData = NULL;
118 return EGL_TRUE;
121 /* Create when needed and bind new context */
122 if (ctx != NULL)
124 struct egl_arosmesa_context * eglctx = egl_arosmesa_context(ctx);
126 if (old_ctx != NULL)
128 _eglPutSurface(old_dsurf);
129 _eglPutSurface(old_rsurf);
130 _eglPutContext(old_ctx);
131 disp->DriverData = NULL;
134 if (eglctx->amesactx == NULL)
136 struct TagItem attributes [14];
137 struct Window * win = ((struct egl_arosmesa_surface *)dsurf)->win;
138 int i = 0;
140 attributes[i].ti_Tag = GLA_Window; attributes[i++].ti_Data = (IPTR)win;
141 attributes[i].ti_Tag = GLA_Left; attributes[i++].ti_Data = win->BorderLeft;
142 attributes[i].ti_Tag = GLA_Top; attributes[i++].ti_Data = win->BorderTop;
143 attributes[i].ti_Tag = GLA_Bottom; attributes[i++].ti_Data = win->BorderBottom;
144 attributes[i].ti_Tag = GLA_Right; attributes[i++].ti_Data = win->BorderRight;
146 attributes[i].ti_Tag = GLA_DoubleBuf; attributes[i++].ti_Data = GL_TRUE;
148 attributes[i].ti_Tag = GLA_RGBMode; attributes[i++].ti_Data = GL_TRUE;
150 attributes[i].ti_Tag = GLA_NoStencil; attributes[i++].ti_Data = GL_TRUE;
151 attributes[i].ti_Tag = GLA_NoAccum; attributes[i++].ti_Data = GL_TRUE;
153 attributes[i].ti_Tag = TAG_DONE;
155 eglctx->amesactx = glACreateContext(attributes);
158 if (eglctx->amesactx != NULL)
160 glAMakeCurrent(eglctx->amesactx);
161 disp->DriverData = eglctx->amesactx;
162 return EGL_TRUE;
166 return EGL_FALSE;
169 static _EGLSurface * egl_arosmesa_createwindowsurface(_EGLDriver *drv, _EGLDisplay *disp,
170 _EGLConfig *conf, EGLNativeWindowType window, const EGLint *attrib_list)
172 struct egl_arosmesa_surface * surf = calloc(1, sizeof(struct egl_arosmesa_surface));
174 if (!_eglInitSurface(&surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list))
176 free(surf);
177 return NULL;
180 surf->base.Width = window->Width - window->BorderLeft - window->BorderRight;
181 surf->base.Height = window->Height - window->BorderTop - window->BorderBottom;
182 surf->win = window;
184 return &surf->base;
187 static _EGLContext * egl_arosmesa_createcontext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
188 _EGLContext *share_list, const EGLint *attrib_list)
190 struct egl_arosmesa_context * ctx = calloc(1, sizeof(struct egl_arosmesa_context));
192 if (!_eglInitContext(&ctx->base, disp, conf, attrib_list))
194 free(ctx);
195 return NULL;
198 ctx->amesactx = NULL; /* Context is created elsewhere */
200 return &ctx->base;
203 static void create_configs(_EGLDisplay *dpy)
205 _EGLConfig * cfg = calloc(1, sizeof(_EGLConfig));
206 _eglInitConfig(cfg, dpy, 1);
208 cfg->RenderableType = EGL_OPENGL_BIT;
209 cfg->Conformant = EGL_OPENGL_BIT;
210 cfg->SurfaceType = EGL_WINDOW_BIT;
212 _eglSetConfigKey(cfg, EGL_RED_SIZE, 8);
213 _eglSetConfigKey(cfg, EGL_GREEN_SIZE, 8);
214 _eglSetConfigKey(cfg, EGL_BLUE_SIZE, 8);
215 _eglSetConfigKey(cfg, EGL_ALPHA_SIZE, 8);
216 _eglSetConfigKey(cfg, EGL_DEPTH_SIZE, 24);
217 _eglSetConfigKey(cfg, EGL_STENCIL_SIZE, 8);
219 _eglLinkConfig(cfg);
222 static EGLBoolean
223 egl_arosmesa_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
225 if (dpy->Options.TestOnly)
226 return EGL_TRUE;
228 create_configs(dpy);
230 dpy->ClientAPIs |= EGL_OPENGL_BIT;
231 dpy->VersionMajor = 1;
232 dpy->VersionMinor = 4;
234 return EGL_TRUE;
237 void egl_arosmesa_init_driver_api(_EGLDriver * drv)
240 _eglInitDriverFallbacks(drv);
242 drv->API.Initialize = egl_arosmesa_initialize;
243 drv->API.CreateContext = egl_arosmesa_createcontext;
244 drv->API.CreateWindowSurface = egl_arosmesa_createwindowsurface;
245 drv->API.MakeCurrent = egl_arosmesa_makecurrent;
246 drv->API.SwapBuffers = egl_arosmesa_swapbuffers;
247 drv->API.DestroySurface = egl_arosmesa_destroysurface;
248 drv->API.DestroyContext = egl_arosmesa_destroycontext;
249 drv->API.Terminate = egl_arosmesa_terminate;
250 drv->API.GetProcAddress = egl_arosmesa_getprocaddress;
253 void egl_arosmesa_unload(_EGLDriver *drv)
255 free(drv);
258 _EGLDriver *
259 _eglBuiltInDriverAROSMesa(const char *args)
261 struct egl_arosmesa * drv = calloc(1, sizeof(struct egl_arosmesa));
263 if (!GLBase)
264 GLBase = OpenLibrary("gl.library", 20L);
266 if (GLBase)
268 egl_arosmesa_init_driver_api(&drv->base);
269 drv->base.Name = "AROSMesa";
270 drv->base.Unload = egl_arosmesa_unload;
272 return &drv->base;
274 else
275 return NULL;
278 static VOID CloseMesa()
280 if (GLBase)
282 CloseLibrary(GLBase);
283 GLBase = NULL;
287 ADD2EXPUNGELIB(CloseMesa, 5)