1ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/*
2ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston Copyright (c) 2008, 2009 Apple Inc.
3ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
4ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston Permission is hereby granted, free of charge, to any person
5ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston obtaining a copy of this software and associated documentation files
6ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston (the "Software"), to deal in the Software without restriction,
7ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston including without limitation the rights to use, copy, modify, merge,
8ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston publish, distribute, sublicense, and/or sell copies of the Software,
9ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston and to permit persons to whom the Software is furnished to do so,
10ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston subject to the following conditions:
11ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
12ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston The above copyright notice and this permission notice shall be
13ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston included in all copies or substantial portions of the Software.
14ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
15ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
19ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston DEALINGS IN THE SOFTWARE.
23ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
24ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston Except as contained in this notice, the name(s) of the above
25ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston copyright holders shall not be used in advertising or otherwise to
26ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston promote the sale, use or other dealings in this Software without
27ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston prior written authorization.
28ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston*/
29ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
30ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <stdbool.h>
31ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <stdio.h>
32ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <stdlib.h>
33ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <assert.h>
34ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <GL/gl.h>
35a1cb3babbef2af222b839a058694acc82a7074f1Jeremy Huddleston
36a1cb3babbef2af222b839a058694acc82a7074f1Jeremy Huddleston/* <rdar://problem/6953344> */
37a1cb3babbef2af222b839a058694acc82a7074f1Jeremy Huddleston#define glTexImage1D glTexImage1D_OSX
38a1cb3babbef2af222b839a058694acc82a7074f1Jeremy Huddleston#define glTexImage2D glTexImage2D_OSX
39a1cb3babbef2af222b839a058694acc82a7074f1Jeremy Huddleston#define glTexImage3D glTexImage3D_OSX
40ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <OpenGL/OpenGL.h>
41ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <OpenGL/CGLContext.h>
42ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <OpenGL/CGLRenderers.h>
439a00dd974699e369b1eb292103fbde8bc6adfb87Jeremy Huddleston#include <OpenGL/CGLTypes.h>
44a1cb3babbef2af222b839a058694acc82a7074f1Jeremy Huddleston#undef glTexImage1D
45a1cb3babbef2af222b839a058694acc82a7074f1Jeremy Huddleston#undef glTexImage2D
46a1cb3babbef2af222b839a058694acc82a7074f1Jeremy Huddleston#undef glTexImage3D
47a1cb3babbef2af222b839a058694acc82a7074f1Jeremy Huddleston
489a00dd974699e369b1eb292103fbde8bc6adfb87Jeremy Huddleston#ifndef kCGLPFAOpenGLProfile
499a00dd974699e369b1eb292103fbde8bc6adfb87Jeremy Huddleston#define kCGLPFAOpenGLProfile 99
509a00dd974699e369b1eb292103fbde8bc6adfb87Jeremy Huddleston#endif
519a00dd974699e369b1eb292103fbde8bc6adfb87Jeremy Huddleston
529a00dd974699e369b1eb292103fbde8bc6adfb87Jeremy Huddleston#ifndef kCGLOGLPVersion_3_2_Core
539a00dd974699e369b1eb292103fbde8bc6adfb87Jeremy Huddleston#define kCGLOGLPVersion_3_2_Core 0x3200
549a00dd974699e369b1eb292103fbde8bc6adfb87Jeremy Huddleston#endif
559a00dd974699e369b1eb292103fbde8bc6adfb87Jeremy Huddleston
56ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "apple_cgl.h"
57ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "apple_visual.h"
58ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "apple_glx.h"
594c9bab78a118953baf307e31cd53e731299f0151Jeremy Huddleston#include "glxconfig.h"
60ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
61ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonenum
62ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
63ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   MAX_ATTR = 60
64ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston};
65ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
669eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddlestonstatic char __crashreporter_info_buff__[4096] = { 0 };
679eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddlestonstatic const char *__crashreporter_info__ __attribute__((__used__)) =
689eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston    &__crashreporter_info_buff__[0];
699eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
709eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston// This is actually a toolchain requirement, but I'm not sure the correct check,
719eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston// but it should be fine to just only include it for Leopard and later.  This line
729eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston// just tells the linker to never strip this symbol (such as for space optimization)
739eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston__asm__ (".desc ___crashreporter_info__, 0x10");
749eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston#endif
759eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston
76ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonvoid
7702b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddlestonapple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const struct glx_config * mode,
78ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                          bool * double_buffered, bool * uses_stereo,
79ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                          bool offscreen)
80ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
81ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   CGLPixelFormatAttribute attr[MAX_ATTR];
82ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int numattr = 0;
83ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   GLint vsref = 0;
84ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   CGLError error = 0;
8504ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston   bool use_core_profile = getenv("LIBGL_PROFILE_CORE");
869a00dd974699e369b1eb292103fbde8bc6adfb87Jeremy Huddleston
87ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (offscreen) {
88ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      apple_glx_diagnostic
89ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         ("offscreen rendering enabled.  Using kCGLPFAOffScreen\n");
90ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
91ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFAOffScreen;
92ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
93ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   else if (getenv("LIBGL_ALWAYS_SOFTWARE") != NULL) {
94ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      apple_glx_diagnostic
95ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         ("Software rendering requested.  Using kCGLRendererGenericFloatID.\n");
96ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFARendererID;
97ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLRendererGenericFloatID;
98ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
99ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   else if (getenv("LIBGL_ALLOW_SOFTWARE") != NULL) {
100ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      apple_glx_diagnostic
101ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         ("Software rendering is not being excluded.  Not using kCGLPFAAccelerated.\n");
102ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
103ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   else {
104ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFAAccelerated;
105ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
106ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
107ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   /*
108ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    * The program chose a config based on the fbconfigs or visuals.
109ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    * Those are based on the attributes from CGL, so we probably
110ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    * do want the closest match for the color, depth, and accum.
111ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    */
112ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   attr[numattr++] = kCGLPFAClosestPolicy;
113ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
11402b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston   if (mode->stereoMode) {
115ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFAStereo;
116ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      *uses_stereo = true;
117ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
118ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   else {
119ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      *uses_stereo = false;
120ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
121ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
1225fdf1f784bf449d7ce9839506fa23c5357696c4cJonas Maebe   if (!offscreen && mode->doubleBufferMode) {
123ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFADoubleBuffer;
124ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      *double_buffered = true;
125ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
126ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   else {
127ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      *double_buffered = false;
128ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
129ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
130ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   attr[numattr++] = kCGLPFAColorSize;
13102b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston   attr[numattr++] = mode->redBits + mode->greenBits + mode->blueBits;
132ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   attr[numattr++] = kCGLPFAAlphaSize;
13302b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston   attr[numattr++] = mode->alphaBits;
134ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
13502b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston   if ((mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits) > 0) {
136ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFAAccumSize;
13702b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston      attr[numattr++] = mode->accumRedBits + mode->accumGreenBits +
13802b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston         mode->accumBlueBits + mode->accumAlphaBits;
139ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
140ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
14102b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston   if (mode->depthBits > 0) {
142ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFADepthSize;
14302b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston      attr[numattr++] = mode->depthBits;
144ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
145ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
14602b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston   if (mode->stencilBits > 0) {
147ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFAStencilSize;
14802b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston      attr[numattr++] = mode->stencilBits;
149ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
150ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
15102b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston   if (mode->sampleBuffers > 0) {
152ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFAMultisample;
153ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFASampleBuffers;
15402b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston      attr[numattr++] = mode->sampleBuffers;
155ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      attr[numattr++] = kCGLPFASamples;
15602b6e97c75bf2e013064e789b70704c6376e0628Jeremy Huddleston      attr[numattr++] = mode->samples;
157ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
158ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
15904ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston   /* Debugging support for Core profiles to support newer versions of OpenGL */
16004ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston   if (use_core_profile) {
16104ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston      attr[numattr++] = kCGLPFAOpenGLProfile;
16204ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston      attr[numattr++] = kCGLOGLPVersion_3_2_Core;
16304ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston   }
16404ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston
165ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   attr[numattr++] = 0;
166ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
167ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   assert(numattr < MAX_ATTR);
168ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
169ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   error = apple_cgl.choose_pixel_format(attr, pfobj, &vsref);
170ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
17104ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston   if ((error == kCGLBadAttribute || vsref == 0) && use_core_profile) {
17204ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston      apple_glx_diagnostic
17304ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston         ("Trying again without CoreProfile: error=%s, vsref=%d\n", apple_cgl.error_string(error), vsref);
17404ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston
17504ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston      if (!error)
17604ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston         apple_cgl.destroy_pixel_format(*pfobj);
17704ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston
17804ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston      numattr -= 3;
17904ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston      attr[numattr++] = 0;
18004ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston
18104ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston      error = apple_cgl.choose_pixel_format(attr, pfobj, &vsref);
18204ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston   }
18304ce3be4010305902cc5ae81e8e0c8550d043a1eJeremy Huddleston
184ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (error) {
1859eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston      snprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__),
1869eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston               "CGLChoosePixelFormat error: %s\n", apple_cgl.error_string(error));
1879eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston      fprintf(stderr, "%s", __crashreporter_info_buff__);
188ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
189ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
190002a3a74273b81dfb226e1c3f0a8c18525ed0af4Jon Turney
191002a3a74273b81dfb226e1c3f0a8c18525ed0af4Jon Turney   if (!*pfobj) {
1929eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston      snprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__),
1939eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston               "No matching pixelformats found, perhaps try using LIBGL_ALLOW_SOFTWARE\n");
1949eb1d36c978a9b15ae2e999c630492dfffd7f165Jeremy Huddleston      fprintf(stderr, "%s", __crashreporter_info_buff__);
195002a3a74273b81dfb226e1c3f0a8c18525ed0af4Jon Turney      abort();
196002a3a74273b81dfb226e1c3f0a8c18525ed0af4Jon Turney   }
197ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
198