~ubuntu-branches/ubuntu/precise/mesa-lts-quantal/precise-updates

« back to all changes in this revision

Viewing changes to src/gallium/state_trackers/wgl/stw_ext_pixelformat.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2012-11-30 20:58:34 UTC
  • Revision ID: package-import@ubuntu.com-20121130205834-gazuvne3fpwlf012
Tags: upstream-9.0
ImportĀ upstreamĀ versionĀ 9.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 *
 
3
 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
 
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 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.
 
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
 
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
      *pvalue = pfi->pfd.dwFlags & PFD_SWAP_COPY ? WGL_SWAP_COPY_ARB : WGL_SWAP_UNDEFINED_ARB;
 
92
      return TRUE;
 
93
 
 
94
   case WGL_SWAP_LAYER_BUFFERS_ARB:
 
95
      *pvalue = FALSE;
 
96
      return TRUE;
 
97
 
 
98
   case WGL_NUMBER_OVERLAYS_ARB:
 
99
      *pvalue = 0;
 
100
      return TRUE;
 
101
 
 
102
   case WGL_NUMBER_UNDERLAYS_ARB:
 
103
      *pvalue = 0;
 
104
      return TRUE;
 
105
   }
 
106
 
 
107
   if (iLayerPlane != 0)
 
108
      return FALSE;
 
109
 
 
110
   switch (attrib) {
 
111
   case WGL_ACCELERATION_ARB:
 
112
      *pvalue = WGL_FULL_ACCELERATION_ARB;
 
113
      break;
 
114
 
 
115
   case WGL_TRANSPARENT_ARB:
 
116
      *pvalue = FALSE;
 
117
      break;
 
118
 
 
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:
 
124
      break;
 
125
 
 
126
   case WGL_SHARE_DEPTH_ARB:
 
127
   case WGL_SHARE_STENCIL_ARB:
 
128
   case WGL_SHARE_ACCUM_ARB:
 
129
      *pvalue = TRUE;
 
130
      break;
 
131
 
 
132
   case WGL_SUPPORT_GDI_ARB:
 
133
      *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_GDI ? TRUE : FALSE;
 
134
      break;
 
135
 
 
136
   case WGL_SUPPORT_OPENGL_ARB:
 
137
      *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_OPENGL ? TRUE : FALSE;
 
138
      break;
 
139
 
 
140
   case WGL_DOUBLE_BUFFER_ARB:
 
141
      *pvalue = pfi->pfd.dwFlags & PFD_DOUBLEBUFFER ? TRUE : FALSE;
 
142
      break;
 
143
 
 
144
   case WGL_STEREO_ARB:
 
145
      *pvalue = pfi->pfd.dwFlags & PFD_STEREO ? TRUE : FALSE;
 
146
      break;
 
147
 
 
148
   case WGL_PIXEL_TYPE_ARB:
 
149
      switch (pfi->pfd.iPixelType) {
 
150
      case PFD_TYPE_RGBA:
 
151
         if (util_format_is_float(pfi->stvis.color_format)) {
 
152
            *pvalue = WGL_TYPE_RGBA_FLOAT_ARB;
 
153
         }
 
154
         else {
 
155
            *pvalue = WGL_TYPE_RGBA_ARB;
 
156
         }
 
157
         break;
 
158
      case PFD_TYPE_COLORINDEX:
 
159
         *pvalue = WGL_TYPE_COLORINDEX_ARB;
 
160
         break;
 
161
      default:
 
162
         return FALSE;
 
163
      }
 
164
      break;
 
165
 
 
166
   case WGL_COLOR_BITS_ARB:
 
167
      *pvalue = pfi->pfd.cColorBits;
 
168
      break;
 
169
 
 
170
   case WGL_RED_BITS_ARB:
 
171
      *pvalue = pfi->pfd.cRedBits;
 
172
      break;
 
173
 
 
174
   case WGL_RED_SHIFT_ARB:
 
175
      *pvalue = pfi->pfd.cRedShift;
 
176
      break;
 
177
 
 
178
   case WGL_GREEN_BITS_ARB:
 
179
      *pvalue = pfi->pfd.cGreenBits;
 
180
      break;
 
181
 
 
182
   case WGL_GREEN_SHIFT_ARB:
 
183
      *pvalue = pfi->pfd.cGreenShift;
 
184
      break;
 
185
 
 
186
   case WGL_BLUE_BITS_ARB:
 
187
      *pvalue = pfi->pfd.cBlueBits;
 
188
      break;
 
189
 
 
190
   case WGL_BLUE_SHIFT_ARB:
 
191
      *pvalue = pfi->pfd.cBlueShift;
 
192
      break;
 
193
 
 
194
   case WGL_ALPHA_BITS_ARB:
 
195
      *pvalue = pfi->pfd.cAlphaBits;
 
196
      break;
 
197
 
 
198
   case WGL_ALPHA_SHIFT_ARB:
 
199
      *pvalue = pfi->pfd.cAlphaShift;
 
200
      break;
 
201
 
 
202
   case WGL_ACCUM_BITS_ARB:
 
203
      *pvalue = pfi->pfd.cAccumBits;
 
204
      break;
 
205
 
 
206
   case WGL_ACCUM_RED_BITS_ARB:
 
207
      *pvalue = pfi->pfd.cAccumRedBits;
 
208
      break;
 
209
 
 
210
   case WGL_ACCUM_GREEN_BITS_ARB:
 
211
      *pvalue = pfi->pfd.cAccumGreenBits;
 
212
      break;
 
213
 
 
214
   case WGL_ACCUM_BLUE_BITS_ARB:
 
215
      *pvalue = pfi->pfd.cAccumBlueBits;
 
216
      break;
 
217
 
 
218
   case WGL_ACCUM_ALPHA_BITS_ARB:
 
219
      *pvalue = pfi->pfd.cAccumAlphaBits;
 
220
      break;
 
221
 
 
222
   case WGL_DEPTH_BITS_ARB:
 
223
      *pvalue = pfi->pfd.cDepthBits;
 
224
      break;
 
225
 
 
226
   case WGL_STENCIL_BITS_ARB:
 
227
      *pvalue = pfi->pfd.cStencilBits;
 
228
      break;
 
229
 
 
230
   case WGL_AUX_BUFFERS_ARB:
 
231
      *pvalue = pfi->pfd.cAuxBuffers;
 
232
      break;
 
233
 
 
234
   case WGL_SAMPLE_BUFFERS_ARB:
 
235
      *pvalue = 1;
 
236
      break;
 
237
 
 
238
   case WGL_SAMPLES_ARB:
 
239
      *pvalue = pfi->stvis.samples;
 
240
      break;
 
241
 
 
242
 
 
243
   /* WGL_ARB_pbuffer */
 
244
 
 
245
   case WGL_MAX_PBUFFER_WIDTH_ARB:
 
246
   case WGL_MAX_PBUFFER_HEIGHT_ARB:
 
247
      *pvalue = stw_dev->max_2d_length;
 
248
      break;
 
249
 
 
250
   case WGL_MAX_PBUFFER_PIXELS_ARB:
 
251
      *pvalue = stw_dev->max_2d_length * stw_dev->max_2d_length;
 
252
      break;
 
253
 
 
254
   case WGL_DRAW_TO_PBUFFER_ARB:
 
255
      *pvalue = 1;
 
256
      break;
 
257
 
 
258
 
 
259
   default:
 
260
      return FALSE;
 
261
   }
 
