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/format/u_format.h"
46 #include "util/u_memory.h"
47 #include "stw_device.h"
48 #include "stw_pixelformat.h"
52 stw_query_attrib(int iPixelFormat
, int iLayerPlane
, int attrib
, int *pvalue
)
55 const struct stw_pixelformat_info
*pfi
;
57 count
= stw_pixelformat_get_extended_count();
59 if (attrib
== WGL_NUMBER_PIXEL_FORMATS_ARB
) {
60 *pvalue
= (int) count
;
64 pfi
= stw_pixelformat_get_info(iPixelFormat
);
70 case WGL_DRAW_TO_WINDOW_ARB
:
71 *pvalue
= pfi
->pfd
.dwFlags
& PFD_DRAW_TO_WINDOW
? TRUE
: FALSE
;
74 case WGL_DRAW_TO_BITMAP_ARB
:
75 *pvalue
= pfi
->pfd
.dwFlags
& PFD_DRAW_TO_BITMAP
? TRUE
: FALSE
;
78 case WGL_NEED_PALETTE_ARB
:
79 *pvalue
= pfi
->pfd
.dwFlags
& PFD_NEED_PALETTE
? TRUE
: FALSE
;
82 case WGL_NEED_SYSTEM_PALETTE_ARB
:
83 *pvalue
= pfi
->pfd
.dwFlags
& PFD_NEED_SYSTEM_PALETTE
? TRUE
: FALSE
;
86 case WGL_SWAP_METHOD_ARB
:
87 if (pfi
->pfd
.dwFlags
& PFD_SWAP_COPY
)
88 *pvalue
= WGL_SWAP_COPY_ARB
;
89 else if (pfi
->pfd
.dwFlags
& PFD_SWAP_EXCHANGE
)
90 *pvalue
= WGL_SWAP_EXCHANGE_EXT
;
92 *pvalue
= WGL_SWAP_UNDEFINED_ARB
;
95 case WGL_SWAP_LAYER_BUFFERS_ARB
:
99 case WGL_NUMBER_OVERLAYS_ARB
:
103 case WGL_NUMBER_UNDERLAYS_ARB
:
107 case WGL_BIND_TO_TEXTURE_RGB_ARB
:
108 /* WGL_ARB_render_texture */
109 *pvalue
= pfi
->bindToTextureRGB
;
112 case WGL_BIND_TO_TEXTURE_RGBA_ARB
:
113 /* WGL_ARB_render_texture */
114 *pvalue
= pfi
->bindToTextureRGBA
;
118 if (iLayerPlane
!= 0)
122 case WGL_ACCELERATION_ARB
:
123 *pvalue
= WGL_FULL_ACCELERATION_ARB
;
126 case WGL_TRANSPARENT_ARB
:
130 case WGL_TRANSPARENT_RED_VALUE_ARB
:
131 case WGL_TRANSPARENT_GREEN_VALUE_ARB
:
132 case WGL_TRANSPARENT_BLUE_VALUE_ARB
:
133 case WGL_TRANSPARENT_ALPHA_VALUE_ARB
:
134 case WGL_TRANSPARENT_INDEX_VALUE_ARB
:
137 case WGL_SHARE_DEPTH_ARB
:
138 case WGL_SHARE_STENCIL_ARB
:
139 case WGL_SHARE_ACCUM_ARB
:
143 case WGL_SUPPORT_GDI_ARB
:
144 *pvalue
= pfi
->pfd
.dwFlags
& PFD_SUPPORT_GDI
? TRUE
: FALSE
;
147 case WGL_SUPPORT_OPENGL_ARB
:
148 *pvalue
= pfi
->pfd
.dwFlags
& PFD_SUPPORT_OPENGL
? TRUE
: FALSE
;
151 case WGL_DOUBLE_BUFFER_ARB
:
152 *pvalue
= pfi
->pfd
.dwFlags
& PFD_DOUBLEBUFFER
? TRUE
: FALSE
;
156 *pvalue
= pfi
->pfd
.dwFlags
& PFD_STEREO
? TRUE
: FALSE
;
159 case WGL_PIXEL_TYPE_ARB
:
160 switch (pfi
->pfd
.iPixelType
) {
162 if (util_format_is_float(pfi
->stvis
.color_format
)) {
163 *pvalue
= WGL_TYPE_RGBA_FLOAT_ARB
;
166 *pvalue
= WGL_TYPE_RGBA_ARB
;
169 case PFD_TYPE_COLORINDEX
:
170 *pvalue
= WGL_TYPE_COLORINDEX_ARB
;
177 case WGL_COLOR_BITS_ARB
:
178 *pvalue
= pfi
->pfd
.cColorBits
;
181 case WGL_RED_BITS_ARB
:
182 *pvalue
= pfi
->pfd
.cRedBits
;
185 case WGL_RED_SHIFT_ARB
:
186 *pvalue
= pfi
->pfd
.cRedShift
;
189 case WGL_GREEN_BITS_ARB
:
190 *pvalue
= pfi
->pfd
.cGreenBits
;
193 case WGL_GREEN_SHIFT_ARB
:
194 *pvalue
= pfi
->pfd
.cGreenShift
;
197 case WGL_BLUE_BITS_ARB
:
198 *pvalue
= pfi
->pfd
.cBlueBits
;
201 case WGL_BLUE_SHIFT_ARB
:
202 *pvalue
= pfi
->pfd
.cBlueShift
;
205 case WGL_ALPHA_BITS_ARB
:
206 *pvalue
= pfi
->pfd
.cAlphaBits
;
209 case WGL_ALPHA_SHIFT_ARB
:
210 *pvalue
= pfi
->pfd
.cAlphaShift
;
213 case WGL_ACCUM_BITS_ARB
:
214 *pvalue
= pfi
->pfd
.cAccumBits
;
217 case WGL_ACCUM_RED_BITS_ARB
:
218 *pvalue
= pfi
->pfd
.cAccumRedBits
;
221 case WGL_ACCUM_GREEN_BITS_ARB
:
222 *pvalue
= pfi
->pfd
.cAccumGreenBits
;
225 case WGL_ACCUM_BLUE_BITS_ARB
:
226 *pvalue
= pfi
->pfd
.cAccumBlueBits
;
229 case WGL_ACCUM_ALPHA_BITS_ARB
:
230 *pvalue
= pfi
->pfd
.cAccumAlphaBits
;
233 case WGL_DEPTH_BITS_ARB
:
234 *pvalue
= pfi
->pfd
.cDepthBits
;
237 case WGL_STENCIL_BITS_ARB
:
238 *pvalue
= pfi
->pfd
.cStencilBits
;
241 case WGL_AUX_BUFFERS_ARB
:
242 *pvalue
= pfi
->pfd
.cAuxBuffers
;
245 case WGL_SAMPLE_BUFFERS_ARB
:
246 *pvalue
= (pfi
->stvis
.samples
> 1);
249 case WGL_SAMPLES_ARB
:
250 *pvalue
= pfi
->stvis
.samples
;
254 /* WGL_ARB_pbuffer */
256 case WGL_MAX_PBUFFER_WIDTH_ARB
:
257 case WGL_MAX_PBUFFER_HEIGHT_ARB
:
258 *pvalue
= stw_dev
->max_2d_length
;
261 case WGL_MAX_PBUFFER_PIXELS_ARB
:
262 *pvalue
= stw_dev
->max_2d_length
* stw_dev
->max_2d_length
;
265 case WGL_DRAW_TO_PBUFFER_ARB
:
277 struct attrib_match_info
284 static const struct attrib_match_info attrib_match
[] = {
285 /* WGL_ARB_pixel_format */
286 { WGL_DRAW_TO_WINDOW_ARB
, 0, TRUE
},
287 { WGL_DRAW_TO_BITMAP_ARB
, 0, TRUE
},
288 { WGL_ACCELERATION_ARB
, 0, TRUE
},
289 { WGL_NEED_PALETTE_ARB
, 0, TRUE
},
290 { WGL_NEED_SYSTEM_PALETTE_ARB
, 0, TRUE
},
291 { WGL_SWAP_LAYER_BUFFERS_ARB
, 0, TRUE
},
292 { WGL_SWAP_METHOD_ARB
, 0, TRUE
},
293 { WGL_NUMBER_OVERLAYS_ARB
, 4, FALSE
},
294 { WGL_NUMBER_UNDERLAYS_ARB
, 4, FALSE
},
295 /*{ WGL_SHARE_DEPTH_ARB, 0, TRUE },*/ /* no overlays -- ignore */
296 /*{ WGL_SHARE_STENCIL_ARB, 0, TRUE },*/ /* no overlays -- ignore */
297 /*{ WGL_SHARE_ACCUM_ARB, 0, TRUE },*/ /* no overlays -- ignore */
298 { WGL_SUPPORT_GDI_ARB
, 0, TRUE
},
299 { WGL_SUPPORT_OPENGL_ARB
, 0, TRUE
},
300 { WGL_DOUBLE_BUFFER_ARB
, 0, TRUE
},
301 { WGL_STEREO_ARB
, 0, TRUE
},
302 { WGL_PIXEL_TYPE_ARB
, 0, TRUE
},
303 { WGL_COLOR_BITS_ARB
, 1, FALSE
},
304 { WGL_RED_BITS_ARB
, 1, FALSE
},
305 { WGL_GREEN_BITS_ARB
, 1, FALSE
},
306 { WGL_BLUE_BITS_ARB
, 1, FALSE
},
307 { WGL_ALPHA_BITS_ARB
, 1, FALSE
},
308 { WGL_ACCUM_BITS_ARB
, 1, FALSE
},
309 { WGL_ACCUM_RED_BITS_ARB
, 1, FALSE
},
310 { WGL_ACCUM_GREEN_BITS_ARB
, 1, FALSE
},
311 { WGL_ACCUM_BLUE_BITS_ARB
, 1, FALSE
},
312 { WGL_ACCUM_ALPHA_BITS_ARB
, 1, FALSE
},
313 { WGL_DEPTH_BITS_ARB
, 1, FALSE
},
314 { WGL_STENCIL_BITS_ARB
, 1, FALSE
},
315 { WGL_AUX_BUFFERS_ARB
, 2, FALSE
},
317 /* WGL_ARB_multisample */
318 { WGL_SAMPLE_BUFFERS_ARB
, 2, FALSE
},
319 { WGL_SAMPLES_ARB
, 2, FALSE
},
321 /* WGL_ARB_render_texture */
322 { WGL_BIND_TO_TEXTURE_RGB_ARB
, 0, FALSE
},
323 { WGL_BIND_TO_TEXTURE_RGBA_ARB
, 0, FALSE
},
326 struct stw_pixelformat_score
334 score_pixelformats(struct stw_pixelformat_score
*scores
,
340 const struct attrib_match_info
*ami
= NULL
;
343 /* Find out if a given attribute should be considered for score calculation.
345 for (i
= 0; i
< ARRAY_SIZE(attrib_match
); i
++) {
346 if (attrib_match
[i
].attribute
== attribute
) {
347 ami
= &attrib_match
[i
];
354 /* Iterate all pixelformats, query the requested attribute and calculate
357 for (index
= 0; index
< count
; index
++) {
360 if (!stw_query_attrib(index
+ 1, 0, attribute
, &actual_value
))
364 /* For an exact match criteria, if the actual and expected values
365 * differ, the score is set to 0 points, effectively removing the
366 * pixelformat from a list of matching pixelformats.
368 if (actual_value
!= expected_value
)
369 scores
[index
].points
= 0;
372 /* For a minimum match criteria, if the actual value is smaller than
373 * the expected value, the pixelformat is rejected (score set to
374 * 0). However, if the actual value is bigger, the pixelformat is
375 * given a penalty to favour pixelformats that more closely match the
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
)
390 WINGDIAPI BOOL APIENTRY
391 wglChoosePixelFormatARB(HDC hdc
, const int *piAttribIList
,
392 const FLOAT
*pfAttribFList
, UINT nMaxFormats
,
393 int *piFormats
, UINT
*nNumFormats
)
396 struct stw_pixelformat_score
*scores
;
401 /* Allocate and initialize pixelformat score table -- better matches
402 * have higher scores. Start with a high score and take out penalty
403 * points for a mismatch when the match does not have to be exact.
404 * Set a score to 0 if there is a mismatch for an exact match criteria.
406 count
= stw_pixelformat_get_extended_count();
407 scores
= (struct stw_pixelformat_score
*)
408 MALLOC(count
* sizeof(struct stw_pixelformat_score
));
411 for (i
= 0; i
< count
; i
++) {
412 scores
[i
].points
= 0x7fffffff;
416 /* Given the attribute list calculate a score for each pixelformat.
418 if (piAttribIList
!= NULL
) {
419 while (*piAttribIList
!= 0) {
420 if (!score_pixelformats(scores
, count
, piAttribIList
[0],
428 if (pfAttribFList
!= NULL
) {
429 while (*pfAttribFList
!= 0) {
430 if (!score_pixelformats(scores
, count
, (int) pfAttribFList
[0],
431 (int) pfAttribFList
[1])) {
439 /* Bubble-sort the resulting scores. Pixelformats with higher scores go
440 * first. TODO: Find out if there are any patent issues with it.
448 for (i
= 1; i
< n
; i
++) {
449 if (scores
[i
- 1].points
< scores
[i
].points
) {
450 struct stw_pixelformat_score score
= scores
[i
- 1];
452 scores
[i
- 1] = scores
[i
];
462 /* Return a list of pixelformats that are the best match.
463 * Reject pixelformats with non-positive scores.
465 for (i
= 0; i
< count
; i
++) {
466 if (scores
[i
].points
> 0) {
467 piFormats
[*nNumFormats
] = scores
[i
].index
+ 1;
469 if (*nNumFormats
>= nMaxFormats
) {
480 WINGDIAPI BOOL APIENTRY
481 wglGetPixelFormatAttribfvARB(HDC hdc
, int iPixelFormat
, int iLayerPlane
,
482 UINT nAttributes
, const int *piAttributes
,
489 for (i
= 0; i
< nAttributes
; i
++) {
492 if (!stw_query_attrib(iPixelFormat
, iLayerPlane
,
493 piAttributes
[i
], &value
))
495 pfValues
[i
] = (FLOAT
) value
;
502 WINGDIAPI BOOL APIENTRY
503 wglGetPixelFormatAttribivARB(HDC hdc
, int iPixelFormat
, int iLayerPlane
,
504 UINT nAttributes
, const int *piAttributes
,
511 for (i
= 0; i
< nAttributes
; i
++) {
512 if (!stw_query_attrib(iPixelFormat
, iLayerPlane
,
513 piAttributes
[i
], &piValues
[i
]))