Home | History | Annotate | Download | only in apple
      1 /*
      2  Copyright (c) 2008, 2009 Apple Inc.
      3 
      4  Permission is hereby granted, free of charge, to any person
      5  obtaining a copy of this software and associated documentation files
      6  (the "Software"), to deal in the Software without restriction,
      7  including without limitation the rights to use, copy, modify, merge,
      8  publish, distribute, sublicense, and/or sell copies of the Software,
      9  and to permit persons to whom the Software is furnished to do so,
     10  subject to the following conditions:
     11 
     12  The above copyright notice and this permission notice shall be
     13  included in all copies or substantial portions of the Software.
     14 
     15  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
     19  HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     20  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  DEALINGS IN THE SOFTWARE.
     23 
     24  Except as contained in this notice, the name(s) of the above
     25  copyright holders shall not be used in advertising or otherwise to
     26  promote the sale, use or other dealings in this Software without
     27  prior written authorization.
     28 */
     29 
     30 #include <stdbool.h>
     31 #include <stdio.h>
     32 #include <stdlib.h>
     33 #include <assert.h>
     34 #include <GL/gl.h>
     35 
     36 /* <rdar://problem/6953344> */
     37 #define glTexImage1D glTexImage1D_OSX
     38 #define glTexImage2D glTexImage2D_OSX
     39 #define glTexImage3D glTexImage3D_OSX
     40 #include <OpenGL/OpenGL.h>
     41 #include <OpenGL/CGLContext.h>
     42 #include <OpenGL/CGLRenderers.h>
     43 #include <OpenGL/CGLTypes.h>
     44 #undef glTexImage1D
     45 #undef glTexImage2D
     46 #undef glTexImage3D
     47 
     48 #ifndef kCGLPFAOpenGLProfile
     49 #define kCGLPFAOpenGLProfile 99
     50 #endif
     51 
     52 #ifndef kCGLOGLPVersion_3_2_Core
     53 #define kCGLOGLPVersion_3_2_Core 0x3200
     54 #endif
     55 
     56 #include "apple_cgl.h"
     57 #include "apple_visual.h"
     58 #include "apple_glx.h"
     59 #include "glxconfig.h"
     60 
     61 enum
     62 {
     63    MAX_ATTR = 60
     64 };
     65 
     66 static char __crashreporter_info_buff__[4096] = { 0 };
     67 static const char *__crashreporter_info__ __attribute__((__used__)) =
     68     &__crashreporter_info_buff__[0];
     69 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
     70 // This is actually a toolchain requirement, but I'm not sure the correct check,
     71 // but it should be fine to just only include it for Leopard and later.  This line
     72 // just tells the linker to never strip this symbol (such as for space optimization)
     73 __asm__ (".desc ___crashreporter_info__, 0x10");
     74 #endif
     75 
     76 void
     77 apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const struct glx_config * mode,
     78                           bool * double_buffered, bool * uses_stereo,
     79                           bool offscreen)
     80 {
     81    CGLPixelFormatAttribute attr[MAX_ATTR];
     82    int numattr = 0;
     83    GLint vsref = 0;
     84    CGLError error = 0;
     85    bool use_core_profile = getenv("LIBGL_PROFILE_CORE");
     86 
     87    if (offscreen) {
     88       apple_glx_diagnostic
     89          ("offscreen rendering enabled.  Using kCGLPFAOffScreen\n");
     90 
     91       attr[numattr++] = kCGLPFAOffScreen;
     92    }
     93    else if (getenv("LIBGL_ALWAYS_SOFTWARE") != NULL) {
     94       apple_glx_diagnostic
     95          ("Software rendering requested.  Using kCGLRendererGenericFloatID.\n");
     96       attr[numattr++] = kCGLPFARendererID;
     97       attr[numattr++] = kCGLRendererGenericFloatID;
     98    }
     99    else if (getenv("LIBGL_ALLOW_SOFTWARE") != NULL) {
    100       apple_glx_diagnostic
    101          ("Software rendering is not being excluded.  Not using kCGLPFAAccelerated.\n");
    102    }
    103    else {
    104       attr[numattr++] = kCGLPFAAccelerated;
    105    }
    106 
    107    /*
    108     * The program chose a config based on the fbconfigs or visuals.
    109     * Those are based on the attributes from CGL, so we probably
    110     * do want the closest match for the color, depth, and accum.
    111     */
    112    attr[numattr++] = kCGLPFAClosestPolicy;
    113 
    114    if (mode->stereoMode) {
    115       attr[numattr++] = kCGLPFAStereo;
    116       *uses_stereo = true;
    117    }
    118    else {
    119       *uses_stereo = false;
    120    }
    121 
    122    if (!offscreen && mode->doubleBufferMode) {
    123       attr[numattr++] = kCGLPFADoubleBuffer;
    124       *double_buffered = true;
    125    }
    126    else {
    127       *double_buffered = false;
    128    }
    129 
    130    attr[numattr++] = kCGLPFAColorSize;
    131    attr[numattr++] = mode->redBits + mode->greenBits + mode->blueBits;
    132    attr[numattr++] = kCGLPFAAlphaSize;
    133    attr[numattr++] = mode->alphaBits;
    134 
    135    if ((mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits) > 0) {
    136       attr[numattr++] = kCGLPFAAccumSize;
    137       attr[numattr++] = mode->accumRedBits + mode->accumGreenBits +
    138          mode->accumBlueBits + mode->accumAlphaBits;
    139    }
    140 
    141    if (mode->depthBits > 0) {
    142       attr[numattr++] = kCGLPFADepthSize;
    143       attr[numattr++] = mode->depthBits;
    144    }
    145 
    146    if (mode->stencilBits > 0) {
    147       attr[numattr++] = kCGLPFAStencilSize;
    148       attr[numattr++] = mode->stencilBits;
    149    }
    150 
    151    if (mode->sampleBuffers > 0) {
    152       attr[numattr++] = kCGLPFAMultisample;
    153       attr[numattr++] = kCGLPFASampleBuffers;
    154       attr[numattr++] = mode->sampleBuffers;
    155       attr[numattr++] = kCGLPFASamples;
    156       attr[numattr++] = mode->samples;
    157    }
    158 
    159    /* Debugging support for Core profiles to support newer versions of OpenGL */
    160    if (use_core_profile) {
    161       attr[numattr++] = kCGLPFAOpenGLProfile;
    162       attr[numattr++] = kCGLOGLPVersion_3_2_Core;
    163    }
    164 
    165    attr[numattr++] = 0;
    166 
    167    assert(numattr < MAX_ATTR);
    168 
    169    error = apple_cgl.choose_pixel_format(attr, pfobj, &vsref);
    170 
    171    if ((error == kCGLBadAttribute || vsref == 0) && use_core_profile) {
    172       apple_glx_diagnostic
    173          ("Trying again without CoreProfile: error=%s, vsref=%d\n", apple_cgl.error_string(error), vsref);
    174 
    175       if (!error)
    176          apple_cgl.destroy_pixel_format(*pfobj);
    177 
    178       numattr -= 3;
    179       attr[numattr++] = 0;
    180 
    181       error = apple_cgl.choose_pixel_format(attr, pfobj, &vsref);
    182    }
    183 
    184    if (error) {
    185       snprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__),
    186                "CGLChoosePixelFormat error: %s\n", apple_cgl.error_string(error));
    187       fprintf(stderr, "%s", __crashreporter_info_buff__);
    188       abort();
    189    }
    190 
    191    if (!*pfobj) {
    192       snprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__),
    193                "No matching pixelformats found, perhaps try using LIBGL_ALLOW_SOFTWARE\n");
    194       fprintf(stderr, "%s", __crashreporter_info_buff__);
    195       abort();
    196    }
    197 }
    198