262
 
 
263
   return TRUE;
 
264
}
 
265
 
 
266
struct attrib_match_info
 
267
{
 
268
   int attribute;
 
269
   int weight;
 
270
   BOOL exact;
 
271
};
 
272
 
 
273
static const struct attrib_match_info attrib_match[] = {
 
274
 
 
275
   /* WGL_ARB_pixel_format */
 
276
   { WGL_DRAW_TO_WINDOW_ARB,      0, TRUE },
 
277
   { WGL_DRAW_TO_BITMAP_ARB,      0, TRUE },
 
278
   { WGL_ACCELERATION_ARB,        0, TRUE },
 
279
   { WGL_NEED_PALETTE_ARB,        0, TRUE },
 
280
   { WGL_NEED_SYSTEM_PALETTE_ARB, 0, TRUE },
 
281
   { WGL_SWAP_LAYER_BUFFERS_ARB,  0, TRUE },
 
282
   { WGL_SWAP_METHOD_ARB,         0, TRUE },
 
283
   { WGL_NUMBER_OVERLAYS_ARB,     4, FALSE },
 
284
   { WGL_NUMBER_UNDERLAYS_ARB,    4, FALSE },
 
285
   /*{ WGL_SHARE_DEPTH_ARB,         0, TRUE },*/     /* no overlays -- ignore */
 
286
   /*{ WGL_SHARE_STENCIL_ARB,       0, TRUE },*/   /* no overlays -- ignore */
 
287
   /*{ WGL_SHARE_ACCUM_ARB,         0, TRUE },*/     /* no overlays -- ignore */
 
288
   { WGL_SUPPORT_GDI_ARB,         0, TRUE },
 
289
   { WGL_SUPPORT_OPENGL_ARB,      0, TRUE },
 
290
   { WGL_DOUBLE_BUFFER_ARB,       0, TRUE },
 
291
   { WGL_STEREO_ARB,              0, TRUE },
 
292
   { WGL_PIXEL_TYPE_ARB,          0, TRUE },
 
293
   { WGL_COLOR_BITS_ARB,          1, FALSE },
 
294
   { WGL_RED_BITS_ARB,            1, FALSE },
 
295
   { WGL_GREEN_BITS_ARB,          1, FALSE },
 
296
   { WGL_BLUE_BITS_ARB,           1, FALSE },
 
297
   { WGL_ALPHA_BITS_ARB,          1, FALSE },
 
298
   { WGL_ACCUM_BITS_ARB,          1, FALSE },
 
299
   { WGL_ACCUM_RED_BITS_ARB,      1, FALSE },
 
300
   { WGL_ACCUM_GREEN_BITS_ARB,    1, FALSE },
 
301
   { WGL_ACCUM_BLUE_BITS_ARB,     1, FALSE },
 
302
   { WGL_ACCUM_ALPHA_BITS_ARB,    1, FALSE },
 
303
   { WGL_DEPTH_BITS_ARB,          1, FALSE },
 
304
   { WGL_STENCIL_BITS_ARB,        1, FALSE },
 
305
   { WGL_AUX_BUFFERS_ARB,         2, FALSE },
 
306
 
 
307
   /* WGL_ARB_multisample */
 
308
   { WGL_SAMPLE_BUFFERS_ARB,      2, FALSE },
 
309
   { WGL_SAMPLES_ARB,             2, FALSE }
 
310
};
 
