Annotation of tme/generic/fb.c, revision 1.1.1.2

1.1.1.2 ! root        1: /* $Id: fb.c,v 1.4 2005/05/09 01:54:47 fredette Exp $ */
1.1       root        2: 
                      3: /* generic/fb.c - generic framebuffer implementation support: */
                      4: 
                      5: /*
                      6:  * Copyright (c) 2003 Matt Fredette
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *      This product includes software developed by Matt Fredette.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     25:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     26:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     27:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     28:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     29:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     31:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     32:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     33:  * POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35: 
                     36: #include <tme/common.h>
1.1.1.2 ! root       37: _TME_RCSID("$Id: fb.c,v 1.4 2005/05/09 01:54:47 fredette Exp $");
1.1       root       38: 
                     39: /* includes: */
                     40: #include <tme/generic/fb.h>
                     41: 
                     42: /* include the automatically-generated translation functions: */
                     43: #include "fb-xlat-auto.c"
                     44: 
                     45: /* this returns the best translation function: */
                     46: const struct tme_fb_xlat *
                     47: tme_fb_xlat_best(const struct tme_fb_xlat *xlat_user)
                     48: {
                     49:   unsigned int xlat_i;
                     50:   const struct tme_fb_xlat *xlat;
                     51:   const struct tme_fb_xlat *xlat_best;
                     52:   unsigned int xlat_best_score, xlat_score;
                     53: 
                     54:   /* loop over the xlats: */
                     55:   xlat_best = NULL;
                     56:   xlat_best_score = 0;
                     57:   for (xlat_i = 0;
                     58:        xlat_i < TME_ARRAY_ELS(tme_fb_xlats);
                     59:        xlat_i++) {
                     60: 
                     61:     /* get this xlat: */
                     62:     xlat = &tme_fb_xlats[xlat_i];
                     63:     xlat_score = 0;
                     64: 
                     65:     /* if this xlat only works for a particular value of the given
                     66:        member, and the user's value is different, we cannot use this
                     67:        xlat.  otherwise, increase this xlat's score: */
                     68: #define TME_FB_XLAT_SCORE(score, member, specific)     \
                     69: if ((xlat->member specific)                            \
                     70:     && (xlat->member != xlat_user->member)) {          \
                     71:   continue;                                            \
                     72: }                                                      \
                     73: if (xlat->member specific)                             \
                     74:   xlat_score += score
                     75: 
                     76:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_width, != 0);
                     77:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_height, != 0);
                     78:     TME_FB_XLAT_SCORE(  0, tme_fb_xlat_scale, || TRUE);
                     79:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_depth, != 0);
                     80:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_bits_per_pixel, != 0);
                     81:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_skipx, >= 0);
                     82:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_scanline_pad, != 0);
                     83:     TME_FB_XLAT_SCORE(  0, tme_fb_xlat_src_order, || TRUE);
1.1.1.2 ! root       84:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_class, != TME_FB_XLAT_CLASS_ANY);
        !            85:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_map, != TME_FB_XLAT_MAP_ANY);
        !            86:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_map_bits, != 0);
        !            87:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_mask_g, != TME_FB_XLAT_MASK_ANY);
        !            88:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_mask_r, != TME_FB_XLAT_MASK_ANY);
        !            89:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_mask_b, != TME_FB_XLAT_MASK_ANY);
1.1       root       90:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_depth, != 0);
                     91:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_bits_per_pixel, != 0);
                     92:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_skipx, >= 0);
                     93:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_scanline_pad, != 0);
                     94:     TME_FB_XLAT_SCORE(  0, tme_fb_xlat_dst_order, || TRUE);
1.1.1.2 ! root       95:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_map, != TME_FB_XLAT_MAP_ANY);
        !            96:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_mask_g, != TME_FB_XLAT_MASK_ANY);
        !            97:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_mask_r, != TME_FB_XLAT_MASK_ANY);
        !            98:     TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_mask_b, != TME_FB_XLAT_MASK_ANY);
