|
|
1.1.1.3 ! root 1: /* $Id: fb.c,v 1.5 2007/08/25 21:05:30 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.3 ! root 37: _TME_RCSID("$Id: fb.c,v 1.5 2007/08/25 21:05:30 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: 1.1.1.3 ! root 45: /* macros: */ ! 46: #define TME_FB_COLORSET_DIRECT_COLOR (1) ! 47: #define TME_FB_COLORSET_PSEUDO_COLOR (2) ! 48: 1.1 root 49: /* this returns the best translation function: */ 50: const struct tme_fb_xlat * 51: tme_fb_xlat_best(const struct tme_fb_xlat *xlat_user) 52: { 53: unsigned int xlat_i; 54: const struct tme_fb_xlat *xlat; 55: const struct tme_fb_xlat *xlat_best; 56: unsigned int xlat_best_score, xlat_score; 57: 58: /* loop over the xlats: */ 59: xlat_best = NULL; 60: xlat_best_score = 0; 61: for (xlat_i = 0; 62: xlat_i < TME_ARRAY_ELS(tme_fb_xlats); 63: xlat_i++) { 64: 65: /* get this xlat: */ 66: xlat = &tme_fb_xlats[xlat_i]; 67: xlat_score = 0; 68: 69: /* if this xlat only works for a particular value of the given 70: member, and the user's value is different, we cannot use this 71: xlat. otherwise, increase this xlat's score: */ 72: #define TME_FB_XLAT_SCORE(score, member, specific) \ 73: if ((xlat->member specific) \ 74: && (xlat->member != xlat_user->member)) { \ 75: continue; \ 76: } \ 77: if (xlat->member specific) \ 78: xlat_score += score 79: 80: TME_FB_XLAT_SCORE(100, tme_fb_xlat_width, != 0); 81: TME_FB_XLAT_SCORE(100, tme_fb_xlat_height, != 0); 82: TME_FB_XLAT_SCORE( 0, tme_fb_xlat_scale, || TRUE); 83: TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_depth, != 0); 84: TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_bits_per_pixel, != 0); 85: TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_skipx, >= 0); 86: TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_scanline_pad, != 0); 87: TME_FB_XLAT_SCORE( 0, tme_fb_xlat_src_order, || TRUE); 1.1.1.2 root 88: TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_class, != TME_FB_XLAT_CLASS_ANY); 89: TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_map, != TME_FB_XLAT_MAP_ANY); 90: TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_map_bits, != 0); 91: TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_mask_g, != TME_FB_XLAT_MASK_ANY); 92: TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_mask_r, != TME_FB_XLAT_MASK_ANY); 93: TME_FB_XLAT_SCORE(100, tme_fb_xlat_src_mask_b, != TME_FB_XLAT_MASK_ANY); 1.1 root 94: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_depth, != 0); 95: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_bits_per_pixel, != 0); 96: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_skipx, >= 0); 97: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_scanline_pad, != 0); 98: TME_FB_XLAT_SCORE( 0, tme_fb_xlat_dst_order, || TRUE); 1.1.1.2 root 99: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_map, != TME_FB_XLAT_MAP_ANY); 100: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_mask_g, != TME_FB_XLAT_MASK_ANY); 101: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_mask_r, != TME_FB_XLAT_MASK_ANY); 102: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_mask_b, != TME_FB_XLAT_MASK_ANY); 1.1 root 103: 104: #undef TME_FB_XLAT_SCORE 105: 106: /* update the best xlat: */ 107: if (xlat_best == NULL 108: || xlat_best_score < xlat_score) { 109: xlat_best = xlat; 110: xlat_best_score = xlat_score; 111: } 112: } 113: 114: /* return the best xlat: */ 115: assert (xlat_best != NULL); 116: return (xlat_best); 117: } 118: 119: /* this returns nonzero iff the translation function is optimal: */ 120: int 121: tme_fb_xlat_is_optimal(const struct tme_fb_xlat *xlat) 122: { 123: return (xlat->tme_fb_xlat_width != 0 124: && xlat->tme_fb_xlat_height != 0 125: && xlat->tme_fb_xlat_src_depth != 0 126: && xlat->tme_fb_xlat_src_bits_per_pixel != 0 127: && xlat->tme_fb_xlat_src_skipx >= 0 128: && xlat->tme_fb_xlat_src_scanline_pad != 0 1.1.1.2 root 129: && xlat->tme_fb_xlat_src_class != TME_FB_XLAT_CLASS_ANY 130: && xlat->tme_fb_xlat_src_map != TME_FB_XLAT_MAP_ANY 131: && xlat->tme_fb_xlat_src_map_bits != 0 132: && xlat->tme_fb_xlat_src_mask_g != TME_FB_XLAT_MASK_ANY 133: && xlat->tme_fb_xlat_src_mask_r != TME_FB_XLAT_MASK_ANY 134: && xlat->tme_fb_xlat_src_mask_b != TME_FB_XLAT_MASK_ANY 1.1 root 135: && xlat->tme_fb_xlat_dst_depth != 0 136: && xlat->tme_fb_xlat_dst_bits_per_pixel != 0 137: && xlat->tme_fb_xlat_dst_skipx >= 0 1.1.1.2 root 138: && xlat->tme_fb_xlat_dst_scanline_pad != 0 139: && xlat->tme_fb_xlat_dst_map != TME_FB_XLAT_MAP_ANY 140: && xlat->tme_fb_xlat_dst_mask_g != TME_FB_XLAT_MASK_ANY 141: && xlat->tme_fb_xlat_dst_mask_r != TME_FB_XLAT_MASK_ANY 142: && xlat->tme_fb_xlat_dst_mask_b != TME_FB_XLAT_MASK_ANY 143: ); 1.1 root 144: } 145: 146: /* this returns the number of bytes required for a source framebuffer 147: scanline: */ 148: static unsigned long 149: _tme_fb_xlat_src_bypl(const struct tme_fb_connection *src) 150: { 151: /* NB that this definition must match the one in the 152: automatically-generated xlat functions: */ 153: const unsigned long src_bypl 154: = (((((src->tme_fb_connection_skipx 155: + src->tme_fb_connection_width) 156: * src->tme_fb_connection_bits_per_pixel) 157: + (src->tme_fb_connection_scanline_pad - 1)) 158: & -src->tme_fb_connection_scanline_pad) 159: / 8); 160: return (src_bypl); 161: } 162: 163: /* this returns the number of bytes required for a source framebuffer: */ 164: static unsigned long 165: _tme_fb_xlat_src_bypb_real(const struct tme_fb_connection *src) 166: { 167: /* NB that these definitions must match those in the 168: automatically-generated xlat functions: */ 169: const unsigned long src_bypl 170: = _tme_fb_xlat_src_bypl(src); 171: const unsigned long src_bypb_real 172: = (((src->tme_fb_connection_height * src_bypl) + 3) & -4); 173: return (src_bypb_real); 174: } 175: 176: /* this returns the number of bytes allocated for a source framebuffer. 177: this includes the guard regions that are needed to guarantee that 178: the translation function main loop terminates: */ 179: static unsigned long 180: _tme_fb_xlat_src_bypb(const struct tme_fb_connection *src) 181: { 182: /* NB that this definition must match the one in the 183: automatically-generated xlat functions: */ 184: const unsigned long src_bypl 185: = _tme_fb_xlat_src_bypl(src); 186: const unsigned long src_bypb_real 187: = _tme_fb_xlat_src_bypb_real(src); 188: const unsigned long src_bypb 189: = ((src_bypb_real + (src_bypl * 2)) & -4); 190: return (src_bypb); 191: } 192: 193: /* this forces the next translation to retranslate the entire buffer: */ 194: void 195: tme_fb_xlat_redraw(struct tme_fb_connection *src) 196: { 197: const tme_uint32_t *src_user; 198: tme_uint32_t *src_back; 199: unsigned int count32; 200: 201: src_user 202: = ((const tme_uint32_t *) 203: src->tme_fb_connection_buffer); 204: src_back 205: = ((tme_uint32_t *) 206: (src->tme_fb_connection_buffer 207: + _tme_fb_xlat_src_bypb(src))); 208: for (count32 = _tme_fb_xlat_src_bypb_real(src) / sizeof(tme_uint32_t); 209: count32-- > 0; ) { 210: *(src_back++) = ~(*(src_user++)); 211: } 212: } 213: 214: /* this allocates memory for a source framebuffer: */ 215: int 216: tme_fb_xlat_alloc_src(struct tme_fb_connection *src) 217: { 218: 219: /* allocate the buffer. remember, this is really two buffers - the 220: first half is the real, current framebuffer, and the second half 221: holds the last frame that was translated: */ 222: src->tme_fb_connection_buffer 223: = tme_new0(tme_uint8_t, 224: _tme_fb_xlat_src_bypb(src) * 2); 225: 226: /* force the next translation to do a complete redraw: */ 227: tme_fb_xlat_redraw(src); 228: 229: return (TME_OK); 230: } 231: 1.1.1.2 root 232: /* this internal function gets or sets the needed colors on a 233: destination framebuffer connection that is using the common 234: translation functions: */ 235: static tme_uint32_t 236: _tme_fb_xlat_colors_get_set(const struct tme_fb_connection *src, 237: unsigned int scale, 238: struct tme_fb_connection *dst, 239: struct tme_fb_color **_colors, 240: int get) 241: { 242: tme_uint32_t src_mask; 243: tme_uint32_t src_mask_g; 244: tme_uint32_t src_mask_r; 245: tme_uint32_t src_mask_b; 246: tme_uint32_t src_shift_g; 247: tme_uint32_t src_shift_r; 248: tme_uint32_t src_shift_b; 249: const void *src_map_g; 250: const void *src_map_r; 251: const void *src_map_b; 252: tme_uint32_t value_g; 253: tme_uint32_t value_r; 254: tme_uint32_t value_b; 255: tme_uint32_t src_max_g; 256: tme_uint32_t src_max_r; 257: tme_uint32_t src_max_b; 258: tme_uint32_t color_count; 259: tme_uint32_t color_i; 1.1.1.3 ! root 260: tme_uint32_t color_j; ! 261: int compress_colors; ! 262: unsigned int dst_depth_g; ! 263: unsigned int dst_depth_r; ! 264: unsigned int dst_depth_b; 1.1.1.2 root 265: struct tme_fb_color *colors; 266: tme_uint32_t *pixels; 267: tme_uint32_t invert_mask; 1.1.1.3 ! root 268: tme_uint32_t colorset; 1.1.1.2 root 269: 270: /* get how to decompose source pixels into subfields. if source 271: pixels have no subfields, act as if all of the subfields are the 272: entire source pixel: */ 273: src_mask = (0xffffffff >> (32 - src->tme_fb_connection_depth)); 274: src_mask_g = src->tme_fb_connection_mask_g; 275: src_mask_r = src->tme_fb_connection_mask_r; 276: src_mask_b = src->tme_fb_connection_mask_b; 277: if (src_mask_g == 0) { 278: src_mask_g = src_mask; 279: src_mask_r = src_mask; 280: src_mask_b = src_mask; 281: } 282: 283: /* if source intensities are index mapped, their common maximum is 284: the mask of the mapping size range in bits: */ 285: src_map_g = src->tme_fb_connection_map_g; 286: src_map_r = src->tme_fb_connection_map_r; 287: src_map_b = src->tme_fb_connection_map_b; 288: if (src_map_g != NULL) { 289: src_max_g = (0xffffffff >> (32 - src->tme_fb_connection_map_bits)); 290: src_max_r = src_max_g; 291: src_max_b = src_max_g; 292: } 293: 294: /* otherwise, source intensities are linearly mapped, and each 295: primary's maximum intensity is the base mask of its subfield: */ 296: else { 297: src_max_g = TME_FB_XLAT_MAP_BASE_MASK(src_mask_g); 298: src_max_r = TME_FB_XLAT_MAP_BASE_MASK(src_mask_r); 299: src_max_b = TME_FB_XLAT_MAP_BASE_MASK(src_mask_b); 300: } 301: 302: /* the source intensity maximums must be greater than zero, and not 303: larger than 16 bits: */ 304: assert (src_max_g > 0 && src_max_g <= 0xffff); 305: assert (src_max_r > 0 && src_max_r <= 0xffff); 306: assert (src_max_b > 0 && src_max_b <= 0xffff); 307: 308: /* get any inversion mask: */ 309: invert_mask = (src->tme_fb_connection_inverted ? 0xffff : 0); 310: 311: /* if we're halving, the intensity maximums are four times what they 312: would be otherwise, because the intensities from four pixels are 313: added together: */ 314: if (scale == TME_FB_XLAT_SCALE_HALF) { 315: src_max_g *= 4; 316: src_max_r *= 4; 317: src_max_b *= 4; 318: } 319: 320: /* if we're not halving, and either the source pixel mask is less 321: than the maximum index mask or source pixels have no subfields, 322: we will index map source pixels directly to destination 323: pixels: */ 324: if (scale != TME_FB_XLAT_SCALE_HALF 325: && (src_mask <= TME_FB_XLAT_MAP_INDEX_MASK_MAX 326: || src_mask_g == src_mask)) { 327: 328: /* we will allocate as many colors as we have source pixels: */ 329: color_count = src_mask + 1; 1.1.1.3 ! root 330: colorset = TME_FB_COLORSET_NONE; 1.1.1.2 root 331: } 332: 333: /* otherwise, either we're halving, or source pixels are too big to 334: map directly and they have subfields. the translation code will 335: decompose pixels into intensities: */ 336: 337: /* if the source class is monochrome, we only have to deal with 338: the green primary: */ 339: else if (src->tme_fb_connection_class == TME_FB_XLAT_CLASS_MONOCHROME) { 340: 341: /* the translation function will index map green intensity values 342: directly into pixels. we may need to scale the intensities so 343: they can be indexed: */ 344: for (; src_max_g > TME_FB_XLAT_MAP_INDEX_MASK_MAX; src_max_g >>= 1); 345: 346: /* allocate colors for src_max_g intensities: */ 347: color_count = src_max_g + 1; 1.1.1.3 ! root 348: colorset = TME_FB_COLORSET_NONE; 1.1.1.2 root 349: src_mask_g = TME_FB_XLAT_MAP_INDEX_MASK_MAX; 350: src_map_g = NULL; 351: src_mask_r = src_mask_g; 352: src_mask_b = src_mask_g; 353: src_map_r = src_map_g; 354: src_map_b = src_map_g; 355: src_max_r = src_max_g; 356: src_max_b = src_max_g; 357: } 358: 359: /* otherwise, we have to deal with all three primaries: */ 360: 361: /* if the destination is color and has subfields: */ 362: else if (dst->tme_fb_connection_class == TME_FB_XLAT_CLASS_COLOR 363: && dst->tme_fb_connection_mask_g != 0) { 364: 365: /* if the destination maps intensities linearly, we don't need to 366: allocate colors at all: */ 367: if (dst->tme_fb_connection_map_g == NULL) { 368: 369: /* however, we can't do this yet with a source framebuffer that 370: is inverted: */ 371: if (src->tme_fb_connection_inverted) { 372: abort(); 373: } 374: 375: /* nothing to do */ 376: *_colors = NULL; 1.1.1.3 ! root 377: dst->tme_fb_connection_map_pixel_count = 0; ! 378: return (TME_FB_COLORSET_NONE); 1.1.1.2 root 379: } 380: 381: /* otherwise, the translation function will index map the 382: intensity values into subfield values. we may need to scale 383: the intensities so they can be indexed: */ 384: for (; src_max_g > TME_FB_XLAT_MAP_INDEX_MASK_MAX; src_max_g >>= 1); 385: for (; src_max_r > TME_FB_XLAT_MAP_INDEX_MASK_MAX; src_max_r >>= 1); 386: for (; src_max_b > TME_FB_XLAT_MAP_INDEX_MASK_MAX; src_max_b >>= 1); 387: 388: /* size the color array: */ 389: color_count = src_max_g + 1 + src_max_r + 1 + src_max_b + 1; 1.1.1.3 ! root 390: colorset = TME_FB_COLORSET_DIRECT_COLOR; 1.1.1.2 root 391: 392: /* if we're getting the needed colors: */ 393: if (get) { 394: 395: /* allocate the color array: */ 396: colors = tme_new0(struct tme_fb_color, color_count); 397: 398: /* make the colors to allocate from all of the different 399: primary intensities: */ 400: color_i = 0; 401: #define _TME_FB_XLAT_INDEX_COLORS(value, max, primary) \ 402: do { \ 403: for (value = 0; value <= (max); value++, color_i++) { \ 404: colors[color_i].primary = ((0xffff * value) / (max)) ^ invert_mask;\ 405: } \ 406: } while (/* CONSTCOND */ 0) 407: _TME_FB_XLAT_INDEX_COLORS(value_g, src_max_g, tme_fb_color_value_g); 408: _TME_FB_XLAT_INDEX_COLORS(value_r, src_max_r, tme_fb_color_value_r); 409: _TME_FB_XLAT_INDEX_COLORS(value_b, src_max_b, tme_fb_color_value_b); 410: #undef _TME_FB_XLAT_INDEX_COLORS 411: 412: /* return the needed colors: */ 413: *_colors = colors; 1.1.1.3 ! root 414: dst->tme_fb_connection_map_pixel_count = color_count; ! 415: return (colorset); 1.1.1.2 root 416: } 417: 418: /* set up the intensity index maps: */ 419: colors = *_colors; 420: color_i = 0; 421: #define __TME_FB_XLAT_INDEX_SUBFIELDS(value, max, primary_mask, primary_shift, primary_map, type)\ 422: do { \ 423: dst->primary_map = tme_new(type, (max) + 1); \ 424: for (value = 0; value <= (max); value++, color_i++) { \ 425: ((type *) dst->primary_map)[value] \ 426: = ((colors[color_i].tme_fb_color_pixel \ 427: & dst->primary_mask) \ 428: >> primary_shift); \ 429: } \ 430: } while (/* CONSTCOND */ 0) 431: #define _TME_FB_XLAT_INDEX_SUBFIELDS(value, max, primary_mask, primary_shift, primary_map)\ 432: do { \ 433: for (primary_shift = 0; \ 434: ((dst->primary_mask >> primary_shift) & 1) == 0; \ 435: primary_shift++); \ 436: if (TME_FB_XLAT_MAP_BASE_MASK(dst->primary_mask) <= 0xff) { \ 437: __TME_FB_XLAT_INDEX_SUBFIELDS(value, max, primary_mask, primary_shift, primary_map, tme_uint8_t);\ 438: } \ 439: else { \ 440: __TME_FB_XLAT_INDEX_SUBFIELDS(value, max, primary_mask, primary_shift, primary_map, tme_uint16_t);\ 441: } \ 442: } while (/* CONSTCOND */ 0) 443: _TME_FB_XLAT_INDEX_SUBFIELDS(value_g, src_max_g, tme_fb_connection_mask_g, src_shift_g, tme_fb_connection_map_g); 444: _TME_FB_XLAT_INDEX_SUBFIELDS(value_r, src_max_r, tme_fb_connection_mask_r, src_shift_r, tme_fb_connection_map_r); 445: _TME_FB_XLAT_INDEX_SUBFIELDS(value_b, src_max_b, tme_fb_connection_mask_b, src_shift_b, tme_fb_connection_map_b); 446: #undef _TME_FB_XLAT_INDEX_SUBFIELDS 447: #undef __TME_FB_XLAT_INDEX_SUBFIELDS 448: } 449: 450: /* otherwise, the destination is either not color or it doesn't 451: have subfields. we need to allocate colors to map fake 452: source pixels: */ 453: else { 454: src_mask_g = TME_FB_XLAT_MASK_DEFAULT_G; 455: src_mask_r = TME_FB_XLAT_MASK_DEFAULT_R; 456: src_mask_b = TME_FB_XLAT_MASK_DEFAULT_B; 457: src_map_g = NULL; 458: src_map_r = NULL; 459: src_map_b = NULL; 460: src_max_g = TME_FB_XLAT_MAP_BASE_MASK(src_mask_g); 461: src_max_r = TME_FB_XLAT_MAP_BASE_MASK(src_mask_r); 462: src_max_b = TME_FB_XLAT_MAP_BASE_MASK(src_mask_b); 463: color_count = (src_mask_g | src_mask_r | src_mask_b) + 1; 1.1.1.3 ! root 464: colorset = TME_FB_COLORSET_PSEUDO_COLOR; 1.1.1.2 root 465: } 466: 467: /* if we get here, we're allocating colors from source pixel values 468: (or possibly fake source pixel values): */ 469: 470: /* if we're getting the needed colors: */ 471: if (get) { 472: 1.1.1.3 ! root 473: /* if the number of colors we need is clearly more than the ! 474: destination's depth can possibly handle, and the destination is ! 475: either monochrome or is color with no pixel subfields, asking ! 476: for this huge number of distinct colors will probably get us a ! 477: poorly representative subset. ! 478: ! 479: in general, we can't help this. but in the specific case of ! 480: source pixels that directly map to intensity(s), we can remove ! 481: some of the less significant bits of the source pixel subfield ! 482: mask(s), so that we only ask to allocate as many distinct ! 483: colors as the destination's depth can handle: */ ! 484: compress_colors ! 485: = ((color_count >> dst->tme_fb_connection_depth) > 0 ! 486: && (dst->tme_fb_connection_class == TME_FB_XLAT_CLASS_MONOCHROME ! 487: || dst->tme_fb_connection_mask_g == 0) ! 488: && src_map_g == NULL); ! 489: if (compress_colors) { ! 490: ! 491: /* get the depth for each primary: */ ! 492: if (src->tme_fb_connection_class == TME_FB_XLAT_CLASS_MONOCHROME) { ! 493: dst_depth_g = dst->tme_fb_connection_depth; ! 494: dst_depth_r = 0; ! 495: dst_depth_b = 0; ! 496: } ! 497: else { ! 498: dst_depth_r = dst->tme_fb_connection_depth; ! 499: dst_depth_g = (dst_depth_r + 2) / 3; ! 500: dst_depth_r -= dst_depth_g; ! 501: dst_depth_b = (dst_depth_r + 1) / 2; ! 502: dst_depth_r -= dst_depth_b; ! 503: } ! 504: ! 505: /* remove some of the less significant bits in the subfield ! 506: masks and recalculate the source intensity maximums: */ ! 507: #define _TME_FB_XLAT_LIMIT_MASK(src_mask_i, src_max_i, dst_depth_i) \ ! 508: do { \ ! 509: src_mask_i ^= (src_mask_i & (src_mask_i >> dst_depth_i)); \ ! 510: src_max_i = (src_mask_i ? TME_FB_XLAT_MAP_BASE_MASK(src_mask_i) : 1); \ ! 511: } while (/* CONSTCOND */ 0) ! 512: _TME_FB_XLAT_LIMIT_MASK(src_mask_g, src_max_g, dst_depth_g); ! 513: _TME_FB_XLAT_LIMIT_MASK(src_mask_r, src_max_r, dst_depth_r); ! 514: _TME_FB_XLAT_LIMIT_MASK(src_mask_b, src_max_b, dst_depth_b); ! 515: #undef _TME_FB_XLAT_LIMIT_MASK ! 516: } ! 517: 1.1.1.2 root 518: /* make shift counts for the subfields and shift their trailing zeroes off: */ 519: for (src_shift_g = 0; (src_mask_g & 1) == 0; src_shift_g++, src_mask_g >>= 1); 520: for (src_shift_r = 0; (src_mask_r & 1) == 0; src_shift_r++, src_mask_r >>= 1); 521: for (src_shift_b = 0; (src_mask_b & 1) == 0; src_shift_b++, src_mask_b >>= 1); 522: 523: /* allocate the color array: */ 524: colors = tme_new0(struct tme_fb_color, color_count); 525: 526: /* loop over the source pixels: */ 527: for (color_i = 0; 528: color_i < color_count; 529: color_i++) { 530: 531: /* get the raw primary values: */ 532: value_g = (color_i >> src_shift_g) & src_mask_g; 533: value_r = (color_i >> src_shift_r) & src_mask_r; 534: value_b = (color_i >> src_shift_b) & src_mask_b; 535: 1.1.1.3 ! root 536: /* we give a distinct pixel value for each distinct color we ask ! 537: for, since we may ask for a lot of duplicates. this isn't ! 538: really a pixel value at all, anywhere - it only serves to ! 539: group duplicate colors together in the color array: */ ! 540: if (compress_colors) { ! 541: color_j = value_g; ! 542: color_j = (color_j * (src_mask_r + 1)) + value_r; ! 543: color_j = (color_j * (src_mask_b + 1)) + value_b; ! 544: } ! 545: else { ! 546: color_j = color_i; ! 547: } ! 548: 1.1.1.2 root 549: /* if the primaries are index mapped, turn the raw primary 550: values into intensities: */ 551: if (src_map_g != NULL) { 552: 553: /* if intensities are stored as 8 bits: */ 554: if (src_max_g <= 0xff) { 555: value_g = ((const tme_uint8_t *) src_map_g)[value_g]; 556: value_r = ((const tme_uint8_t *) src_map_r)[value_r]; 557: value_b = ((const tme_uint8_t *) src_map_b)[value_b]; 558: } 559: 560: /* otherwise, intensities are stored as 16 bits: */ 561: else { 562: value_g = ((const tme_uint16_t *) src_map_g)[value_g]; 563: value_r = ((const tme_uint16_t *) src_map_r)[value_r]; 564: value_b = ((const tme_uint16_t *) src_map_b)[value_b]; 565: } 566: } 567: 568: /* scale the intensities to 16 bits and possibly invert them: */ 569: value_g = ((0xffff * value_g) / src_max_g) ^ invert_mask; 570: value_r = ((0xffff * value_r) / src_max_r) ^ invert_mask; 571: value_b = ((0xffff * value_b) / src_max_b) ^ invert_mask; 572: 573: /* if the source class is monochrome, use only the green primary: */ 574: if (src->tme_fb_connection_class == TME_FB_XLAT_CLASS_MONOCHROME) { 575: value_r = value_g; 576: value_b = value_g; 577: } 578: 579: /* allocate this color: */ 1.1.1.3 ! root 580: colors[color_i].tme_fb_color_pixel = color_j; 1.1.1.2 root 581: colors[color_i].tme_fb_color_value_g = value_g; 582: colors[color_i].tme_fb_color_value_r = value_r; 583: colors[color_i].tme_fb_color_value_b = value_b; 584: } 585: 586: /* return the needed colors: */ 587: *_colors = colors; 1.1.1.3 ! root 588: dst->tme_fb_connection_map_pixel_count = color_count; ! 589: return (colorset); 1.1.1.2 root 590: } 591: 592: /* otherwise, take in the allocated colors: */ 593: colors = *_colors; 594: pixels = tme_new(tme_uint32_t, color_count); 595: for (color_i = 0; 596: color_i < color_count; 597: color_i++) { 598: pixels[color_i] = colors[color_i].tme_fb_color_pixel; 599: } 600: dst->tme_fb_connection_map_pixel = pixels; 601: dst->tme_fb_connection_map_pixel_count = color_count; 602: tme_free(colors); 603: return (0); 604: } 605: 606: /* this gets the needed colors on a destination framebuffer connection 607: that is using the common translation functions: */ 608: tme_uint32_t 609: tme_fb_xlat_colors_get(const struct tme_fb_connection *src, 610: unsigned int scale, 611: struct tme_fb_connection *dst, 612: struct tme_fb_color **_colors) 613: { 614: return (_tme_fb_xlat_colors_get_set(src, scale, dst, _colors, TRUE)); 615: } 616: 617: /* this sets the needed colors on a destination framebuffer connection 618: that is using the common translation functions: */ 619: void 620: tme_fb_xlat_colors_set(const struct tme_fb_connection *src, 621: unsigned int scale, 622: struct tme_fb_connection *dst, 623: struct tme_fb_color *colors) 624: { 625: _tme_fb_xlat_colors_get_set(src, scale, dst, &colors, FALSE); 626: } 627: 1.1 root 628: /* this scores a framebuffer connection: */ 629: int 630: tme_fb_connection_score(struct tme_connection *conn, unsigned int *_score) 631: { 632: struct tme_fb_connection *conn_fb; 633: struct tme_fb_connection *conn_fb_other; 634: 635: /* both sides must be Ethernet connections: */ 636: assert(conn->tme_connection_type == TME_CONNECTION_FRAMEBUFFER); 637: assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_FRAMEBUFFER); 638: 639: /* one side must be a real display and the other side must be a 640: framebuffer emulator: */ 641: conn_fb = (struct tme_fb_connection *) conn; 642: conn_fb_other = (struct tme_fb_connection *) conn->tme_connection_other; 643: *_score = ((conn_fb->tme_fb_connection_mode_change != NULL) 644: != (conn_fb_other->tme_fb_connection_mode_change != NULL)); 645: return (TME_OK); 646: } 647:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.