summaryrefslogtreecommitdiff
path: root/hw/xquartz/GL/capabilities.c
blob: 3a540258b43ac28c5ebf9f3695af79e2050e887d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <stdio.h>
#include <stdlib.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 DIAGNOSTIC 0

static void handleBufferModes(struct glCapabilities *cap, GLint bufferModes) {
    if(bufferModes & kCGLStereoscopicBit) {
	cap->stereo = true;
    }

    if(bufferModes & kCGLDoubleBufferBit) {
	cap->buffers = 2;
    } else {
	cap->buffers = 1;
    }
}

static void initCapabilities(struct glCapabilities *cap) {
    cap->stereo = cap->buffers = cap->aux_buffers = 0;
}

enum {
    MAX_DISPLAYS = 32
};

/*Return true if an error occured. */
bool getGlCapabilities(struct glCapabilities *cap) {
    CGDirectDisplayID dspys[MAX_DISPLAYS];
    CGDisplayErr err;
    CGOpenGLDisplayMask displayMask;
    CGDisplayCount i, displayCount = 0;

    initCapabilities(cap);
    
    err = CGGetActiveDisplayList(MAX_DISPLAYS, dspys, &displayCount);
    if(err) {
#ifdef DIAGNOSTIC
	fprintf(stderr, "CGGetActiveDisplayList %s\n", CGLErrorString (err));
#endif
	return true;
    }
 
    for(i = 0; i < displayCount; ++i) {
        displayMask = CGDisplayIDToOpenGLDisplayMask(dspys[i]);
       
	CGLRendererInfoObj info;
	GLint numRenderers = 0, r, accelerated = 0, flags = 0, aux = 0;
    
	err = CGLQueryRendererInfo (displayMask, &info, &numRenderers);
        if(!err) {
            CGLDescribeRenderer (info, 0, kCGLRPRendererCount, &numRenderers);
            for(r = 0; r < numRenderers; ++r) {
                // find accelerated renderer (assume only one)
                CGLDescribeRenderer (info, r, kCGLRPAccelerated, &accelerated);
                if(accelerated) {
                    err = CGLDescribeRenderer(info, r, kCGLRPBufferModes, &flags);
		    if(err) {
			CGLDestroyRendererInfo(info);
			return true;
		    }

		    handleBufferModes(cap, flags);

		    err = CGLDescribeRenderer(info, r, kCGLRPMaxAuxBuffers, &aux);
		    if(err) {
			CGLDestroyRendererInfo(info);
			return true;
		    }

		    cap->aux_buffers = aux;
                }
            }
	    CGLDestroyRendererInfo(info);
	}
    }

    /* No error occured.  We are done. */
    return false;
}