- Main Page
- Related Pages
- Modules
- Files

- File List
- Globals

# 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