1 /**************************************************************************
3 * Copyright 2008 VMware, Inc.
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 VMWARE 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 if (pfi
->pfd
.dwFlags
& PFD_SWAP_COPY
)
92 *pvalue
= WGL_SWAP_COPY_ARB
;
93 else if (pfi
->pfd
.dwFlags
& PFD_SWAP_EXCHANGE
)
94 *pvalue
= WGL_SWAP_EXCHANGE_EXT
;
96 *pvalue
= WGL_SWAP_UNDEFINED_ARB
;
99 case WGL_SWAP_LAYER_BUFFERS_ARB
:
103 case WGL_NUMBER_OVERLAYS_ARB
:
107 case WGL_NUMBER_UNDERLAYS_ARB
:
111 case WGL_BIND_TO_TEXTURE_RGB_ARB
:
112 /* WGL_ARB_render_texture */
113 *pvalue
= pfi
->bindToTextureRGB
;
116 case WGL_BIND_TO_TEXTURE_RGBA_ARB
:
117 /* WGL_ARB_render_texture */
118 *pvalue
= pfi
->bindToTextureRGBA
;
122 if (iLayerPlane
!= 0)
126 case WGL_ACCELERATION_ARB
:
127 *pvalue
= WGL_FULL_ACCELERATION_ARB
;
130 case WGL_TRANSPARENT_ARB
:
134 case WGL_TRANSPARENT_RED_VALUE_ARB
:
135 case WGL_TRANSPARENT_GREEN_VALUE_ARB
:
136 case WGL_TRANSPARENT_BLUE_VALUE_ARB
:
137 case WGL_TRANSPARENT_ALPHA_VALUE_ARB
:
138 case WGL_TRANSPARENT_INDEX_VALUE_ARB
:
141 case WGL_SHARE_DEPTH_ARB
:
142 case WGL_SHARE_STENCIL_ARB
:
143 case WGL_SHARE_ACCUM_ARB
:
147 case WGL_SUPPORT_GDI_ARB
:
148 *pvalue
= pfi
->pfd
.dwFlags
& PFD_SUPPORT_GDI
? TRUE
: FALSE
;
151 case WGL_SUPPORT_OPENGL_ARB
:
152 *pvalue
= pfi
->pfd
.dwFlags
& PFD_SUPPORT_OPENGL
? TRUE
: FALSE
;
155 case WGL_DOUBLE_BUFFER_ARB
:
156 *pvalue
= pfi
->pfd
.dwFlags
& PFD_DOUBLEBUFFER
? TRUE
: FALSE
;
160 *pvalue
= pfi
->pfd
.dwFlags
& PFD_STEREO
? TRUE
: FALSE
;
163 case WGL_PIXEL_TYPE_ARB
:
164 switch (pfi
->pfd
.iPixelType
) {
166 if (util_format_is_float(pfi
->stvis
.color_format
)) {
167 *pvalue
= WGL_TYPE_RGBA_FLOAT_ARB
;
170 *pvalue
= WGL_TYPE_RGBA_ARB
;
173 case PFD_TYPE_COLORINDEX
:
174 *pvalue
= WGL_TYPE_COLORINDEX_ARB
;
181 case WGL_COLOR_BITS_ARB
:
182 *pvalue
= pfi
->pfd
.cColorBits
;
185 case WGL_RED_BITS_ARB
:
186 *pvalue
= pfi
->pfd
.cRedBits
;
189 case WGL_RED_SHIFT_ARB
:
190 *pvalue
= pfi
->pfd
.cRedShift
;
193 case WGL_GREEN_BITS_ARB
:
194 *pvalue
= pfi
->pfd
.cGreenBits
;
197 case WGL_GREEN_SHIFT_ARB
:
198 *pvalue
= pfi
->pfd
.cGreenShift
;
201 case WGL_BLUE_BITS_ARB
:
202 *pvalue
= pfi
->pfd
.cBlueBits
;
205 case WGL_BLUE_SHIFT_ARB
:
206 *pvalue
= pfi
->pfd
.cBlueShift
;
209 case WGL_ALPHA_BITS_ARB
:
210 *pvalue
= pfi
->pfd
.cAlphaBits
;
213 case WGL_ALPHA_SHIFT_ARB
:
214 *pvalue
= pfi
->pfd
.cAlphaShift
;
217 case WGL_ACCUM_BITS_ARB
:
218 *pvalue
= pfi
->pfd
.cAccumBits
;
221 case WGL_ACCUM_RED_BITS_ARB
:
222 *pvalue
= pfi
->pfd
.cAccumRedBits
;
225 case WGL_ACCUM_GREEN_BITS_ARB
:
226 *pvalue
= pfi
->pfd
.cAccumGreenBits
;
229 case WGL_ACCUM_BLUE_BITS_ARB
:
230 *pvalue
= pfi
->pfd
.cAccumBlueBits
;
233 case WGL_ACCUM_ALPHA_BITS_ARB
:
234 *pvalue
= pfi
->pfd
.cAccumAlphaBits
;
237 case WGL_DEPTH_BITS_ARB
:
238 *pvalue
= pfi
->pfd
.cDepthBits
;
241 case WGL_STENCIL_BITS_ARB
:
242 *pvalue
= pfi
->pfd
.cStencilBits
;
245 case WGL_AUX_BUFFERS_ARB
:
246 *pvalue
= pfi
->pfd
.cAuxBuffers
;
249 case WGL_SAMPLE_BUFFERS_ARB
:
250 *pvalue
= (pfi
->stvis
.samples
> 1);
253 case WGL_SAMPLES_ARB
:
254 *pvalue
= pfi
->stvis
.samples
;
258 /* WGL_ARB_pbuffer */
260 case WGL_MAX_PBUFFER_WIDTH_ARB
:
261 case WGL_MAX_PBUFFER_HEIGHT_ARB
:
262 *pvalue
= stw_dev
->max_2d_length
;
265 case WGL_MAX_PBUFFER_PIXELS_ARB
:
266 *pvalue
= stw_dev
->max_2d_length
* stw_dev
->max_2d_length
;
269 case WGL_DRAW_TO_PBUFFER_ARB
:
281 struct attrib_match_info
288 static const 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
},
326 /* WGL_ARB_render_texture */
327 { WGL_BIND_TO_TEXTURE_RGB_ARB
, 0, FALSE
},
328 { WGL_BIND_TO_TEXTURE_RGBA_ARB
, 0, FALSE
},
331 struct stw_pixelformat_score
339 struct stw_pixelformat_score
*scores
,
345 const struct attrib_match_info
*ami
= NULL
;
348 /* Find out if a given attribute should be considered for score calculation.
350 for (i
= 0; i
< sizeof( attrib_match
) / sizeof( attrib_match
[0] ); i
++) {
351 if (attrib_match
[i
].attribute
== attribute
) {
352 ami
= &attrib_match
[i
];
359 /* Iterate all pixelformats, query the requested attribute and calculate
362 for (index
= 0; index
< count
; index
++) {
365 if (!stw_query_attrib( index
+ 1, 0, attribute
, &actual_value
))
369 /* For an exact match criteria, if the actual and expected values differ,
370 * the score is set to 0 points, effectively removing the pixelformat
371 * from a list of matching pixelformats.
373 if (actual_value
!= expected_value
)
374 scores
[index
].points
= 0;
377 /* For a minimum match criteria, if the actual value is smaller than the expected
378 * value, the pixelformat is rejected (score set to 0). However, if the actual
379 * value is bigger, the pixelformat is given a penalty to favour pixelformats that
380 * more closely match the expected values.
382 if (actual_value
< expected_value
)
383 scores
[index
].points
= 0;
384 else if (actual_value
> expected_value
)
385 scores
[index
].points
-= (actual_value
- expected_value
) * ami
->weight
;
392 WINGDIAPI BOOL APIENTRY
393 wglChoosePixelFormatARB(
395 const int *piAttribIList
,
396 const FLOAT
*pfAttribFList
,
402 struct stw_pixelformat_score
*scores
;
407 /* Allocate and initialize pixelformat score table -- better matches
408 * have higher scores. Start with a high score and take out penalty
409 * points for a mismatch when the match does not have to be exact.
410 * Set a score to 0 if there is a mismatch for an exact match criteria.
412 count
= stw_pixelformat_get_extended_count();
413 scores
= (struct stw_pixelformat_score
*) MALLOC( count
* sizeof( struct stw_pixelformat_score
) );
416 for (i
= 0; i
< count
; i
++) {
417 scores
[i
].points
= 0x7fffffff;
421 /* Given the attribute list calculate a score for each pixelformat.
423 if (piAttribIList
!= NULL
) {
424 while (*piAttribIList
!= 0) {
425 if (!score_pixelformats( scores
, count
, piAttribIList
[0], piAttribIList
[1] )) {
432 if (pfAttribFList
!= NULL
) {
433 while (*pfAttribFList
!= 0) {
434 if (!score_pixelformats( scores
, count
, (int) pfAttribFList
[0], (int) pfAttribFList
[1] )) {
442 /* Bubble-sort the resulting scores. Pixelformats with higher scores go first.
443 * TODO: Find out if there are any patent issues with it.
451 for (i
= 1; i
< n
; i
++) {
452 if (scores
[i
- 1].points
< scores
[i
].points
) {
453 struct stw_pixelformat_score score
= scores
[i
- 1];
455 scores
[i
- 1] = scores
[i
];
465 /* Return a list of pixelformats that are the best match.
466 * Reject pixelformats with non-positive scores.
468 for (i
= 0; i
< count
; i
++) {
469 if (scores
[i
].points
> 0) {
470 piFormats
[*nNumFormats
] = scores
[i
].index
+ 1;
472 if (*nNumFormats
>= nMaxFormats
) {
482 WINGDIAPI BOOL APIENTRY
483 wglGetPixelFormatAttribfvARB(
488 const int *piAttributes
,
495 for (i
= 0; i
< nAttributes
; i
++) {
498 if (!stw_query_attrib( iPixelFormat
, iLayerPlane
, piAttributes
[i
], &value
))
500 pfValues
[i
] = (FLOAT
) value
;
506 WINGDIAPI BOOL APIENTRY
507 wglGetPixelFormatAttribivARB(
512 const int *piAttributes
,
519 for (i
= 0; i
< nAttributes
; i
++) {
520 if (!stw_query_attrib( iPixelFormat
, iLayerPlane
, piAttributes
[i
], &piValues
[i
] ))