|
|
1.1 root 1: /* $Id: fb.c,v 1.2 2003/07/31 01:35:12 fredette Exp $ */
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>
37: _TME_RCSID("$Id: fb.c,v 1.2 2003/07/31 01:35:12 fredette Exp $");
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);
84: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_depth, != 0);
85: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_bits_per_pixel, != 0);
86: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_skipx, >= 0);
87: TME_FB_XLAT_SCORE(100, tme_fb_xlat_dst_scanline_pad, != 0);
88: TME_FB_XLAT_SCORE( 0, tme_fb_xlat_dst_order, || TRUE);
89:
90: #undef TME_FB_XLAT_SCORE
91:
92: /* update the best xlat: */
93: if (xlat_best == NULL
94: || xlat_best_score < xlat_score) {
95: xlat_best = xlat;
96: xlat_best_score = xlat_score;
97: }
98: }
99:
100: /* return the best xlat: */
101: assert (xlat_best != NULL);
102: return (xlat_best);
103: }
104:
105: /* this returns nonzero iff the translation function is optimal: */
106: int
107: tme_fb_xlat_is_optimal(const struct tme_fb_xlat *xlat)
108: {
109: return (xlat->tme_fb_xlat_width != 0
110: && xlat->tme_fb_xlat_height != 0
111: && xlat->tme_fb_xlat_src_depth != 0
112: && xlat->tme_fb_xlat_src_bits_per_pixel != 0
113: && xlat->tme_fb_xlat_src_skipx >= 0
114: && xlat->tme_fb_xlat_src_scanline_pad != 0
115: && xlat->tme_fb_xlat_dst_depth != 0
116: && xlat->tme_fb_xlat_dst_bits_per_pixel != 0
117: && xlat->tme_fb_xlat_dst_skipx >= 0
118: && xlat->tme_fb_xlat_dst_scanline_pad != 0);
119: }
120:
121: /* this returns the number of bytes required for a source framebuffer
122: scanline: */
123: static unsigned long
124: _tme_fb_xlat_src_bypl(const struct tme_fb_connection *src)
125: {
126: /* NB that this definition must match the one in the
127: automatically-generated xlat functions: */
128: const unsigned long src_bypl
129: = (((((src->tme_fb_connection_skipx
130: + src->tme_fb_connection_width)
131: * src->tme_fb_connection_bits_per_pixel)
132: + (src->tme_fb_connection_scanline_pad - 1))
133: & -src->tme_fb_connection_scanline_pad)
134: / 8);
135: return (src_bypl);
136: }
137:
138: /* this returns the number of bytes required for a source framebuffer: */
139: static unsigned long
140: _tme_fb_xlat_src_bypb_real(const struct tme_fb_connection *src)
141: {
142: /* NB that these definitions must match those in the
143: automatically-generated xlat functions: */
144: const unsigned long src_bypl
145: = _tme_fb_xlat_src_bypl(src);
146: const unsigned long src_bypb_real
147: = (((src->tme_fb_connection_height * src_bypl) + 3) & -4);
148: return (src_bypb_real);
149: }
150:
151: /* this returns the number of bytes allocated for a source framebuffer.
152: this includes the guard regions that are needed to guarantee that
153: the translation function main loop terminates: */
154: static unsigned long
155: _tme_fb_xlat_src_bypb(const struct tme_fb_connection *src)
156: {
157: /* NB that this definition must match the one in the
158: automatically-generated xlat functions: */
159: const unsigned long src_bypl
160: = _tme_fb_xlat_src_bypl(src);
161: const unsigned long src_bypb_real
162: = _tme_fb_xlat_src_bypb_real(src);
163: const unsigned long src_bypb
164: = ((src_bypb_real + (src_bypl * 2)) & -4);
165: return (src_bypb);
166: }
167:
168: /* this forces the next translation to retranslate the entire buffer: */
169: void
170: tme_fb_xlat_redraw(struct tme_fb_connection *src)
171: {
172: const tme_uint32_t *src_user;
173: tme_uint32_t *src_back;
174: unsigned int count32;
175:
176: src_user
177: = ((const tme_uint32_t *)
178: src->tme_fb_connection_buffer);
179: src_back
180: = ((tme_uint32_t *)
181: (src->tme_fb_connection_buffer
182: + _tme_fb_xlat_src_bypb(src)));
183: for (count32 = _tme_fb_xlat_src_bypb_real(src) / sizeof(tme_uint32_t);
184: count32-- > 0; ) {
185: *(src_back++) = ~(*(src_user++));
186: }
187: }
188:
189: /* this allocates memory for a source framebuffer: */
190: int
191: tme_fb_xlat_alloc_src(struct tme_fb_connection *src)
192: {
193:
194: /* allocate the buffer. remember, this is really two buffers - the
195: first half is the real, current framebuffer, and the second half
196: holds the last frame that was translated: */
197: src->tme_fb_connection_buffer
198: = tme_new0(tme_uint8_t,
199: _tme_fb_xlat_src_bypb(src) * 2);
200:
201: /* force the next translation to do a complete redraw: */
202: tme_fb_xlat_redraw(src);
203:
204: return (TME_OK);
205: }
206:
207: /* this scores a framebuffer connection: */
208: int
209: tme_fb_connection_score(struct tme_connection *conn, unsigned int *_score)
210: {
211: struct tme_fb_connection *conn_fb;
212: struct tme_fb_connection *conn_fb_other;
213:
214: /* both sides must be Ethernet connections: */
215: assert(conn->tme_connection_type == TME_CONNECTION_FRAMEBUFFER);
216: assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_FRAMEBUFFER);
217:
218: /* one side must be a real display and the other side must be a
219: framebuffer emulator: */
220: conn_fb = (struct tme_fb_connection *) conn;
221: conn_fb_other = (struct tme_fb_connection *) conn->tme_connection_other;
222: *_score = ((conn_fb->tme_fb_connection_mode_change != NULL)
223: != (conn_fb_other->tme_fb_connection_mode_change != NULL));
224: return (TME_OK);
225: }
226:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.