311
 
 
312
struct stw_pixelformat_score
 
313
{
 
314
   int points;
 
315
   uint index;
 
316
};
 
317
 
 
318
static BOOL
 
319
score_pixelformats(
 
320
   struct stw_pixelformat_score *scores,
 
321
   uint count,
 
322
   int attribute,
 
323
   int expected_value )
 
324
{
 
325
   uint i;
 
326
   const struct attrib_match_info *ami = NULL;
 
327
   uint index;
 
328
 
 
329
   /* Find out if a given attribute should be considered for score calculation.
 
330
    */
 
331
   for (i = 0; i < sizeof( attrib_match ) / sizeof( attrib_match[0] ); i++) {
 
332
      if (attrib_match[i].attribute == attribute) {
 
333
         ami = &attrib_match[i];
 
334
         break;
 
335
      }
 
336
   }
 
337
   if (ami == NULL)
 
338
      return TRUE;
 
339
 
 
340
   /* Iterate all pixelformats, query the requested attribute and calculate
 
341
    * score points.
 
342
    */
 
343
   for (index = 0; index < count; index++) {
 
344
      int actual_value;
 
345
 
 
346
      if (!stw_query_attrib( index + 1, 0, attribute, &actual_value ))
 
347
         return FALSE;
 
348
 
 
349
      if (ami->exact) {
 
350
         /* For an exact match criteria, if the actual and expected values differ,
 
351
          * the score is set to 0 points, effectively removing the pixelformat
 
352
          * from a list of matching pixelformats.
 
353
          */
 
354
         if (actual_value != expected_value)
 
355
            scores[index].points = 0;
 
356
      }
 
357
      else {
 
358
         /* For a minimum match criteria, if the actual value is smaller than the expected
 
359
          * value, the pixelformat is rejected (score set to 0). However, if the actual
 
360
          * value is bigger, the pixelformat is given a penalty to favour pixelformats that
 
361
          * more closely match the expected values.
 
362
          */
 
363
         if (actual_value < expected_value)
 
364
            scores[index].points = 0;
 
365
         else if (actual_value > expected_value)
 
366
            scores[index].points -= (actual_value - expected_value) * ami->weight;
 
367
      }
 
368
   }
 
369
 
 
370
   return TRUE;
 
371
}
 
372
 
 
373
WINGDIAPI BOOL APIENTRY
 
374
wglChoosePixelFormatARB(
 
375
   HDC hdc,
 
376
   const int *piAttribIList,
 
377
   const FLOAT *pfAttribFList,
 
378
   UINT nMaxFormats,
 
379
   int *piFormats,
 
380
   UINT *nNumFormats )
 
