|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.