1.1       root       99: 
                    100: #undef TME_FB_XLAT_SCORE
                    101: 
                    102:     /* update the best xlat: */
                    103:     if (xlat_best == NULL
                    104:        || xlat_best_score < xlat_score) {
                    105:       xlat_best = xlat;
                    106:       xlat_best_score = xlat_score;
                    107:     }
                    108:   }
                    109: 
                    110:   /* return the best xlat: */
                    111:   assert (xlat_best != NULL);
                    112:   return (xlat_best);
                    113: }
                    114: 
                    115: /* this returns nonzero iff the translation function is optimal: */
                    116: int
                    117: tme_fb_xlat_is_optimal(const struct tme_fb_xlat *xlat)
                    118: {
                    119:   return (xlat->tme_fb_xlat_width != 0
                    120:          && xlat->tme_fb_xlat_height != 0
                    121:          && xlat->tme_fb_xlat_src_depth != 0
                    122:          && xlat->tme_fb_xlat_src_bits_per_pixel != 0
                    123:          && xlat->tme_fb_xlat_src_skipx >= 0
                    124:          && xlat->tme_fb_xlat_src_scanline_pad != 0
1.1.1.2 ! root      125:          && xlat->tme_fb_xlat_src_class != TME_FB_XLAT_CLASS_ANY
        !           126:          && xlat->tme_fb_xlat_src_map != TME_FB_XLAT_MAP_ANY
        !           127:          && xlat->tme_fb_xlat_src_map_bits != 0
        !           128:          && xlat->tme_fb_xlat_src_mask_g != TME_FB_XLAT_MASK_ANY
        !           129:          && xlat->tme_fb_xlat_src_mask_r != TME_FB_XLAT_MASK_ANY
        !           130:          && xlat->tme_fb_xlat_src_mask_b != TME_FB_XLAT_MASK_ANY
1.1       root      131:          && xlat->tme_fb_xlat_dst_depth != 0
                    132:          && xlat->tme_fb_xlat_dst_bits_per_pixel != 0
                    133:          && xlat->tme_fb_xlat_dst_skipx >= 0
1.1.1.2 ! root      134:          && xlat->tme_fb_xlat_dst_scanline_pad != 0
        !           135:          && xlat->tme_fb_xlat_dst_map != TME_FB_XLAT_MAP_ANY
        !           136:          && xlat->tme_fb_xlat_dst_mask_g != TME_FB_XLAT_MASK_ANY
        !           137:          && xlat->tme_fb_xlat_dst_mask_r != TME_FB_XLAT_MASK_ANY
        !           138:          && xlat->tme_fb_xlat_dst_mask_b != TME_FB_XLAT_MASK_ANY
        !           139:          );
1.1       root      140: }
                    141: 
                    142: /* this returns the number of bytes required for a source framebuffer
                    143:    scanline: */
                    144: static unsigned long
                    145: _tme_fb_xlat_src_bypl(const struct tme_fb_connection *src)
                    146: {
                    147:   /* NB that this definition must match the one in the
                    148:      automatically-generated xlat functions: */
                    149:   const unsigned long src_bypl
                    150:     = (((((src->tme_fb_connection_skipx
                    151:           + src->tme_fb_connection_width)
                    152:          * src->tme_fb_connection_bits_per_pixel)
                    153:         + (src->tme_fb_connection_scanline_pad - 1))
                    154:        & -src->tme_fb_connection_scanline_pad)
                    155:        / 8);
                    156:   return (src_bypl);
                    157: }
                    158: 
                    159: /* this returns the number of bytes required for a source framebuffer: */
                    160: static unsigned long
                    161: _tme_fb_xlat_src_bypb_real(const struct tme_fb_connection *src)
                    162: {
                    163:   /* NB that these definitions must match those in the
                    164:      automatically-generated xlat functions: */
                    165:   const unsigned long src_bypl
                    166:     = _tme_fb_xlat_src_bypl(src);
                    167:   const unsigned long src_bypb_real
                    168:     = (((src->tme_fb_connection_height * src_bypl) + 3) & -4);
                    169:   return (src_bypb_real);
                    170: }
                    171: 
                    172: /* this returns the number of bytes allocated for a source framebuffer.
                    173:    this includes the guard regions that are needed to guarantee that
                    174:    the translation function main loop terminates: */
                    175: static unsigned long
                    176: _tme_fb_xlat_src_bypb(const struct tme_fb_connection *src)
                    177: {
                    178:   /* NB that this definition must match the one in the
                    179:      automatically-generated xlat functions: */
                    180:   const unsigned long src_bypl
                    181:     = _tme_fb_xlat_src_bypl(src);
                    182:   const unsigned long src_bypb_real
                    183:     = _tme_fb_xlat_src_bypb_real(src);
                    184:   const unsigned long src_bypb
                    185:     = ((src_bypb_real + (src_bypl * 2)) & -4);
                    186:   return (src_bypb);
                    187: }
                    188: 
                    189: /* this forces the next translation to retranslate the entire buffer: */
                    190: void
                    191: tme_fb_xlat_redraw(struct tme_fb_connection *src)
                    192: {
                    193:   const tme_uint32_t *src_user;
                    194:   tme_uint32_t *src_back;
                    195:   unsigned int count32;
                    196: 
                    197:   src_user
                    198:     = ((const tme_uint32_t *) 
                    199:        src->tme_fb_connection_buffer);
                    200:   src_back
                    201:     = ((tme_uint32_t *) 
                    202:        (src->tme_fb_connection_buffer
                    203:        + _tme_fb_xlat_src_bypb(src)));
                    204:   for (count32 = _tme_fb_xlat_src_bypb_real(src) / sizeof(tme_uint32_t);
                    205:        count32-- > 0; ) {
                    206:     *(src_back++) = ~(*(src_user++));
                    207:   }
                    208: }
                    209: 
                    210: /* this allocates memory for a source framebuffer: */
                    211: int
                    212: tme_fb_xlat_alloc_src(struct tme_fb_connection *src)
                    213: {
                    214: 
                    215:   /* allocate the buffer.  remember, this is really two buffers - the
                    216:      first half is the real, current framebuffer, and the second half
                    217:      holds the last frame that was translated: */
                    218:   src->tme_fb_connection_buffer
                    219:     = tme_new0(tme_uint8_t,
                    220:               _tme_fb_xlat_src_bypb(src) * 2);
                    221: 
                    222:   /* force the next translation to do a complete redraw: */
                    223:   tme_fb_xlat_redraw(src);
                    224:   
                    225:   return (TME_OK);
                    226: }
                    227: 
