aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xquartz/GL/capabilities.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xquartz/GL/capabilities.c')
-rw-r--r--xorg-server/hw/xquartz/GL/capabilities.c1086
1 files changed, 543 insertions, 543 deletions
diff --git a/xorg-server/hw/xquartz/GL/capabilities.c b/xorg-server/hw/xquartz/GL/capabilities.c
index fc7dd57dd..da52cc7c4 100644
--- a/xorg-server/hw/xquartz/GL/capabilities.c
+++ b/xorg-server/hw/xquartz/GL/capabilities.c
@@ -1,543 +1,543 @@
-/*
- * Copyright (c) 2008 Apple Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <OpenGL/OpenGL.h>
-#include <OpenGL/gl.h>
-#include <OpenGL/glu.h>
-#include <OpenGL/glext.h>
-#include <ApplicationServices/ApplicationServices.h>
-
-#include "capabilities.h"
-
-#define Cursor X_Cursor
-#include "os.h"
-#undef Cursor
-
-static void handleBufferModes(struct glCapabilitiesConfig *c, GLint bufferModes) {
- if(bufferModes & kCGLStereoscopicBit) {
- c->stereo = true;
- }
-
- if(bufferModes & kCGLDoubleBufferBit) {
- c->buffers = 2;
- } else {
- c->buffers = 1;
- }
-}
-
-static void handleStencilModes(struct glCapabilitiesConfig *c, GLint smodes) {
- int offset = 0;
-
- if(kCGL0Bit & smodes)
- c->stencil_bit_depths[offset++] = 0;
-
- if(kCGL1Bit & smodes)
- c->stencil_bit_depths[offset++] = 1;
-
- if(kCGL2Bit & smodes)
- c->stencil_bit_depths[offset++] = 2;
-
- if(kCGL3Bit & smodes)
- c->stencil_bit_depths[offset++] = 3;
-
- if(kCGL4Bit & smodes)
- c->stencil_bit_depths[offset++] = 4;
-
- if(kCGL5Bit & smodes)
- c->stencil_bit_depths[offset++] = 5;
-
- if(kCGL6Bit & smodes)
- c->stencil_bit_depths[offset++] = 6;
-
- if(kCGL8Bit & smodes)
- c->stencil_bit_depths[offset++] = 8;
-
- if(kCGL10Bit & smodes)
- c->stencil_bit_depths[offset++] = 10;
-
- if(kCGL12Bit & smodes)
- c->stencil_bit_depths[offset++] = 12;
-
- if(kCGL16Bit & smodes)
- c->stencil_bit_depths[offset++] = 16;
-
- if(kCGL24Bit & smodes)
- c->stencil_bit_depths[offset++] = 24;
-
- if(kCGL32Bit & smodes)
- c->stencil_bit_depths[offset++] = 32;
-
- if(kCGL48Bit & smodes)
- c->stencil_bit_depths[offset++] = 48;
-
- if(kCGL64Bit & smodes)
- c->stencil_bit_depths[offset++] = 64;
-
- if(kCGL96Bit & smodes)
- c->stencil_bit_depths[offset++] = 96;
-
- if(kCGL128Bit & smodes)
- c->stencil_bit_depths[offset++] = 128;
-
- assert(offset < GLCAPS_STENCIL_BIT_DEPTH_BUFFERS);
-
- c->total_stencil_bit_depths = offset;
-}
-
-static int handleColorAndAccumulation(struct glColorBufCapabilities *c,
- GLint cmodes, int forAccum) {
- int offset = 0;
-
- /*1*/
- if(kCGLRGB444Bit & cmodes) {
- c[offset].r = 4;
- c[offset].g = 4;
- c[offset].b = 4;
- ++offset;
- }
-
- /*2*/
- if(kCGLARGB4444Bit & cmodes) {
- c[offset].a = 4;
- c[offset].r = 4;
- c[offset].g = 4;
- c[offset].b = 4;
- c[offset].is_argb = true;
- ++offset;
- }
-
- /*3*/
- if(kCGLRGB444A8Bit & cmodes) {
- c[offset].r = 4;
- c[offset].g = 4;
- c[offset].b = 4;
- c[offset].a = 8;
- ++offset;
- }
-
- /*4*/
- if(kCGLRGB555Bit & cmodes) {
- c[offset].r = 5;
- c[offset].g = 5;
- c[offset].b = 5;
- ++offset;
- }
-
- /*5*/
- if(kCGLARGB1555Bit & cmodes) {
- c[offset].a = 1;
- c[offset].r = 5;
- c[offset].g = 5;
- c[offset].b = 5;
- c[offset].is_argb = true;
- ++offset;
- }
-
- /*6*/
- if(kCGLRGB555A8Bit & cmodes) {
- c[offset].r = 5;
- c[offset].g = 5;
- c[offset].b = 5;
- c[offset].a = 8;
- ++offset;
- }
-
- /*7*/
- if(kCGLRGB565Bit & cmodes) {
- c[offset].r = 5;
- c[offset].g = 6;
- c[offset].b = 5;
- ++offset;
- }
-
- /*8*/
- if(kCGLRGB565A8Bit & cmodes) {
- c[offset].r = 5;
- c[offset].g = 6;
- c[offset].b = 5;
- c[offset].a = 8;
- ++offset;
- }
-
- /*9*/
- if(kCGLRGB888Bit & cmodes) {
- c[offset].r = 8;
- c[offset].g = 8;
- c[offset].b = 8;
- ++offset;
- }
-
- /*10*/
- if(kCGLARGB8888Bit & cmodes) {
- c[offset].a = 8;
- c[offset].r = 8;
- c[offset].g = 8;
- c[offset].b = 8;
- c[offset].is_argb = true;
- ++offset;
- }
-
- /*11*/
- if(kCGLRGB888A8Bit & cmodes) {
- c[offset].r = 8;
- c[offset].g = 8;
- c[offset].b = 8;
- c[offset].a = 8;
- ++offset;
- }
-
- if(forAccum) {
-//#if 0
- /* FIXME
- * Disable this path, because some part of libGL, X, or Xplugin
- * doesn't work with sizes greater than 8.
- * When this is enabled and visuals are chosen using depths
- * such as 16, the result is that the windows don't redraw
- * and are often white, until a resize.
- */
-
- /*12*/
- if(kCGLRGB101010Bit & cmodes) {
- c[offset].r = 10;
- c[offset].g = 10;
- c[offset].b = 10;
- ++offset;
- }
-
- /*13*/
- if(kCGLARGB2101010Bit & cmodes) {
- c[offset].a = 2;
- c[offset].r = 10;
- c[offset].g = 10;
- c[offset].b = 10;
- c[offset].is_argb = true;
- ++offset;
- }
-
- /*14*/
- if(kCGLRGB101010_A8Bit & cmodes) {
- c[offset].r = 10;
- c[offset].g = 10;
- c[offset].b = 10;
- c[offset].a = 8;
- ++offset;
- }
-
- /*15*/
- if(kCGLRGB121212Bit & cmodes) {
- c[offset].r = 12;
- c[offset].g = 12;
- c[offset].b = 12;
- ++offset;
- }
-
- /*16*/
- if(kCGLARGB12121212Bit & cmodes) {
- c[offset].a = 12;
- c[offset].r = 12;
- c[offset].g = 12;
- c[offset].b = 12;
- c[offset].is_argb = true;
- ++offset;
- }
-
- /*17*/
- if(kCGLRGB161616Bit & cmodes) {
- c[offset].r = 16;
- c[offset].g = 16;
- c[offset].b = 16;
- ++offset;
- }
-
- /*18*/
- if(kCGLRGBA16161616Bit & cmodes) {
- c[offset].r = 16;
- c[offset].g = 16;
- c[offset].b = 16;
- c[offset].a = 16;
- ++offset;
- }
- }
-//#endif
-
- /* FIXME should we handle the floating point color modes, and if so, how? */
-
- return offset;
-}
-
-
-static void handleColorModes(struct glCapabilitiesConfig *c, GLint cmodes) {
- c->total_color_buffers = handleColorAndAccumulation(c->color_buffers,
- cmodes, 0);
-
- assert(c->total_color_buffers < GLCAPS_COLOR_BUFFERS);
-}
-
-static void handleAccumulationModes(struct glCapabilitiesConfig *c, GLint cmodes) {
- c->total_accum_buffers = handleColorAndAccumulation(c->accum_buffers,
- cmodes, 1);
- assert(c->total_accum_buffers < GLCAPS_COLOR_BUFFERS);
-}
-
-static void handleDepthModes(struct glCapabilitiesConfig *c, GLint dmodes) {
- int offset = 0;
-#define DEPTH(flag,value) do { \
- if(dmodes & flag) { \
- c->depth_buffers[offset++] = value; \
- } \
- } while(0)
-
- /*1*/
- DEPTH(kCGL0Bit, 0);
- /*2*/
- DEPTH(kCGL1Bit, 1);
- /*3*/
- DEPTH(kCGL2Bit, 2);
- /*4*/
- DEPTH(kCGL3Bit, 3);
- /*5*/
- DEPTH(kCGL4Bit, 4);
- /*6*/
- DEPTH(kCGL5Bit, 5);
- /*7*/
- DEPTH(kCGL6Bit, 6);
- /*8*/
- DEPTH(kCGL8Bit, 8);
- /*9*/
- DEPTH(kCGL10Bit, 10);
- /*10*/
- DEPTH(kCGL12Bit, 12);
- /*11*/
- DEPTH(kCGL16Bit, 16);
- /*12*/
- DEPTH(kCGL24Bit, 24);
- /*13*/
- DEPTH(kCGL32Bit, 32);
- /*14*/
- DEPTH(kCGL48Bit, 48);
- /*15*/
- DEPTH(kCGL64Bit, 64);
- /*16*/
- DEPTH(kCGL96Bit, 96);
- /*17*/
- DEPTH(kCGL128Bit, 128);
-
-#undef DEPTH
-
- c->total_depth_buffer_depths = offset;
- assert(c->total_depth_buffer_depths < GLCAPS_DEPTH_BUFFERS);
-}
-
-/* Return non-zero if an error occured. */
-static CGLError handleRendererDescriptions(CGLRendererInfoObj info, GLint r,
- struct glCapabilitiesConfig *c) {
- CGLError err;
- GLint accelerated = 0, flags = 0, aux = 0, samplebufs = 0, samples = 0;
-
- err = CGLDescribeRenderer (info, r, kCGLRPAccelerated, &accelerated);
-
- if(err)
- return err;
-
- c->accelerated = accelerated;
-
- /* Buffering modes: single/double, stereo */
- err = CGLDescribeRenderer(info, r, kCGLRPBufferModes, &flags);
-
- if(err)
- return err;
-
- handleBufferModes(c, flags);
-
- /* AUX buffers */
- err = CGLDescribeRenderer(info, r, kCGLRPMaxAuxBuffers, &aux);
-
- if(err)
- return err;
-
- c->aux_buffers = aux;
-
-
- /* Depth buffer size */
- err = CGLDescribeRenderer(info, r, kCGLRPDepthModes, &flags);
-
- if(err)
- return err;
-
- handleDepthModes(c, flags);
-
-
- /* Multisample buffers */
- err = CGLDescribeRenderer(info, r, kCGLRPMaxSampleBuffers, &samplebufs);
-
- if(err)
- return err;
-
- c->multisample_buffers = samplebufs;
-
-
- /* Multisample samples per multisample buffer */
- err = CGLDescribeRenderer(info, r, kCGLRPMaxSamples, &samples);
-
- if(err)
- return err;
-
- c->multisample_samples = samples;
-
-
- /* Stencil bit depths */
- err = CGLDescribeRenderer(info, r, kCGLRPStencilModes, &flags);
-
- if(err)
- return err;
-
- handleStencilModes(c, flags);
-
-
- /* Color modes (RGB/RGBA depths supported */
- err = CGLDescribeRenderer(info, r, kCGLRPColorModes, &flags);
-
- if(err)
- return err;
-
- handleColorModes(c, flags);
-
- err = CGLDescribeRenderer(info, r, kCGLRPAccumModes, &flags);
-
- if(err)
- return err;
-
- handleAccumulationModes(c, flags);
-
- return kCGLNoError;
-}
-
-static void initCapabilities(struct glCapabilities *cap) {
- cap->configurations = NULL;
- cap->total_configurations = 0;
-}
-
-static void initConfig(struct glCapabilitiesConfig *c) {
- int i;
-
- c->accelerated = false;
- c->stereo = false;
- c->aux_buffers = 0;
- c->buffers = 0;
-
- c->total_depth_buffer_depths = 0;
-
- for(i = 0; i < GLCAPS_DEPTH_BUFFERS; ++i) {
- c->depth_buffers[i] = GLCAPS_INVALID_DEPTH_VALUE;
- }
-
- c->multisample_buffers = 0;
- c->multisample_samples = 0;
-
- c->total_stencil_bit_depths = 0;
-
- for(i = 0; i < GLCAPS_STENCIL_BIT_DEPTH_BUFFERS; ++i) {
- c->stencil_bit_depths[i] = GLCAPS_INVALID_STENCIL_DEPTH;
- }
-
- c->total_color_buffers = 0;
-
- for(i = 0; i < GLCAPS_COLOR_BUFFERS; ++i) {
- c->color_buffers[i].r = c->color_buffers[i].g =
- c->color_buffers[i].b = c->color_buffers[i].a =
- GLCAPS_COLOR_BUF_INVALID_VALUE;
- c->color_buffers[i].is_argb = false;
- }
-
- c->total_accum_buffers = 0;
-
- for(i = 0; i < GLCAPS_COLOR_BUFFERS; ++i) {
- c->accum_buffers[i].r = c->accum_buffers[i].g =
- c->accum_buffers[i].b = c->accum_buffers[i].a =
- GLCAPS_COLOR_BUF_INVALID_VALUE;
- c->accum_buffers[i].is_argb = false;
- }
-
- c->next = NULL;
-}
-
-void freeGlCapabilities(struct glCapabilities *cap) {
- struct glCapabilitiesConfig *conf, *next;
-
- conf = cap->configurations;
-
- while(conf) {
- next = conf->next;
- free(conf);
- conf = next;
- }
-
- cap->configurations = NULL;
-}
-
-/*Return true if an error occured. */
-bool getGlCapabilities(struct glCapabilities *cap) {
- CGLRendererInfoObj info;
- CGLError err;
- GLint numRenderers = 0, r;
-
- initCapabilities(cap);
-
- err = CGLQueryRendererInfo((GLuint)-1, &info, &numRenderers);
- if(err) {
- fprintf(stderr, "CGLQueryRendererInfo error: %s\n", CGLErrorString(err));
- return err;
- }
-
- for(r = 0; r < numRenderers; r++) {
- struct glCapabilitiesConfig tmpconf, *conf;
-
- initConfig(&tmpconf);
-
- err = handleRendererDescriptions(info, r, &tmpconf);
- if(err) {
- fprintf(stderr, "handleRendererDescriptions returned error: %s\n", CGLErrorString(err));
- fprintf(stderr, "trying to continue...\n");
- continue;
- }
-
- conf = malloc(sizeof(*conf));
- if(NULL == conf) {
- FatalError("Unable to allocate memory for OpenGL capabilities\n");
- }
-
- /* Copy the struct. */
- *conf = tmpconf;
-
- /* Now link the configuration into the list. */
- conf->next = cap->configurations;
- cap->configurations = conf;
- }
-
- CGLDestroyRendererInfo(info);
-
- /* No error occured. We are done. */
- return kCGLNoError;
-}
+/*
+ * Copyright (c) 2008 Apple Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#include <OpenGL/glext.h>
+#include <ApplicationServices/ApplicationServices.h>
+
+#include "capabilities.h"
+
+#define Cursor X_Cursor
+#include "os.h"
+#undef Cursor
+
+static void handleBufferModes(struct glCapabilitiesConfig *c, GLint bufferModes) {
+ if(bufferModes & kCGLStereoscopicBit) {
+ c->stereo = true;
+ }
+
+ if(bufferModes & kCGLDoubleBufferBit) {
+ c->buffers = 2;
+ } else {
+ c->buffers = 1;
+ }
+}
+
+static void handleStencilModes(struct glCapabilitiesConfig *c, GLint smodes) {
+ int offset = 0;
+
+ if(kCGL0Bit & smodes)
+ c->stencil_bit_depths[offset++] = 0;
+
+ if(kCGL1Bit & smodes)
+ c->stencil_bit_depths[offset++] = 1;
+
+ if(kCGL2Bit & smodes)
+ c->stencil_bit_depths[offset++] = 2;
+
+ if(kCGL3Bit & smodes)
+ c->stencil_bit_depths[offset++] = 3;
+
+ if(kCGL4Bit & smodes)
+ c->stencil_bit_depths[offset++] = 4;
+
+ if(kCGL5Bit & smodes)
+ c->stencil_bit_depths[offset++] = 5;
+
+ if(kCGL6Bit & smodes)
+ c->stencil_bit_depths[offset++] = 6;
+
+ if(kCGL8Bit & smodes)
+ c->stencil_bit_depths[offset++] = 8;
+
+ if(kCGL10Bit & smodes)
+ c->stencil_bit_depths[offset++] = 10;
+
+ if(kCGL12Bit & smodes)
+ c->stencil_bit_depths[offset++] = 12;
+
+ if(kCGL16Bit & smodes)
+ c->stencil_bit_depths[offset++] = 16;
+
+ if(kCGL24Bit & smodes)
+ c->stencil_bit_depths[offset++] = 24;
+
+ if(kCGL32Bit & smodes)
+ c->stencil_bit_depths[offset++] = 32;
+
+ if(kCGL48Bit & smodes)
+ c->stencil_bit_depths[offset++] = 48;
+
+ if(kCGL64Bit & smodes)
+ c->stencil_bit_depths[offset++] = 64;
+
+ if(kCGL96Bit & smodes)
+ c->stencil_bit_depths[offset++] = 96;
+
+ if(kCGL128Bit & smodes)
+ c->stencil_bit_depths[offset++] = 128;
+
+ assert(offset < GLCAPS_STENCIL_BIT_DEPTH_BUFFERS);
+
+ c->total_stencil_bit_depths = offset;
+}
+
+static int handleColorAndAccumulation(struct glColorBufCapabilities *c,
+ GLint cmodes, int forAccum) {
+ int offset = 0;
+
+ /*1*/
+ if(kCGLRGB444Bit & cmodes) {
+ c[offset].r = 4;
+ c[offset].g = 4;
+ c[offset].b = 4;
+ ++offset;
+ }
+
+ /*2*/
+ if(kCGLARGB4444Bit & cmodes) {
+ c[offset].a = 4;
+ c[offset].r = 4;
+ c[offset].g = 4;
+ c[offset].b = 4;
+ c[offset].is_argb = true;
+ ++offset;
+ }
+
+ /*3*/
+ if(kCGLRGB444A8Bit & cmodes) {
+ c[offset].r = 4;
+ c[offset].g = 4;
+ c[offset].b = 4;
+ c[offset].a = 8;
+ ++offset;
+ }
+
+ /*4*/
+ if(kCGLRGB555Bit & cmodes) {
+ c[offset].r = 5;
+ c[offset].g = 5;
+ c[offset].b = 5;
+ ++offset;
+ }
+
+ /*5*/
+ if(kCGLARGB1555Bit & cmodes) {
+ c[offset].a = 1;
+ c[offset].r = 5;
+ c[offset].g = 5;
+ c[offset].b = 5;
+ c[offset].is_argb = true;
+ ++offset;
+ }
+
+ /*6*/
+ if(kCGLRGB555A8Bit & cmodes) {
+ c[offset].r = 5;
+ c[offset].g = 5;
+ c[offset].b = 5;
+ c[offset].a = 8;
+ ++offset;
+ }
+
+ /*7*/
+ if(kCGLRGB565Bit & cmodes) {
+ c[offset].r = 5;
+ c[offset].g = 6;
+ c[offset].b = 5;
+ ++offset;
+ }
+
+ /*8*/
+ if(kCGLRGB565A8Bit & cmodes) {
+ c[offset].r = 5;
+ c[offset].g = 6;
+ c[offset].b = 5;
+ c[offset].a = 8;
+ ++offset;
+ }
+
+ /*9*/
+ if(kCGLRGB888Bit & cmodes) {
+ c[offset].r = 8;
+ c[offset].g = 8;
+ c[offset].b = 8;
+ ++offset;
+ }
+
+ /*10*/
+ if(kCGLARGB8888Bit & cmodes) {
+ c[offset].a = 8;
+ c[offset].r = 8;
+ c[offset].g = 8;
+ c[offset].b = 8;
+ c[offset].is_argb = true;
+ ++offset;
+ }
+
+ /*11*/
+ if(kCGLRGB888A8Bit & cmodes) {
+ c[offset].r = 8;
+ c[offset].g = 8;
+ c[offset].b = 8;
+ c[offset].a = 8;
+ ++offset;
+ }
+
+ if(forAccum) {
+//#if 0
+ /* FIXME
+ * Disable this path, because some part of libGL, X, or Xplugin
+ * doesn't work with sizes greater than 8.
+ * When this is enabled and visuals are chosen using depths
+ * such as 16, the result is that the windows don't redraw
+ * and are often white, until a resize.
+ */
+
+ /*12*/
+ if(kCGLRGB101010Bit & cmodes) {
+ c[offset].r = 10;
+ c[offset].g = 10;
+ c[offset].b = 10;
+ ++offset;
+ }
+
+ /*13*/
+ if(kCGLARGB2101010Bit & cmodes) {
+ c[offset].a = 2;
+ c[offset].r = 10;
+ c[offset].g = 10;
+ c[offset].b = 10;
+ c[offset].is_argb = true;
+ ++offset;
+ }
+
+ /*14*/
+ if(kCGLRGB101010_A8Bit & cmodes) {
+ c[offset].r = 10;
+ c[offset].g = 10;
+ c[offset].b = 10;
+ c[offset].a = 8;
+ ++offset;
+ }
+
+ /*15*/
+ if(kCGLRGB121212Bit & cmodes) {
+ c[offset].r = 12;
+ c[offset].g = 12;
+ c[offset].b = 12;
+ ++offset;
+ }
+
+ /*16*/
+ if(kCGLARGB12121212Bit & cmodes) {
+ c[offset].a = 12;
+ c[offset].r = 12;
+ c[offset].g = 12;
+ c[offset].b = 12;
+ c[offset].is_argb = true;
+ ++offset;
+ }
+
+ /*17*/
+ if(kCGLRGB161616Bit & cmodes) {
+ c[offset].r = 16;
+ c[offset].g = 16;
+ c[offset].b = 16;
+ ++offset;
+ }
+
+ /*18*/
+ if(kCGLRGBA16161616Bit & cmodes) {
+ c[offset].r = 16;
+ c[offset].g = 16;
+ c[offset].b = 16;
+ c[offset].a = 16;
+ ++offset;
+ }
+ }
+//#endif
+
+ /* FIXME should we handle the floating point color modes, and if so, how? */
+
+ return offset;
+}
+
+
+static void handleColorModes(struct glCapabilitiesConfig *c, GLint cmodes) {
+ c->total_color_buffers = handleColorAndAccumulation(c->color_buffers,
+ cmodes, 0);
+
+ assert(c->total_color_buffers < GLCAPS_COLOR_BUFFERS);
+}
+
+static void handleAccumulationModes(struct glCapabilitiesConfig *c, GLint cmodes) {
+ c->total_accum_buffers = handleColorAndAccumulation(c->accum_buffers,
+ cmodes, 1);
+ assert(c->total_accum_buffers < GLCAPS_COLOR_BUFFERS);
+}
+
+static void handleDepthModes(struct glCapabilitiesConfig *c, GLint dmodes) {
+ int offset = 0;
+#define DEPTH(flag,value) do { \
+ if(dmodes & flag) { \
+ c->depth_buffers[offset++] = value; \
+ } \
+ } while(0)
+
+ /*1*/
+ DEPTH(kCGL0Bit, 0);
+ /*2*/
+ DEPTH(kCGL1Bit, 1);
+ /*3*/
+ DEPTH(kCGL2Bit, 2);
+ /*4*/
+ DEPTH(kCGL3Bit, 3);
+ /*5*/
+ DEPTH(kCGL4Bit, 4);
+ /*6*/
+ DEPTH(kCGL5Bit, 5);
+ /*7*/
+ DEPTH(kCGL6Bit, 6);
+ /*8*/
+ DEPTH(kCGL8Bit, 8);
+ /*9*/
+ DEPTH(kCGL10Bit, 10);
+ /*10*/
+ DEPTH(kCGL12Bit, 12);
+ /*11*/
+ DEPTH(kCGL16Bit, 16);
+ /*12*/
+ DEPTH(kCGL24Bit, 24);
+ /*13*/
+ DEPTH(kCGL32Bit, 32);
+ /*14*/
+ DEPTH(kCGL48Bit, 48);
+ /*15*/
+ DEPTH(kCGL64Bit, 64);
+ /*16*/
+ DEPTH(kCGL96Bit, 96);
+ /*17*/
+ DEPTH(kCGL128Bit, 128);
+
+#undef DEPTH
+
+ c->total_depth_buffer_depths = offset;
+ assert(c->total_depth_buffer_depths < GLCAPS_DEPTH_BUFFERS);
+}
+
+/* Return non-zero if an error occured. */
+static CGLError handleRendererDescriptions(CGLRendererInfoObj info, GLint r,
+ struct glCapabilitiesConfig *c) {
+ CGLError err;
+ GLint accelerated = 0, flags = 0, aux = 0, samplebufs = 0, samples = 0;
+
+ err = CGLDescribeRenderer (info, r, kCGLRPAccelerated, &accelerated);
+
+ if(err)
+ return err;
+
+ c->accelerated = accelerated;
+
+ /* Buffering modes: single/double, stereo */
+ err = CGLDescribeRenderer(info, r, kCGLRPBufferModes, &flags);
+
+ if(err)
+ return err;
+
+ handleBufferModes(c, flags);
+
+ /* AUX buffers */
+ err = CGLDescribeRenderer(info, r, kCGLRPMaxAuxBuffers, &aux);
+
+ if(err)
+ return err;
+
+ c->aux_buffers = aux;
+
+
+ /* Depth buffer size */
+ err = CGLDescribeRenderer(info, r, kCGLRPDepthModes, &flags);
+
+ if(err)
+ return err;
+
+ handleDepthModes(c, flags);
+
+
+ /* Multisample buffers */
+ err = CGLDescribeRenderer(info, r, kCGLRPMaxSampleBuffers, &samplebufs);
+
+ if(err)
+ return err;
+
+ c->multisample_buffers = samplebufs;
+
+
+ /* Multisample samples per multisample buffer */
+ err = CGLDescribeRenderer(info, r, kCGLRPMaxSamples, &samples);
+
+ if(err)
+ return err;
+
+ c->multisample_samples = samples;
+
+
+ /* Stencil bit depths */
+ err = CGLDescribeRenderer(info, r, kCGLRPStencilModes, &flags);
+
+ if(err)
+ return err;
+
+ handleStencilModes(c, flags);
+
+
+ /* Color modes (RGB/RGBA depths supported */
+ err = CGLDescribeRenderer(info, r, kCGLRPColorModes, &flags);
+
+ if(err)
+ return err;
+
+ handleColorModes(c, flags);
+
+ err = CGLDescribeRenderer(info, r, kCGLRPAccumModes, &flags);
+
+ if(err)
+ return err;
+
+ handleAccumulationModes(c, flags);
+
+ return kCGLNoError;
+}
+
+static void initCapabilities(struct glCapabilities *cap) {
+ cap->configurations = NULL;
+ cap->total_configurations = 0;
+}
+
+static void initConfig(struct glCapabilitiesConfig *c) {
+ int i;
+
+ c->accelerated = false;
+ c->stereo = false;
+ c->aux_buffers = 0;
+ c->buffers = 0;
+
+ c->total_depth_buffer_depths = 0;
+
+ for(i = 0; i < GLCAPS_DEPTH_BUFFERS; ++i) {
+ c->depth_buffers[i] = GLCAPS_INVALID_DEPTH_VALUE;
+ }
+
+ c->multisample_buffers = 0;
+ c->multisample_samples = 0;
+
+ c->total_stencil_bit_depths = 0;
+
+ for(i = 0; i < GLCAPS_STENCIL_BIT_DEPTH_BUFFERS; ++i) {
+ c->stencil_bit_depths[i] = GLCAPS_INVALID_STENCIL_DEPTH;
+ }
+
+ c->total_color_buffers = 0;
+
+ for(i = 0; i < GLCAPS_COLOR_BUFFERS; ++i) {
+ c->color_buffers[i].r = c->color_buffers[i].g =
+ c->color_buffers[i].b = c->color_buffers[i].a =
+ GLCAPS_COLOR_BUF_INVALID_VALUE;
+ c->color_buffers[i].is_argb = false;
+ }
+
+ c->total_accum_buffers = 0;
+
+ for(i = 0; i < GLCAPS_COLOR_BUFFERS; ++i) {
+ c->accum_buffers[i].r = c->accum_buffers[i].g =
+ c->accum_buffers[i].b = c->accum_buffers[i].a =
+ GLCAPS_COLOR_BUF_INVALID_VALUE;
+ c->accum_buffers[i].is_argb = false;
+ }
+
+ c->next = NULL;
+}
+
+void freeGlCapabilities(struct glCapabilities *cap) {
+ struct glCapabilitiesConfig *conf, *next;
+
+ conf = cap->configurations;
+
+ while(conf) {
+ next = conf->next;
+ free(conf);
+ conf = next;
+ }
+
+ cap->configurations = NULL;
+}
+
+/*Return true if an error occured. */
+bool getGlCapabilities(struct glCapabilities *cap) {
+ CGLRendererInfoObj info;
+ CGLError err;
+ GLint numRenderers = 0, r;
+
+ initCapabilities(cap);
+
+ err = CGLQueryRendererInfo((GLuint)-1, &info, &numRenderers);
+ if(err) {
+ ErrorF("CGLQueryRendererInfo error: %s\n", CGLErrorString(err));
+ return err;
+ }
+
+ for(r = 0; r < numRenderers; r++) {
+ struct glCapabilitiesConfig tmpconf, *conf;
+
+ initConfig(&tmpconf);
+
+ err = handleRendererDescriptions(info, r, &tmpconf);
+ if(err) {
+ ErrorF("handleRendererDescriptions returned error: %s\n", CGLErrorString(err));
+ ErrorF("trying to continue...\n");
+ continue;
+ }
+
+ conf = malloc(sizeof(*conf));
+ if(NULL == conf) {
+ FatalError("Unable to allocate memory for OpenGL capabilities\n");
+ }
+
+ /* Copy the struct. */
+ *conf = tmpconf;
+
+ /* Now link the configuration into the list. */
+ conf->next = cap->configurations;
+ cap->configurations = conf;
+ }
+
+ CGLDestroyRendererInfo(info);
+
+ /* No error occured. We are done. */
+ return kCGLNoError;
+}