381
{
 
382
   uint count;
 
383
   struct stw_pixelformat_score *scores;
 
384
   uint i;
 
385
 
 
386
   *nNumFormats = 0;
 
387
 
 
388
   /* Allocate and initialize pixelformat score table -- better matches
 
389
    * have higher scores. Start with a high score and take out penalty
 
390
    * points for a mismatch when the match does not have to be exact.
 
391
    * Set a score to 0 if there is a mismatch for an exact match criteria.
 
392
    */
 
393
   count = stw_pixelformat_get_extended_count();
 
394
   scores = (struct stw_pixelformat_score *) MALLOC( count * sizeof( struct stw_pixelformat_score ) );
 
395
   if (scores == NULL)
 
396
      return FALSE;
 
397
   for (i = 0; i < count; i++) {
 
398
      scores[i].points = 0x7fffffff;
 
399
      scores[i].index = i;
 
400
   }
 
401
 
 
402
   /* Given the attribute list calculate a score for each pixelformat.
 
403
    */
 
404
   if (piAttribIList != NULL) {
 
405
      while (*piAttribIList != 0) {
 
406
         if (!score_pixelformats( scores, count, piAttribIList[0], piAttribIList[1] )) {
 
407
            FREE( scores );
 
408
            return FALSE;
 
409
         }
 
410
         piAttribIList += 2;
 
411
      }
 
412
   }
 
413
   if (pfAttribFList != NULL) {
 
414
      while (*pfAttribFList != 0) {
 
415
         if (!score_pixelformats( scores, count, (int) pfAttribFList[0], (int) pfAttribFList[1] )) {
 
416
            FREE( scores );
 
417
            return FALSE;
 
418
         }
 
419
         pfAttribFList += 2;
 
420
      }
 
421
   }
 
422
 
 
423
   /* Bubble-sort the resulting scores. Pixelformats with higher scores go first.
 
424
    * TODO: Find out if there are any patent issues with it.
 
425
    */
 
426
   if (count > 1) {
 
427
      uint n = count;
 
428
      boolean swapped;
 
429
 
 
430
      do {
 
431
         swapped = FALSE;
 
432
         for (i = 1; i < n; i++) {
 
433
            if (scores[i - 1].points < scores[i].points) {
 
434
               struct stw_pixelformat_score score = scores[i - 1];
 
435
 
 
436
               scores[i - 1] = scores[i];
 
437
               scores[i] = score;
 
438
               swapped = TRUE;
 
439
            }
 
440
         }
 
441
         n--;
 
442
      }
 
443
      while (swapped);
 
444
   }
 
445
 
 
446
   /* Return a list of pixelformats that are the best match.
 
447
    * Reject pixelformats with non-positive scores.
 
448
    */
 
449
   for (i = 0; i < count; i++) {
 
450
      if (scores[i].points > 0) {
 
451
         if (*nNumFormats < nMaxFormats)
 
452
            piFormats[*nNumFormats] = scores[i].index + 1;
 
453
         (*nNumFormats)++;
 
454
      }
 
455
   }
 
456
 
 
457
   FREE( scores );
 
458
   return TRUE;
 
459
}
 
460
 
 
461
WINGDIAPI BOOL APIENTRY
 
462
wglGetPixelFormatAttribfvARB(
 
463
   HDC hdc,
 
464
   int iPixelFormat,
 
465
   int iLayerPlane,
 
466
   UINT nAttributes,
 
467
   const int *piAttributes,
 
468
   FLOAT *pfValues )
 
469
{
 
470
   UINT i;
 
471
 
 
472
   (void) hdc;
 
473
 
 
474
   for (i = 0; i < nAttributes; i++) {
 
475
      int value;
 
476
 
 
477
      if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value ))
 
478
         return FALSE;
 
479
      pfValues[i] = (FLOAT) value;
 
480
   }
 
481
 
 
482
   return TRUE;
 
483
}
 
484
 
 
485
WINGDIAPI BOOL APIENTRY
 
486
wglGetPixelFormatAttribivARB(
 
487
   HDC hdc,
 
488
   int iPixelFormat,
 
489
   int iLayerPlane,
 
490
   UINT nAttributes,
 
491
   const int *piAttributes,
 
492
   int *piValues )
 
493
{
 
494
   UINT i;
 
495
 
 
496
   (void) hdc;
 
497
 
 
498
   for (i = 0; i < nAttributes; i++) {
 
499
      if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] ))
 
500
         return FALSE;
 
501
   }
 
502
 
 
503
   return TRUE;
 
504
}