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 **************************************************************************/
30 #include "pipe/p_compiler.h"
31 #include "util/u_memory.h"
32 #include "stw_public.h"
33 #include "stw_pixelformat.h"
34 #include "stw_arbpixelformat.h"
36 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
37 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
38 #define WGL_DRAW_TO_BITMAP_ARB 0x2002
39 #define WGL_ACCELERATION_ARB 0x2003
40 #define WGL_NEED_PALETTE_ARB 0x2004
41 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
42 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
43 #define WGL_SWAP_METHOD_ARB 0x2007
44 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
45 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
46 #define WGL_TRANSPARENT_ARB 0x200A
47 #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
48 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
49 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
50 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
51 #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
52 #define WGL_SHARE_DEPTH_ARB 0x200C
53 #define WGL_SHARE_STENCIL_ARB 0x200D
54 #define WGL_SHARE_ACCUM_ARB 0x200E
55 #define WGL_SUPPORT_GDI_ARB 0x200F
56 #define WGL_SUPPORT_OPENGL_ARB 0x2010
57 #define WGL_DOUBLE_BUFFER_ARB 0x2011
58 #define WGL_STEREO_ARB 0x2012
59 #define WGL_PIXEL_TYPE_ARB 0x2013
60 #define WGL_COLOR_BITS_ARB 0x2014
61 #define WGL_RED_BITS_ARB 0x2015
62 #define WGL_RED_SHIFT_ARB 0x2016
63 #define WGL_GREEN_BITS_ARB 0x2017
64 #define WGL_GREEN_SHIFT_ARB 0x2018
65 #define WGL_BLUE_BITS_ARB 0x2019
66 #define WGL_BLUE_SHIFT_ARB 0x201A
67 #define WGL_ALPHA_BITS_ARB 0x201B
68 #define WGL_ALPHA_SHIFT_ARB 0x201C
69 #define WGL_ACCUM_BITS_ARB 0x201D
70 #define WGL_ACCUM_RED_BITS_ARB 0x201E
71 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
72 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
73 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
74 #define WGL_DEPTH_BITS_ARB 0x2022
75 #define WGL_STENCIL_BITS_ARB 0x2023
76 #define WGL_AUX_BUFFERS_ARB 0x2024
78 #define WGL_NO_ACCELERATION_ARB 0x2025
79 #define WGL_GENERIC_ACCELERATION_ARB 0x2026
80 #define WGL_FULL_ACCELERATION_ARB 0x2027
82 #define WGL_SWAP_EXCHANGE_ARB 0x2028
83 #define WGL_SWAP_COPY_ARB 0x2029
84 #define WGL_SWAP_UNDEFINED_ARB 0x202A
86 #define WGL_TYPE_RGBA_ARB 0x202B
87 #define WGL_TYPE_COLORINDEX_ARB 0x202C
89 /* From arb_multisample:
91 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
92 #define WGL_SAMPLES_ARB 0x2042
104 const struct pixelformat_info
*pf
;
106 count
= pixelformat_get_extended_count();
108 if (attrib
== WGL_NUMBER_PIXEL_FORMATS_ARB
) {
109 *pvalue
= (int) count
;
113 index
= (uint
) iPixelFormat
- 1;
117 pf
= pixelformat_get_info( index
);
120 case WGL_DRAW_TO_WINDOW_ARB
:
124 case WGL_DRAW_TO_BITMAP_ARB
:
128 case WGL_NEED_PALETTE_ARB
:
132 case WGL_NEED_SYSTEM_PALETTE_ARB
:
136 case WGL_SWAP_METHOD_ARB
:
137 if (pf
->flags
& PF_FLAG_DOUBLEBUFFER
)
138 *pvalue
= WGL_SWAP_COPY_ARB
;
140 *pvalue
= WGL_SWAP_UNDEFINED_ARB
;
143 case WGL_SWAP_LAYER_BUFFERS_ARB
:
147 case WGL_NUMBER_OVERLAYS_ARB
:
151 case WGL_NUMBER_UNDERLAYS_ARB
:
156 if (iLayerPlane
!= 0)
160 case WGL_ACCELERATION_ARB
:
161 *pvalue
= WGL_FULL_ACCELERATION_ARB
;
164 case WGL_TRANSPARENT_ARB
:
168 case WGL_TRANSPARENT_RED_VALUE_ARB
:
169 case WGL_TRANSPARENT_GREEN_VALUE_ARB
:
170 case WGL_TRANSPARENT_BLUE_VALUE_ARB
:
171 case WGL_TRANSPARENT_ALPHA_VALUE_ARB
:
172 case WGL_TRANSPARENT_INDEX_VALUE_ARB
:
175 case WGL_SHARE_DEPTH_ARB
:
176 case WGL_SHARE_STENCIL_ARB
:
177 case WGL_SHARE_ACCUM_ARB
:
181 case WGL_SUPPORT_GDI_ARB
:
185 case WGL_SUPPORT_OPENGL_ARB
:
189 case WGL_DOUBLE_BUFFER_ARB
:
190 if (pf
->flags
& PF_FLAG_DOUBLEBUFFER
)
200 case WGL_PIXEL_TYPE_ARB
:
201 *pvalue
= WGL_TYPE_RGBA_ARB
;
204 case WGL_COLOR_BITS_ARB
:
205 *pvalue
= (int) (pf
->color
.redbits
+ pf
->color
.greenbits
+ pf
->color
.bluebits
);
208 case WGL_RED_BITS_ARB
:
209 *pvalue
= (int) pf
->color
.redbits
;
212 case WGL_RED_SHIFT_ARB
:
213 *pvalue
= (int) pf
->color
.redshift
;
216 case WGL_GREEN_BITS_ARB
:
217 *pvalue
= (int) pf
->color
.greenbits
;
220 case WGL_GREEN_SHIFT_ARB
:
221 *pvalue
= (int) pf
->color
.greenshift
;
224 case WGL_BLUE_BITS_ARB
:
225 *pvalue
= (int) pf
->color
.bluebits
;
228 case WGL_BLUE_SHIFT_ARB
:
229 *pvalue
= (int) pf
->color
.blueshift
;
232 case WGL_ALPHA_BITS_ARB
:
233 *pvalue
= (int) pf
->alpha
.alphabits
;
236 case WGL_ALPHA_SHIFT_ARB
:
237 *pvalue
= (int) pf
->alpha
.alphashift
;
240 case WGL_ACCUM_BITS_ARB
:
241 case WGL_ACCUM_RED_BITS_ARB
:
242 case WGL_ACCUM_GREEN_BITS_ARB
:
243 case WGL_ACCUM_BLUE_BITS_ARB
:
244 case WGL_ACCUM_ALPHA_BITS_ARB
:
248 case WGL_DEPTH_BITS_ARB
:
249 *pvalue
= (int) pf
->depth
.depthbits
;
252 case WGL_STENCIL_BITS_ARB
:
253 *pvalue
= (int) pf
->depth
.stencilbits
;
256 case WGL_AUX_BUFFERS_ARB
:
260 case WGL_SAMPLE_BUFFERS_ARB
:
261 if (pf
->flags
& PF_FLAG_MULTISAMPLED
)
262 *pvalue
= stw_query_sample_buffers();
267 case WGL_SAMPLES_ARB
:
268 if (pf
->flags
& PF_FLAG_MULTISAMPLED
)
269 *pvalue
= stw_query_samples();
281 struct attrib_match_info
288 static struct attrib_match_info attrib_match
[] = {
290 /* WGL_ARB_pixel_format */
291 { WGL_DRAW_TO_WINDOW_ARB
, 0, TRUE
},
292 { WGL_DRAW_TO_BITMAP_ARB
, 0, TRUE
},
293 { WGL_ACCELERATION_ARB
, 0, TRUE
},
294 { WGL_NEED_PALETTE_ARB
, 0, TRUE
},
295 { WGL_NEED_SYSTEM_PALETTE_ARB
, 0, TRUE
},
296 { WGL_SWAP_LAYER_BUFFERS_ARB
, 0, TRUE
},
297 { WGL_SWAP_METHOD_ARB
, 0, TRUE
},
298 { WGL_NUMBER_OVERLAYS_ARB
, 4, FALSE
},
299 { WGL_NUMBER_UNDERLAYS_ARB
, 4, FALSE
},
300 /*{ WGL_SHARE_DEPTH_ARB, 0, TRUE },*/ /* no overlays -- ignore */
301 /*{ WGL_SHARE_STENCIL_ARB, 0, TRUE },*/ /* no overlays -- ignore */
302 /*{ WGL_SHARE_ACCUM_ARB, 0, TRUE },*/ /* no overlays -- ignore */
303 { WGL_SUPPORT_GDI_ARB
, 0, TRUE
},
304 { WGL_SUPPORT_OPENGL_ARB
, 0, TRUE
},
305 { WGL_DOUBLE_BUFFER_ARB
, 0, TRUE
},
306 { WGL_STEREO_ARB
, 0, TRUE
},
307 { WGL_PIXEL_TYPE_ARB
, 0, TRUE
},
308 { WGL_COLOR_BITS_ARB
, 1, FALSE
},
309 { WGL_RED_BITS_ARB
, 1, FALSE
},
310 { WGL_GREEN_BITS_ARB
, 1, FALSE
},
311 { WGL_BLUE_BITS_ARB
, 1, FALSE
},
312 { WGL_ALPHA_BITS_ARB
, 1, FALSE
},
313 { WGL_ACCUM_BITS_ARB
, 1, FALSE
},
314 { WGL_ACCUM_RED_BITS_ARB
, 1, FALSE
},
315 { WGL_ACCUM_GREEN_BITS_ARB
, 1, FALSE
},
316 { WGL_ACCUM_BLUE_BITS_ARB
, 1, FALSE
},
317 { WGL_ACCUM_ALPHA_BITS_ARB
, 1, FALSE
},
318 { WGL_DEPTH_BITS_ARB
, 1, FALSE
},
319 { WGL_STENCIL_BITS_ARB
, 1, FALSE
},
320 { WGL_AUX_BUFFERS_ARB
, 2, FALSE
},
322 /* WGL_ARB_multisample */
323 { WGL_SAMPLE_BUFFERS_ARB
, 2, FALSE
},
324 { WGL_SAMPLES_ARB
, 2, FALSE
}
327 struct pixelformat_score
335 struct pixelformat_score
*scores
,
341 struct attrib_match_info
*ami
= NULL
;
344 /* Find out if a given attribute should be considered for score calculation.
346 for (i
= 0; i
< sizeof( attrib_match
) / sizeof( attrib_match
[0] ); i
++) {
347 if (attrib_match
[i
].attribute
== attribute
) {
348 ami
= &attrib_match
[i
];
355 /* Iterate all pixelformats, query the requested attribute and calculate
358 for (index
= 0; index
< count
; index
++) {
361 if (!query_attrib( index
+ 1, 0, attribute
, &actual_value
))
365 /* For an exact match criteria, if the actual and expected values differ,
366 * the score is set to 0 points, effectively removing the pixelformat
367 * from a list of matching pixelformats.
369 if (actual_value
!= expected_value
)
370 scores
[index
].points
= 0;
373 /* For a minimum match criteria, if the actual value is smaller than the expected
374 * value, the pixelformat is rejected (score set to 0). However, if the actual
375 * value is bigger, the pixelformat is given a penalty to favour pixelformats that
376 * more closely match the expected values.
378 if (actual_value
< expected_value
)
379 scores
[index
].points
= 0;
380 else if (actual_value
> expected_value
)
381 scores
[index
].points
-= (actual_value
- expected_value
) * ami
->weight
;
388 WINGDIAPI BOOL APIENTRY
389 wglChoosePixelFormatARB(
391 const int *piAttribIList
,
392 const FLOAT
*pfAttribFList
,
398 struct pixelformat_score
*scores
;
403 /* Allocate and initialize pixelformat score table -- better matches
404 * have higher scores. Start with a high score and take out penalty
405 * points for a mismatch when the match does not have to be exact.
406 * Set a score to 0 if there is a mismatch for an exact match criteria.
408 count
= pixelformat_get_extended_count();
409 scores
= (struct pixelformat_score
*) MALLOC( count
* sizeof( struct pixelformat_score
) );
412 for (i
= 0; i
< count
; i
++) {
413 scores
[i
].points
= 0x7fffffff;
417 /* Given the attribute list calculate a score for each pixelformat.
419 if (piAttribIList
!= NULL
) {
420 while (*piAttribIList
!= 0) {
421 if (!score_pixelformats( scores
, count
, piAttribIList
[0], piAttribIList
[1] )) {
428 if (pfAttribFList
!= NULL
) {
429 while (*pfAttribFList
!= 0) {
430 if (!score_pixelformats( scores
, count
, (int) pfAttribFList
[0], (int) pfAttribFList
[1] )) {
438 /* Bubble-sort the resulting scores. Pixelformats with higher scores go first.
439 * TODO: Find out if there are any patent issues with it.
447 for (i
= 1; i
< n
; i
++) {
448 if (scores
[i
- 1].points
< scores
[i
].points
) {
449 struct pixelformat_score score
= scores
[i
- 1];
451 scores
[i
- 1] = scores
[i
];
461 /* Return a list of pixelformats that are the best match.
462 * Reject pixelformats with non-positive scores.
464 for (i
= 0; i
< count
; i
++) {
465 if (scores
[i
].points
> 0) {
466 if (*nNumFormats
< nMaxFormats
)
467 piFormats
[*nNumFormats
] = scores
[i
].index
+ 1;
476 WINGDIAPI BOOL APIENTRY
477 wglGetPixelFormatAttribfvARB(
482 const int *piAttributes
,
489 for (i
= 0; i
< nAttributes
; i
++) {
492 if (!query_attrib( iPixelFormat
, iLayerPlane
, piAttributes
[i
], &value
))
494 pfValues
[i
] = (FLOAT
) value
;
500 WINGDIAPI BOOL APIENTRY
501 wglGetPixelFormatAttribivARB(
506 const int *piAttributes
,
513 for (i
= 0; i
< nAttributes
; i
++) {
514 if (!query_attrib( iPixelFormat
, iLayerPlane
, piAttributes
[i
], &piValues
[i
] ))