Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. /**
  29.  * @file
  30.  *
  31.  * WGL_ARB_pixel_format extension implementation.
  32.  *
  33.  * @sa http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
  34.  */
  35.  
  36.  
  37. #include <windows.h>
  38.  
  39. #define WGL_WGLEXT_PROTOTYPES
  40.  
  41. #include <GL/gl.h>
  42. #include <GL/wglext.h>
  43.  
  44. #include "pipe/p_compiler.h"
  45. #include "util/u_format.h"
  46. #include "util/u_memory.h"
  47. #include "stw_device.h"
  48. #include "stw_pixelformat.h"
  49.  
  50.  
  51. static boolean
  52. stw_query_attrib(
  53.    int iPixelFormat,
  54.    int iLayerPlane,
  55.    int attrib,
  56.    int *pvalue )
  57. {
  58.    uint count;
  59.    const struct stw_pixelformat_info *pfi;
  60.  
  61.    count = stw_pixelformat_get_extended_count();
  62.  
  63.    if (attrib == WGL_NUMBER_PIXEL_FORMATS_ARB) {
  64.       *pvalue = (int) count;
  65.       return TRUE;
  66.    }
  67.  
  68.    pfi = stw_pixelformat_get_info( iPixelFormat );
  69.    if (!pfi) {
  70.       return FALSE;
  71.    }
  72.  
  73.    switch (attrib) {
  74.    case WGL_DRAW_TO_WINDOW_ARB:
  75.       *pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_WINDOW ? TRUE : FALSE;
  76.       return TRUE;
  77.  
  78.    case WGL_DRAW_TO_BITMAP_ARB:
  79.       *pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_BITMAP ? TRUE : FALSE;
  80.       return TRUE;
  81.  
  82.    case WGL_NEED_PALETTE_ARB:
  83.       *pvalue = pfi->pfd.dwFlags & PFD_NEED_PALETTE ? TRUE : FALSE;
  84.       return TRUE;
  85.  
  86.    case WGL_NEED_SYSTEM_PALETTE_ARB:
  87.       *pvalue = pfi->pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE;
  88.       return TRUE;
  89.  
  90.    case WGL_SWAP_METHOD_ARB:
  91.       *pvalue = pfi->pfd.dwFlags & PFD_SWAP_COPY ? WGL_SWAP_COPY_ARB : WGL_SWAP_UNDEFINED_ARB;
  92.       return TRUE;
  93.  
  94.    case WGL_SWAP_LAYER_BUFFERS_ARB:
  95.       *pvalue = FALSE;
  96.       return TRUE;
  97.  
  98.    case WGL_NUMBER_OVERLAYS_ARB:
  99.       *pvalue = 0;
  100.       return TRUE;
  101.  
  102.    case WGL_NUMBER_UNDERLAYS_ARB:
  103.       *pvalue = 0;
  104.       return TRUE;
  105.    }
  106.  
  107.    if (iLayerPlane != 0)
  108.       return FALSE;
  109.  
  110.    switch (attrib) {
  111.    case WGL_ACCELERATION_ARB:
  112.       *pvalue = WGL_FULL_ACCELERATION_ARB;
  113.       break;
  114.  
  115.    case WGL_TRANSPARENT_ARB:
  116.       *pvalue = FALSE;
  117.       break;
  118.  
  119.    case WGL_TRANSPARENT_RED_VALUE_ARB:
  120.    case WGL_TRANSPARENT_GREEN_VALUE_ARB:
  121.    case WGL_TRANSPARENT_BLUE_VALUE_ARB:
  122.    case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
  123.    case WGL_TRANSPARENT_INDEX_VALUE_ARB:
  124.       break;
  125.  
  126.    case WGL_SHARE_DEPTH_ARB:
  127.    case WGL_SHARE_STENCIL_ARB:
  128.    case WGL_SHARE_ACCUM_ARB:
  129.       *pvalue = TRUE;
  130.       break;
  131.  
  132.    case WGL_SUPPORT_GDI_ARB:
  133.       *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_GDI ? TRUE : FALSE;
  134.       break;
  135.  
  136.    case WGL_SUPPORT_OPENGL_ARB:
  137.       *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_OPENGL ? TRUE : FALSE;
  138.       break;
  139.  
  140.    case WGL_DOUBLE_BUFFER_ARB:
  141.       *pvalue = pfi->pfd.dwFlags & PFD_DOUBLEBUFFER ? TRUE : FALSE;
  142.       break;
  143.  
  144.    case WGL_STEREO_ARB:
  145.       *pvalue = pfi->pfd.dwFlags & PFD_STEREO ? TRUE : FALSE;
  146.       break;
  147.  
  148.    case WGL_PIXEL_TYPE_ARB:
  149.       switch (pfi->pfd.iPixelType) {
  150.       case PFD_TYPE_RGBA:
  151.          if (util_format_is_float(pfi->stvis.color_format)) {
  152.             *pvalue = WGL_TYPE_RGBA_FLOAT_ARB;
  153.          }
  154.          else {
  155.             *pvalue = WGL_TYPE_RGBA_ARB;
  156.          }
  157.          break;
  158.       case PFD_TYPE_COLORINDEX:
  159.          *pvalue = WGL_TYPE_COLORINDEX_ARB;
  160.          break;
  161.       default:
  162.          return FALSE;
  163.       }
  164.       break;
  165.  
  166.    case WGL_COLOR_BITS_ARB:
  167.       *pvalue = pfi->pfd.cColorBits;
  168.       break;
  169.  
  170.    case WGL_RED_BITS_ARB:
  171.       *pvalue = pfi->pfd.cRedBits;
  172.       break;
  173.  
  174.    case WGL_RED_SHIFT_ARB:
  175.       *pvalue = pfi->pfd.cRedShift;
  176.       break;
  177.  
  178.    case WGL_GREEN_BITS_ARB:
  179.       *pvalue = pfi->pfd.cGreenBits;
  180.       break;
  181.  
  182.    case WGL_GREEN_SHIFT_ARB:
  183.       *pvalue = pfi->pfd.cGreenShift;
  184.       break;
  185.  
  186.    case WGL_BLUE_BITS_ARB:
  187.       *pvalue = pfi->pfd.cBlueBits;
  188.       break;
  189.  
  190.    case WGL_BLUE_SHIFT_ARB:
  191.       *pvalue = pfi->pfd.cBlueShift;
  192.       break;
  193.  
  194.    case WGL_ALPHA_BITS_ARB:
  195.       *pvalue = pfi->pfd.cAlphaBits;
  196.       break;
  197.  
  198.    case WGL_ALPHA_SHIFT_ARB:
  199.       *pvalue = pfi->pfd.cAlphaShift;
  200.       break;
  201.  
  202.    case WGL_ACCUM_BITS_ARB:
  203.       *pvalue = pfi->pfd.cAccumBits;
  204.       break;
  205.  
  206.    case WGL_ACCUM_RED_BITS_ARB:
  207.       *pvalue = pfi->pfd.cAccumRedBits;
  208.       break;
  209.  
  210.    case WGL_ACCUM_GREEN_BITS_ARB:
  211.       *pvalue = pfi->pfd.cAccumGreenBits;
  212.       break;
  213.  
  214.    case WGL_ACCUM_BLUE_BITS_ARB:
  215.       *pvalue = pfi->pfd.cAccumBlueBits;
  216.       break;
  217.  
  218.    case WGL_ACCUM_ALPHA_BITS_ARB:
  219.       *pvalue = pfi->pfd.cAccumAlphaBits;
  220.       break;
  221.  
  222.    case WGL_DEPTH_BITS_ARB:
  223.       *pvalue = pfi->pfd.cDepthBits;
  224.       break;
  225.  
  226.    case WGL_STENCIL_BITS_ARB:
  227.       *pvalue = pfi->pfd.cStencilBits;
  228.       break;
  229.  
  230.    case WGL_AUX_BUFFERS_ARB:
  231.       *pvalue = pfi->pfd.cAuxBuffers;
  232.       break;
  233.  
  234.    case WGL_SAMPLE_BUFFERS_ARB:
  235.       *pvalue = 1;
  236.       break;
  237.  
  238.    case WGL_SAMPLES_ARB:
  239.       *pvalue = pfi->stvis.samples;
  240.       break;
  241.  
  242.  
  243.    /* WGL_ARB_pbuffer */
  244.  
  245.    case WGL_MAX_PBUFFER_WIDTH_ARB:
  246.    case WGL_MAX_PBUFFER_HEIGHT_ARB:
  247.       *pvalue = stw_dev->max_2d_length;
  248.       break;
  249.  
  250.    case WGL_MAX_PBUFFER_PIXELS_ARB:
  251.       *pvalue = stw_dev->max_2d_length * stw_dev->max_2d_length;
  252.       break;
  253.  
  254.    case WGL_DRAW_TO_PBUFFER_ARB:
  255.       *pvalue = 1;
  256.       break;
  257.  
  258.  
  259.    default:
  260.       return FALSE;
  261.    }
  262.  
  263.    return TRUE;
  264. }
  265.  
  266. struct attrib_match_info
  267. {
  268.    int attribute;
  269.    int weight;
  270.    BOOL exact;
  271. };
  272.  
  273. static const struct attrib_match_info attrib_match[] = {
  274.  
  275.    /* WGL_ARB_pixel_format */
  276.    { WGL_DRAW_TO_WINDOW_ARB,      0, TRUE },
  277.    { WGL_DRAW_TO_BITMAP_ARB,      0, TRUE },
  278.    { WGL_ACCELERATION_ARB,        0, TRUE },
  279.    { WGL_NEED_PALETTE_ARB,        0, TRUE },
  280.    { WGL_NEED_SYSTEM_PALETTE_ARB, 0, TRUE },
  281.    { WGL_SWAP_LAYER_BUFFERS_ARB,  0, TRUE },
  282.    { WGL_SWAP_METHOD_ARB,         0, TRUE },
  283.    { WGL_NUMBER_OVERLAYS_ARB,     4, FALSE },
  284.    { WGL_NUMBER_UNDERLAYS_ARB,    4, FALSE },
  285.    /*{ WGL_SHARE_DEPTH_ARB,         0, TRUE },*/     /* no overlays -- ignore */
  286.    /*{ WGL_SHARE_STENCIL_ARB,       0, TRUE },*/   /* no overlays -- ignore */
  287.    /*{ WGL_SHARE_ACCUM_ARB,         0, TRUE },*/     /* no overlays -- ignore */
  288.    { WGL_SUPPORT_GDI_ARB,         0, TRUE },
  289.    { WGL_SUPPORT_OPENGL_ARB,      0, TRUE },
  290.    { WGL_DOUBLE_BUFFER_ARB,       0, TRUE },
  291.    { WGL_STEREO_ARB,              0, TRUE },
  292.    { WGL_PIXEL_TYPE_ARB,          0, TRUE },
  293.    { WGL_COLOR_BITS_ARB,          1, FALSE },
  294.    { WGL_RED_BITS_ARB,            1, FALSE },
  295.    { WGL_GREEN_BITS_ARB,          1, FALSE },
  296.    { WGL_BLUE_BITS_ARB,           1, FALSE },
  297.    { WGL_ALPHA_BITS_ARB,          1, FALSE },
  298.    { WGL_ACCUM_BITS_ARB,          1, FALSE },
  299.    { WGL_ACCUM_RED_BITS_ARB,      1, FALSE },
  300.    { WGL_ACCUM_GREEN_BITS_ARB,    1, FALSE },
  301.    { WGL_ACCUM_BLUE_BITS_ARB,     1, FALSE },
  302.    { WGL_ACCUM_ALPHA_BITS_ARB,    1, FALSE },
  303.    { WGL_DEPTH_BITS_ARB,          1, FALSE },
  304.    { WGL_STENCIL_BITS_ARB,        1, FALSE },
  305.    { WGL_AUX_BUFFERS_ARB,         2, FALSE },
  306.  
  307.    /* WGL_ARB_multisample */
  308.    { WGL_SAMPLE_BUFFERS_ARB,      2, FALSE },
  309.    { WGL_SAMPLES_ARB,             2, FALSE }
  310. };
  311.  
  312. struct stw_pixelformat_score
  313. {
  314.    int points;
  315.    uint index;
  316. };
  317.  
  318. static BOOL
  319. score_pixelformats(
  320.    struct stw_pixelformat_score *scores,
  321.    uint count,
  322.    int attribute,
  323.    int expected_value )
  324. {
  325.    uint i;
  326.    const struct attrib_match_info *ami = NULL;
  327.    uint index;
  328.  
  329.    /* Find out if a given attribute should be considered for score calculation.
  330.     */
  331.    for (i = 0; i < sizeof( attrib_match ) / sizeof( attrib_match[0] ); i++) {
  332.       if (attrib_match[i].attribute == attribute) {
  333.          ami = &attrib_match[i];
  334.          break;
  335.       }
  336.    }
  337.    if (ami == NULL)
  338.       return TRUE;
  339.  
  340.    /* Iterate all pixelformats, query the requested attribute and calculate
  341.     * score points.
  342.     */
  343.    for (index = 0; index < count; index++) {
  344.       int actual_value;
  345.  
  346.       if (!stw_query_attrib( index + 1, 0, attribute, &actual_value ))
  347.          return FALSE;
  348.  
  349.       if (ami->exact) {
  350.          /* For an exact match criteria, if the actual and expected values differ,
  351.           * the score is set to 0 points, effectively removing the pixelformat
  352.           * from a list of matching pixelformats.
  353.           */
  354.          if (actual_value != expected_value)
  355.             scores[index].points = 0;
  356.       }
  357.       else {
  358.          /* For a minimum match criteria, if the actual value is smaller than the expected
  359.           * value, the pixelformat is rejected (score set to 0). However, if the actual
  360.           * value is bigger, the pixelformat is given a penalty to favour pixelformats that
  361.           * more closely match the expected values.
  362.           */
  363.          if (actual_value < expected_value)
  364.             scores[index].points = 0;
  365.          else if (actual_value > expected_value)
  366.             scores[index].points -= (actual_value - expected_value) * ami->weight;
  367.       }
  368.    }
  369.  
  370.    return TRUE;
  371. }
  372.  
  373. WINGDIAPI BOOL APIENTRY
  374. wglChoosePixelFormatARB(
  375.    HDC hdc,
  376.    const int *piAttribIList,
  377.    const FLOAT *pfAttribFList,
  378.    UINT nMaxFormats,
  379.    int *piFormats,
  380.    UINT *nNumFormats )
  381. {
  382.    uint count;
  383.    struct stw_pixelformat_score *scores;
  384.    uint i;
  385.  
  386.    *nNumFormats = 0;
  387.  
  388.    /* Allocate and initialize pixelformat score table -- better matches
  389.     * have higher scores. Start with a high score and take out penalty
  390.     * points for a mismatch when the match does not have to be exact.
  391.     * Set a score to 0 if there is a mismatch for an exact match criteria.
  392.     */
  393.    count = stw_pixelformat_get_extended_count();
  394.    scores = (struct stw_pixelformat_score *) MALLOC( count * sizeof( struct stw_pixelformat_score ) );
  395.    if (scores == NULL)
  396.       return FALSE;
  397.    for (i = 0; i < count; i++) {
  398.       scores[i].points = 0x7fffffff;
  399.       scores[i].index = i;
  400.    }
  401.  
  402.    /* Given the attribute list calculate a score for each pixelformat.
  403.     */
  404.    if (piAttribIList != NULL) {
  405.       while (*piAttribIList != 0) {
  406.          if (!score_pixelformats( scores, count, piAttribIList[0], piAttribIList[1] )) {
  407.             FREE( scores );
  408.             return FALSE;
  409.          }
  410.          piAttribIList += 2;
  411.       }
  412.    }
  413.    if (pfAttribFList != NULL) {
  414.       while (*pfAttribFList != 0) {
  415.          if (!score_pixelformats( scores, count, (int) pfAttribFList[0], (int) pfAttribFList[1] )) {
  416.             FREE( scores );
  417.             return FALSE;
  418.          }
  419.          pfAttribFList += 2;
  420.       }
  421.    }
  422.  
  423.    /* Bubble-sort the resulting scores. Pixelformats with higher scores go first.
  424.     * TODO: Find out if there are any patent issues with it.
  425.     */
  426.    if (count > 1) {
  427.       uint n = count;
  428.       boolean swapped;
  429.  
  430.       do {
  431.          swapped = FALSE;
  432.          for (i = 1; i < n; i++) {
  433.             if (scores[i - 1].points < scores[i].points) {
  434.                struct stw_pixelformat_score score = scores[i - 1];
  435.  
  436.                scores[i - 1] = scores[i];
  437.                scores[i] = score;
  438.                swapped = TRUE;
  439.             }
  440.          }
  441.          n--;
  442.       }
  443.       while (swapped);
  444.    }
  445.  
  446.    /* Return a list of pixelformats that are the best match.
  447.     * Reject pixelformats with non-positive scores.
  448.     */
  449.    for (i = 0; i < count; i++) {
  450.       if (scores[i].points > 0) {
  451.          if (*nNumFormats < nMaxFormats)
  452.             piFormats[*nNumFormats] = scores[i].index + 1;
  453.          (*nNumFormats)++;
  454.       }
  455.    }
  456.  
  457.    FREE( scores );
  458.    return TRUE;
  459. }
  460.  
  461. WINGDIAPI BOOL APIENTRY
  462. wglGetPixelFormatAttribfvARB(
  463.    HDC hdc,
  464.    int iPixelFormat,
  465.    int iLayerPlane,
  466.    UINT nAttributes,
  467.    const int *piAttributes,
  468.    FLOAT *pfValues )
  469. {
  470.    UINT i;
  471.  
  472.    (void) hdc;
  473.  
  474.    for (i = 0; i < nAttributes; i++) {
  475.       int value;
  476.  
  477.       if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value ))
  478.          return FALSE;
  479.       pfValues[i] = (FLOAT) value;
  480.    }
  481.  
  482.    return TRUE;
  483. }
  484.  
  485. WINGDIAPI BOOL APIENTRY
  486. wglGetPixelFormatAttribivARB(
  487.    HDC hdc,
  488.    int iPixelFormat,
  489.    int iLayerPlane,
  490.    UINT nAttributes,
  491.    const int *piAttributes,
  492.    int *piValues )
  493. {
  494.    UINT i;
  495.  
  496.    (void) hdc;
  497.  
  498.    for (i = 0; i < nAttributes; i++) {
  499.       if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] ))
  500.          return FALSE;
  501.    }
  502.  
  503.    return TRUE;
  504. }
  505.