AllegroGL 0.4.4
|
00001 /* This code is (C) AllegroGL contributors, and double licensed under 00002 * the GPL and zlib licenses. See gpl.txt or zlib.txt for details. 00003 */ 00008 #include <allegro.h> 00009 00010 #include "alleggl.h" 00011 #include "allglint.h" 00012 00013 00014 static int best, best_score; 00015 00016 00017 #define target allegro_gl_display_info 00018 #define req __allegro_gl_required_settings 00019 #define sug __allegro_gl_suggested_settings 00020 00021 #define PREFIX_I "agl-scorer INFO: " 00022 00023 00024 /* __allegro_gl_fill_in_info() 00025 * Will fill in missing settings by 'guessing' 00026 * what the user intended. 00027 */ 00028 void __allegro_gl_fill_in_info() { 00029 00030 int all_components = AGL_RED_DEPTH | AGL_GREEN_DEPTH | AGL_BLUE_DEPTH 00031 | AGL_ALPHA_DEPTH; 00032 00033 /* If all color components were set, but not the color depth */ 00034 if ((((req | sug) & AGL_COLOR_DEPTH) == 0) 00035 && (((req | sug) & all_components) == all_components)) { 00036 00037 target.colour_depth = target.pixel_size.rgba.r 00038 + target.pixel_size.rgba.g 00039 + target.pixel_size.rgba.b 00040 + target.pixel_size.rgba.a; 00041 00042 /* Round depth to 8 bits */ 00043 target.colour_depth = (target.colour_depth + 7) / 8; 00044 } 00045 /* If only some components were set, guess the others */ 00046 else if ((req | sug) & all_components) { 00047 00048 int avg = ((req | sug) & AGL_RED_DEPTH ? target.pixel_size.rgba.r: 0) 00049 + ((req | sug) & AGL_GREEN_DEPTH ? target.pixel_size.rgba.g: 0) 00050 + ((req | sug) & AGL_BLUE_DEPTH ? target.pixel_size.rgba.b: 0) 00051 + ((req | sug) & AGL_ALPHA_DEPTH ? target.pixel_size.rgba.a: 0); 00052 00053 int num = ((req | sug) & AGL_RED_DEPTH ? 1 : 0) 00054 + ((req | sug) & AGL_GREEN_DEPTH ? 1 : 0) 00055 + ((req | sug) & AGL_BLUE_DEPTH ? 1 : 0) 00056 + ((req | sug) & AGL_ALPHA_DEPTH ? 1 : 0); 00057 00058 avg /= (num ? num : 1); 00059 00060 if (((req | sug) & AGL_RED_DEPTH )== 0) { 00061 sug |= AGL_RED_DEPTH; 00062 target.pixel_size.rgba.r = avg; 00063 } 00064 if (((req | sug) & AGL_GREEN_DEPTH) == 0) { 00065 sug |= AGL_GREEN_DEPTH; 00066 target.pixel_size.rgba.g = avg; 00067 } 00068 if (((req | sug) & AGL_BLUE_DEPTH) == 0) { 00069 sug |= AGL_BLUE_DEPTH; 00070 target.pixel_size.rgba.b = avg; 00071 } 00072 if (((req | sug) & AGL_ALPHA_DEPTH) == 0) { 00073 sug |= AGL_ALPHA_DEPTH; 00074 target.pixel_size.rgba.a = avg; 00075 } 00076 00077 /* If color depth wasn't defined, figure it out */ 00078 if (((req | sug) & AGL_COLOR_DEPTH) == 0) { 00079 __allegro_gl_fill_in_info(); 00080 } 00081 } 00082 00083 /* If the user forgot to set a color depth in AGL, but used the 00084 * Allegro one instead 00085 */ 00086 if ((((req | sug) & AGL_COLOR_DEPTH) == 0) && (target.colour_depth == 0)) { 00087 BITMAP *temp = create_bitmap(1, 1); 00088 if (temp) { 00089 allegro_gl_set(AGL_COLOR_DEPTH, bitmap_color_depth(temp)); 00090 allegro_gl_set(AGL_REQUIRE, AGL_COLOR_DEPTH); 00091 destroy_bitmap(temp); 00092 } 00093 } 00094 00095 00096 /* Prefer double-buffering */ 00097 if (!((req | sug) & AGL_DOUBLEBUFFER)) { 00098 allegro_gl_set(AGL_DOUBLEBUFFER, 1); 00099 allegro_gl_set(AGL_SUGGEST, AGL_DOUBLEBUFFER); 00100 } 00101 00102 /* Prefer no multisamping */ 00103 if (!((req | sug) & (AGL_SAMPLE_BUFFERS | AGL_SAMPLES))) { 00104 allegro_gl_set(AGL_SAMPLE_BUFFERS, 0); 00105 allegro_gl_set(AGL_SAMPLES, 0); 00106 allegro_gl_set(AGL_SUGGEST, AGL_SAMPLE_BUFFERS | AGL_SAMPLES); 00107 } 00108 00109 /* Prefer monoscopic */ 00110 if (!((req | sug) & AGL_STEREO)) { 00111 allegro_gl_set(AGL_STEREO, 0); 00112 allegro_gl_set(AGL_SUGGEST, AGL_STEREO); 00113 } 00114 00115 /* Prefer unsigned normalized buffers */ 00116 if (!((req | sug) & (AGL_FLOAT_COLOR | AGL_FLOAT_Z))) { 00117 allegro_gl_set(AGL_FLOAT_COLOR, 0); 00118 allegro_gl_set(AGL_FLOAT_Z, 0); 00119 allegro_gl_set(AGL_SUGGEST, AGL_FLOAT_COLOR | AGL_FLOAT_Z); 00120 } 00121 } 00122 00123 00124 00125 void __allegro_gl_reset_scorer(void) 00126 { 00127 best = -1; 00128 best_score = -1; 00129 } 00130 00131 00132 00133 static int get_score(struct allegro_gl_display_info *dinfo) 00134 { 00135 int score = 0; 00136 00137 if (dinfo->colour_depth != target.colour_depth) { 00138 if (req & AGL_COLOR_DEPTH) { 00139 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00140 get_config_text("Color depth requirement not met.")); 00141 return -1; 00142 } 00143 } 00144 else { 00145 /* If requested color depths agree */ 00146 score += 128; 00147 } 00148 00149 00150 if (sug & AGL_COLOR_DEPTH) { 00151 if (dinfo->colour_depth < target.colour_depth) 00152 score += (96 * dinfo->colour_depth) / target.colour_depth; 00153 else 00154 score += 96 + 96 / (1 + dinfo->colour_depth - target.colour_depth); 00155 } 00156 00157 00158 /* check colour component widths here and Allegro formatness */ 00159 if ((req & AGL_RED_DEPTH) 00160 && (dinfo->pixel_size.rgba.r != target.pixel_size.rgba.r)) { 00161 00162 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00163 get_config_text("Red depth requirement not met.")); 00164 return -1; 00165 } 00166 00167 if (sug & AGL_RED_DEPTH) { 00168 if (dinfo->pixel_size.rgba.r < target.pixel_size.rgba.r) { 00169 score += (16 * dinfo->pixel_size.rgba.r) / target.pixel_size.rgba.r; 00170 } 00171 else { 00172 score += 16 00173 + 16 / (1 + dinfo->pixel_size.rgba.r - target.pixel_size.rgba.r); 00174 } 00175 } 00176 00177 if ((req & AGL_GREEN_DEPTH) 00178 && (dinfo->pixel_size.rgba.g != target.pixel_size.rgba.g)) { 00179 00180 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00181 get_config_text("Green depth requirement not met.")); 00182 return -1; 00183 } 00184 00185 if (sug & AGL_GREEN_DEPTH) { 00186 if (dinfo->pixel_size.rgba.g < target.pixel_size.rgba.g) { 00187 score += (16 * dinfo->pixel_size.rgba.g) / target.pixel_size.rgba.g; 00188 } 00189 else { 00190 score += 16 00191 + 16 / (1 + dinfo->pixel_size.rgba.g - target.pixel_size.rgba.g); 00192 } 00193 } 00194 00195 if ((req & AGL_BLUE_DEPTH) 00196 && (dinfo->pixel_size.rgba.b != target.pixel_size.rgba.b)) { 00197 00198 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00199 get_config_text("Blue depth requirement not met.")); 00200 return -1; 00201 } 00202 00203 if (sug & AGL_BLUE_DEPTH) { 00204 if (dinfo->pixel_size.rgba.b < target.pixel_size.rgba.b) { 00205 score += (16 * dinfo->pixel_size.rgba.b) / target.pixel_size.rgba.b; 00206 } 00207 else { 00208 score += 16 00209 + 16 / (1 + dinfo->pixel_size.rgba.b - target.pixel_size.rgba.b); 00210 } 00211 } 00212 00213 if ((req & AGL_ALPHA_DEPTH) 00214 && (dinfo->pixel_size.rgba.a != target.pixel_size.rgba.a)) { 00215 00216 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00217 get_config_text("Alpha depth requirement not met.")); 00218 return -1; 00219 } 00220 00221 if (sug & AGL_ALPHA_DEPTH) { 00222 if (dinfo->pixel_size.rgba.a < target.pixel_size.rgba.a) { 00223 score += (16 * dinfo->pixel_size.rgba.a) / target.pixel_size.rgba.a; 00224 } 00225 else { 00226 score += 16 00227 + 16 / (1 + dinfo->pixel_size.rgba.a - target.pixel_size.rgba.a); 00228 } 00229 } 00230 00231 00232 if ((req & AGL_ACC_RED_DEPTH) 00233 && (dinfo->accum_size.rgba.r != target.accum_size.rgba.r)) { 00234 00235 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00236 get_config_text("Accumulator Red depth requirement not met.")); 00237 return -1; 00238 } 00239 00240 if (sug & AGL_ACC_RED_DEPTH) { 00241 if (dinfo->accum_size.rgba.r < target.accum_size.rgba.r) { 00242 score += (16 * dinfo->accum_size.rgba.r) / target.accum_size.rgba.r; 00243 } 00244 else { 00245 score += 16 00246 + 16 / (1 + dinfo->accum_size.rgba.r - target.accum_size.rgba.r); 00247 } 00248 } 00249 00250 if ((req & AGL_ACC_GREEN_DEPTH) 00251 && (dinfo->accum_size.rgba.g != target.accum_size.rgba.g)) { 00252 00253 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00254 get_config_text("Accumulator Green depth requirement not met.")); 00255 return -1; 00256 } 00257 00258 if (sug & AGL_ACC_GREEN_DEPTH) { 00259 if (dinfo->accum_size.rgba.g < target.accum_size.rgba.g) { 00260 score += (16 * dinfo->accum_size.rgba.g) / target.accum_size.rgba.g; 00261 } 00262 else { 00263 score += 16 00264 + 16 / (1 + dinfo->accum_size.rgba.g - target.accum_size.rgba.g); 00265 } 00266 } 00267 00268 if ((req & AGL_ACC_BLUE_DEPTH) 00269 && (dinfo->accum_size.rgba.b != target.accum_size.rgba.b)) { 00270 00271 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00272 get_config_text("Accumulator Blue depth requirement not met.")); 00273 return -1; 00274 } 00275 00276 if (sug & AGL_ACC_BLUE_DEPTH) { 00277 if (dinfo->accum_size.rgba.b < target.accum_size.rgba.b) { 00278 score += (16 * dinfo->accum_size.rgba.b) / target.accum_size.rgba.b; 00279 } 00280 else { 00281 score += 16 00282 + 16 / (1 + dinfo->accum_size.rgba.b - target.accum_size.rgba.b); 00283 } 00284 } 00285 00286 if ((req & AGL_ACC_ALPHA_DEPTH) 00287 && (dinfo->accum_size.rgba.a != target.accum_size.rgba.a)) { 00288 00289 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00290 get_config_text("Accumulator Alpha depth requirement not met.")); 00291 return -1; 00292 } 00293 00294 if (sug & AGL_ACC_ALPHA_DEPTH) { 00295 if (dinfo->accum_size.rgba.a < target.accum_size.rgba.a) { 00296 score += (16 * dinfo->accum_size.rgba.a) / target.accum_size.rgba.a; 00297 } 00298 else { 00299 score += 16 00300 + 16 / (1 + dinfo->accum_size.rgba.a - target.accum_size.rgba.a); 00301 } 00302 } 00303 00304 00305 00306 if (!dinfo->doublebuffered != !target.doublebuffered) { 00307 if (req & AGL_DOUBLEBUFFER) { 00308 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00309 get_config_text("Double Buffer requirement not met.")); 00310 return -1; 00311 } 00312 } 00313 else { 00314 score += (sug & AGL_DOUBLEBUFFER) ? 256 : 1; 00315 } 00316 00317 if (!dinfo->stereo != !target.stereo) { 00318 if (req & AGL_STEREO) { 00319 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00320 get_config_text("Stereo Buffer requirement not met.")); 00321 return -1; 00322 } 00323 } 00324 else { 00325 if (sug & AGL_STEREO) { 00326 score += 128; 00327 } 00328 } 00329 00330 if ((req & AGL_AUX_BUFFERS) && (dinfo->aux_buffers < target.aux_buffers)) { 00331 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00332 get_config_text("Aux Buffer requirement not met.")); 00333 return -1; 00334 } 00335 00336 if (sug & AGL_AUX_BUFFERS) { 00337 if (dinfo->aux_buffers < target.aux_buffers) { 00338 score += (64 * dinfo->aux_buffers) / target.aux_buffers; 00339 } 00340 else { 00341 score += 64 + 64 / (1 + dinfo->aux_buffers - target.aux_buffers); 00342 } 00343 } 00344 00345 if ((req & AGL_Z_DEPTH) && (dinfo->depth_size != target.depth_size)) { 00346 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00347 get_config_text("Z-Buffer requirement not met.")); 00348 return -1; 00349 } 00350 if (sug & AGL_Z_DEPTH) { 00351 if (dinfo->depth_size < target.depth_size) { 00352 score += (64 * dinfo->depth_size) / target.depth_size; 00353 } 00354 else { 00355 score += 64 + 64 / (1 + dinfo->depth_size - target.depth_size); 00356 } 00357 } 00358 00359 if ((req & AGL_STENCIL_DEPTH) 00360 && (dinfo->stencil_size != target.stencil_size)) { 00361 00362 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00363 get_config_text("Stencil depth requirement not met.")); 00364 return -1; 00365 } 00366 00367 if (sug & AGL_STENCIL_DEPTH) { 00368 if (dinfo->stencil_size < target.stencil_size) { 00369 score += (64 * dinfo->stencil_size) / target.stencil_size; 00370 } 00371 else { 00372 score += 64 + 64 / (1 + dinfo->stencil_size - target.stencil_size); 00373 } 00374 } 00375 00376 if ((req & AGL_RENDERMETHOD) 00377 && ((dinfo->rmethod != target.rmethod) || (target.rmethod == 2))) { 00378 00379 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00380 get_config_text("Render Method requirement not met")); 00381 return -1; 00382 } 00383 00384 if ((sug & AGL_RENDERMETHOD) && (dinfo->rmethod == target.rmethod)) { 00385 score += 1024; 00386 } 00387 else if (dinfo->rmethod == 1) { 00388 score++; /* Add 1 for h/w accel */ 00389 } 00390 00391 if ((req & AGL_SAMPLE_BUFFERS) 00392 && (dinfo->sample_buffers != target.sample_buffers)) { 00393 ustrzcpy(allegro_gl_error, AGL_ERROR_SIZE, 00394 get_config_text("Multisample Buffers requirement not met")); 00395 return -1; 00396 } 00397 00398 if (sug & AGL_SAMPLE_BUFFERS) { 00399 if (dinfo->sample_buffers < target.sample_buffers) { 00400 score += (64 * dinfo->sample_buffers) / target.sample_buffers; 00401 } 00402 else { 00403 score += 64 00404 + 64 / (1 + dinfo->sample_buffers - target.sample_buffers); 00405 } 00406 } 00407 00408 if ((req & AGL_SAMPLES) && (dinfo->samples != target.samples)) { 00409 ustrzcpy(allegro_gl_error, AGL_ERROR_SIZE, 00410 get_config_text("Multisample Samples requirement not met")); 00411 return -1; 00412 } 00413 00414 if (sug & AGL_SAMPLES) { 00415 if (dinfo->samples < target.samples) { 00416 score += (64 * dinfo->samples) / target.samples; 00417 } 00418 else { 00419 score += 64 + 64 / (1 + dinfo->samples - target.samples); 00420 } 00421 } 00422 00423 00424 if (!dinfo->float_color != !target.float_color) { 00425 if (req & AGL_FLOAT_COLOR) { 00426 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00427 get_config_text("Float Color requirement not met.")); 00428 return -1; 00429 } 00430 } 00431 else { 00432 if (sug & AGL_FLOAT_COLOR) { 00433 score += 128; 00434 } 00435 } 00436 00437 if (!dinfo->float_depth != !target.float_depth) { 00438 if (req & AGL_FLOAT_Z) { 00439 ustrzcpy (allegro_gl_error, AGL_ERROR_SIZE, 00440 get_config_text("Float Depth requirement not met.")); 00441 return -1; 00442 } 00443 } 00444 else { 00445 if (sug & AGL_FLOAT_Z) { 00446 score += 128; 00447 } 00448 } 00449 00450 TRACE(PREFIX_I "Score is : %i\n", score); 00451 return score; 00452 } 00453 00454 #undef target 00455 #undef req 00456 #undef sug 00457 00458 00459 00460 int __allegro_gl_score_config(int refnum, 00461 struct allegro_gl_display_info *dinfo) 00462 { 00463 int score = get_score(dinfo); 00464 if (score == -1) { 00465 TRACE(PREFIX_I "score_config: %s\n", allegro_gl_error); 00466 return score; 00467 } 00468 00469 if (score == best_score) { 00470 /* 00471 TRACE(PREFIX_I "score_config: score == best_score, should we change " 00472 "scoring algorithm?\n"); 00473 */ 00474 } 00475 00476 if (score > best_score) { 00477 best_score = score; 00478 best = refnum; 00479 } 00480 00481 return score; 00482 } 00483 00484 00485 00486 int __allegro_gl_best_config(void) 00487 { 00488 return best; 00489 } 00490