xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

capabilities.c (13602B)


      1 /*
      2  * Copyright (c) 2008-2012 Apple Inc.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     17  * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     20  * DEALINGS IN THE SOFTWARE.
     21  */
     22 
     23 #ifdef HAVE_DIX_CONFIG_H
     24 #include <dix-config.h>
     25 #endif
     26 
     27 #include <stdio.h>
     28 #include <stdlib.h>
     29 #include <assert.h>
     30 
     31 #define Cursor Mac_Cursor
     32 #define BOOL   Mac_BOOL
     33 #include <OpenGL/OpenGL.h>
     34 #include <OpenGL/gl.h>
     35 #include <OpenGL/glu.h>
     36 #include <OpenGL/glext.h>
     37 #include <ApplicationServices/ApplicationServices.h>
     38 #undef Cursor
     39 #undef BOOL
     40 
     41 #include "capabilities.h"
     42 
     43 #include "os.h"
     44 
     45 static void
     46 handleBufferModes(struct glCapabilitiesConfig *c, GLint bufferModes)
     47 {
     48     if (bufferModes & kCGLStereoscopicBit) {
     49         c->stereo = true;
     50     }
     51 
     52     if (bufferModes & kCGLDoubleBufferBit) {
     53         c->buffers = 2;
     54     }
     55     else {
     56         c->buffers = 1;
     57     }
     58 }
     59 
     60 static void
     61 handleStencilModes(struct glCapabilitiesConfig *c, GLint smodes)
     62 {
     63     int offset = 0;
     64 
     65     if (kCGL0Bit & smodes)
     66         c->stencil_bit_depths[offset++] = 0;
     67 
     68     if (kCGL1Bit & smodes)
     69         c->stencil_bit_depths[offset++] = 1;
     70 
     71     if (kCGL2Bit & smodes)
     72         c->stencil_bit_depths[offset++] = 2;
     73 
     74     if (kCGL3Bit & smodes)
     75         c->stencil_bit_depths[offset++] = 3;
     76 
     77     if (kCGL4Bit & smodes)
     78         c->stencil_bit_depths[offset++] = 4;
     79 
     80     if (kCGL5Bit & smodes)
     81         c->stencil_bit_depths[offset++] = 5;
     82 
     83     if (kCGL6Bit & smodes)
     84         c->stencil_bit_depths[offset++] = 6;
     85 
     86     if (kCGL8Bit & smodes)
     87         c->stencil_bit_depths[offset++] = 8;
     88 
     89     if (kCGL10Bit & smodes)
     90         c->stencil_bit_depths[offset++] = 10;
     91 
     92     if (kCGL12Bit & smodes)
     93         c->stencil_bit_depths[offset++] = 12;
     94 
     95     if (kCGL16Bit & smodes)
     96         c->stencil_bit_depths[offset++] = 16;
     97 
     98     if (kCGL24Bit & smodes)
     99         c->stencil_bit_depths[offset++] = 24;
    100 
    101     if (kCGL32Bit & smodes)
    102         c->stencil_bit_depths[offset++] = 32;
    103 
    104     if (kCGL48Bit & smodes)
    105         c->stencil_bit_depths[offset++] = 48;
    106 
    107     if (kCGL64Bit & smodes)
    108         c->stencil_bit_depths[offset++] = 64;
    109 
    110     if (kCGL96Bit & smodes)
    111         c->stencil_bit_depths[offset++] = 96;
    112 
    113     if (kCGL128Bit & smodes)
    114         c->stencil_bit_depths[offset++] = 128;
    115 
    116     assert(offset < GLCAPS_STENCIL_BIT_DEPTH_BUFFERS);
    117 
    118     c->total_stencil_bit_depths = offset;
    119 }
    120 
    121 static int
    122 handleColorAndAccumulation(struct glColorBufCapabilities *c,
    123                            GLint cmodes, int forAccum)
    124 {
    125     int offset = 0;
    126 
    127     /*1*/
    128     if (kCGLRGB444Bit & cmodes) {
    129         c[offset].r = 4;
    130         c[offset].g = 4;
    131         c[offset].b = 4;
    132         ++offset;
    133     }
    134 
    135     /*2*/
    136     if (kCGLARGB4444Bit & cmodes) {
    137         c[offset].a = 4;
    138         c[offset].r = 4;
    139         c[offset].g = 4;
    140         c[offset].b = 4;
    141         c[offset].is_argb = true;
    142         ++offset;
    143     }
    144 
    145     /*3*/
    146     if (kCGLRGB444A8Bit & cmodes) {
    147         c[offset].r = 4;
    148         c[offset].g = 4;
    149         c[offset].b = 4;
    150         c[offset].a = 8;
    151         ++offset;
    152     }
    153 
    154     /*4*/
    155     if (kCGLRGB555Bit & cmodes) {
    156         c[offset].r = 5;
    157         c[offset].g = 5;
    158         c[offset].b = 5;
    159         ++offset;
    160     }
    161 
    162     /*5*/
    163     if (kCGLARGB1555Bit & cmodes) {
    164         c[offset].a = 1;
    165         c[offset].r = 5;
    166         c[offset].g = 5;
    167         c[offset].b = 5;
    168         c[offset].is_argb = true;
    169         ++offset;
    170     }
    171 
    172     /*6*/
    173     if (kCGLRGB555A8Bit & cmodes) {
    174         c[offset].r = 5;
    175         c[offset].g = 5;
    176         c[offset].b = 5;
    177         c[offset].a = 8;
    178         ++offset;
    179     }
    180 
    181     /*7*/
    182     if (kCGLRGB565Bit & cmodes) {
    183         c[offset].r = 5;
    184         c[offset].g = 6;
    185         c[offset].b = 5;
    186         ++offset;
    187     }
    188 
    189     /*8*/
    190     if (kCGLRGB565A8Bit & cmodes) {
    191         c[offset].r = 5;
    192         c[offset].g = 6;
    193         c[offset].b = 5;
    194         c[offset].a = 8;
    195         ++offset;
    196     }
    197 
    198     /*9*/
    199     if (kCGLRGB888Bit & cmodes) {
    200         c[offset].r = 8;
    201         c[offset].g = 8;
    202         c[offset].b = 8;
    203         ++offset;
    204     }
    205 
    206     /*10*/
    207     if (kCGLARGB8888Bit & cmodes) {
    208         c[offset].a = 8;
    209         c[offset].r = 8;
    210         c[offset].g = 8;
    211         c[offset].b = 8;
    212         c[offset].is_argb = true;
    213         ++offset;
    214     }
    215 
    216     /*11*/
    217     if (kCGLRGB888A8Bit & cmodes) {
    218         c[offset].r = 8;
    219         c[offset].g = 8;
    220         c[offset].b = 8;
    221         c[offset].a = 8;
    222         ++offset;
    223     }
    224 
    225     if (forAccum) {
    226         //#if 0
    227         /* FIXME
    228          * Disable this path, because some part of libGL, X, or Xplugin
    229          * doesn't work with sizes greater than 8.
    230          * When this is enabled and visuals are chosen using depths
    231          * such as 16, the result is that the windows don't redraw
    232          * and are often white, until a resize.
    233          */
    234 
    235         /*12*/
    236         if (kCGLRGB101010Bit & cmodes) {
    237             c[offset].r = 10;
    238             c[offset].g = 10;
    239             c[offset].b = 10;
    240             ++offset;
    241         }
    242 
    243         /*13*/
    244         if (kCGLARGB2101010Bit & cmodes) {
    245             c[offset].a = 2;
    246             c[offset].r = 10;
    247             c[offset].g = 10;
    248             c[offset].b = 10;
    249             c[offset].is_argb = true;
    250             ++offset;
    251         }
    252 
    253         /*14*/
    254         if (kCGLRGB101010_A8Bit & cmodes) {
    255             c[offset].r = 10;
    256             c[offset].g = 10;
    257             c[offset].b = 10;
    258             c[offset].a = 8;
    259             ++offset;
    260         }
    261 
    262         /*15*/
    263         if (kCGLRGB121212Bit & cmodes) {
    264             c[offset].r = 12;
    265             c[offset].g = 12;
    266             c[offset].b = 12;
    267             ++offset;
    268         }
    269 
    270         /*16*/
    271         if (kCGLARGB12121212Bit & cmodes) {
    272             c[offset].a = 12;
    273             c[offset].r = 12;
    274             c[offset].g = 12;
    275             c[offset].b = 12;
    276             c[offset].is_argb = true;
    277             ++offset;
    278         }
    279 
    280         /*17*/
    281         if (kCGLRGB161616Bit & cmodes) {
    282             c[offset].r = 16;
    283             c[offset].g = 16;
    284             c[offset].b = 16;
    285             ++offset;
    286         }
    287 
    288         /*18*/
    289         if (kCGLRGBA16161616Bit & cmodes) {
    290             c[offset].r = 16;
    291             c[offset].g = 16;
    292             c[offset].b = 16;
    293             c[offset].a = 16;
    294             ++offset;
    295         }
    296     }
    297     //#endif
    298 
    299     /* FIXME should we handle the floating point color modes, and if so, how? */
    300 
    301     return offset;
    302 }
    303 
    304 static void
    305 handleColorModes(struct glCapabilitiesConfig *c, GLint cmodes)
    306 {
    307     c->total_color_buffers = handleColorAndAccumulation(c->color_buffers,
    308                                                         cmodes, 0);
    309 
    310     assert(c->total_color_buffers < GLCAPS_COLOR_BUFFERS);
    311 }
    312 
    313 static void
    314 handleAccumulationModes(struct glCapabilitiesConfig *c, GLint cmodes)
    315 {
    316     c->total_accum_buffers = handleColorAndAccumulation(c->accum_buffers,
    317                                                         cmodes, 1);
    318     assert(c->total_accum_buffers < GLCAPS_COLOR_BUFFERS);
    319 }
    320 
    321 static void
    322 handleDepthModes(struct glCapabilitiesConfig *c, GLint dmodes)
    323 {
    324     int offset = 0;
    325 #define DEPTH(flag, value) do { \
    326         if (dmodes & flag) { \
    327             c->depth_buffers[offset++] = value; \
    328         } \
    329 } while (0)
    330 
    331     /*1*/
    332     DEPTH(kCGL0Bit, 0);
    333     /*2*/
    334     DEPTH(kCGL1Bit, 1);
    335     /*3*/
    336     DEPTH(kCGL2Bit, 2);
    337     /*4*/
    338     DEPTH(kCGL3Bit, 3);
    339     /*5*/
    340     DEPTH(kCGL4Bit, 4);
    341     /*6*/
    342     DEPTH(kCGL5Bit, 5);
    343     /*7*/
    344     DEPTH(kCGL6Bit, 6);
    345     /*8*/
    346     DEPTH(kCGL8Bit, 8);
    347     /*9*/
    348     DEPTH(kCGL10Bit, 10);
    349     /*10*/
    350     DEPTH(kCGL12Bit, 12);
    351     /*11*/
    352     DEPTH(kCGL16Bit, 16);
    353     /*12*/
    354     DEPTH(kCGL24Bit, 24);
    355     /*13*/
    356     DEPTH(kCGL32Bit, 32);
    357     /*14*/
    358     DEPTH(kCGL48Bit, 48);
    359     /*15*/
    360     DEPTH(kCGL64Bit, 64);
    361     /*16*/
    362     DEPTH(kCGL96Bit, 96);
    363     /*17*/
    364     DEPTH(kCGL128Bit, 128);
    365 
    366 #undef DEPTH
    367 
    368     c->total_depth_buffer_depths = offset;
    369     assert(c->total_depth_buffer_depths < GLCAPS_DEPTH_BUFFERS);
    370 }
    371 
    372 /* Return non-zero if an error occurred. */
    373 static CGLError
    374 handleRendererDescriptions(CGLRendererInfoObj info, GLint r,
    375                            struct glCapabilitiesConfig *c)
    376 {
    377     CGLError err;
    378     GLint accelerated = 0, flags = 0, aux = 0, samplebufs = 0, samples = 0;
    379 
    380     err = CGLDescribeRenderer(info, r, kCGLRPAccelerated, &accelerated);
    381 
    382     if (err)
    383         return err;
    384 
    385     c->accelerated = accelerated;
    386 
    387     /* Buffering modes: single/double, stereo */
    388     err = CGLDescribeRenderer(info, r, kCGLRPBufferModes, &flags);
    389 
    390     if (err)
    391         return err;
    392 
    393     handleBufferModes(c, flags);
    394 
    395     /* AUX buffers */
    396     err = CGLDescribeRenderer(info, r, kCGLRPMaxAuxBuffers, &aux);
    397 
    398     if (err)
    399         return err;
    400 
    401     c->aux_buffers = aux;
    402 
    403     /* Depth buffer size */
    404     err = CGLDescribeRenderer(info, r, kCGLRPDepthModes, &flags);
    405 
    406     if (err)
    407         return err;
    408 
    409     handleDepthModes(c, flags);
    410 
    411     /* Multisample buffers */
    412     err = CGLDescribeRenderer(info, r, kCGLRPMaxSampleBuffers, &samplebufs);
    413 
    414     if (err)
    415         return err;
    416 
    417     c->multisample_buffers = samplebufs;
    418 
    419     /* Multisample samples per multisample buffer */
    420     err = CGLDescribeRenderer(info, r, kCGLRPMaxSamples, &samples);
    421 
    422     if (err)
    423         return err;
    424 
    425     c->multisample_samples = samples;
    426 
    427     /* Stencil bit depths */
    428     err = CGLDescribeRenderer(info, r, kCGLRPStencilModes, &flags);
    429 
    430     if (err)
    431         return err;
    432 
    433     handleStencilModes(c, flags);
    434 
    435     /* Color modes (RGB/RGBA depths supported */
    436     err = CGLDescribeRenderer(info, r, kCGLRPColorModes, &flags);
    437 
    438     if (err)
    439         return err;
    440 
    441     handleColorModes(c, flags);
    442 
    443     err = CGLDescribeRenderer(info, r, kCGLRPAccumModes, &flags);
    444 
    445     if (err)
    446         return err;
    447 
    448     handleAccumulationModes(c, flags);
    449 
    450     return kCGLNoError;
    451 }
    452 
    453 static void
    454 initCapabilities(struct glCapabilities *cap)
    455 {
    456     cap->configurations = NULL;
    457     cap->total_configurations = 0;
    458 }
    459 
    460 static void
    461 initConfig(struct glCapabilitiesConfig *c)
    462 {
    463     int i;
    464 
    465     c->accelerated = false;
    466     c->stereo = false;
    467     c->aux_buffers = 0;
    468     c->buffers = 0;
    469 
    470     c->total_depth_buffer_depths = 0;
    471 
    472     for (i = 0; i < GLCAPS_DEPTH_BUFFERS; ++i) {
    473         c->depth_buffers[i] = GLCAPS_INVALID_DEPTH_VALUE;
    474     }
    475 
    476     c->multisample_buffers = 0;
    477     c->multisample_samples = 0;
    478 
    479     c->total_stencil_bit_depths = 0;
    480 
    481     for (i = 0; i < GLCAPS_STENCIL_BIT_DEPTH_BUFFERS; ++i) {
    482         c->stencil_bit_depths[i] = GLCAPS_INVALID_STENCIL_DEPTH;
    483     }
    484 
    485     c->total_color_buffers = 0;
    486 
    487     for (i = 0; i < GLCAPS_COLOR_BUFFERS; ++i) {
    488         c->color_buffers[i].r = c->color_buffers[i].g =
    489                                     c->color_buffers[i].b =
    490                                         c->color_buffers[i].a =
    491                                             GLCAPS_COLOR_BUF_INVALID_VALUE;
    492         c->color_buffers[i].is_argb = false;
    493     }
    494 
    495     c->total_accum_buffers = 0;
    496 
    497     for (i = 0; i < GLCAPS_COLOR_BUFFERS; ++i) {
    498         c->accum_buffers[i].r = c->accum_buffers[i].g =
    499                                     c->accum_buffers[i].b =
    500                                         c->accum_buffers[i].a =
    501                                             GLCAPS_COLOR_BUF_INVALID_VALUE;
    502         c->accum_buffers[i].is_argb = false;
    503     }
    504 
    505     c->next = NULL;
    506 }
    507 
    508 void
    509 freeGlCapabilities(struct glCapabilities *cap)
    510 {
    511     struct glCapabilitiesConfig *conf, *next;
    512 
    513     conf = cap->configurations;
    514 
    515     while (conf) {
    516         next = conf->next;
    517         free(conf);
    518         conf = next;
    519     }
    520 
    521     cap->configurations = NULL;
    522 }
    523 
    524 /* Return true if an error occurred. */
    525 bool
    526 getGlCapabilities(struct glCapabilities *cap)
    527 {
    528     CGLRendererInfoObj info;
    529     CGLError err;
    530     GLint numRenderers = 0, r;
    531 
    532     initCapabilities(cap);
    533 
    534     err = CGLQueryRendererInfo((GLuint) - 1, &info, &numRenderers);
    535     if (err) {
    536         ErrorF("CGLQueryRendererInfo error: %s\n", CGLErrorString(err));
    537         return err;
    538     }
    539 
    540     for (r = 0; r < numRenderers; r++) {
    541         struct glCapabilitiesConfig tmpconf, *conf;
    542 
    543         initConfig(&tmpconf);
    544 
    545         err = handleRendererDescriptions(info, r, &tmpconf);
    546         if (err) {
    547             ErrorF("handleRendererDescriptions returned error: %s\n",
    548                    CGLErrorString(
    549                        err));
    550             ErrorF("trying to continue...\n");
    551             continue;
    552         }
    553 
    554         conf = malloc(sizeof(*conf));
    555         if (NULL == conf) {
    556             FatalError("Unable to allocate memory for OpenGL capabilities\n");
    557         }
    558 
    559         /* Copy the struct. */
    560         *conf = tmpconf;
    561 
    562         /* Now link the configuration into the list. */
    563         conf->next = cap->configurations;
    564         cap->configurations = conf;
    565     }
    566 
    567     CGLDestroyRendererInfo(info);
    568 
    569     /* No error occurred.  We are done. */
    570     return kCGLNoError;
    571 }