1
/**************************************************************************
3
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
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.
26
**************************************************************************/
31
* WGL_ARB_pixel_format extension implementation.
33
* @sa http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
39
#define WGL_WGLEXT_PROTOTYPES
42
#include <GL/wglext.h>
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"
59
const struct stw_pixelformat_info *pfi;
61
count = stw_pixelformat_get_extended_count();
63
if (attrib == WGL_NUMBER_PIXEL_FORMATS_ARB) {
64
*pvalue = (int) count;
68
pfi = stw_pixelformat_get_info( iPixelFormat );
74
case WGL_DRAW_TO_WINDOW_ARB:
75
*pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_WINDOW ? TRUE : FALSE;
78
case WGL_DRAW_TO_BITMAP_ARB:
79
*pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_BITMAP ? TRUE : FALSE;
82
case WGL_NEED_PALETTE_ARB:
83
*pvalue = pfi->pfd.dwFlags & PFD_NEED_PALETTE ? TRUE : FALSE;
86
case WGL_NEED_SYSTEM_PALETTE_ARB:
87
*pvalue = pfi->pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE;
90
case WGL_SWAP_METHOD_ARB:
91
*pvalue = pfi->pfd.dwFlags & PFD_SWAP_COPY ? WGL_SWAP_COPY_ARB : WGL_SWAP_UNDEFINED_ARB;
94
case WGL_SWAP_LAYER_BUFFERS_ARB:
98
case WGL_NUMBER_OVERLAYS_ARB:
102
case WGL_NUMBER_UNDERLAYS_ARB:
107
if (iLayerPlane != 0)
111
case WGL_ACCELERATION_ARB:
112
*pvalue = WGL_FULL_ACCELERATION_ARB;
115
case WGL_TRANSPARENT_ARB:
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:
126
case WGL_SHARE_DEPTH_ARB:
127
case WGL_SHARE_STENCIL_ARB:
128
case WGL_SHARE_ACCUM_ARB:
132
case WGL_SUPPORT_GDI_ARB:
133
*pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_GDI ? TRUE : FALSE;
136
case WGL_SUPPORT_OPENGL_ARB:
137
*pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_OPENGL ? TRUE : FALSE;
140
case WGL_DOUBLE_BUFFER_ARB:
141
*pvalue = pfi->pfd.dwFlags & PFD_DOUBLEBUFFER ? TRUE : FALSE;
145
*pvalue = pfi->pfd.dwFlags & PFD_STEREO ? TRUE : FALSE;
148
case WGL_PIXEL_TYPE_ARB:
149
switch (pfi->pfd.iPixelType) {
151
if (util_format_is_float(pfi->stvis.color_format)) {
152
*pvalue = WGL_TYPE_RGBA_FLOAT_ARB;
155
*pvalue = WGL_TYPE_RGBA_ARB;
158
case PFD_TYPE_COLORINDEX:
159
*pvalue = WGL_TYPE_COLORINDEX_ARB;
166
case WGL_COLOR_BITS_ARB:
167
*pvalue = pfi->pfd.cColorBits;
170
case WGL_RED_BITS_ARB:
171
*pvalue = pfi->pfd.cRedBits;
174
case WGL_RED_SHIFT_ARB:
175
*pvalue = pfi->pfd.cRedShift;
178
case WGL_GREEN_BITS_ARB:
179
*pvalue = pfi->pfd.cGreenBits;
182
case WGL_GREEN_SHIFT_ARB:
183
*pvalue = pfi->pfd.cGreenShift;
186
case WGL_BLUE_BITS_ARB:
187
*pvalue = pfi->pfd.cBlueBits;
190
case WGL_BLUE_SHIFT_ARB:
191
*pvalue = pfi->pfd.cBlueShift;
194
case WGL_ALPHA_BITS_ARB:
195
*pvalue = pfi->pfd.cAlphaBits;
198
case WGL_ALPHA_SHIFT_ARB:
199
*pvalue = pfi->pfd.cAlphaShift;
202
case WGL_ACCUM_BITS_ARB:
203
*pvalue = pfi->pfd.cAccumBits;
206
case WGL_ACCUM_RED_BITS_ARB:
207
*pvalue = pfi->pfd.cAccumRedBits;
210
case WGL_ACCUM_GREEN_BITS_ARB:
211
*pvalue = pfi->pfd.cAccumGreenBits;
214
case WGL_ACCUM_BLUE_BITS_ARB:
215
*pvalue = pfi->pfd.cAccumBlueBits;
218
case WGL_ACCUM_ALPHA_BITS_ARB:
219
*pvalue = pfi->pfd.cAccumAlphaBits;
222
case WGL_DEPTH_BITS_ARB:
223
*pvalue = pfi->pfd.cDepthBits;
226
case WGL_STENCIL_BITS_ARB:
227
*pvalue = pfi->pfd.cStencilBits;
230
case WGL_AUX_BUFFERS_ARB:
231
*pvalue = pfi->pfd.cAuxBuffers;
234
case WGL_SAMPLE_BUFFERS_ARB:
238
case WGL_SAMPLES_ARB:
239
*pvalue = pfi->stvis.samples;
243
/* WGL_ARB_pbuffer */
245
case WGL_MAX_PBUFFER_WIDTH_ARB:
246
case WGL_MAX_PBUFFER_HEIGHT_ARB:
247
*pvalue = stw_dev->max_2d_length;
250
case WGL_MAX_PBUFFER_PIXELS_ARB:
251
*pvalue = stw_dev->max_2d_length * stw_dev->max_2d_length;
254
case WGL_DRAW_TO_PBUFFER_ARB:
266
struct attrib_match_info
273
static const struct attrib_match_info attrib_match[] = {
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 },
307
/* WGL_ARB_multisample */
308
{ WGL_SAMPLE_BUFFERS_ARB, 2, FALSE },
309
{ WGL_SAMPLES_ARB, 2, FALSE }
312
struct stw_pixelformat_score
320
struct stw_pixelformat_score *scores,
326
const struct attrib_match_info *ami = NULL;
329
/* Find out if a given attribute should be considered for score calculation.
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];
340
/* Iterate all pixelformats, query the requested attribute and calculate
343
for (index = 0; index < count; index++) {
346
if (!stw_query_attrib( index + 1, 0, attribute, &actual_value ))
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.
354
if (actual_value != expected_value)
355
scores[index].points = 0;
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.
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;
373
WINGDIAPI BOOL APIENTRY
374
wglChoosePixelFormatARB(
376
const int *piAttribIList,
377
const FLOAT *pfAttribFList,
383
struct stw_pixelformat_score *scores;
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.
393
count = stw_pixelformat_get_extended_count();
394
scores = (struct stw_pixelformat_score *) MALLOC( count * sizeof( struct stw_pixelformat_score ) );
397
for (i = 0; i < count; i++) {
398
scores[i].points = 0x7fffffff;
402
/* Given the attribute list calculate a score for each pixelformat.
404
if (piAttribIList != NULL) {
405
while (*piAttribIList != 0) {
406
if (!score_pixelformats( scores, count, piAttribIList[0], piAttribIList[1] )) {
413
if (pfAttribFList != NULL) {
414
while (*pfAttribFList != 0) {
415
if (!score_pixelformats( scores, count, (int) pfAttribFList[0], (int) pfAttribFList[1] )) {
423
/* Bubble-sort the resulting scores. Pixelformats with higher scores go first.
424
* TODO: Find out if there are any patent issues with it.
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];
436
scores[i - 1] = scores[i];
446
/* Return a list of pixelformats that are the best match.
447
* Reject pixelformats with non-positive scores.
449
for (i = 0; i < count; i++) {
450
if (scores[i].points > 0) {
451
if (*nNumFormats < nMaxFormats)
452
piFormats[*nNumFormats] = scores[i].index + 1;
461
WINGDIAPI BOOL APIENTRY
462
wglGetPixelFormatAttribfvARB(
467
const int *piAttributes,
474
for (i = 0; i < nAttributes; i++) {
477
if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value ))
479
pfValues[i] = (FLOAT) value;
485
WINGDIAPI BOOL APIENTRY
486
wglGetPixelFormatAttribivARB(
491
const int *piAttributes,
498
for (i = 0; i < nAttributes; i++) {
499
if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] ))