AllegroGL: scorer.c Source File

AllegroGL 0.4.4

- Main Page
- Related Pages
- Modules
- Files

- File List
- Globals

scorer.c
Go to the documentation of this file.
1 /* This code is (C) AllegroGL contributors, and double licensed under
2 * the GPL and zlib licenses. See gpl.txt or zlib.txt for details.
3 */
8 #include <allegro.h>
9
10 #include "alleggl.h"
11 #include "allglint.h"
12
13
14 static int best, best_score;
15
16
17 #define target allegro_gl_display_info
18 #define req __allegro_gl_required_settings
19 #define sug __allegro_gl_suggested_settings
20
21 #define PREFIX_I "agl-scorer INFO: "
22
23
24 /* __allegro_gl_fill_in_info()
25 * Will fill in missing settings by 'guessing'
26 * what the user intended.
27 */
28 void __allegro_gl_fill_in_info() {
29
30 int all_components = AGL_RED_DEPTH | AGL_GREEN_DEPTH | AGL_BLUE_DEPTH
31 | AGL_ALPHA_DEPTH;
32
33 /* If all color components were set, but not the color depth */
34 if ((((req | sug) & AGL_COLOR_DEPTH) == 0)
35 && (((req | sug) & all_components) == all_components)) {
36
37 target.colour_depth = target.pixel_size.rgba.r
38 + target.pixel_size.rgba.g
39 + target.pixel_size.rgba.b
40 + target.pixel_size.rgba.a;
41
42 /* Round depth to 8 bits */
43 target.colour_depth = (target.colour_depth + 7) / 8;
44 }
45 /* If only some components were set, guess the others */
46 else if ((req | sug) & all_components) {
47
48 int avg = ((req | sug) & AGL_RED_DEPTH ? target.pixel_size.rgba.r: 0)
49 + ((req | sug) & AGL_GREEN_DEPTH ? target.pixel_size.rgba.g: 0)
50 + ((req | sug) & AGL_BLUE_DEPTH ? target.pixel_size.rgba.b: 0)
51 + ((req | sug) & AGL_ALPHA_DEPTH ? target.pixel_size.rgba.a: 0);
52
53 int num = ((req | sug) & AGL_RED_DEPTH ? 1 : 0)
54 + ((req | sug) & AGL_GREEN_DEPTH ? 1 : 0)
55 + ((req | sug) & AGL_BLUE_DEPTH ? 1 : 0)
56 + ((req | sug) & AGL_ALPHA_DEPTH ? 1 : 0);
57
58 avg /= (num ? num : 1);
59
60 if (((req | sug) & AGL_RED_DEPTH )== 0) {
61 sug |= AGL_RED_DEPTH;
62 target.pixel_size.rgba.r = avg;
63 }
64 if (((req | sug) & AGL_GREEN_DEPTH) == 0) {
65 sug |= AGL_GREEN_DEPTH;
66 target.pixel_size.rgba.g = avg;
67 }
68 if (((req | sug) & AGL_BLUE_DEPTH) == 0) {
69 sug |= AGL_BLUE_DEPTH;
70 target.pixel_size.rgba.b = avg;
71 }
72 if (((req | sug) & AGL_ALPHA_DEPTH) == 0) {
73 sug |= AGL_ALPHA_DEPTH;
74 target.pixel_size.rgba.a = avg;
75 }
76
77 /* If color depth wasn't defined, figure it out */
78 if (((req | sug) & AGL_COLOR_DEPTH) == 0) {
79 __allegro_gl_fill_in_info();
80 }
81 }
82
83 /* If the user forgot to set a color depth in AGL, but used the
84 * Allegro one instead
85 */
86 if ((((req | sug) & AGL_COLOR_DEPTH) == 0) && (target.colour_depth == 0)) {
87 BITMAP *temp = create_bitmap(1, 1);
88 if (temp) {
89 allegro_gl_set(AGL_COLOR_DEPTH, bitmap_color_depth(temp));
90 allegro_gl_set(AGL_REQUIRE, AGL_COLOR_DEPTH);
91 destroy_bitmap(temp);
92 }
93 }
94
95
96 /* Prefer double-buffering */
97 if (!((req | sug) & AGL_DOUBLEBUFFER)) {
98 allegro_gl_set(AGL_DOUBLEBUFFER, 1);
99 allegro_gl_set(AGL_SUGGEST, AGL_DOUBLEBUFFER);
100 }
101
102 /* Prefer no multisamping */
103 if (!((req | sug) & (AGL_SAMPLE_BUFFERS | AGL_SAMPLES))) {
104 allegro_gl_set(AGL_SAMPLE_BUFFERS, 0);
105 allegro_gl_set(AGL_SAMPLES, 0);
106 allegro_gl_set(AGL_SUGGEST, AGL_SAMPLE_BUFFERS | AGL_SAMPLES);
107 }
108
109 /* Prefer monoscopic */
110 if (!((req | sug) & AGL_STEREO)) {
111 allegro_gl_set(AGL_STEREO, 0);
112 allegro_gl_set(AGL_SUGGEST, AGL_STEREO);
113 }
114
115 /* Prefer unsigned normalized buffers */
116 if (!((req | sug) & (AGL_FLOAT_COLOR | AGL_FLOAT_Z))) {
117 allegro_gl_set(AGL_FLOAT_COLOR, 0);
118 allegro_gl_set(AGL_FLOAT_Z, 0);
119 allegro_gl_set(AGL_SUGGEST, AGL_FLOAT_COLOR | AGL_FLOAT_Z);
120 }
121 }
122
123
124
125 void __allegro_gl_reset_scorer(void)
126 {
127 best = -1;
128 best_score = -1;
129 }
130
131
132
133 static int get_score(struct allegro_gl_display_info *dinfo)
134 {
135 int score = 0;
136
137 if (dinfo->colour_depth != target.colour_depth) {
138 if (req & AGL_COLOR_DEPTH) {
139 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
140 get_config_text("Color depth requirement not met."));
141 return -1;
142 }
143 }
144 else {
145 /* If requested color depths agree */
146 score += 128;
147 }
148
149
150 if (sug & AGL_COLOR_DEPTH) {
151 if (dinfo->colour_depth < target.colour_depth)
152 score += (96 * dinfo->colour_depth) / target.colour_depth;
153 else
154 score += 96 + 96 / (1 + dinfo->colour_depth - target.colour_depth);
155 }
156
157
158 /* check colour component widths here and Allegro formatness */
159 if ((req & AGL_RED_DEPTH)
160 && (dinfo->pixel_size.rgba.r != target.pixel_size.rgba.r)) {
161
162 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
163 get_config_text("Red depth requirement not met."));
164 return -1;
165 }
166
167 if (sug & AGL_RED_DEPTH) {
168 if (dinfo->pixel_size.rgba.r < target.pixel_size.rgba.r) {
169 score += (16 * dinfo->pixel_size.rgba.r) / target.pixel_size.rgba.r;
170 }
171 else {
172 score += 16
173 + 16 / (1 + dinfo->pixel_size.rgba.r - target.pixel_size.rgba.r);
174 }
175 }
176
177 if ((req & AGL_GREEN_DEPTH)
178 && (dinfo->pixel_size.rgba.g != target.pixel_size.rgba.g)) {
179
180 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
181 get_config_text("Green depth requirement not met."));
182 return -1;
183 }
184
185 if (sug & AGL_GREEN_DEPTH) {
186 if (dinfo->pixel_size.rgba.g < target.pixel_size.rgba.g) {
187 score += (16 * dinfo->pixel_size.rgba.g) / target.pixel_size.rgba.g;
188 }
189 else {
190 score += 16
191 + 16 / (1 + dinfo->pixel_size.rgba.g - target.pixel_size.rgba.g);
192 }
193 }
194
195 if ((req & AGL_BLUE_DEPTH)
196 && (dinfo->pixel_size.rgba.b != target.pixel_size.rgba.b)) {
197
198 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
199 get_config_text("Blue depth requirement not met."));
200 return -1;
201 }
202
203 if (sug & AGL_BLUE_DEPTH) {
204 if (dinfo->pixel_size.rgba.b < target.pixel_size.rgba.b) {
205 score += (16 * dinfo->pixel_size.rgba.b) / target.pixel_size.rgba.b;
206 }
207 else {
208 score += 16
209 + 16 / (1 + dinfo->pixel_size.rgba.b - target.pixel_size.rgba.b);
210 }
211 }
212
213 if ((req & AGL_ALPHA_DEPTH)
214 && (dinfo->pixel_size.rgba.a != target.pixel_size.rgba.a)) {
215
216 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
217 get_config_text("Alpha depth requirement not met."));
218 return -1;
219 }
220
221 if (sug & AGL_ALPHA_DEPTH) {
222 if (dinfo->pixel_size.rgba.a < target.pixel_size.rgba.a) {
223 score += (16 * dinfo->pixel_size.rgba.a) / target.pixel_size.rgba.a;
224 }
225 else {
226 score += 16
227 + 16 / (1 + dinfo->pixel_size.rgba.a - target.pixel_size.rgba.a);
228 }
229 }
230
231
232 if ((req & AGL_ACC_RED_DEPTH)
233 && (dinfo->accum_size.rgba.r != target.accum_size.rgba.r)) {
234
235 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
236 get_config_text("Accumulator Red depth requirement not met."));
237 return -1;
238 }
239
240 if (sug & AGL_ACC_RED_DEPTH) {
241 if (dinfo->accum_size.rgba.r < target.accum_size.rgba.r) {
242 score += (16 * dinfo->accum_size.rgba.r) / target.accum_size.rgba.r;
243 }
244 else {
245 score += 16
246 + 16 / (1 + dinfo->accum_size.rgba.r - target.accum_size.rgba.r);
247 }
248 }
249
250 if ((req & AGL_ACC_GREEN_DEPTH)
251 && (dinfo->accum_size.rgba.g != target.accum_size.rgba.g)) {
252
253 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
254 get_config_text("Accumulator Green depth requirement not met."));
255 return -1;
256 }
257
258 if (sug & AGL_ACC_GREEN_DEPTH) {
259 if (dinfo->accum_size.rgba.g < target.accum_size.rgba.g) {
260 score += (16 * dinfo->accum_size.rgba.g) / target.accum_size.rgba.g;
261 }
262 else {
263 score += 16
264 + 16 / (1 + dinfo->accum_size.rgba.g - target.accum_size.rgba.g);
265 }
266 }
267
268 if ((req & AGL_ACC_BLUE_DEPTH)
269 && (dinfo->accum_size.rgba.b != target.accum_size.rgba.b)) {
270
271 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
272 get_config_text("Accumulator Blue depth requirement not met."));
273 return -1;
274 }
275
276 if (sug & AGL_ACC_BLUE_DEPTH) {
277 if (dinfo->accum_size.rgba.b < target.accum_size.rgba.b) {
278 score += (16 * dinfo->accum_size.rgba.b) / target.accum_size.rgba.b;
279 }
280 else {
281 score += 16
282 + 16 / (1 + dinfo->accum_size.rgba.b - target.accum_size.rgba.b);
283 }
284 }
285
286 if ((req & AGL_ACC_ALPHA_DEPTH)
287 && (dinfo->accum_size.rgba.a != target.accum_size.rgba.a)) {
288
289 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
290 get_config_text("Accumulator Alpha depth requirement not met."));
291 return -1;
292 }
293
294 if (sug & AGL_ACC_ALPHA_DEPTH) {
295 if (dinfo->accum_size.rgba.a < target.accum_size.rgba.a) {
296 score += (16 * dinfo->accum_size.rgba.a) / target.accum_size.rgba.a;
297 }
298 else {
299 score += 16
300 + 16 / (1 + dinfo->accum_size.rgba.a - target.accum_size.rgba.a);
301 }
302 }
303
304
305
306 if (!dinfo->doublebuffered != !target.doublebuffered) {
307 if (req & AGL_DOUBLEBUFFER) {
308 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
309 get_config_text("Double Buffer requirement not met."));
310 return -1;
311 }
312 }
313 else {
314 score += (sug & AGL_DOUBLEBUFFER) ? 256 : 1;
315 }
316
317 if (!dinfo->stereo != !target.stereo) {
318 if (req & AGL_STEREO) {
319 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
320 get_config_text("Stereo Buffer requirement not met."));
321 return -1;
322 }
323 }
324 else {
325 if (sug & AGL_STEREO) {
326 score += 128;
327 }
328 }
329
330 if ((req & AGL_AUX_BUFFERS) && (dinfo->aux_buffers < target.aux_buffers)) {
331 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
332 get_config_text("Aux Buffer requirement not met."));
333 return -1;
334 }
335
336 if (sug & AGL_AUX_BUFFERS) {
337 if (dinfo->aux_buffers < target.aux_buffers) {
338 score += (64 * dinfo->aux_buffers) / target.aux_buffers;
339 }
340 else {
341 score += 64 + 64 / (1 + dinfo->aux_buffers - target.aux_buffers);
342 }
343 }
344
345 if ((req & AGL_Z_DEPTH) && (dinfo->depth_size != target.depth_size)) {
346 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
347 get_config_text("Z-Buffer requirement not met."));
348 return -1;
349 }
350 if (sug & AGL_Z_DEPTH) {
351 if (dinfo->depth_size < target.depth_size) {
352 score += (64 * dinfo->depth_size) / target.depth_size;
353 }
354 else {
355 score += 64 + 64 / (1 + dinfo->depth_size - target.depth_size);
356 }
357 }
358
359 if ((req & AGL_STENCIL_DEPTH)
360 && (dinfo->stencil_size != target.stencil_size)) {
361
362 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
363 get_config_text("Stencil depth requirement not met."));
364 return -1;
365 }
366
367 if (sug & AGL_STENCIL_DEPTH) {
368 if (dinfo->stencil_size < target.stencil_size) {
369 score += (64 * dinfo->stencil_size) / target.stencil_size;
370 }
371 else {
372 score += 64 + 64 / (1 + dinfo->stencil_size - target.stencil_size);
373 }
374 }
375
376 if ((req & AGL_RENDERMETHOD)
377 && ((dinfo->rmethod != target.rmethod) || (target.rmethod == 2))) {
378
379 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
380 get_config_text("Render Method requirement not met"));
381 return -1;
382 }
383
384 if ((sug & AGL_RENDERMETHOD) && (dinfo->rmethod == target.rmethod)) {
385 score += 1024;
386 }
387 else if (dinfo->rmethod == 1) {
388 score++; /* Add 1 for h/w accel */
389 }
390
391 if ((req & AGL_SAMPLE_BUFFERS)
392 && (dinfo->sample_buffers != target.sample_buffers)) {
393 ustrzcpy(allegro_gl_error, AGL_ERROR_SIZE,
394 get_config_text("Multisample Buffers requirement not met"));
395 return -1;
396 }
397
398 if (sug & AGL_SAMPLE_BUFFERS) {
399 if (dinfo->sample_buffers < target.sample_buffers) {
400 score += (64 * dinfo->sample_buffers) / target.sample_buffers;
401 }
402 else {
403 score += 64
404 + 64 / (1 + dinfo->sample_buffers - target.sample_buffers);
405 }
406 }
407
408 if ((req & AGL_SAMPLES) && (dinfo->samples != target.samples)) {
409 ustrzcpy(allegro_gl_error, AGL_ERROR_SIZE,
410 get_config_text("Multisample Samples requirement not met"));
411 return -1;
412 }
413
414 if (sug & AGL_SAMPLES) {
415 if (dinfo->samples < target.samples) {
416 score += (64 * dinfo->samples) / target.samples;
417 }
418 else {
419 score += 64 + 64 / (1 + dinfo->samples - target.samples);
420 }
421 }
422
423
424 if (!dinfo->float_color != !target.float_color) {
425 if (req & AGL_FLOAT_COLOR) {
426 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
427 get_config_text("Float Color requirement not met."));
428 return -1;
429 }
430 }
431 else {
432 if (sug & AGL_FLOAT_COLOR) {
433 score += 128;
434 }
435 }
436
437 if (!dinfo->float_depth != !target.float_depth) {
438 if (req & AGL_FLOAT_Z) {
439 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE,
440 get_config_text("Float Depth requirement not met."));
441 return -1;
442 }
443 }
444 else {
445 if (sug & AGL_FLOAT_Z) {
446 score += 128;
447 }
448 }
449
450 TRACE(PREFIX_I "Score is : %i\n", score);
451 return score;
452 }
453
454 #undef target
455 #undef req
456 #undef sug
457
458
459
460 int __allegro_gl_score_config(int refnum,
461 struct allegro_gl_display_info *dinfo)
462 {
463 int score = get_score(dinfo);
464 if (score == -1) {
465 TRACE(PREFIX_I "score_config: %s\n", allegro_gl_error);
466 return score;
467 }
468
469 if (score == best_score) {
470 /*
471 TRACE(PREFIX_I "score_config: score == best_score, should we change "
472 "scoring algorithm?\n");
473 */
474 }
475
476 if (score > best_score) {
477 best_score = score;
478 best = refnum;
479 }
480
481 return score;
482 }
483
484
485
486 int __allegro_gl_best_config(void)
487 {
488 return best;
489 }
490
AGL_SAMPLE_BUFFERS
#define AGL_SAMPLE_BUFFERS
Define multisample parameters Some OpenGL ICDs expose an extension called GL_ARB_multisample which pr...
Definition: alleggl.h:361
AGL_GREEN_DEPTH
#define AGL_GREEN_DEPTH
Select the green depth of the frame buffer.
Definition: alleggl.h:205
AGL_STEREO
#define AGL_STEREO
Creates seperate left/right buffers for stereo display.
Definition: alleggl.h:269
AGL_REQUIRE
#define AGL_REQUIRE
Reject other values for these settings.
Definition: alleggl.h:393
AGL_DOUBLEBUFFER
#define AGL_DOUBLEBUFFER
Creates a backbuffer if set.
Definition: alleggl.h:260
AGL_ALPHA_DEPTH
#define AGL_ALPHA_DEPTH
Select the alpha depth of the frame buffer.
Definition: alleggl.h:218
AGL_SUGGEST
#define AGL_SUGGEST
Prefer the assigned values for these settings.
Definition: alleggl.h:392
AGL_SAMPLES
#define AGL_SAMPLES
Define multisample samples Set this value to the number of samples that can be accepted in the multis...
Definition: alleggl.h:369
AGL_ACC_BLUE_DEPTH
#define AGL_ACC_BLUE_DEPTH
Select the blue depth of the accumulator buffer.
Definition: alleggl.h:246
AGL_ACC_ALPHA_DEPTH
#define AGL_ACC_ALPHA_DEPTH
Select the alpha depth of the accumulator buffer.
Definition: alleggl.h:254
AGL_ACC_GREEN_DEPTH
#define AGL_ACC_GREEN_DEPTH
Select the green depth of the accumulator buffer.
Definition: alleggl.h:238
allegro_gl_set
void allegro_gl_set(int option, int value)
Sets a configuration option.
Definition: alleggl.c:274
AGL_Z_DEPTH
#define AGL_Z_DEPTH
Select the depth of the z-buffer.
Definition: alleggl.h:282
AGL_STENCIL_DEPTH
#define AGL_STENCIL_DEPTH
Select the depth of the stencil buffer.
Definition: alleggl.h:291
AGL_FLOAT_COLOR
#define AGL_FLOAT_COLOR
Floating-point Color buffer.
Definition: alleggl.h:375
AGL_COLOR_DEPTH
#define AGL_COLOR_DEPTH
Specify the total color depth of the frame buffer.
Definition: alleggl.h:223
AGL_FLOAT_Z
#define AGL_FLOAT_Z
Floating-point Depth buffer.
Definition: alleggl.h:379
AGL_AUX_BUFFERS
#define AGL_AUX_BUFFERS
Creates additional auxiliary buffers.
Definition: alleggl.h:275
AGL_ACC_RED_DEPTH
#define AGL_ACC_RED_DEPTH
Select the red depth of the accumulator buffer.
Definition: alleggl.h:231
alleggl.h
Main header file for AllegroGL.
AGL_BLUE_DEPTH
#define AGL_BLUE_DEPTH
Select the blue depth of the frame buffer.
Definition: alleggl.h:211
AGL_RED_DEPTH
#define AGL_RED_DEPTH
Select the red depth of the frame buffer.
Definition: alleggl.h:199
AGL_RENDERMETHOD
#define AGL_RENDERMETHOD
Set it if you&#39;d like AllegroGL to pay special attention on whether hardware acceleration is present o...
Definition: alleggl.h:310