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_device.h"
47 #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 index
= (uint
) iPixelFormat
- 1;
72 pfi
= stw_pixelformat_get_info( index
);
75 case WGL_DRAW_TO_WINDOW_ARB
:
76 *pvalue
= pfi
->pfd
.dwFlags
& PFD_DRAW_TO_WINDOW
? TRUE
: FALSE
;
79 case WGL_DRAW_TO_BITMAP_ARB
:
80 *pvalue
= pfi
->pfd
.dwFlags
& PFD_DRAW_TO_BITMAP
? TRUE
: FALSE
;
83 case WGL_NEED_PALETTE_ARB
:
84 *pvalue
= pfi
->pfd
.dwFlags
& PFD_NEED_PALETTE
? TRUE
: FALSE
;
87 case WGL_NEED_SYSTEM_PALETTE_ARB
:
88 *pvalue
= pfi
->pfd
.dwFlags
& PFD_NEED_SYSTEM_PALETTE
? TRUE
: FALSE
;
91 case WGL_SWAP_METHOD_ARB
:
92 *pvalue
= pfi
->pfd
.dwFlags
& PFD_SWAP_COPY
? WGL_SWAP_COPY_ARB
: WGL_SWAP_UNDEFINED_ARB
;
95 case WGL_SWAP_LAYER_BUFFERS_ARB
:
99 case WGL_NUMBER_OVERLAYS_ARB
:
103 case WGL_NUMBER_UNDERLAYS_ARB
:
108 if (iLayerPlane
!= 0)
112 case WGL_ACCELERATION_ARB
:
113 *pvalue
= WGL_FULL_ACCELERATION_ARB
;
116 case WGL_TRANSPARENT_ARB
:
120 case WGL_TRANSPARENT_RED_VALUE_ARB
:
121 case WGL_TRANSPARENT_GREEN_VALUE_ARB
:
122 case WGL_TRANSPARENT_BLUE_VALUE_ARB
:
123 case WGL_TRANSPARENT_ALPHA_VALUE_ARB
:
124 case WGL_TRANSPARENT_INDEX_VALUE_ARB
:
127 case WGL_SHARE_DEPTH_ARB
:
128 case WGL_SHARE_STENCIL_ARB
:
129 case WGL_SHARE_ACCUM_ARB
:
133 case WGL_SUPPORT_GDI_ARB
:
134 *pvalue
= pfi
->pfd
.dwFlags
& PFD_SUPPORT_GDI
? TRUE
: FALSE
;
137 case WGL_SUPPORT_OPENGL_ARB
:
138 *pvalue
= pfi
->pfd
.dwFlags
& PFD_SUPPORT_OPENGL
? TRUE
: FALSE
;
141 case WGL_DOUBLE_BUFFER_ARB
:
142 *pvalue
= pfi
->pfd
.dwFlags
& PFD_DOUBLEBUFFER
? TRUE
: FALSE
;
146 *pvalue
= pfi
->pfd
.dwFlags
& PFD_STEREO
? TRUE
: FALSE
;
149 case WGL_PIXEL_TYPE_ARB
:
150 switch (pfi
->pfd
.iPixelType
) {
152 *pvalue
= WGL_TYPE_RGBA_ARB
;
154 case PFD_TYPE_COLORINDEX
:
155 *pvalue
= WGL_TYPE_COLORINDEX_ARB
;
162 case WGL_COLOR_BITS_ARB
:
163 *pvalue
= pfi
->pfd
.cColorBits
;
166 case WGL_RED_BITS_ARB
:
167 *pvalue
= pfi
->pfd
.cRedBits
;
170 case WGL_RED_SHIFT_ARB
:
171 *pvalue
= pfi
->pfd
.cRedShift
;
174 case WGL_GREEN_BITS_ARB
:
175 *pvalue
= pfi
->pfd
.cGreenBits
;
178 case WGL_GREEN_SHIFT_ARB
:
179 *pvalue
= pfi
->pfd
.cGreenShift
;
182 case WGL_BLUE_BITS_ARB
:
183 *pvalue
= pfi
->pfd
.cBlueBits
;
186 case WGL_BLUE_SHIFT_ARB
:
187 *pvalue
= pfi
->pfd
.cBlueShift
;
190 case WGL_ALPHA_BITS_ARB
:
191 *pvalue
= pfi
->pfd
.cAlphaBits
;
194 case WGL_ALPHA_SHIFT_ARB
:
195 *pvalue
= pfi
->pfd
.cAlphaShift
;
198 case WGL_ACCUM_BITS_ARB
:
199 *pvalue
= pfi
->pfd
.cAccumBits
;
202 case WGL_ACCUM_RED_BITS_ARB
:
203 *pvalue
= pfi
->pfd
.cAccumRedBits
;
206 case WGL_ACCUM_GREEN_BITS_ARB
:
207 *pvalue
= pfi
->pfd
.cAccumGreenBits
;
210 case WGL_ACCUM_BLUE_BITS_ARB
:
211 *pvalue
= pfi
->pfd
.cAccumBlueBits
;
214 case WGL_ACCUM_ALPHA_BITS_ARB
:
215 *pvalue
= pfi
->pfd
.cAccumAlphaBits
;
218 case WGL_DEPTH_BITS_ARB
:
219 *pvalue
= pfi
->pfd
.cDepthBits
;
222 case WGL_STENCIL_BITS_ARB
:
223 *pvalue
= pfi
->pfd
.cStencilBits
;
226 case WGL_AUX_BUFFERS_ARB
:
227 *pvalue
= pfi
->pfd
.cAuxBuffers
;
230 case WGL_SAMPLE_BUFFERS_ARB
:
234 case WGL_SAMPLES_ARB
:
235 *pvalue
= pfi
->stvis
.samples
;
239 /* WGL_ARB_pbuffer */
241 case WGL_MAX_PBUFFER_WIDTH_ARB
:
242 case WGL_MAX_PBUFFER_HEIGHT_ARB
:
243 *pvalue
= stw_dev
->max_2d_length
;
246 case WGL_MAX_PBUFFER_PIXELS_ARB
:
247 *pvalue
= stw_dev
->max_2d_length
* stw_dev
->max_2d_length
;
250 case WGL_DRAW_TO_PBUFFER_ARB
:
262 struct attrib_match_info
269 static const struct attrib_match_info attrib_match
[] = {
271 /* WGL_ARB_pixel_format */
272 { WGL_DRAW_TO_WINDOW_ARB
, 0, TRUE
},
273 { WGL_DRAW_TO_BITMAP_ARB
, 0, TRUE
},
274 { WGL_ACCELERATION_ARB
, 0, TRUE
},
275 { WGL_NEED_PALETTE_ARB
, 0, TRUE
},
276 { WGL_NEED_SYSTEM_PALETTE_ARB
, 0, TRUE
},
277 { WGL_SWAP_LAYER_BUFFERS_ARB
, 0, TRUE
},
278 { WGL_SWAP_METHOD_ARB
, 0, TRUE
},
279 { WGL_NUMBER_OVERLAYS_ARB
, 4, FALSE
},
280 { WGL_NUMBER_UNDERLAYS_ARB
, 4, FALSE
},
281 /*{ WGL_SHARE_DEPTH_ARB, 0, TRUE },*/ /* no overlays -- ignore */
282 /*{ WGL_SHARE_STENCIL_ARB, 0, TRUE },*/ /* no overlays -- ignore */
283 /*{ WGL_SHARE_ACCUM_ARB, 0, TRUE },*/ /* no overlays -- ignore */
284 { WGL_SUPPORT_GDI_ARB
, 0, TRUE
},
285 { WGL_SUPPORT_OPENGL_ARB
, 0, TRUE
},
286 { WGL_DOUBLE_BUFFER_ARB
, 0, TRUE
},
287 { WGL_STEREO_ARB
, 0, TRUE
},
288 { WGL_PIXEL_TYPE_ARB
, 0, TRUE
},
289 { WGL_COLOR_BITS_ARB
, 1, FALSE
},
290 { WGL_RED_BITS_ARB
, 1, FALSE
},
291 { WGL_GREEN_BITS_ARB
, 1, FALSE
},
292 { WGL_BLUE_BITS_ARB
, 1, FALSE
},
293 { WGL_ALPHA_BITS_ARB
, 1, FALSE
},
294 { WGL_ACCUM_BITS_ARB
, 1, FALSE
},
295 { WGL_ACCUM_RED_BITS_ARB
, 1, FALSE
},
296 { WGL_ACCUM_GREEN_BITS_ARB
, 1, FALSE
},
297 { WGL_ACCUM_BLUE_BITS_ARB
, 1, FALSE
},
298 { WGL_ACCUM_ALPHA_BITS_ARB
, 1, FALSE
},
299 { WGL_DEPTH_BITS_ARB
, 1, FALSE
},
300 { WGL_STENCIL_BITS_ARB
, 1, FALSE
},
301 { WGL_AUX_BUFFERS_ARB
, 2, FALSE
},
303 /* WGL_ARB_multisample */
304 { WGL_SAMPLE_BUFFERS_ARB
, 2, FALSE
},
305 { WGL_SAMPLES_ARB
, 2, FALSE
}
308 struct stw_pixelformat_score
316 struct stw_pixelformat_score
*scores
,
322 const struct attrib_match_info
*ami
= NULL
;
325 /* Find out if a given attribute should be considered for score calculation.
327 for (i
= 0; i
< sizeof( attrib_match
) / sizeof( attrib_match
[0] ); i
++) {
328 if (attrib_match
[i
].attribute
== attribute
) {
329 ami
= &attrib_match
[i
];
336 /* Iterate all pixelformats, query the requested attribute and calculate
339 for (index
= 0; index
< count
; index
++) {
342 if (!stw_query_attrib( index
+ 1, 0, attribute
, &actual_value
))
346 /* For an exact match criteria, if the actual and expected values differ,
347 * the score is set to 0 points, effectively removing the pixelformat
348 * from a list of matching pixelformats.
350 if (actual_value
!= expected_value
)
351 scores
[index
].points
= 0;
354 /* For a minimum match criteria, if the actual value is smaller than the expected
355 * value, the pixelformat is rejected (score set to 0). However, if the actual
356 * value is bigger, the pixelformat is given a penalty to favour pixelformats that
357 * more closely match the expected values.
359 if (actual_value
< expected_value
)
360 scores
[index
].points
= 0;
361 else if (actual_value
> expected_value
)
362 scores
[index
].points
-= (actual_value
- expected_value
) * ami
->weight
;
369 WINGDIAPI BOOL APIENTRY
370 wglChoosePixelFormatARB(
372 const int *piAttribIList
,
373 const FLOAT
*pfAttribFList
,
379 struct stw_pixelformat_score
*scores
;
384 /* Allocate and initialize pixelformat score table -- better matches
385 * have higher scores. Start with a high score and take out penalty
386 * points for a mismatch when the match does not have to be exact.
387 * Set a score to 0 if there is a mismatch for an exact match criteria.
389 count
= stw_pixelformat_get_extended_count();
390 scores
= (struct stw_pixelformat_score
*) MALLOC( count
* sizeof( struct stw_pixelformat_score
) );
393 for (i
= 0; i
< count
; i
++) {
394 scores
[i
].points
= 0x7fffffff;
398 /* Given the attribute list calculate a score for each pixelformat.
400 if (piAttribIList
!= NULL
) {
401 while (*piAttribIList
!= 0) {
402 if (!score_pixelformats( scores
, count
, piAttribIList
[0], piAttribIList
[1] )) {
409 if (pfAttribFList
!= NULL
) {
410 while (*pfAttribFList
!= 0) {
411 if (!score_pixelformats( scores
, count
, (int) pfAttribFList
[0], (int) pfAttribFList
[1] )) {
419 /* Bubble-sort the resulting scores. Pixelformats with higher scores go first.
420 * TODO: Find out if there are any patent issues with it.
428 for (i
= 1; i
< n
; i
++) {
429 if (scores
[i
- 1].points
< scores
[i
].points
) {
430 struct stw_pixelformat_score score
= scores
[i
- 1];
432 scores
[i
- 1] = scores
[i
];
442 /* Return a list of pixelformats that are the best match.
443 * Reject pixelformats with non-positive scores.
445 for (i
= 0; i
< count
; i
++) {
446 if (scores
[i
].points
> 0) {
447 if (*nNumFormats
< nMaxFormats
)
448 piFormats
[*nNumFormats
] = scores
[i
].index
+ 1;
457 WINGDIAPI BOOL APIENTRY
458 wglGetPixelFormatAttribfvARB(
463 const int *piAttributes
,
470 for (i
= 0; i
< nAttributes
; i
++) {
473 if (!stw_query_attrib( iPixelFormat
, iLayerPlane
, piAttributes
[i
], &value
))
475 pfValues
[i
] = (FLOAT
) value
;
481 WINGDIAPI BOOL APIENTRY
482 wglGetPixelFormatAttribivARB(
487 const int *piAttributes
,
494 for (i
= 0; i
< nAttributes
; i
++) {
495 if (!stw_query_attrib( iPixelFormat
, iLayerPlane
, piAttributes
[i
], &piValues
[i
] ))