Path: blob/21.2-virgl/src/gallium/frontends/wgl/stw_ext_pixelformat.c
4561 views
/**************************************************************************1*2* Copyright 2008 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627/**28* @file29*30* WGL_ARB_pixel_format extension implementation.31*32* @sa http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt33*/343536#include <windows.h>3738#define WGL_WGLEXT_PROTOTYPES3940#include <GL/gl.h>41#include <GL/wglext.h>4243#include "pipe/p_compiler.h"44#include "util/format/u_format.h"45#include "util/u_memory.h"46#include "stw_device.h"47#include "stw_pixelformat.h"484950static boolean51stw_query_attrib(HDC hdc, int iPixelFormat, int iLayerPlane, int attrib, int *pvalue)52{53uint count;54const struct stw_pixelformat_info *pfi;5556count = stw_pixelformat_get_extended_count(hdc);5758if (attrib == WGL_NUMBER_PIXEL_FORMATS_ARB) {59*pvalue = (int) count;60return TRUE;61}6263pfi = stw_pixelformat_get_info(iPixelFormat);64if (!pfi) {65return FALSE;66}6768switch (attrib) {69case WGL_DRAW_TO_WINDOW_ARB:70*pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_WINDOW ? TRUE : FALSE;71return TRUE;7273case WGL_DRAW_TO_BITMAP_ARB:74*pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_BITMAP ? TRUE : FALSE;75return TRUE;7677case WGL_NEED_PALETTE_ARB:78*pvalue = pfi->pfd.dwFlags & PFD_NEED_PALETTE ? TRUE : FALSE;79return TRUE;8081case WGL_NEED_SYSTEM_PALETTE_ARB:82*pvalue = pfi->pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE;83return TRUE;8485case WGL_SWAP_METHOD_ARB:86if (pfi->pfd.dwFlags & PFD_SWAP_COPY)87*pvalue = WGL_SWAP_COPY_ARB;88else if (pfi->pfd.dwFlags & PFD_SWAP_EXCHANGE)89*pvalue = WGL_SWAP_EXCHANGE_EXT;90else91*pvalue = WGL_SWAP_UNDEFINED_ARB;92return TRUE;9394case WGL_SWAP_LAYER_BUFFERS_ARB:95*pvalue = FALSE;96return TRUE;9798case WGL_NUMBER_OVERLAYS_ARB:99*pvalue = 0;100return TRUE;101102case WGL_NUMBER_UNDERLAYS_ARB:103*pvalue = 0;104return TRUE;105106case WGL_BIND_TO_TEXTURE_RGB_ARB:107/* WGL_ARB_render_texture */108*pvalue = pfi->bindToTextureRGB;109return TRUE;110111case WGL_BIND_TO_TEXTURE_RGBA_ARB:112/* WGL_ARB_render_texture */113*pvalue = pfi->bindToTextureRGBA;114return TRUE;115}116117if (iLayerPlane != 0)118return FALSE;119120switch (attrib) {121case WGL_ACCELERATION_ARB:122*pvalue = WGL_FULL_ACCELERATION_ARB;123break;124125case WGL_TRANSPARENT_ARB:126*pvalue = FALSE;127break;128129case WGL_TRANSPARENT_RED_VALUE_ARB:130case WGL_TRANSPARENT_GREEN_VALUE_ARB:131case WGL_TRANSPARENT_BLUE_VALUE_ARB:132case WGL_TRANSPARENT_ALPHA_VALUE_ARB:133case WGL_TRANSPARENT_INDEX_VALUE_ARB:134break;135136case WGL_SHARE_DEPTH_ARB:137case WGL_SHARE_STENCIL_ARB:138case WGL_SHARE_ACCUM_ARB:139*pvalue = TRUE;140break;141142case WGL_SUPPORT_GDI_ARB:143*pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_GDI ? TRUE : FALSE;144break;145146case WGL_SUPPORT_OPENGL_ARB:147*pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_OPENGL ? TRUE : FALSE;148break;149150case WGL_DOUBLE_BUFFER_ARB:151*pvalue = pfi->pfd.dwFlags & PFD_DOUBLEBUFFER ? TRUE : FALSE;152break;153154case WGL_STEREO_ARB:155*pvalue = pfi->pfd.dwFlags & PFD_STEREO ? TRUE : FALSE;156break;157158case WGL_PIXEL_TYPE_ARB:159switch (pfi->pfd.iPixelType) {160case PFD_TYPE_RGBA:161if (util_format_is_float(pfi->stvis.color_format)) {162*pvalue = WGL_TYPE_RGBA_FLOAT_ARB;163}164else {165*pvalue = WGL_TYPE_RGBA_ARB;166}167break;168case PFD_TYPE_COLORINDEX:169*pvalue = WGL_TYPE_COLORINDEX_ARB;170break;171default:172return FALSE;173}174break;175176case WGL_COLOR_BITS_ARB:177*pvalue = pfi->pfd.cColorBits;178break;179180case WGL_RED_BITS_ARB:181*pvalue = pfi->pfd.cRedBits;182break;183184case WGL_RED_SHIFT_ARB:185*pvalue = pfi->pfd.cRedShift;186break;187188case WGL_GREEN_BITS_ARB:189*pvalue = pfi->pfd.cGreenBits;190break;191192case WGL_GREEN_SHIFT_ARB:193*pvalue = pfi->pfd.cGreenShift;194break;195196case WGL_BLUE_BITS_ARB:197*pvalue = pfi->pfd.cBlueBits;198break;199200case WGL_BLUE_SHIFT_ARB:201*pvalue = pfi->pfd.cBlueShift;202break;203204case WGL_ALPHA_BITS_ARB:205*pvalue = pfi->pfd.cAlphaBits;206break;207208case WGL_ALPHA_SHIFT_ARB:209*pvalue = pfi->pfd.cAlphaShift;210break;211212case WGL_ACCUM_BITS_ARB:213*pvalue = pfi->pfd.cAccumBits;214break;215216case WGL_ACCUM_RED_BITS_ARB:217*pvalue = pfi->pfd.cAccumRedBits;218break;219220case WGL_ACCUM_GREEN_BITS_ARB:221*pvalue = pfi->pfd.cAccumGreenBits;222break;223224case WGL_ACCUM_BLUE_BITS_ARB:225*pvalue = pfi->pfd.cAccumBlueBits;226break;227228case WGL_ACCUM_ALPHA_BITS_ARB:229*pvalue = pfi->pfd.cAccumAlphaBits;230break;231232case WGL_DEPTH_BITS_ARB:233*pvalue = pfi->pfd.cDepthBits;234break;235236case WGL_STENCIL_BITS_ARB:237*pvalue = pfi->pfd.cStencilBits;238break;239240case WGL_AUX_BUFFERS_ARB:241*pvalue = pfi->pfd.cAuxBuffers;242break;243244case WGL_SAMPLE_BUFFERS_ARB:245*pvalue = (pfi->stvis.samples > 1);246break;247248case WGL_SAMPLES_ARB:249*pvalue = pfi->stvis.samples;250break;251252253/* WGL_ARB_pbuffer */254255case WGL_MAX_PBUFFER_WIDTH_ARB:256case WGL_MAX_PBUFFER_HEIGHT_ARB:257*pvalue = stw_dev->max_2d_length;258break;259260case WGL_MAX_PBUFFER_PIXELS_ARB:261*pvalue = stw_dev->max_2d_length * stw_dev->max_2d_length;262break;263264case WGL_DRAW_TO_PBUFFER_ARB:265*pvalue = 1;266break;267268269default:270return FALSE;271}272273return TRUE;274}275276struct attrib_match_info277{278int attribute;279int weight;280BOOL exact;281};282283static const struct attrib_match_info attrib_match[] = {284/* WGL_ARB_pixel_format */285{ WGL_DRAW_TO_WINDOW_ARB, 0, TRUE },286{ WGL_DRAW_TO_BITMAP_ARB, 0, TRUE },287{ WGL_ACCELERATION_ARB, 0, TRUE },288{ WGL_NEED_PALETTE_ARB, 0, TRUE },289{ WGL_NEED_SYSTEM_PALETTE_ARB, 0, TRUE },290{ WGL_SWAP_LAYER_BUFFERS_ARB, 0, TRUE },291{ WGL_SWAP_METHOD_ARB, 0, TRUE },292{ WGL_NUMBER_OVERLAYS_ARB, 4, FALSE },293{ WGL_NUMBER_UNDERLAYS_ARB, 4, FALSE },294/*{ WGL_SHARE_DEPTH_ARB, 0, TRUE },*/ /* no overlays -- ignore */295/*{ WGL_SHARE_STENCIL_ARB, 0, TRUE },*/ /* no overlays -- ignore */296/*{ WGL_SHARE_ACCUM_ARB, 0, TRUE },*/ /* no overlays -- ignore */297{ WGL_SUPPORT_GDI_ARB, 0, TRUE },298{ WGL_SUPPORT_OPENGL_ARB, 0, TRUE },299{ WGL_DOUBLE_BUFFER_ARB, 0, TRUE },300{ WGL_STEREO_ARB, 0, TRUE },301{ WGL_PIXEL_TYPE_ARB, 0, TRUE },302{ WGL_COLOR_BITS_ARB, 1, FALSE },303{ WGL_RED_BITS_ARB, 1, FALSE },304{ WGL_GREEN_BITS_ARB, 1, FALSE },305{ WGL_BLUE_BITS_ARB, 1, FALSE },306{ WGL_ALPHA_BITS_ARB, 1, FALSE },307{ WGL_ACCUM_BITS_ARB, 1, FALSE },308{ WGL_ACCUM_RED_BITS_ARB, 1, FALSE },309{ WGL_ACCUM_GREEN_BITS_ARB, 1, FALSE },310{ WGL_ACCUM_BLUE_BITS_ARB, 1, FALSE },311{ WGL_ACCUM_ALPHA_BITS_ARB, 1, FALSE },312{ WGL_DEPTH_BITS_ARB, 1, FALSE },313{ WGL_STENCIL_BITS_ARB, 1, FALSE },314{ WGL_AUX_BUFFERS_ARB, 2, FALSE },315316/* WGL_ARB_multisample */317{ WGL_SAMPLE_BUFFERS_ARB, 2, FALSE },318{ WGL_SAMPLES_ARB, 2, FALSE },319320/* WGL_ARB_render_texture */321{ WGL_BIND_TO_TEXTURE_RGB_ARB, 0, FALSE },322{ WGL_BIND_TO_TEXTURE_RGBA_ARB, 0, FALSE },323};324325struct stw_pixelformat_score326{327int points;328uint index;329};330331332static BOOL333score_pixelformats(HDC hdc,334struct stw_pixelformat_score *scores,335uint count,336int attribute,337int expected_value)338{339uint i;340const struct attrib_match_info *ami = NULL;341uint index;342343/* Find out if a given attribute should be considered for score calculation.344*/345for (i = 0; i < ARRAY_SIZE(attrib_match); i++) {346if (attrib_match[i].attribute == attribute) {347ami = &attrib_match[i];348break;349}350}351if (ami == NULL)352return TRUE;353354/* Iterate all pixelformats, query the requested attribute and calculate355* score points.356*/357for (index = 0; index < count; index++) {358int actual_value;359360if (!stw_query_attrib(hdc, index + 1, 0, attribute, &actual_value))361return FALSE;362363if (ami->exact) {364/* For an exact match criteria, if the actual and expected values365* differ, the score is set to 0 points, effectively removing the366* pixelformat from a list of matching pixelformats.367*/368if (actual_value != expected_value)369scores[index].points = 0;370}371else {372/* For a minimum match criteria, if the actual value is smaller than373* the expected value, the pixelformat is rejected (score set to374* 0). However, if the actual value is bigger, the pixelformat is375* given a penalty to favour pixelformats that more closely match the376* expected values.377*/378if (actual_value < expected_value)379scores[index].points = 0;380else if (actual_value > expected_value)381scores[index].points -= (actual_value - expected_value)382* ami->weight;383}384}385386return TRUE;387}388389390WINGDIAPI BOOL APIENTRY391wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList,392const FLOAT *pfAttribFList, UINT nMaxFormats,393int *piFormats, UINT *nNumFormats)394{395uint count;396struct stw_pixelformat_score *scores;397uint i;398399*nNumFormats = 0;400401/* Allocate and initialize pixelformat score table -- better matches402* have higher scores. Start with a high score and take out penalty403* points for a mismatch when the match does not have to be exact.404* Set a score to 0 if there is a mismatch for an exact match criteria.405*/406count = stw_pixelformat_get_extended_count(hdc);407scores = (struct stw_pixelformat_score *)408MALLOC(count * sizeof(struct stw_pixelformat_score));409if (scores == NULL)410return FALSE;411for (i = 0; i < count; i++) {412scores[i].points = 0x7fffffff;413scores[i].index = i;414}415416/* Given the attribute list calculate a score for each pixelformat.417*/418if (piAttribIList != NULL) {419while (*piAttribIList != 0) {420if (!score_pixelformats(hdc, scores, count, piAttribIList[0],421piAttribIList[1])) {422FREE(scores);423return FALSE;424}425piAttribIList += 2;426}427}428if (pfAttribFList != NULL) {429while (*pfAttribFList != 0) {430if (!score_pixelformats(hdc, scores, count, (int) pfAttribFList[0],431(int) pfAttribFList[1])) {432FREE(scores);433return FALSE;434}435pfAttribFList += 2;436}437}438439/* Bubble-sort the resulting scores. Pixelformats with higher scores go440* first. TODO: Find out if there are any patent issues with it.441*/442if (count > 1) {443uint n = count;444boolean swapped;445446do {447swapped = FALSE;448for (i = 1; i < n; i++) {449if (scores[i - 1].points < scores[i].points) {450struct stw_pixelformat_score score = scores[i - 1];451452scores[i - 1] = scores[i];453scores[i] = score;454swapped = TRUE;455}456}457n--;458}459while (swapped);460}461462/* Return a list of pixelformats that are the best match.463* Reject pixelformats with non-positive scores.464*/465for (i = 0; i < count; i++) {466if (scores[i].points > 0) {467piFormats[*nNumFormats] = scores[i].index + 1;468(*nNumFormats)++;469if (*nNumFormats >= nMaxFormats) {470break;471}472}473}474475FREE(scores);476return TRUE;477}478479480WINGDIAPI BOOL APIENTRY481wglGetPixelFormatAttribfvARB(HDC hdc, int iPixelFormat, int iLayerPlane,482UINT nAttributes, const int *piAttributes,483FLOAT *pfValues)484{485UINT i;486487for (i = 0; i < nAttributes; i++) {488int value = 0;489490if (!stw_query_attrib(hdc, iPixelFormat, iLayerPlane,491piAttributes[i], &value))492return FALSE;493pfValues[i] = (FLOAT) value;494}495496return TRUE;497}498499500WINGDIAPI BOOL APIENTRY501wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane,502UINT nAttributes, const int *piAttributes,503int *piValues)504{505UINT i;506507for (i = 0; i < nAttributes; i++) {508if (!stw_query_attrib(hdc, iPixelFormat, iLayerPlane,509piAttributes[i], &piValues[i]))510return FALSE;511}512513return TRUE;514}515516517