• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2008 VMware, Inc.
4  * All Rights Reserved.
5  *
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:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
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.
25  *
26  **************************************************************************/
27 
28 /**
29  * @file
30  *
31  * WGL_ARB_pixel_format extension implementation.
32  *
33  * @sa http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
34  */
35 
36 
37 #include <windows.h>
38 
39 #define WGL_WGLEXT_PROTOTYPES
40 
41 #include <GL/gl.h>
42 #include <GL/wglext.h>
43 
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"
49 
50 
51 static boolean
stw_query_attrib(int iPixelFormat,int iLayerPlane,int attrib,int * pvalue)52 stw_query_attrib(
53    int iPixelFormat,
54    int iLayerPlane,
55    int attrib,
56    int *pvalue )
57 {
58    uint count;
59    const struct stw_pixelformat_info *pfi;
60 
61    count = stw_pixelformat_get_extended_count();
62 
63    if (attrib == WGL_NUMBER_PIXEL_FORMATS_ARB) {
64       *pvalue = (int) count;
65       return TRUE;
66    }
67 
68    pfi = stw_pixelformat_get_info( iPixelFormat );
69    if (!pfi) {
70       return FALSE;
71    }
72 
73    switch (attrib) {
74    case WGL_DRAW_TO_WINDOW_ARB:
75       *pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_WINDOW ? TRUE : FALSE;
76       return TRUE;
77 
78    case WGL_DRAW_TO_BITMAP_ARB:
79       *pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_BITMAP ? TRUE : FALSE;
80       return TRUE;
81 
82    case WGL_NEED_PALETTE_ARB:
83       *pvalue = pfi->pfd.dwFlags & PFD_NEED_PALETTE ? TRUE : FALSE;
84       return TRUE;
85 
86    case WGL_NEED_SYSTEM_PALETTE_ARB:
87       *pvalue = pfi->pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE;
88       return TRUE;
89 
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;
95       else
96          *pvalue = WGL_SWAP_UNDEFINED_ARB;
97       return TRUE;
98 
99    case WGL_SWAP_LAYER_BUFFERS_ARB:
100       *pvalue = FALSE;
101       return TRUE;
102 
103    case WGL_NUMBER_OVERLAYS_ARB:
104       *pvalue = 0;
105       return TRUE;
106 
107    case WGL_NUMBER_UNDERLAYS_ARB:
108       *pvalue = 0;
109       return TRUE;
110 
111    case WGL_BIND_TO_TEXTURE_RGB_ARB:
112       /* WGL_ARB_render_texture */
113       *pvalue = pfi->bindToTextureRGB;
114       return TRUE;
115 
116    case WGL_BIND_TO_TEXTURE_RGBA_ARB:
117       /* WGL_ARB_render_texture */
118       *pvalue = pfi->bindToTextureRGBA;
119       return TRUE;
120    }
121 
122    if (iLayerPlane != 0)
123       return FALSE;
124 
125    switch (attrib) {
126    case WGL_ACCELERATION_ARB:
127       *pvalue = WGL_FULL_ACCELERATION_ARB;
128       break;
129 
130    case WGL_TRANSPARENT_ARB:
131       *pvalue = FALSE;
132       break;
133 
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:
139       break;
140 
141    case WGL_SHARE_DEPTH_ARB:
142    case WGL_SHARE_STENCIL_ARB:
143    case WGL_SHARE_ACCUM_ARB:
144       *pvalue = TRUE;
145       break;
146 
147    case WGL_SUPPORT_GDI_ARB:
148       *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_GDI ? TRUE : FALSE;
149       break;
150 
151    case WGL_SUPPORT_OPENGL_ARB:
152       *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_OPENGL ? TRUE : FALSE;
153       break;
154 
155    case WGL_DOUBLE_BUFFER_ARB:
156       *pvalue = pfi->pfd.dwFlags & PFD_DOUBLEBUFFER ? TRUE : FALSE;
157       break;
158 
159    case WGL_STEREO_ARB:
160       *pvalue = pfi->pfd.dwFlags & PFD_STEREO ? TRUE : FALSE;
161       break;
162 
163    case WGL_PIXEL_TYPE_ARB:
164       switch (pfi->pfd.iPixelType) {
165       case PFD_TYPE_RGBA:
166          if (util_format_is_float(pfi->stvis.color_format)) {
167             *pvalue = WGL_TYPE_RGBA_FLOAT_ARB;
168          }
169          else {
170             *pvalue = WGL_TYPE_RGBA_ARB;
171          }
172          break;
173       case PFD_TYPE_COLORINDEX:
174          *pvalue = WGL_TYPE_COLORINDEX_ARB;
175          break;
176       default:
177          return FALSE;
178       }
179       break;
180 
181    case WGL_COLOR_BITS_ARB:
182       *pvalue = pfi->pfd.cColorBits;
183       break;
184 
185    case WGL_RED_BITS_ARB:
186       *pvalue = pfi->pfd.cRedBits;
187       break;
188 
189    case WGL_RED_SHIFT_ARB:
190       *pvalue = pfi->pfd.cRedShift;
191       break;
192 
193    case WGL_GREEN_BITS_ARB:
194       *pvalue = pfi->pfd.cGreenBits;
195       break;
196 
197    case WGL_GREEN_SHIFT_ARB:
198       *pvalue = pfi->pfd.cGreenShift;
199       break;
200 
201    case WGL_BLUE_BITS_ARB:
202       *pvalue = pfi->pfd.cBlueBits;
203       break;
204 
205    case WGL_BLUE_SHIFT_ARB:
206       *pvalue = pfi->pfd.cBlueShift;
207       break;
208 
209    case WGL_ALPHA_BITS_ARB:
210       *pvalue = pfi->pfd.cAlphaBits;
211       break;
212 
213    case WGL_ALPHA_SHIFT_ARB:
214       *pvalue = pfi->pfd.cAlphaShift;
215       break;
216 
217    case WGL_ACCUM_BITS_ARB:
218       *pvalue = pfi->pfd.cAccumBits;
219       break;
220 
221    case WGL_ACCUM_RED_BITS_ARB:
222       *pvalue = pfi->pfd.cAccumRedBits;
223       break;
224 
225    case WGL_ACCUM_GREEN_BITS_ARB:
226       *pvalue = pfi->pfd.cAccumGreenBits;
227       break;
228 
229    case WGL_ACCUM_BLUE_BITS_ARB:
230       *pvalue = pfi->pfd.cAccumBlueBits;
231       break;
232 
233    case WGL_ACCUM_ALPHA_BITS_ARB:
234       *pvalue = pfi->pfd.cAccumAlphaBits;
235       break;
236 
237    case WGL_DEPTH_BITS_ARB:
238       *pvalue = pfi->pfd.cDepthBits;
239       break;
240 
241    case WGL_STENCIL_BITS_ARB:
242       *pvalue = pfi->pfd.cStencilBits;
243       break;
244 
245    case WGL_AUX_BUFFERS_ARB:
246       *pvalue = pfi->pfd.cAuxBuffers;
247       break;
248 
249    case WGL_SAMPLE_BUFFERS_ARB:
250       *pvalue = (pfi->stvis.samples > 1);
251       break;
252 
253    case WGL_SAMPLES_ARB:
254       *pvalue = pfi->stvis.samples;
255       break;
256 
257 
258    /* WGL_ARB_pbuffer */
259 
260    case WGL_MAX_PBUFFER_WIDTH_ARB:
261    case WGL_MAX_PBUFFER_HEIGHT_ARB:
262       *pvalue = stw_dev->max_2d_length;
263       break;
264 
265    case WGL_MAX_PBUFFER_PIXELS_ARB:
266       *pvalue = stw_dev->max_2d_length * stw_dev->max_2d_length;
267       break;
268 
269    case WGL_DRAW_TO_PBUFFER_ARB:
270       *pvalue = 1;
271       break;
272 
273 
274    default:
275       return FALSE;
276    }
277 
278    return TRUE;
279 }
280 
281 struct attrib_match_info
282 {
283    int attribute;
284    int weight;
285    BOOL exact;
286 };
287 
288 static const struct attrib_match_info attrib_match[] = {
289 
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 },
321 
322    /* WGL_ARB_multisample */
323    { WGL_SAMPLE_BUFFERS_ARB,      2, FALSE },
324    { WGL_SAMPLES_ARB,             2, FALSE },
325 
326    /* WGL_ARB_render_texture */
327    { WGL_BIND_TO_TEXTURE_RGB_ARB, 0, FALSE },
328    { WGL_BIND_TO_TEXTURE_RGBA_ARB, 0, FALSE },
329 };
330 
331 struct stw_pixelformat_score
332 {
333    int points;
334    uint index;
335 };
336 
337 static BOOL
score_pixelformats(struct stw_pixelformat_score * scores,uint count,int attribute,int expected_value)338 score_pixelformats(
339    struct stw_pixelformat_score *scores,
340    uint count,
341    int attribute,
342    int expected_value )
343 {
344    uint i;
345    const struct attrib_match_info *ami = NULL;
346    uint index;
347 
348    /* Find out if a given attribute should be considered for score calculation.
349     */
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];
353          break;
354       }
355    }
356    if (ami == NULL)
357       return TRUE;
358 
359    /* Iterate all pixelformats, query the requested attribute and calculate
360     * score points.
361     */
362    for (index = 0; index < count; index++) {
363       int actual_value;
364 
365       if (!stw_query_attrib( index + 1, 0, attribute, &actual_value ))
366          return FALSE;
367 
368       if (ami->exact) {
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.
372           */
373          if (actual_value != expected_value)
374             scores[index].points = 0;
375       }
376       else {
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.
381           */
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;
386       }
387    }
388 
389    return TRUE;
390 }
391 
392 WINGDIAPI BOOL APIENTRY
wglChoosePixelFormatARB(HDC hdc,const int * piAttribIList,const FLOAT * pfAttribFList,UINT nMaxFormats,int * piFormats,UINT * nNumFormats)393 wglChoosePixelFormatARB(
394    HDC hdc,
395    const int *piAttribIList,
396    const FLOAT *pfAttribFList,
397    UINT nMaxFormats,
398    int *piFormats,
399    UINT *nNumFormats )
400 {
401    uint count;
402    struct stw_pixelformat_score *scores;
403    uint i;
404 
405    *nNumFormats = 0;
406 
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.
411     */
412    count = stw_pixelformat_get_extended_count();
413    scores = (struct stw_pixelformat_score *) MALLOC( count * sizeof( struct stw_pixelformat_score ) );
414    if (scores == NULL)
415       return FALSE;
416    for (i = 0; i < count; i++) {
417       scores[i].points = 0x7fffffff;
418       scores[i].index = i;
419    }
420 
421    /* Given the attribute list calculate a score for each pixelformat.
422     */
423    if (piAttribIList != NULL) {
424       while (*piAttribIList != 0) {
425          if (!score_pixelformats( scores, count, piAttribIList[0], piAttribIList[1] )) {
426             FREE( scores );
427             return FALSE;
428          }
429          piAttribIList += 2;
430       }
431    }
432    if (pfAttribFList != NULL) {
433       while (*pfAttribFList != 0) {
434          if (!score_pixelformats( scores, count, (int) pfAttribFList[0], (int) pfAttribFList[1] )) {
435             FREE( scores );
436             return FALSE;
437          }
438          pfAttribFList += 2;
439       }
440    }
441 
442    /* Bubble-sort the resulting scores. Pixelformats with higher scores go first.
443     * TODO: Find out if there are any patent issues with it.
444     */
445    if (count > 1) {
446       uint n = count;
447       boolean swapped;
448 
449       do {
450          swapped = FALSE;
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];
454 
455                scores[i - 1] = scores[i];
456                scores[i] = score;
457                swapped = TRUE;
458             }
459          }
460          n--;
461       }
462       while (swapped);
463    }
464 
465    /* Return a list of pixelformats that are the best match.
466     * Reject pixelformats with non-positive scores.
467     */
468    for (i = 0; i < count; i++) {
469       if (scores[i].points > 0) {
470 	 piFormats[*nNumFormats] = scores[i].index + 1;
471          (*nNumFormats)++;
472 	 if (*nNumFormats >= nMaxFormats) {
473 	    break;
474 	 }
475       }
476    }
477 
478    FREE( scores );
479    return TRUE;
480 }
481 
482 WINGDIAPI BOOL APIENTRY
wglGetPixelFormatAttribfvARB(HDC hdc,int iPixelFormat,int iLayerPlane,UINT nAttributes,const int * piAttributes,FLOAT * pfValues)483 wglGetPixelFormatAttribfvARB(
484    HDC hdc,
485    int iPixelFormat,
486    int iLayerPlane,
487    UINT nAttributes,
488    const int *piAttributes,
489    FLOAT *pfValues )
490 {
491    UINT i;
492 
493    (void) hdc;
494 
495    for (i = 0; i < nAttributes; i++) {
496       int value;
497 
498       if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value ))
499          return FALSE;
500       pfValues[i] = (FLOAT) value;
501    }
502 
503    return TRUE;
504 }
505 
506 WINGDIAPI BOOL APIENTRY
wglGetPixelFormatAttribivARB(HDC hdc,int iPixelFormat,int iLayerPlane,UINT nAttributes,const int * piAttributes,int * piValues)507 wglGetPixelFormatAttribivARB(
508    HDC hdc,
509    int iPixelFormat,
510    int iLayerPlane,
511    UINT nAttributes,
512    const int *piAttributes,
513    int *piValues )
514 {
515    UINT i;
516 
517    (void) hdc;
518 
519    for (i = 0; i < nAttributes; i++) {
520       if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] ))
521          return FALSE;
522    }
523 
524    return TRUE;
525 }
526