1.1.1.2 ! root      228: /* this internal function gets or sets the needed colors on a
        !           229:    destination framebuffer connection that is using the common
        !           230:    translation functions: */
        !           231: static tme_uint32_t
        !           232: _tme_fb_xlat_colors_get_set(const struct tme_fb_connection *src,
        !           233:                            unsigned int scale,
        !           234:                            struct tme_fb_connection *dst,
        !           235:                            struct tme_fb_color **_colors,
        !           236:                            int get)
        !           237: {
        !           238:   tme_uint32_t src_mask;
        !           239:   tme_uint32_t src_mask_g;
        !           240:   tme_uint32_t src_mask_r;
        !           241:   tme_uint32_t src_mask_b;
        !           242:   tme_uint32_t src_shift_g;
        !           243:   tme_uint32_t src_shift_r;
        !           244:   tme_uint32_t src_shift_b;
        !           245:   const void *src_map_g;
        !           246:   const void *src_map_r;
        !           247:   const void *src_map_b;
        !           248:   tme_uint32_t value_g;
        !           249:   tme_uint32_t value_r;
        !           250:   tme_uint32_t value_b;
        !           251:   tme_uint32_t src_max_g;
        !           252:   tme_uint32_t src_max_r;
        !           253:   tme_uint32_t src_max_b;
        !           254:   tme_uint32_t color_count;
        !           255:   tme_uint32_t color_i;
        !           256:   struct tme_fb_color *colors;
        !           257:   tme_uint32_t *pixels;
        !           258:   tme_uint32_t invert_mask;
        !           259: 
        !           260:   /* get how to decompose source pixels into subfields.  if source
        !           261:      pixels have no subfields, act as if all of the subfields are the
        !           262:      entire source pixel: */
        !           263:   src_mask = (0xffffffff >> (32 - src->tme_fb_connection_depth));
        !           264:   src_mask_g = src->tme_fb_connection_mask_g;
        !           265:   src_mask_r = src->tme_fb_connection_mask_r;
        !           266:   src_mask_b = src->tme_fb_connection_mask_b;
        !           267:   if (src_mask_g == 0) {
        !           268:     src_mask_g = src_mask;
        !           269:     src_mask_r = src_mask;
        !           270:     src_mask_b = src_mask;
        !           271:   }
        !           272: 
        !           273:   /* if source intensities are index mapped, their common maximum is
        !           274:      the mask of the mapping size range in bits: */
        !           275:   src_map_g = src->tme_fb_connection_map_g;
        !           276:   src_map_r = src->tme_fb_connection_map_r;
        !           277:   src_map_b = src->tme_fb_connection_map_b;
        !           278:   if (src_map_g != NULL) {
        !           279:     src_max_g = (0xffffffff >> (32 - src->tme_fb_connection_map_bits));
        !           280:     src_max_r = src_max_g;
        !           281:     src_max_b = src_max_g;
        !           282:   }
        !           283: 
        !           284:   /* otherwise, source intensities are linearly mapped, and each
        !           285:      primary's maximum intensity is the base mask of its subfield: */
        !           286:   else {
        !           287:     src_max_g = TME_FB_XLAT_MAP_BASE_MASK(src_mask_g);
        !           288:     src_max_r = TME_FB_XLAT_MAP_BASE_MASK(src_mask_r);
        !           289:     src_max_b = TME_FB_XLAT_MAP_BASE_MASK(src_mask_b);
        !           290:   }
        !           291: 
        !           292:   /* the source intensity maximums must be greater than zero, and not
        !           293:      larger than 16 bits: */
        !           294:   assert (src_max_g > 0 && src_max_g <= 0xffff);
        !           295:   assert (src_max_r > 0 && src_max_r <= 0xffff);
        !           296:   assert (src_max_b > 0 && src_max_b <= 0xffff);
        !           297: 
        !           298:   /* get any inversion mask: */
        !           299:   invert_mask = (src->tme_fb_connection_inverted ? 0xffff : 0);
        !           300: 
        !           301:   /* if we're halving, the intensity maximums are four times what they
        !           302:      would be otherwise, because the intensities from four pixels are
        !           303:      added together: */
        !           304:   if (scale == TME_FB_XLAT_SCALE_HALF) {
        !           305:     src_max_g *= 4;
        !           306:     src_max_r *= 4;
        !           307:     src_max_b *= 4;
        !           308:   }
        !           309: 
        !           310:   /* if we're not halving, and either the source pixel mask is less
        !           311:      than the maximum index mask or source pixels have no subfields,
        !           312:      we will index map source pixels directly to destination
        !           313:      pixels: */
        !           314:   if (scale != TME_FB_XLAT_SCALE_HALF
        !           315:       && (src_mask <= TME_FB_XLAT_MAP_INDEX_MASK_MAX
        !           316:          || src_mask_g == src_mask)) {
        !           317: 
        !           318:     /* we will allocate as many colors as we have source pixels: */
        !           319:     color_count = src_mask + 1;
        !           320:   }
        !           321:   
        !           322:   /* otherwise, either we're halving, or source pixels are too big to
        !           323:      map directly and they have subfields.  the translation code will 
        !           324:      decompose pixels into intensities: */
        !           325: 
        !           326:   /* if the source class is monochrome, we only have to deal with
        !           327:      the green primary: */
        !           328:   else if (src->tme_fb_connection_class == TME_FB_XLAT_CLASS_MONOCHROME) {
        !           329: 
        !           330:     /* the translation function will index map green intensity values
        !           331:        directly into pixels.  we may need to scale the intensities so
        !           332:        they can be indexed: */
        !           333:     for (; src_max_g > TME_FB_XLAT_MAP_INDEX_MASK_MAX; src_max_g >>= 1);
        !           334: 
        !           335:     /* allocate colors for src_max_g intensities: */
        !           336:     color_count = src_max_g + 1;
        !           337:     src_mask_g = TME_FB_XLAT_MAP_INDEX_MASK_MAX;
        !           338:     src_map_g = NULL;
        !           339:     src_mask_r = src_mask_g;
        !           340:     src_mask_b = src_mask_g;
        !           341:     src_map_r = src_map_g;
        !           342:     src_map_b = src_map_g;
        !           343:     src_max_r = src_max_g;
        !           344:     src_max_b = src_max_g;
        !           345:   }
        !           346: 
        !           347:   /* otherwise, we have to deal with all three primaries: */
        !           348: 
        !           349:   /* if the destination is color and has subfields: */
        !           350:   else if (dst->tme_fb_connection_class == TME_FB_XLAT_CLASS_COLOR
        !           351:           && dst->tme_fb_connection_mask_g != 0) {
        !           352:        
        !           353:     /* if the destination maps intensities linearly, we don't need to
        !           354:        allocate colors at all: */
        !           355:     if (dst->tme_fb_connection_map_g == NULL) {
        !           356: 
        !           357:       /* however, we can't do this yet with a source framebuffer that
        !           358:         is inverted: */
        !           359:       if (src->tme_fb_connection_inverted) {
        !           360:        abort();
        !           361:       }
        !           362:          
        !           363:       /* nothing to do */
        !           364:       *_colors = NULL;
        !           365:       return (0);
        !           366:     }
        !           367: 
        !           368:     /* otherwise, the translation function will index map the
        !           369:        intensity values into subfield values.  we may need to scale
        !           370:        the intensities so they can be indexed: */
        !           371:     for (; src_max_g > TME_FB_XLAT_MAP_INDEX_MASK_MAX; src_max_g >>= 1);
        !           372:     for (; src_max_r > TME_FB_XLAT_MAP_INDEX_MASK_MAX; src_max_r >>= 1);
        !           373:     for (; src_max_b > TME_FB_XLAT_MAP_INDEX_MASK_MAX; src_max_b >>= 1);
        !           374: 
        !           375:     /* size the color array: */
        !           376:     color_count = src_max_g + 1 + src_max_r + 1 + src_max_b + 1;
        !           377: 
        !           378:     /* if we're getting the needed colors: */
        !           379:     if (get) {
        !           380: 
        !           381:       /* allocate the color array: */
        !           382:       colors = tme_new0(struct tme_fb_color, color_count);
        !           383: 
        !           384:       /* make the colors to allocate from all of the different
        !           385:         primary intensities: */
        !           386:       color_i = 0;
        !           387: #define _TME_FB_XLAT_INDEX_COLORS(value, max, primary)         \
        !           388:   do {                                                         \
        !           389:     for (value = 0; value <= (max); value++, color_i++) {      \
        !           390:       colors[color_i].primary = ((0xffff * value) / (max)) ^ invert_mask;\
        !           391:     }                                                          \
        !           392:   } while (/* CONSTCOND */ 0)
        !           393:       _TME_FB_XLAT_INDEX_COLORS(value_g, src_max_g, tme_fb_color_value_g);
        !           394:       _TME_FB_XLAT_INDEX_COLORS(value_r, src_max_r, tme_fb_color_value_r);
        !           395:       _TME_FB_XLAT_INDEX_COLORS(value_b, src_max_b, tme_fb_color_value_b);
        !           396: #undef _TME_FB_XLAT_INDEX_COLORS
        !           397: 
        !           398:       /* return the needed colors: */
        !           399:       *_colors = colors;
        !           400:       return (color_count);
        !           401:     }
        !           402: 
        !           403:     /* set up the intensity index maps: */
        !           404:     colors = *_colors;
        !           405:     color_i = 0;
        !           406: #define __TME_FB_XLAT_INDEX_SUBFIELDS(value, max, primary_mask, primary_shift, primary_map, type)\
        !           407:   do {                                                                                 \
        !           408:     dst->primary_map = tme_new(type, (max) + 1);                                       \
        !           409:     for (value = 0; value <= (max); value++, color_i++) {                              \
        !           410:       ((type *) dst->primary_map)[value]                                               \
        !           411:        = ((colors[color_i].tme_fb_color_pixel                                          \
        !           412:            & dst->primary_mask)                                                        \
        !           413:           >> primary_shift);                                                           \
        !           414:     }                                                                                  \
        !           415:   } while (/* CONSTCOND */  0)
        !           416: #define _TME_FB_XLAT_INDEX_SUBFIELDS(value, max, primary_mask, primary_shift, primary_map)\
        !           417:   do {                                                                                 \
        !           418:     for (primary_shift = 0;                                                            \
        !           419:         ((dst->primary_mask >> primary_shift) & 1) == 0;                               \
        !           420:         primary_shift++);                                                              \
        !           421:     if (TME_FB_XLAT_MAP_BASE_MASK(dst->primary_mask) <= 0xff) {                        \
        !           422:       __TME_FB_XLAT_INDEX_SUBFIELDS(value, max, primary_mask, primary_shift, primary_map, tme_uint8_t);\
        !           423:     }                                                                                  \
        !           424:     else {                                                                             \
        !           425:       __TME_FB_XLAT_INDEX_SUBFIELDS(value, max, primary_mask, primary_shift, primary_map, tme_uint16_t);\
        !           426:     }                                                                                  \
        !           427:   } while (/* CONSTCOND */ 0)
        !           428:     _TME_FB_XLAT_INDEX_SUBFIELDS(value_g, src_max_g, tme_fb_connection_mask_g, src_shift_g, tme_fb_connection_map_g);
        !           429:     _TME_FB_XLAT_INDEX_SUBFIELDS(value_r, src_max_r, tme_fb_connection_mask_r, src_shift_r, tme_fb_connection_map_r);
        !           430:     _TME_FB_XLAT_INDEX_SUBFIELDS(value_b, src_max_b, tme_fb_connection_mask_b, src_shift_b, tme_fb_connection_map_b);
        !           431: #undef _TME_FB_XLAT_INDEX_SUBFIELDS
        !           432: #undef __TME_FB_XLAT_INDEX_SUBFIELDS
        !           433:   }
        !           434: 
        !           435:   /* otherwise, the destination is either not color or it doesn't
        !           436:      have subfields.  we need to allocate colors to map fake
        !           437:      source pixels: */
        !           438:   else {
        !           439:     src_mask_g = TME_FB_XLAT_MASK_DEFAULT_G;
        !           440:     src_mask_r = TME_FB_XLAT_MASK_DEFAULT_R;
        !           441:     src_mask_b = TME_FB_XLAT_MASK_DEFAULT_B;
        !           442:     src_map_g = NULL;
        !           443:     src_map_r = NULL;
        !           444:     src_map_b = NULL;
        !           445:     src_max_g = TME_FB_XLAT_MAP_BASE_MASK(src_mask_g);
        !           446:     src_max_r = TME_FB_XLAT_MAP_BASE_MASK(src_mask_r);
        !           447:     src_max_b = TME_FB_XLAT_MAP_BASE_MASK(src_mask_b);
        !           448:     color_count = (src_mask_g | src_mask_r | src_mask_b) + 1;
        !           449:   }
        !           450: 
        !           451:   /* if we get here, we're allocating colors from source pixel values
        !           452:      (or possibly fake source pixel values): */
        !           453: 
        !           454:   /* if we're getting the needed colors: */
        !           455:   if (get) {
        !           456: 
        !           457:     /* make shift counts for the subfields and shift their trailing zeroes off: */
        !           458:     for (src_shift_g = 0; (src_mask_g & 1) == 0; src_shift_g++, src_mask_g >>= 1);
        !           459:     for (src_shift_r = 0; (src_mask_r & 1) == 0; src_shift_r++, src_mask_r >>= 1);
        !           460:     for (src_shift_b = 0; (src_mask_b & 1) == 0; src_shift_b++, src_mask_b >>= 1);
        !           461: 
        !           462:     /* allocate the color array: */
        !           463:     colors = tme_new0(struct tme_fb_color, color_count);
        !           464: 
        !           465:     /* loop over the source pixels: */
        !           466:     for (color_i = 0;
        !           467:         color_i < color_count;
        !           468:         color_i++) {
        !           469:       
        !           470:       /* get the raw primary values: */
        !           471:       value_g = (color_i >> src_shift_g) & src_mask_g;
        !           472:       value_r = (color_i >> src_shift_r) & src_mask_r;
        !           473:       value_b = (color_i >> src_shift_b) & src_mask_b;
        !           474: 
        !           475:       /* if the primaries are index mapped, turn the raw primary
        !           476:         values into intensities: */
        !           477:       if (src_map_g != NULL) {
        !           478: 
        !           479:        /* if intensities are stored as 8 bits: */
        !           480:        if (src_max_g <= 0xff) {
        !           481:          value_g = ((const tme_uint8_t *) src_map_g)[value_g];
        !           482:          value_r = ((const tme_uint8_t *) src_map_r)[value_r];
        !           483:          value_b = ((const tme_uint8_t *) src_map_b)[value_b];
        !           484:        }
        !           485: 
        !           486:        /* otherwise, intensities are stored as 16 bits: */
        !           487:        else {
        !           488:          value_g = ((const tme_uint16_t *) src_map_g)[value_g];
        !           489:          value_r = ((const tme_uint16_t *) src_map_r)[value_r];
        !           490:          value_b = ((const tme_uint16_t *) src_map_b)[value_b];
        !           491:        }
        !           492:       }
        !           493: 
        !           494:       /* scale the intensities to 16 bits and possibly invert them: */
        !           495:       value_g = ((0xffff * value_g) / src_max_g) ^ invert_mask;
        !           496:       value_r = ((0xffff * value_r) / src_max_r) ^ invert_mask;
        !           497:       value_b = ((0xffff * value_b) / src_max_b) ^ invert_mask;
        !           498: 
        !           499:       /* if the source class is monochrome, use only the green primary: */
        !           500:       if (src->tme_fb_connection_class == TME_FB_XLAT_CLASS_MONOCHROME) {
        !           501:        value_r = value_g;
        !           502:        value_b = value_g;
        !           503:       }
        !           504: 
        !           505:       /* allocate this color: */
        !           506:       colors[color_i].tme_fb_color_value_g = value_g;
        !           507:       colors[color_i].tme_fb_color_value_r = value_r;
        !           508:       colors[color_i].tme_fb_color_value_b = value_b;
        !           509:     }
        !           510: 
        !           511:     /* return the needed colors: */
        !           512:     *_colors = colors;
        !           513:     return (color_count);
        !           514:   }
        !           515: 
        !           516:   /* otherwise, take in the allocated colors: */
        !           517:   colors = *_colors;
        !           518:   pixels = tme_new(tme_uint32_t, color_count);
        !           519:   for (color_i = 0;
        !           520:        color_i < color_count;
        !           521:        color_i++) {
        !           522:     pixels[color_i] = colors[color_i].tme_fb_color_pixel;
        !           523:   }
        !           524:   dst->tme_fb_connection_map_pixel = pixels;
        !           525:   dst->tme_fb_connection_map_pixel_count = color_count;
        !           526:   tme_free(colors);
        !           527:   return (0);
        !           528: }
        !           529: 
        !           530: /* this gets the needed colors on a destination framebuffer connection
        !           531:    that is using the common translation functions: */
        !           532: tme_uint32_t
        !           533: tme_fb_xlat_colors_get(const struct tme_fb_connection *src,
        !           534:                       unsigned int scale,
        !           535:                       struct tme_fb_connection *dst,
        !           536:                       struct tme_fb_color **_colors)
        !           537: {
        !           538:   return (_tme_fb_xlat_colors_get_set(src, scale, dst, _colors, TRUE));
        !           539: }
        !           540: 
        !           541: /* this sets the needed colors on a destination framebuffer connection
        !           542:    that is using the common translation functions: */
        !           543: void
        !           544: tme_fb_xlat_colors_set(const struct tme_fb_connection *src,
        !           545:                       unsigned int scale,
        !           546:                       struct tme_fb_connection *dst,
        !           547:                       struct tme_fb_color *colors)
        !           548: {
        !           549:   _tme_fb_xlat_colors_get_set(src, scale, dst, &colors, FALSE);
        !           550: }
        !           551: 
1.1       root      552: /* this scores a framebuffer connection: */
                    553: int
                    554: tme_fb_connection_score(struct tme_connection *conn, unsigned int *_score)
                    555: {
                    556:   struct tme_fb_connection *conn_fb;
                    557:   struct tme_fb_connection *conn_fb_other;
                    558: 
                    559:   /* both sides must be Ethernet connections: */
                    560:   assert(conn->tme_connection_type == TME_CONNECTION_FRAMEBUFFER);
                    561:   assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_FRAMEBUFFER);
                    562: 
                    563:   /* one side must be a real display and the other side must be a
                    564:      framebuffer emulator: */
                    565:   conn_fb = (struct tme_fb_connection *) conn;
                    566:   conn_fb_other = (struct tme_fb_connection *) conn->tme_connection_other;
                    567:   *_score = ((conn_fb->tme_fb_connection_mode_change != NULL)
                    568:             != (conn_fb_other->tme_fb_connection_mode_change != NULL));
                    569:   return (TME_OK);
                    570: }
                    571: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.