13464ebd5Sriastradh/*
23464ebd5Sriastradh * Copyright © 2010 Intel Corporation
33464ebd5Sriastradh * Copyright © 2011 Apple Inc.
43464ebd5Sriastradh *
53464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a
63464ebd5Sriastradh * copy of this software and associated documentation files (the "Soft-
73464ebd5Sriastradh * ware"), to deal in the Software without restriction, including without
83464ebd5Sriastradh * limitation the rights to use, copy, modify, merge, publish, distribute,
93464ebd5Sriastradh * and/or sell copies of the Software, and to permit persons to whom the
103464ebd5Sriastradh * Software is furnished to do so, provided that the above copyright
113464ebd5Sriastradh * notice(s) and this permission notice appear in all copies of the Soft-
123464ebd5Sriastradh * ware and that both the above copyright notice(s) and this permission
133464ebd5Sriastradh * notice appear in supporting documentation.
143464ebd5Sriastradh *
153464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
163464ebd5Sriastradh * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
173464ebd5Sriastradh * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
183464ebd5Sriastradh * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
193464ebd5Sriastradh * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
203464ebd5Sriastradh * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
213464ebd5Sriastradh * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
223464ebd5Sriastradh * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
233464ebd5Sriastradh * MANCE OF THIS SOFTWARE.
243464ebd5Sriastradh *
253464ebd5Sriastradh * Except as contained in this notice, the name of a copyright holder shall
263464ebd5Sriastradh * not be used in advertising or otherwise to promote the sale, use or
273464ebd5Sriastradh * other dealings in this Software without prior written authorization of
283464ebd5Sriastradh * the copyright holder.
293464ebd5Sriastradh *
303464ebd5Sriastradh * Authors:
313464ebd5Sriastradh *   Kristian Høgsberg (krh@bitplanet.net)
323464ebd5Sriastradh */
333464ebd5Sriastradh
343464ebd5Sriastradh#if defined(GLX_USE_APPLEGL)
353464ebd5Sriastradh
363464ebd5Sriastradh#include <stdbool.h>
373464ebd5Sriastradh#include <dlfcn.h>
383464ebd5Sriastradh
393464ebd5Sriastradh#include "glxclient.h"
40af69d88dSmrg#include "apple/apple_glx_context.h"
41af69d88dSmrg#include "apple/apple_glx.h"
42af69d88dSmrg#include "apple/apple_cgl.h"
433464ebd5Sriastradh#include "glx_error.h"
443464ebd5Sriastradh
453464ebd5Sriastradhstatic void
463464ebd5Sriastradhapplegl_destroy_context(struct glx_context *gc)
473464ebd5Sriastradh{
483464ebd5Sriastradh   apple_glx_destroy_context(&gc->driContext, gc->psc->dpy);
493464ebd5Sriastradh}
503464ebd5Sriastradh
513464ebd5Sriastradhstatic int
523464ebd5Sriastradhapplegl_bind_context(struct glx_context *gc, struct glx_context *old,
533464ebd5Sriastradh		     GLXDrawable draw, GLXDrawable read)
543464ebd5Sriastradh{
553464ebd5Sriastradh   Display *dpy = gc->psc->dpy;
563464ebd5Sriastradh   bool error = apple_glx_make_current_context(dpy,
573464ebd5Sriastradh					       (old && old != &dummyContext) ? old->driContext : NULL,
583464ebd5Sriastradh					       gc ? gc->driContext : NULL, draw);
593464ebd5Sriastradh
603464ebd5Sriastradh   apple_glx_diagnostic("%s: error %s\n", __func__, error ? "YES" : "NO");
613464ebd5Sriastradh   if (error)
623464ebd5Sriastradh      return 1; /* GLXBadContext is the same as Success (0) */
633464ebd5Sriastradh
643464ebd5Sriastradh   apple_glapi_set_dispatch();
653464ebd5Sriastradh
663464ebd5Sriastradh   return Success;
673464ebd5Sriastradh}
683464ebd5Sriastradh
693464ebd5Sriastradhstatic void
703464ebd5Sriastradhapplegl_unbind_context(struct glx_context *gc, struct glx_context *new)
713464ebd5Sriastradh{
723464ebd5Sriastradh   Display *dpy;
733464ebd5Sriastradh   bool error;
743464ebd5Sriastradh
753464ebd5Sriastradh   /* If we don't have a context, then we have nothing to unbind */
763464ebd5Sriastradh   if (!gc)
773464ebd5Sriastradh      return;
783464ebd5Sriastradh
793464ebd5Sriastradh   /* If we have a new context, keep this one around and remove it during bind. */
803464ebd5Sriastradh   if (new)
813464ebd5Sriastradh      return;
823464ebd5Sriastradh
833464ebd5Sriastradh   dpy = gc->psc->dpy;
843464ebd5Sriastradh
853464ebd5Sriastradh   error = apple_glx_make_current_context(dpy,
863464ebd5Sriastradh					  (gc != &dummyContext) ? gc->driContext : NULL,
873464ebd5Sriastradh					  NULL, None);
883464ebd5Sriastradh
893464ebd5Sriastradh   apple_glx_diagnostic("%s: error %s\n", __func__, error ? "YES" : "NO");
903464ebd5Sriastradh}
913464ebd5Sriastradh
923464ebd5Sriastradhstatic void
933464ebd5Sriastradhapplegl_wait_gl(struct glx_context *gc)
943464ebd5Sriastradh{
953464ebd5Sriastradh   glFinish();
963464ebd5Sriastradh}
973464ebd5Sriastradh
983464ebd5Sriastradhstatic void
993464ebd5Sriastradhapplegl_wait_x(struct glx_context *gc)
1003464ebd5Sriastradh{
1013464ebd5Sriastradh   Display *dpy = gc->psc->dpy;
1023464ebd5Sriastradh   apple_glx_waitx(dpy, gc->driContext);
1033464ebd5Sriastradh}
1043464ebd5Sriastradh
1057ec681f3Smrgvoid *
1063464ebd5Sriastradhapplegl_get_proc_address(const char *symbol)
1073464ebd5Sriastradh{
1083464ebd5Sriastradh   return dlsym(apple_cgl_get_dl_handle(), symbol);
1093464ebd5Sriastradh}
1103464ebd5Sriastradh
1113464ebd5Sriastradhstatic const struct glx_context_vtable applegl_context_vtable = {
112af69d88dSmrg   .destroy             = applegl_destroy_context,
113af69d88dSmrg   .bind                = applegl_bind_context,
114af69d88dSmrg   .unbind              = applegl_unbind_context,
115af69d88dSmrg   .wait_gl             = applegl_wait_gl,
116af69d88dSmrg   .wait_x              = applegl_wait_x,
1173464ebd5Sriastradh};
1183464ebd5Sriastradh
1193464ebd5Sriastradhstruct glx_context *
1203464ebd5Sriastradhapplegl_create_context(struct glx_screen *psc,
1213464ebd5Sriastradh		       struct glx_config *config,
1223464ebd5Sriastradh		       struct glx_context *shareList, int renderType)
1233464ebd5Sriastradh{
1243464ebd5Sriastradh   struct glx_context *gc;
1253464ebd5Sriastradh   int errorcode;
1263464ebd5Sriastradh   bool x11error;
1273464ebd5Sriastradh   Display *dpy = psc->dpy;
1283464ebd5Sriastradh   int screen = psc->scr;
1293464ebd5Sriastradh
1303464ebd5Sriastradh   /* TODO: Integrate this with apple_glx_create_context and make
1313464ebd5Sriastradh    * struct apple_glx_context inherit from struct glx_context. */
1323464ebd5Sriastradh
1337ec681f3Smrg   if (!config)
1347ec681f3Smrg      return NULL;
1357ec681f3Smrg
136af69d88dSmrg   gc = calloc(1, sizeof(*gc));
1373464ebd5Sriastradh   if (gc == NULL)
1383464ebd5Sriastradh      return NULL;
1393464ebd5Sriastradh
1403464ebd5Sriastradh   if (!glx_context_init(gc, psc, config)) {
141af69d88dSmrg      free(gc);
1423464ebd5Sriastradh      return NULL;
1433464ebd5Sriastradh   }
1443464ebd5Sriastradh
1453464ebd5Sriastradh   gc->vtable = &applegl_context_vtable;
1463464ebd5Sriastradh   gc->driContext = NULL;
1473464ebd5Sriastradh
1483464ebd5Sriastradh   /* TODO: darwin: Integrate with above to do indirect */
1493464ebd5Sriastradh   if(apple_glx_create_context(&gc->driContext, dpy, screen, config,
1503464ebd5Sriastradh			       shareList ? shareList->driContext : NULL,
1513464ebd5Sriastradh			       &errorcode, &x11error)) {
1523464ebd5Sriastradh      __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error);
1533464ebd5Sriastradh      gc->vtable->destroy(gc);
1543464ebd5Sriastradh      return NULL;
1553464ebd5Sriastradh   }
1563464ebd5Sriastradh
1573464ebd5Sriastradh   gc->currentContextTag = -1;
1583464ebd5Sriastradh   gc->config = config;
1593464ebd5Sriastradh   gc->isDirect = GL_TRUE;
1603464ebd5Sriastradh   gc->xid = 1; /* Just something not None, so we know when to destroy
1613464ebd5Sriastradh		 * it in MakeContextCurrent. */
1623464ebd5Sriastradh
1633464ebd5Sriastradh   return gc;
1643464ebd5Sriastradh}
1653464ebd5Sriastradh
166af69d88dSmrgstatic const struct glx_screen_vtable applegl_screen_vtable = {
167af69d88dSmrg   .create_context         = applegl_create_context,
168af69d88dSmrg   .create_context_attribs = NULL,
169af69d88dSmrg   .query_renderer_integer = NULL,
170af69d88dSmrg   .query_renderer_string  = NULL,
1713464ebd5Sriastradh};
1723464ebd5Sriastradh
1733464ebd5Sriastradh_X_HIDDEN struct glx_screen *
1743464ebd5Sriastradhapplegl_create_screen(int screen, struct glx_display * priv)
1753464ebd5Sriastradh{
1763464ebd5Sriastradh   struct glx_screen *psc;
1773464ebd5Sriastradh
178af69d88dSmrg   psc = calloc(1, sizeof *psc);
1793464ebd5Sriastradh   if (psc == NULL)
1803464ebd5Sriastradh      return NULL;
1813464ebd5Sriastradh
1823464ebd5Sriastradh   glx_screen_init(psc, screen, priv);
1833464ebd5Sriastradh   psc->vtable = &applegl_screen_vtable;
1843464ebd5Sriastradh
1853464ebd5Sriastradh   return psc;
1863464ebd5Sriastradh}
1873464ebd5Sriastradh
1883464ebd5Sriastradh_X_HIDDEN int
1893464ebd5Sriastradhapplegl_create_display(struct glx_display *glx_dpy)
1903464ebd5Sriastradh{
1913464ebd5Sriastradh   if(!apple_init_glx(glx_dpy->dpy))
1923464ebd5Sriastradh      return 1;
1933464ebd5Sriastradh
1943464ebd5Sriastradh   return GLXBadContext;
1953464ebd5Sriastradh}
1963464ebd5Sriastradh
1973464ebd5Sriastradh#endif
198