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_memory.h"
46 #include "stw_pixelformat.h"
58 const struct stw_pixelformat_info
*pfi
;
60 count
= stw_pixelformat_get_extended_count();
62 if (attrib
== WGL_NUMBER_PIXEL_FORMATS_ARB
) {
63 *pvalue
= (int) count
;
67 index
= (uint
) iPixelFormat
- 1;
71 pfi
= stw_pixelformat_get_info( index
);
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 *pvalue
= WGL_TYPE_RGBA_ARB
;
153 case PFD_TYPE_COLORINDEX
:
154 *pvalue
= WGL_TYPE_COLORINDEX_ARB
;
161 case WGL_COLOR_BITS_ARB
:
162 *pvalue
= pfi
->pfd
.cColorBits
;
165 case WGL_RED_BITS_ARB
:
166 *pvalue
= pfi
->pfd
.cRedBits
;
169 case WGL_RED_SHIFT_ARB
:
170 *pvalue
= pfi
->pfd
.cRedShift
;
173 case WGL_GREEN_BITS_ARB
:
174 *pvalue
= pfi
->pfd
.cGreenBits
;
177 case WGL_GREEN_SHIFT_ARB
:
178 *pvalue
= pfi
->pfd
.cGreenShift
;
181 case WGL_BLUE_BITS_ARB
:
182 *pvalue
= pfi
->pfd
.cBlueBits
;
185 case WGL_BLUE_SHIFT_ARB
:
186 *pvalue
= pfi
->pfd
.cBlueShift
;
189 case WGL_ALPHA_BITS_ARB
:
190 *pvalue
= pfi
->pfd
.cAlphaBits
;
193 case WGL_ALPHA_SHIFT_ARB
:
194 *pvalue
= pfi
->pfd
.cAlphaShift
;
197 case WGL_ACCUM_BITS_ARB
:
198 *pvalue
= pfi
->pfd
.cAccumBits
;
201 case WGL_ACCUM_RED_BITS_ARB
:
202 *pvalue
= pfi
->pfd
.cAccumRedBits
;
205 case WGL_ACCUM_GREEN_BITS_ARB
:
206 *pvalue
= pfi
->pfd
.cAccumGreenBits
;
209 case WGL_ACCUM_BLUE_BITS_ARB
:
210 *pvalue
= pfi
->pfd
.cAccumBlueBits
;
213 case WGL_ACCUM_ALPHA_BITS_ARB
:
214 *pvalue
= pfi
->pfd
.cAccumAlphaBits
;
217 case WGL_DEPTH_BITS_ARB
:
218 *pvalue
= pfi
->pfd
.cDepthBits
;
221 case WGL_STENCIL_BITS_ARB
:
222 *pvalue
= pfi
->pfd
.cStencilBits
;
225 case WGL_AUX_BUFFERS_ARB
:
226 *pvalue
= pfi
->pfd
.cAuxBuffers
;
229 case WGL_SAMPLE_BUFFERS_ARB
:
233 case WGL_SAMPLES_ARB
:
234 *pvalue
= pfi
->stvis
.samples
;
244 struct attrib_match_info
251 static const struct attrib_match_info attrib_match
[] = {
253 /* WGL_ARB_pixel_format */
254 { WGL_DRAW_TO_WINDOW_ARB
, 0, TRUE
},
255 { WGL_DRAW_TO_BITMAP_ARB
, 0, TRUE
},
256 { WGL_ACCELERATION_ARB
, 0, TRUE
},
257 { WGL_NEED_PALETTE_ARB
, 0, TRUE
},
258 { WGL_NEED_SYSTEM_PALETTE_ARB
, 0, TRUE
},
259 { WGL_SWAP_LAYER_BUFFERS_ARB
, 0, TRUE
},
260 { WGL_SWAP_METHOD_ARB
, 0, TRUE
},
261 { WGL_NUMBER_OVERLAYS_ARB
, 4, FALSE
},
262 { WGL_NUMBER_UNDERLAYS_ARB
, 4, FALSE
},
263 /*{ WGL_SHARE_DEPTH_ARB, 0, TRUE },*/ /* no overlays -- ignore */
264 /*{ WGL_SHARE_STENCIL_ARB, 0, TRUE },*/ /* no overlays -- ignore */
265 /*{ WGL_SHARE_ACCUM_ARB, 0, TRUE },*/ /* no overlays -- ignore */
266 { WGL_SUPPORT_GDI_ARB
, 0, TRUE
},
267 { WGL_SUPPORT_OPENGL_ARB
, 0, TRUE
},
268 { WGL_DOUBLE_BUFFER_ARB
, 0, TRUE
},
269 { WGL_STEREO_ARB
, 0, TRUE
},
270 { WGL_PIXEL_TYPE_ARB
, 0, TRUE
},
271 { WGL_COLOR_BITS_ARB
, 1, FALSE
},
272 { WGL_RED_BITS_ARB
, 1, FALSE
},
273 { WGL_GREEN_BITS_ARB
, 1, FALSE
},
274 { WGL_BLUE_BITS_ARB
, 1, FALSE
},
275 { WGL_ALPHA_BITS_ARB
, 1, FALSE
},
276 { WGL_ACCUM_BITS_ARB
, 1, FALSE
},
277 { WGL_ACCUM_RED_BITS_ARB
, 1, FALSE
},
278 { WGL_ACCUM_GREEN_BITS_ARB
, 1, FALSE
},
279 { WGL_ACCUM_BLUE_BITS_ARB
, 1, FALSE
},
280 { WGL_ACCUM_ALPHA_BITS_ARB
, 1, FALSE
},
281 { WGL_DEPTH_BITS_ARB
, 1, FALSE
},
282 { WGL_STENCIL_BITS_ARB
, 1, FALSE
},
283 { WGL_AUX_BUFFERS_ARB
, 2, FALSE
},
285 /* WGL_ARB_multisample */
286 { WGL_SAMPLE_BUFFERS_ARB
, 2, FALSE
},
287 { WGL_SAMPLES_ARB
, 2, FALSE
}
290 struct stw_pixelformat_score
298 struct stw_pixelformat_score
*scores
,
304 const struct attrib_match_info
*ami
= NULL
;
307 /* Find out if a given attribute should be considered for score calculation.
309 for (i
= 0; i
< sizeof( attrib_match
) / sizeof( attrib_match
[0] ); i
++) {
310 if (attrib_match
[i
].attribute
== attribute
) {
311 ami
= &attrib_match
[i
];
318 /* Iterate all pixelformats, query the requested attribute and calculate
321 for (index
= 0; index
< count
; index
++) {
324 if (!stw_query_attrib( index
+ 1, 0, attribute
, &actual_value
))
328 /* For an exact match criteria, if the actual and expected values differ,
329 * the score is set to 0 points, effectively removing the pixelformat
330 * from a list of matching pixelformats.
332 if (actual_value
!= expected_value
)
333 scores
[index
].points
= 0;
336 /* For a minimum match criteria, if the actual value is smaller than the expected
337 * value, the pixelformat is rejected (score set to 0). However, if the actual
338 * value is bigger, the pixelformat is given a penalty to favour pixelformats that
339 * more closely match the expected values.
341 if (actual_value
< expected_value
)
342 scores
[index
].points
= 0;
343 else if (actual_value
> expected_value
)
344 scores
[index
].points
-= (actual_value
- expected_value
) * ami
->weight
;
351 WINGDIAPI BOOL APIENTRY
352 wglChoosePixelFormatARB(
354 const int *piAttribIList
,
355 const FLOAT
*pfAttribFList
,
361 struct stw_pixelformat_score
*scores
;
366 /* Allocate and initialize pixelformat score table -- better matches
367 * have higher scores. Start with a high score and take out penalty
368 * points for a mismatch when the match does not have to be exact.
369 * Set a score to 0 if there is a mismatch for an exact match criteria.
371 count
= stw_pixelformat_get_extended_count();
372 scores
= (struct stw_pixelformat_score
*) MALLOC( count
* sizeof( struct stw_pixelformat_score
) );
375 for (i
= 0; i
< count
; i
++) {
376 scores
[i
].points
= 0x7fffffff;
380 /* Given the attribute list calculate a score for each pixelformat.
382 if (piAttribIList
!= NULL
) {
383 while (*piAttribIList
!= 0) {
384 if (!score_pixelformats( scores
, count
, piAttribIList
[0], piAttribIList
[1] )) {
391 if (pfAttribFList
!= NULL
) {
392 while (*pfAttribFList
!= 0) {
393 if (!score_pixelformats( scores
, count
, (int) pfAttribFList
[0], (int) pfAttribFList
[1] )) {
401 /* Bubble-sort the resulting scores. Pixelformats with higher scores go first.
402 * TODO: Find out if there are any patent issues with it.
410 for (i
= 1; i
< n
; i
++) {
411 if (scores
[i
- 1].points
< scores
[i
].points
) {
412 struct stw_pixelformat_score score
= scores
[i
- 1];
414 scores
[i
- 1] = scores
[i
];
424 /* Return a list of pixelformats that are the best match.
425 * Reject pixelformats with non-positive scores.
427 for (i
= 0; i
< count
; i
++) {
428 if (scores
[i
].points
> 0) {
429 if (*nNumFormats
< nMaxFormats
)
430 piFormats
[*nNumFormats
] = scores
[i
].index
+ 1;
439 WINGDIAPI BOOL APIENTRY
440 wglGetPixelFormatAttribfvARB(
445 const int *piAttributes
,
452 for (i
= 0; i
< nAttributes
; i
++) {
455 if (!stw_query_attrib( iPixelFormat
, iLayerPlane
, piAttributes
[i
], &value
))
457 pfValues
[i
] = (FLOAT
) value
;
463 WINGDIAPI BOOL APIENTRY
464 wglGetPixelFormatAttribivARB(
469 const int *piAttributes
,
476 for (i
= 0; i
< nAttributes
; i
++) {
477 if (!stw_query_attrib( iPixelFormat
, iLayerPlane
, piAttributes
[i
], &piValues
[i
] ))