scorer.c

Go to the documentation of this file.
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 

Generated on Sun Nov 11 15:52:55 2007 for AllegroGL by  doxygen 1.5.2