stw_wgl_arbpixelformat.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  *
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  *
00026  **************************************************************************/
00027 
00028 #include <windows.h>
00029 
00030 #include "pipe/p_compiler.h"
00031 #include "util/u_memory.h"
00032 #include "stw_pixelformat.h"
00033 #include "stw_wgl_arbmultisample.h"
00034 #include "stw_wgl_arbpixelformat.h"
00035 
00036 #define WGL_NUMBER_PIXEL_FORMATS_ARB            0x2000
00037 #define WGL_DRAW_TO_WINDOW_ARB                  0x2001
00038 #define WGL_DRAW_TO_BITMAP_ARB                  0x2002
00039 #define WGL_ACCELERATION_ARB                    0x2003
00040 #define WGL_NEED_PALETTE_ARB                    0x2004
00041 #define WGL_NEED_SYSTEM_PALETTE_ARB             0x2005
00042 #define WGL_SWAP_LAYER_BUFFERS_ARB              0x2006
00043 #define WGL_SWAP_METHOD_ARB                     0x2007
00044 #define WGL_NUMBER_OVERLAYS_ARB                 0x2008
00045 #define WGL_NUMBER_UNDERLAYS_ARB                0x2009
00046 #define WGL_TRANSPARENT_ARB                     0x200A
00047 #define WGL_TRANSPARENT_RED_VALUE_ARB           0x2037
00048 #define WGL_TRANSPARENT_GREEN_VALUE_ARB         0x2038
00049 #define WGL_TRANSPARENT_BLUE_VALUE_ARB          0x2039
00050 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB         0x203A
00051 #define WGL_TRANSPARENT_INDEX_VALUE_ARB         0x203B
00052 #define WGL_SHARE_DEPTH_ARB                     0x200C
00053 #define WGL_SHARE_STENCIL_ARB                   0x200D
00054 #define WGL_SHARE_ACCUM_ARB                     0x200E
00055 #define WGL_SUPPORT_GDI_ARB                     0x200F
00056 #define WGL_SUPPORT_OPENGL_ARB                  0x2010
00057 #define WGL_DOUBLE_BUFFER_ARB                   0x2011
00058 #define WGL_STEREO_ARB                          0x2012
00059 #define WGL_PIXEL_TYPE_ARB                      0x2013
00060 #define WGL_COLOR_BITS_ARB                      0x2014
00061 #define WGL_RED_BITS_ARB                        0x2015
00062 #define WGL_RED_SHIFT_ARB                       0x2016
00063 #define WGL_GREEN_BITS_ARB                      0x2017
00064 #define WGL_GREEN_SHIFT_ARB                     0x2018
00065 #define WGL_BLUE_BITS_ARB                       0x2019
00066 #define WGL_BLUE_SHIFT_ARB                      0x201A
00067 #define WGL_ALPHA_BITS_ARB                      0x201B
00068 #define WGL_ALPHA_SHIFT_ARB                     0x201C
00069 #define WGL_ACCUM_BITS_ARB                      0x201D
00070 #define WGL_ACCUM_RED_BITS_ARB                  0x201E
00071 #define WGL_ACCUM_GREEN_BITS_ARB                0x201F
00072 #define WGL_ACCUM_BLUE_BITS_ARB                 0x2020
00073 #define WGL_ACCUM_ALPHA_BITS_ARB                0x2021
00074 #define WGL_DEPTH_BITS_ARB                      0x2022
00075 #define WGL_STENCIL_BITS_ARB                    0x2023
00076 #define WGL_AUX_BUFFERS_ARB                     0x2024
00077 
00078 #define WGL_NO_ACCELERATION_ARB                 0x2025
00079 #define WGL_GENERIC_ACCELERATION_ARB            0x2026
00080 #define WGL_FULL_ACCELERATION_ARB               0x2027
00081 
00082 #define WGL_SWAP_EXCHANGE_ARB                   0x2028
00083 #define WGL_SWAP_COPY_ARB                       0x2029
00084 #define WGL_SWAP_UNDEFINED_ARB                  0x202A
00085 
00086 #define WGL_TYPE_RGBA_ARB                       0x202B
00087 #define WGL_TYPE_COLORINDEX_ARB                 0x202C
00088 
00089 static boolean
00090 query_attrib(
00091    int iPixelFormat,
00092    int iLayerPlane,
00093    int attrib,
00094    int *pvalue )
00095 {
00096    uint count;
00097    uint index;
00098    const struct pixelformat_info *pf;
00099 
00100    count = pixelformat_get_extended_count();
00101 
00102    if (attrib == WGL_NUMBER_PIXEL_FORMATS_ARB) {
00103       *pvalue = (int) count;
00104       return TRUE;
00105    }
00106 
00107    index = (uint) iPixelFormat - 1;
00108    if (index >= count)
00109       return FALSE;
00110 
00111    pf = pixelformat_get_info( index );
00112 
00113    switch (attrib) {
00114    case WGL_DRAW_TO_WINDOW_ARB:
00115       *pvalue = TRUE;
00116       return TRUE;
00117 
00118    case WGL_DRAW_TO_BITMAP_ARB:
00119       *pvalue = FALSE;
00120       return TRUE;
00121 
00122    case WGL_NEED_PALETTE_ARB:
00123       *pvalue = FALSE;
00124       return TRUE;
00125 
00126    case WGL_NEED_SYSTEM_PALETTE_ARB:
00127       *pvalue = FALSE;
00128       return TRUE;
00129 
00130    case WGL_SWAP_METHOD_ARB:
00131       if (pf->flags & PF_FLAG_DOUBLEBUFFER)
00132          *pvalue = WGL_SWAP_COPY_ARB;
00133       else
00134          *pvalue = WGL_SWAP_UNDEFINED_ARB;
00135       return TRUE;
00136 
00137    case WGL_SWAP_LAYER_BUFFERS_ARB:
00138       *pvalue = FALSE;
00139       return TRUE;
00140 
00141    case WGL_NUMBER_OVERLAYS_ARB:
00142       *pvalue = 0;
00143       return TRUE;
00144 
00145    case WGL_NUMBER_UNDERLAYS_ARB:
00146       *pvalue = 0;
00147       return TRUE;
00148    }
00149 
00150    if (iLayerPlane != 0)
00151       return FALSE;
00152 
00153    switch (attrib) {
00154    case WGL_ACCELERATION_ARB:
00155       *pvalue = WGL_FULL_ACCELERATION_ARB;
00156       break;
00157 
00158    case WGL_TRANSPARENT_ARB:
00159       *pvalue = FALSE;
00160       break;
00161 
00162    case WGL_TRANSPARENT_RED_VALUE_ARB:
00163    case WGL_TRANSPARENT_GREEN_VALUE_ARB:
00164    case WGL_TRANSPARENT_BLUE_VALUE_ARB:
00165    case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
00166    case WGL_TRANSPARENT_INDEX_VALUE_ARB:
00167       break;
00168 
00169    case WGL_SHARE_DEPTH_ARB:
00170    case WGL_SHARE_STENCIL_ARB:
00171    case WGL_SHARE_ACCUM_ARB:
00172       *pvalue = TRUE;
00173       break;
00174 
00175    case WGL_SUPPORT_GDI_ARB:
00176       *pvalue = FALSE;
00177       break;
00178 
00179    case WGL_SUPPORT_OPENGL_ARB:
00180       *pvalue = TRUE;
00181       break;
00182 
00183    case WGL_DOUBLE_BUFFER_ARB:
00184       if (pf->flags & PF_FLAG_DOUBLEBUFFER)
00185          *pvalue = TRUE;
00186       else
00187          *pvalue = FALSE;
00188       break;
00189 
00190    case WGL_STEREO_ARB:
00191       *pvalue = FALSE;
00192       break;
00193 
00194    case WGL_PIXEL_TYPE_ARB:
00195       *pvalue = WGL_TYPE_RGBA_ARB;
00196       break;
00197 
00198    case WGL_COLOR_BITS_ARB:
00199       *pvalue = (int) (pf->color.redbits + pf->color.greenbits + pf->color.bluebits);
00200       break;
00201 
00202    case WGL_RED_BITS_ARB:
00203       *pvalue = (int) pf->color.redbits;
00204       break;
00205 
00206    case WGL_RED_SHIFT_ARB:
00207       *pvalue = (int) pf->color.redshift;
00208       break;
00209 
00210    case WGL_GREEN_BITS_ARB:
00211       *pvalue = (int) pf->color.greenbits;
00212       break;
00213 
00214    case WGL_GREEN_SHIFT_ARB:
00215       *pvalue = (int) pf->color.greenshift;
00216       break;
00217 
00218    case WGL_BLUE_BITS_ARB:
00219       *pvalue = (int) pf->color.bluebits;
00220       break;
00221 
00222    case WGL_BLUE_SHIFT_ARB:
00223       *pvalue = (int) pf->color.blueshift;
00224       break;
00225 
00226    case WGL_ALPHA_BITS_ARB:
00227       *pvalue = (int) pf->alpha.alphabits;
00228       break;
00229 
00230    case WGL_ALPHA_SHIFT_ARB:
00231       *pvalue = (int) pf->alpha.alphashift;
00232       break;
00233 
00234    case WGL_ACCUM_BITS_ARB:
00235    case WGL_ACCUM_RED_BITS_ARB:
00236    case WGL_ACCUM_GREEN_BITS_ARB:
00237    case WGL_ACCUM_BLUE_BITS_ARB:
00238    case WGL_ACCUM_ALPHA_BITS_ARB:
00239       *pvalue = 0;
00240       break;
00241 
00242    case WGL_DEPTH_BITS_ARB:
00243       *pvalue = (int) pf->depth.depthbits;
00244       break;
00245 
00246    case WGL_STENCIL_BITS_ARB:
00247       *pvalue = (int) pf->depth.stencilbits;
00248       break;
00249 
00250    case WGL_AUX_BUFFERS_ARB:
00251       *pvalue = 0;
00252       break;
00253 
00254    case WGL_SAMPLE_BUFFERS_ARB:
00255       if (pf->flags & PF_FLAG_MULTISAMPLED)
00256          *pvalue = wgl_query_sample_buffers();
00257       else
00258          *pvalue = 0;
00259       break;
00260 
00261    case WGL_SAMPLES_ARB:
00262       if (pf->flags & PF_FLAG_MULTISAMPLED)
00263          *pvalue = wgl_query_samples();
00264       else
00265          *pvalue = 0;
00266       break;
00267 
00268    default:
00269       return FALSE;
00270    }
00271 
00272    return TRUE;
00273 }
00274 
00275 struct attrib_match_info
00276 {
00277    int attribute;
00278    int weight;
00279    BOOL exact;
00280 };
00281 
00282 static struct attrib_match_info attrib_match[] = {
00283 
00284    /* WGL_ARB_pixel_format */
00285    { WGL_DRAW_TO_WINDOW_ARB,      0, TRUE },
00286    { WGL_DRAW_TO_BITMAP_ARB,      0, TRUE },
00287    { WGL_ACCELERATION_ARB,        0, TRUE },
00288    { WGL_NEED_PALETTE_ARB,        0, TRUE },
00289    { WGL_NEED_SYSTEM_PALETTE_ARB, 0, TRUE },
00290    { WGL_SWAP_LAYER_BUFFERS_ARB,  0, TRUE },
00291    { WGL_SWAP_METHOD_ARB,         0, TRUE },
00292    { WGL_NUMBER_OVERLAYS_ARB,     4, FALSE },
00293    { WGL_NUMBER_UNDERLAYS_ARB,    4, FALSE },
00294    /*{ WGL_SHARE_DEPTH_ARB,         0, TRUE },*/     /* no overlays -- ignore */
00295    /*{ WGL_SHARE_STENCIL_ARB,       0, TRUE },*/   /* no overlays -- ignore */
00296    /*{ WGL_SHARE_ACCUM_ARB,         0, TRUE },*/     /* no overlays -- ignore */
00297    { WGL_SUPPORT_GDI_ARB,         0, TRUE },
00298    { WGL_SUPPORT_OPENGL_ARB,      0, TRUE },
00299    { WGL_DOUBLE_BUFFER_ARB,       0, TRUE },
00300    { WGL_STEREO_ARB,              0, TRUE },
00301    { WGL_PIXEL_TYPE_ARB,          0, TRUE },
00302    { WGL_COLOR_BITS_ARB,          1, FALSE },
00303    { WGL_RED_BITS_ARB,            1, FALSE },
00304    { WGL_GREEN_BITS_ARB,          1, FALSE },
00305    { WGL_BLUE_BITS_ARB,           1, FALSE },
00306    { WGL_ALPHA_BITS_ARB,          1, FALSE },
00307    { WGL_ACCUM_BITS_ARB,          1, FALSE },
00308    { WGL_ACCUM_RED_BITS_ARB,      1, FALSE },
00309    { WGL_ACCUM_GREEN_BITS_ARB,    1, FALSE },
00310    { WGL_ACCUM_BLUE_BITS_ARB,     1, FALSE },
00311    { WGL_ACCUM_ALPHA_BITS_ARB,    1, FALSE },
00312    { WGL_DEPTH_BITS_ARB,          1, FALSE },
00313    { WGL_STENCIL_BITS_ARB,        1, FALSE },
00314    { WGL_AUX_BUFFERS_ARB,         2, FALSE },
00315 
00316    /* WGL_ARB_multisample */
00317    { WGL_SAMPLE_BUFFERS_ARB,      2, FALSE },
00318    { WGL_SAMPLES_ARB,             2, FALSE }
00319 };
00320 
00321 struct pixelformat_score
00322 {
00323    int points;
00324    uint index;
00325 };
00326 
00327 static BOOL
00328 score_pixelformats(
00329    struct pixelformat_score *scores,
00330    uint count,
00331    int attribute,
00332    int expected_value )
00333 {
00334    uint i;
00335    struct attrib_match_info *ami = NULL;
00336    uint index;
00337 
00338    /* Find out if a given attribute should be considered for score calculation.
00339     */
00340    for (i = 0; i < sizeof( attrib_match ) / sizeof( attrib_match[0] ); i++) {
00341       if (attrib_match[i].attribute == attribute) {
00342          ami = &attrib_match[i];
00343          break;
00344       }
00345    }
00346    if (ami == NULL)
00347       return TRUE;
00348 
00349    /* Iterate all pixelformats, query the requested attribute and calculate
00350     * score points.
00351     */
00352    for (index = 0; index < count; index++) {
00353       int actual_value;
00354 
00355       if (!query_attrib( index + 1, 0, attribute, &actual_value ))
00356          return FALSE;
00357 
00358       if (ami->exact) {
00359          /* For an exact match criteria, if the actual and expected values differ,
00360           * the score is set to 0 points, effectively removing the pixelformat
00361           * from a list of matching pixelformats.
00362           */
00363          if (actual_value != expected_value)
00364             scores[index].points = 0;
00365       }
00366       else {
00367          /* For a minimum match criteria, if the actual value is smaller than the expected
00368           * value, the pixelformat is rejected (score set to 0). However, if the actual
00369           * value is bigger, the pixelformat is given a penalty to favour pixelformats that
00370           * more closely match the expected values.
00371           */
00372          if (actual_value < expected_value)
00373             scores[index].points = 0;
00374          else if (actual_value > expected_value)
00375             scores[index].points -= (actual_value - expected_value) * ami->weight;
00376       }
00377    }
00378 
00379    return TRUE;
00380 }
00381 
00382 WINGDIAPI BOOL APIENTRY
00383 wglChoosePixelFormatARB(
00384    HDC hdc,
00385    const int *piAttribIList,
00386    const FLOAT *pfAttribFList,
00387    UINT nMaxFormats,
00388    int *piFormats,
00389    UINT *nNumFormats )
00390 {
00391    uint count;
00392    struct pixelformat_score *scores;
00393    uint i;
00394 
00395    *nNumFormats = 0;
00396 
00397    /* Allocate and initialize pixelformat score table -- better matches
00398     * have higher scores. Start with a high score and take out penalty
00399     * points for a mismatch when the match does not have to be exact.
00400     * Set a score to 0 if there is a mismatch for an exact match criteria.
00401     */
00402    count = pixelformat_get_extended_count();
00403    scores = (struct pixelformat_score *) MALLOC( count * sizeof( struct pixelformat_score ) );
00404    if (scores == NULL)
00405       return FALSE;
00406    for (i = 0; i < count; i++) {
00407       scores[i].points = 0x7fffffff;
00408       scores[i].index = i;
00409    }
00410 
00411    /* Given the attribute list calculate a score for each pixelformat.
00412     */
00413    if (piAttribIList != NULL) {
00414       while (*piAttribIList != 0) {
00415          if (!score_pixelformats( scores, count, piAttribIList[0], piAttribIList[1] )) {
00416             FREE( scores );
00417             return FALSE;
00418          }
00419          piAttribIList += 2;
00420       }
00421    }
00422    if (pfAttribFList != NULL) {
00423       while (*pfAttribFList != 0) {
00424          if (!score_pixelformats( scores, count, (int) pfAttribFList[0], (int) pfAttribFList[1] )) {
00425             FREE( scores );
00426             return FALSE;
00427          }
00428          pfAttribFList += 2;
00429       }
00430    }
00431 
00432    /* Bubble-sort the resulting scores. Pixelformats with higher scores go first.
00433     * TODO: Find out if there are any patent issues with it.
00434     */
00435    if (count > 1) {
00436       uint n = count;
00437       boolean swapped;
00438 
00439       do {
00440          swapped = FALSE;
00441          for (i = 1; i < n; i++) {
00442             if (scores[i - 1].points < scores[i].points) {
00443                struct pixelformat_score score = scores[i - 1];
00444 
00445                scores[i - 1] = scores[i];
00446                scores[i] = score;
00447                swapped = TRUE;
00448             }
00449          }
00450          n--;
00451       }
00452       while (swapped);
00453    }
00454 
00455    /* Return a list of pixelformats that are the best match.
00456     * Reject pixelformats with non-positive scores.
00457     */
00458    for (i = 0; i < count; i++) {
00459       if (scores[i].points > 0) {
00460          if (*nNumFormats < nMaxFormats)
00461             piFormats[*nNumFormats] = scores[i].index + 1;
00462          (*nNumFormats)++;
00463       }
00464    }
00465 
00466    FREE( scores );
00467    return TRUE;
00468 }
00469 
00470 WINGDIAPI BOOL APIENTRY
00471 wglGetPixelFormatAttribfvARB(
00472    HDC hdc,
00473    int iPixelFormat,
00474    int iLayerPlane,
00475    UINT nAttributes,
00476    const int *piAttributes,
00477    FLOAT *pfValues )
00478 {
00479    UINT i;
00480 
00481    (void) hdc;
00482 
00483    for (i = 0; i < nAttributes; i++) {
00484       int value;
00485 
00486       if (!query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value ))
00487          return FALSE;
00488       pfValues[i] = (FLOAT) value;
00489    }
00490 
00491    return TRUE;
00492 }
00493 
00494 WINGDIAPI BOOL APIENTRY
00495 wglGetPixelFormatAttribivARB(
00496    HDC hdc,
00497    int iPixelFormat,
00498    int iLayerPlane,
00499    UINT nAttributes,
00500    const int *piAttributes,
00501    int *piValues )
00502 {
00503    UINT i;
00504 
00505    (void) hdc;
00506 
00507    for (i = 0; i < nAttributes; i++) {
00508       if (!query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] ))
00509          return FALSE;
00510    }
00511 
00512    return TRUE;
00513 }

Generated on Tue Sep 29 06:25:18 2009 for Gallium3D by  doxygen 1.5.4