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