13464ebd5Sriastradh/*
23464ebd5Sriastradh Copyright (c) 2008, 2009 Apple Inc.
33464ebd5Sriastradh
43464ebd5Sriastradh Permission is hereby granted, free of charge, to any person
53464ebd5Sriastradh obtaining a copy of this software and associated documentation files
63464ebd5Sriastradh (the "Software"), to deal in the Software without restriction,
73464ebd5Sriastradh including without limitation the rights to use, copy, modify, merge,
83464ebd5Sriastradh publish, distribute, sublicense, and/or sell copies of the Software,
93464ebd5Sriastradh and to permit persons to whom the Software is furnished to do so,
103464ebd5Sriastradh subject to the following conditions:
113464ebd5Sriastradh
123464ebd5Sriastradh The above copyright notice and this permission notice shall be
133464ebd5Sriastradh included in all copies or substantial portions of the Software.
143464ebd5Sriastradh
153464ebd5Sriastradh THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
163464ebd5Sriastradh EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
173464ebd5Sriastradh MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
183464ebd5Sriastradh NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
193464ebd5Sriastradh HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
203464ebd5Sriastradh WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
213464ebd5Sriastradh OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
223464ebd5Sriastradh DEALINGS IN THE SOFTWARE.
233464ebd5Sriastradh
243464ebd5Sriastradh Except as contained in this notice, the name(s) of the above
253464ebd5Sriastradh copyright holders shall not be used in advertising or otherwise to
263464ebd5Sriastradh promote the sale, use or other dealings in this Software without
273464ebd5Sriastradh prior written authorization.
283464ebd5Sriastradh*/
293464ebd5Sriastradh
303464ebd5Sriastradh#include <stdbool.h>
313464ebd5Sriastradh#include <stdio.h>
323464ebd5Sriastradh#include <stdlib.h>
333464ebd5Sriastradh#include <assert.h>
343464ebd5Sriastradh#include <GL/gl.h>
3501e04c3fSmrg#include <util/debug.h>
363464ebd5Sriastradh
373464ebd5Sriastradh/* <rdar://problem/6953344> */
383464ebd5Sriastradh#define glTexImage1D glTexImage1D_OSX
393464ebd5Sriastradh#define glTexImage2D glTexImage2D_OSX
403464ebd5Sriastradh#define glTexImage3D glTexImage3D_OSX
413464ebd5Sriastradh#include <OpenGL/OpenGL.h>
423464ebd5Sriastradh#include <OpenGL/CGLContext.h>
433464ebd5Sriastradh#include <OpenGL/CGLRenderers.h>
443464ebd5Sriastradh#include <OpenGL/CGLTypes.h>
453464ebd5Sriastradh#undef glTexImage1D
463464ebd5Sriastradh#undef glTexImage2D
473464ebd5Sriastradh#undef glTexImage3D
483464ebd5Sriastradh
493464ebd5Sriastradh#ifndef kCGLPFAOpenGLProfile
503464ebd5Sriastradh#define kCGLPFAOpenGLProfile 99
513464ebd5Sriastradh#endif
523464ebd5Sriastradh
533464ebd5Sriastradh#ifndef kCGLOGLPVersion_3_2_Core
543464ebd5Sriastradh#define kCGLOGLPVersion_3_2_Core 0x3200
553464ebd5Sriastradh#endif
563464ebd5Sriastradh
573464ebd5Sriastradh#include "apple_cgl.h"
583464ebd5Sriastradh#include "apple_visual.h"
593464ebd5Sriastradh#include "apple_glx.h"
603464ebd5Sriastradh#include "glxconfig.h"
613464ebd5Sriastradh
623464ebd5Sriastradhenum
633464ebd5Sriastradh{
643464ebd5Sriastradh   MAX_ATTR = 60
653464ebd5Sriastradh};
663464ebd5Sriastradh
67af69d88dSmrgstatic char __crashreporter_info_buff__[4096] = { 0 };
68af69d88dSmrgstatic const char *__crashreporter_info__ __attribute__((__used__)) =
69af69d88dSmrg    &__crashreporter_info_buff__[0];
70af69d88dSmrg#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
71af69d88dSmrg// This is actually a toolchain requirement, but I'm not sure the correct check,
72af69d88dSmrg// but it should be fine to just only include it for Leopard and later.  This line
73af69d88dSmrg// just tells the linker to never strip this symbol (such as for space optimization)
74af69d88dSmrg__asm__ (".desc ___crashreporter_info__, 0x10");
75af69d88dSmrg#endif
76af69d88dSmrg
773464ebd5Sriastradhvoid
783464ebd5Sriastradhapple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const struct glx_config * mode,
793464ebd5Sriastradh                          bool * double_buffered, bool * uses_stereo,
803464ebd5Sriastradh                          bool offscreen)
813464ebd5Sriastradh{
823464ebd5Sriastradh   CGLPixelFormatAttribute attr[MAX_ATTR];
833464ebd5Sriastradh   int numattr = 0;
843464ebd5Sriastradh   GLint vsref = 0;
853464ebd5Sriastradh   CGLError error = 0;
8601e04c3fSmrg   bool use_core_profile = env_var_as_boolean("LIBGL_PROFILE_CORE", false);
873464ebd5Sriastradh
883464ebd5Sriastradh   if (offscreen) {
893464ebd5Sriastradh      apple_glx_diagnostic
903464ebd5Sriastradh         ("offscreen rendering enabled.  Using kCGLPFAOffScreen\n");
913464ebd5Sriastradh
923464ebd5Sriastradh      attr[numattr++] = kCGLPFAOffScreen;
933464ebd5Sriastradh   }
9401e04c3fSmrg   else if (env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false)) {
953464ebd5Sriastradh      apple_glx_diagnostic
963464ebd5Sriastradh         ("Software rendering requested.  Using kCGLRendererGenericFloatID.\n");
973464ebd5Sriastradh      attr[numattr++] = kCGLPFARendererID;
983464ebd5Sriastradh      attr[numattr++] = kCGLRendererGenericFloatID;
993464ebd5Sriastradh   }
10001e04c3fSmrg   else if (env_var_as_boolean("LIBGL_ALLOW_SOFTWARE", false)) {
1013464ebd5Sriastradh      apple_glx_diagnostic
1023464ebd5Sriastradh         ("Software rendering is not being excluded.  Not using kCGLPFAAccelerated.\n");
1033464ebd5Sriastradh   }
1043464ebd5Sriastradh   else {
1053464ebd5Sriastradh      attr[numattr++] = kCGLPFAAccelerated;
1063464ebd5Sriastradh   }
1073464ebd5Sriastradh
1083464ebd5Sriastradh   /*
1093464ebd5Sriastradh    * The program chose a config based on the fbconfigs or visuals.
1103464ebd5Sriastradh    * Those are based on the attributes from CGL, so we probably
1113464ebd5Sriastradh    * do want the closest match for the color, depth, and accum.
1123464ebd5Sriastradh    */
1133464ebd5Sriastradh   attr[numattr++] = kCGLPFAClosestPolicy;
1143464ebd5Sriastradh
1153464ebd5Sriastradh   if (mode->stereoMode) {
1163464ebd5Sriastradh      attr[numattr++] = kCGLPFAStereo;
1173464ebd5Sriastradh      *uses_stereo = true;
1183464ebd5Sriastradh   }
1193464ebd5Sriastradh   else {
1203464ebd5Sriastradh      *uses_stereo = false;
1213464ebd5Sriastradh   }
1223464ebd5Sriastradh
123af69d88dSmrg   if (!offscreen && mode->doubleBufferMode) {
1243464ebd5Sriastradh      attr[numattr++] = kCGLPFADoubleBuffer;
1253464ebd5Sriastradh      *double_buffered = true;
1263464ebd5Sriastradh   }
1273464ebd5Sriastradh   else {
1283464ebd5Sriastradh      *double_buffered = false;
1293464ebd5Sriastradh   }
1303464ebd5Sriastradh
1313464ebd5Sriastradh   attr[numattr++] = kCGLPFAColorSize;
1323464ebd5Sriastradh   attr[numattr++] = mode->redBits + mode->greenBits + mode->blueBits;
1333464ebd5Sriastradh   attr[numattr++] = kCGLPFAAlphaSize;
1343464ebd5Sriastradh   attr[numattr++] = mode->alphaBits;
1353464ebd5Sriastradh
1363464ebd5Sriastradh   if ((mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits) > 0) {
1373464ebd5Sriastradh      attr[numattr++] = kCGLPFAAccumSize;
1383464ebd5Sriastradh      attr[numattr++] = mode->accumRedBits + mode->accumGreenBits +
1393464ebd5Sriastradh         mode->accumBlueBits + mode->accumAlphaBits;
1403464ebd5Sriastradh   }
1413464ebd5Sriastradh
1423464ebd5Sriastradh   if (mode->depthBits > 0) {
1433464ebd5Sriastradh      attr[numattr++] = kCGLPFADepthSize;
1443464ebd5Sriastradh      attr[numattr++] = mode->depthBits;
1453464ebd5Sriastradh   }
1463464ebd5Sriastradh
1473464ebd5Sriastradh   if (mode->stencilBits > 0) {
1483464ebd5Sriastradh      attr[numattr++] = kCGLPFAStencilSize;
1493464ebd5Sriastradh      attr[numattr++] = mode->stencilBits;
1503464ebd5Sriastradh   }
1513464ebd5Sriastradh
1523464ebd5Sriastradh   if (mode->sampleBuffers > 0) {
1533464ebd5Sriastradh      attr[numattr++] = kCGLPFAMultisample;
1543464ebd5Sriastradh      attr[numattr++] = kCGLPFASampleBuffers;
1553464ebd5Sriastradh      attr[numattr++] = mode->sampleBuffers;
1563464ebd5Sriastradh      attr[numattr++] = kCGLPFASamples;
1573464ebd5Sriastradh      attr[numattr++] = mode->samples;
1583464ebd5Sriastradh   }
1593464ebd5Sriastradh
160af69d88dSmrg   /* Debugging support for Core profiles to support newer versions of OpenGL */
161af69d88dSmrg   if (use_core_profile) {
162af69d88dSmrg      attr[numattr++] = kCGLPFAOpenGLProfile;
163af69d88dSmrg      attr[numattr++] = kCGLOGLPVersion_3_2_Core;
164af69d88dSmrg   }
165af69d88dSmrg
1663464ebd5Sriastradh   attr[numattr++] = 0;
1673464ebd5Sriastradh
1683464ebd5Sriastradh   assert(numattr < MAX_ATTR);
1693464ebd5Sriastradh
1703464ebd5Sriastradh   error = apple_cgl.choose_pixel_format(attr, pfobj, &vsref);
1713464ebd5Sriastradh
172af69d88dSmrg   if ((error == kCGLBadAttribute || vsref == 0) && use_core_profile) {
173af69d88dSmrg      apple_glx_diagnostic
174af69d88dSmrg         ("Trying again without CoreProfile: error=%s, vsref=%d\n", apple_cgl.error_string(error), vsref);
175af69d88dSmrg
176af69d88dSmrg      if (!error)
177af69d88dSmrg         apple_cgl.destroy_pixel_format(*pfobj);
178af69d88dSmrg
179af69d88dSmrg      numattr -= 3;
180af69d88dSmrg      attr[numattr++] = 0;
181af69d88dSmrg
182af69d88dSmrg      error = apple_cgl.choose_pixel_format(attr, pfobj, &vsref);
183af69d88dSmrg   }
184af69d88dSmrg
1853464ebd5Sriastradh   if (error) {
186af69d88dSmrg      snprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__),
187af69d88dSmrg               "CGLChoosePixelFormat error: %s\n", apple_cgl.error_string(error));
188af69d88dSmrg      fprintf(stderr, "%s", __crashreporter_info_buff__);
189af69d88dSmrg      abort();
190af69d88dSmrg   }
191af69d88dSmrg
192af69d88dSmrg   if (!*pfobj) {
193af69d88dSmrg      snprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__),
19401e04c3fSmrg               "No matching pixelformats found, perhaps try setting LIBGL_ALLOW_SOFTWARE=true\n");
195af69d88dSmrg      fprintf(stderr, "%s", __crashreporter_info_buff__);
1963464ebd5Sriastradh      abort();
1973464ebd5Sriastradh   }
1983464ebd5Sriastradh}
199