ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/video_blit.cpp
Revision: 1.3
Committed: 2001-06-22T08:34:49Z (23 years, 5 months ago) by gbeauche
Branch: MAIN
Changes since 1.2: +6 -0 lines
Log Message:
- In banked addressing mode, the UAE memory handlers should already handle
  reads/writes to/from the frame buffer correctly. i.e. specialised blitters
  should not be used there.

File Contents

# Content
1 /*
2 * video_blit.cpp - Video/graphics emulation, blitters
3 *
4 * Basilisk II (C) 1997-2001 Christian Bauer
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sysdeps.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27
28 #ifdef ENABLE_VOSF
29 // Format of the target visual
30 struct VisualFormat {
31 int depth; // Screen depth
32 uint32 Rmask, Gmask, Bmask; // RGB mask values
33 uint32 Rshift, Gshift, Bshift; // RGB shift values
34 };
35 static VisualFormat visualFormat;
36
37 /* -------------------------------------------------------------------------- */
38 /* --- Raw Copy / No conversion required --- */
39 /* -------------------------------------------------------------------------- */
40
41 static void Blit_Copy_Raw(uint8 * dest, const uint8 * source, uint32 length)
42 {
43 // This function is likely to be inlined and/or highly optimized
44 memcpy(dest, source, length);
45 }
46
47 /* -------------------------------------------------------------------------- */
48 /* --- RGB 555 --- */
49 /* -------------------------------------------------------------------------- */
50
51 #ifdef WORDS_BIGENDIAN
52 # define FB_FUNC_NAME Blit_RGB555_OBO
53 #else
54 # define FB_FUNC_NAME Blit_RGB555_NBO
55 #endif
56
57 #define FB_BLIT_1(dst, src) \
58 (dst = (((src) >> 8) & 0xff) | (((src) & 0xff) << 8))
59
60 #define FB_BLIT_2(dst, src) \
61 (dst = (((src) >> 8) & 0x00ff00ff) | (((src) & 0x00ff00ff) << 8))
62
63 #define FB_DEPTH 15
64 #include "video_blit.h"
65
66 /* -------------------------------------------------------------------------- */
67 /* --- BGR 555 --- */
68 /* -------------------------------------------------------------------------- */
69
70 #ifdef WORDS_BIGENDIAN
71
72 // Native byte order
73
74 #define FB_BLIT_1(dst, src) \
75 (dst = (((src) >> 10) & 0x001f) | ((src) & 0x03e0) | (((src) << 10) & 0x7c00))
76
77 #define FB_BLIT_2(dst, src) \
78 (dst = (((src) >> 10) & 0x001f001f) | ((src) & 0x03e003e0) | (((src) << 10) & 0x7c007c00))
79
80 #define FB_DEPTH 15
81 #define FB_FUNC_NAME Blit_BGR555_NBO
82 #include "video_blit.h"
83
84 // Opposite byte order (untested)
85
86 #define FB_BLIT_1(dst, src) \
87 (dst = (((src) >> 2) & 0x1f00) | (((src) >> 8) & 3) | (((src) << 8) & 0xe000) | (((src) << 2) & 0x7c))
88
89 #define FB_BLIT_2(dst, src) \
90 (dst = (((src) >> 2) & 0x1f001f00) | (((src) >> 8) & 0x30003) | (((src) << 8) & 0xe000e000) | (((src) << 2) & 0x7c007c))
91
92 #define FB_DEPTH 15
93 #define FB_FUNC_NAME Blit_BGR555_OBO
94 #include "video_blit.h"
95
96 #else
97
98 // Native byte order (untested)
99
100 #define FB_BLIT_1(dst, src) \
101 (dst = (((src) >> 2) & 0x1f) | (((src) >> 8) & 0xe0) | (((src) << 8) & 0x0300) | (((src) << 2) & 0x7c00))
102
103 #define FB_BLIT_2(dst, src) \
104 (dst = (((src) >> 2) & 0x1f001f) | (((src) >> 8) & 0xe000e0) | (((src) << 8) & 0x03000300) | (((src) << 2) & 0x7c007c00))
105
106 #define FB_DEPTH 15
107 #define FB_FUNC_NAME Blit_BGR555_NBO
108 #include "video_blit.h"
109
110 // Opposite byte order (untested)
111
112 #define FB_BLIT_1(dst, src) \
113 (dst = (((src) << 6) & 0x1f00) | ((src) & 0xe003) | (((src) >> 6) & 0x7c))
114
115 #define FB_BLIT_2(dst, src) \
116 (dst = (((src) << 6) & 0x1f001f00) | ((src) & 0xe003e003) | (((src) >> 6) & 0x7c007c))
117
118 #define FB_DEPTH 15
119 #define FB_FUNC_NAME Blit_BGR555_OBO
120 #include "video_blit.h"
121
122 #endif
123
124 /* -------------------------------------------------------------------------- */
125 /* --- RGB 565 --- */
126 /* -------------------------------------------------------------------------- */
127
128 #ifdef WORDS_BIGENDIAN
129
130 // Native byte order
131
132 #define FB_BLIT_1(dst, src) \
133 (dst = (((src) & 0x1f) | (((src) << 1) & 0xffc0)))
134
135 #define FB_BLIT_2(dst, src) \
136 (dst = (((src) & 0x001f001f) | (((src) << 1) & 0xffc0ffc0)))
137
138 #define FB_DEPTH 16
139 #define FB_FUNC_NAME Blit_RGB565_NBO
140 #include "video_blit.h"
141
142 // Opposite byte order
143
144 #define FB_BLIT_1(dst, src) \
145 (dst = ((((src) >> 7) & 0xff) | (((src) << 9) & 0xc000) | (((src) << 8) & 0x1f00)))
146
147 #define FB_BLIT_2(dst, src) \
148 (dst = ((((src) >> 7) & 0x00ff00ff) | (((src) << 9) & 0xc000c000) | (((src) << 8) & 0x1f001f00)))
149
150 #define FB_DEPTH 16
151 #define FB_FUNC_NAME Blit_RGB565_OBO
152 #include "video_blit.h"
153
154 #else
155
156 // Native byte order
157
158 #define FB_BLIT_1(dst, src) \
159 (dst = (((src) >> 8) & 0x001f) | (((src) << 9) & 0xfe00) | (((src) >> 7) & 0x01c0))
160
161 // gb-- Disabled because I don't see any improvement
162 #if 0 && defined(__i386__) && defined(X86_ASSEMBLY)
163
164 #define FB_BLIT_2(dst, src) \
165 __asm__ ( "movl %0,%%ebx\n\t" \
166 "movl %0,%%ebp\n\t" \
167 "andl $0x1f001f00,%%ebx\n\t" \
168 "andl $0x007f007f,%0\n\t" \
169 "andl $0xe000e000,%%ebp\n\t" \
170 "shrl $8,%%ebx\n\t" \
171 "shrl $7,%%ebp\n\t" \
172 "shll $9,%0\n\t" \
173 "orl %%ebx,%%ebp\n\t" \
174 "orl %%ebp,%0\n\t" \
175 : "=r" (dst) : "0" (src) : "ebx", "ebp", "cc" )
176
177 #else
178
179 #define FB_BLIT_2(dst, src) \
180 (dst = (((src) >> 8) & 0x001f001f) | (((src) << 9) & 0xfe00fe00) | (((src) >> 7) & 0x01c001c0))
181
182 #endif
183
184 #define FB_DEPTH 16
185 #define FB_FUNC_NAME Blit_RGB565_NBO
186 #include "video_blit.h"
187
188 // Opposite byte order (untested)
189
190 #define FB_BLIT_1(dst, src) \
191 (dst = (((src) & 0x1f00) | (((src) << 1) & 0xe0fe) | (((src) >> 15) & 1)))
192
193 #define FB_BLIT_2(dst, src) \
194 (dst = (((src) & 0x1f001f00) | (((src) << 1) & 0xe0fee0fe) | (((src) >> 15) & 0x10001)))
195
196 #define FB_DEPTH 16
197 #define FB_FUNC_NAME Blit_RGB565_OBO
198 #include "video_blit.h"
199
200 #endif
201
202 /* -------------------------------------------------------------------------- */
203 /* --- RGB 888 --- */
204 /* -------------------------------------------------------------------------- */
205
206 #ifdef WORDS_BIGENDIAN
207 # define FB_FUNC_NAME Blit_RGB888_OBO
208 #else
209 # define FB_FUNC_NAME Blit_RGB888_NBO
210 #endif
211
212 #define FB_BLIT_2(dst, src) \
213 (dst = (((src) >> 24) & 0xff) | (((src) >> 8) & 0xff00) | (((src) & 0xff00) << 8) | (((src) & 0xff) << 24))
214
215 #define FB_DEPTH 24
216 #include "video_blit.h"
217
218 /* -------------------------------------------------------------------------- */
219 /* --- BGR 888 --- */
220 /* -------------------------------------------------------------------------- */
221
222 // Native byte order [BE] (untested)
223
224 #ifdef WORDS_BIGENDIAN
225
226 #define FB_BLIT_2(dst, src) \
227 (dst = (((src) >> 16) & 0xff) | ((src) & 0xff00) | (((src) & 0xff) << 16))
228
229 #define FB_FUNC_NAME Blit_BGR888_NBO
230 #define FB_DEPTH 24
231 #include "video_blit.h"
232
233 #else
234
235 // Opposite byte order [LE] (untested)
236
237 #define FB_BLIT_2(dst, src) \
238 (dst = (((src) >> 16) & 0xff) | ((src) & 0xff0000) | (((src) & 0xff) << 16))
239
240 #define FB_FUNC_NAME Blit_BGR888_OBO
241 #define FB_DEPTH 24
242 #include "video_blit.h"
243
244 #endif
245
246 // Opposite byte order [BE] (untested) / Native byte order [LE] (untested)
247
248 #ifdef WORDS_BIGENDIAN
249 # define FB_FUNC_NAME Blit_BGR888_OBO
250 #else
251 # define FB_FUNC_NAME Blit_BGR888_NBO
252 #endif
253
254 #define FB_BLIT_2(dst, src) \
255 (dst = ((src) & 0xff00ff) | (((src) & 0xff00) << 16))
256
257 #define FB_DEPTH 24
258 #include "video_blit.h"
259
260 /* -------------------------------------------------------------------------- */
261 /* --- Blitters to the host frame buffer, or XImage buffer --- */
262 /* -------------------------------------------------------------------------- */
263
264 // Function used to update the hosst frame buffer (DGA), or an XImage buffer (WIN)
265 // --> Shall be initialized only through the Screen_blitter_init() function
266 typedef void (*Screen_blit_func)(uint8 * dest, const uint8 * source, uint32 length);
267 Screen_blit_func Screen_blit = 0;
268
269 // Structure used to match the adequate framebuffer update function
270 struct Screen_blit_func_info {
271 int depth; // Screen depth
272 uint32 Rmask; // Red mask
273 uint32 Gmask; // Green mask
274 uint32 Bmask; // Blue mask
275 Screen_blit_func handler_nbo; // Update function (native byte order)
276 Screen_blit_func handler_obo; // Update function (opposite byte order)
277 };
278
279 // Table of visual formats supported and their respective handler
280 static Screen_blit_func_info Screen_blitters[] = {
281 #ifdef WORDS_BIGENDIAN
282 { 1, 0x000000, 0x000000, 0x000000, Blit_Copy_Raw , Blit_Copy_Raw }, // NT
283 { 8, 0x000000, 0x000000, 0x000000, Blit_Copy_Raw , Blit_Copy_Raw }, // OK (NBO)
284 { 15, 0x007c00, 0x0003e0, 0x00001f, Blit_Copy_Raw , Blit_RGB555_OBO }, // OK (OBO)
285 { 15, 0x00001f, 0x0003e0, 0x007c00, Blit_BGR555_NBO , Blit_BGR555_OBO }, // NT
286 { 16, 0x00f800, 0x0007e0, 0x00001f, Blit_RGB565_NBO , Blit_RGB565_OBO }, // OK (OBO)
287 { 24, 0xff0000, 0x00ff00, 0x0000ff, Blit_Copy_Raw , Blit_RGB888_OBO }, // OK (OBO)
288 { 24, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO }, // NT
289 { 32, 0xff0000, 0x00ff00, 0x0000ff, Blit_Copy_Raw , Blit_RGB888_OBO }, // OK
290 { 32, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO } // OK
291 #else
292 { 1, 0x000000, 0x000000, 0x000000, Blit_Copy_Raw , Blit_Copy_Raw }, // NT
293 { 8, 0x000000, 0x000000, 0x000000, Blit_Copy_Raw , Blit_Copy_Raw }, // OK (NBO)
294 { 15, 0x007c00, 0x0003e0, 0x00001f, Blit_RGB555_NBO , Blit_Copy_Raw }, // OK (NBO)
295 { 15, 0x00001f, 0x0003e0, 0x007c00, Blit_BGR555_NBO , Blit_BGR555_OBO }, // NT
296 { 16, 0x00f800, 0x0007e0, 0x00001f, Blit_RGB565_NBO , Blit_RGB565_OBO }, // OK (NBO)
297 { 24, 0xff0000, 0x00ff00, 0x0000ff, Blit_RGB888_NBO , Blit_Copy_Raw }, // OK (NBO)
298 { 24, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO }, // NT
299 { 32, 0xff0000, 0x00ff00, 0x0000ff, Blit_RGB888_NBO , Blit_Copy_Raw }, // OK (NBO)
300 { 32, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO } // NT
301 #endif
302 };
303
304 // Initialize the framebuffer update function
305 // Returns FALSE, if the function was to be reduced to a simple memcpy()
306 // --> In that case, VOSF is not necessary
307 bool Screen_blitter_init(XVisualInfo * visual_info, bool native_byte_order)
308 {
309 #if REAL_ADDRESSING || DIRECT_ADDRESSING
310 visualFormat.depth = visual_info->depth;
311 visualFormat.Rmask = visual_info->red_mask;
312 visualFormat.Gmask = visual_info->green_mask;
313 visualFormat.Bmask = visual_info->blue_mask;
314
315 // Compute RGB shift values
316 visualFormat.Rshift = 0;
317 for (uint32 Rmask = visualFormat.Rmask; Rmask && ((Rmask & 1) != 1); Rmask >>= 1)
318 ++visualFormat.Rshift;
319 visualFormat.Gshift = 0;
320 for (uint32 Gmask = visualFormat.Gmask; Gmask && ((Gmask & 1) != 1); Gmask >>= 1)
321 ++visualFormat.Gshift;
322 visualFormat.Bshift = 0;
323 for (uint32 Bmask = visualFormat.Bmask; Bmask && ((Bmask & 1) != 1); Bmask >>= 1)
324 ++visualFormat.Bshift;
325
326 // Search for an adequate blit function
327 bool blitter_found = false;
328 const int blitters_count = sizeof(Screen_blitters)/sizeof(Screen_blitters[0]);
329 for (int i = 0; !blitter_found && (i < blitters_count); i++) {
330 if ( (visualFormat.depth == Screen_blitters[i].depth)
331 && (visualFormat.Rmask == Screen_blitters[i].Rmask)
332 && (visualFormat.Gmask == Screen_blitters[i].Gmask)
333 && (visualFormat.Bmask == Screen_blitters[i].Bmask)
334 )
335 {
336 blitter_found = true;
337 Screen_blit = native_byte_order
338 ? Screen_blitters[i].handler_nbo
339 : Screen_blitters[i].handler_obo
340 ;
341 }
342 }
343
344 // No appropriate blitter found, dump RGB mask values and abort()
345 if (!blitter_found) {
346 fprintf(stderr, "### No appropriate blitter found\n");
347 fprintf(stderr, "\tR/G/B mask values : 0x%06x, 0x%06x, 0x%06x (depth = %d)\n",
348 visualFormat.Rmask, visualFormat.Gmask, visualFormat.Bmask, visualFormat.depth);
349 fprintf(stderr, "\tR/G/B shift values : %d/%d/%d\n",
350 visualFormat.Rshift, visualFormat.Gshift, visualFormat.Bshift);
351 abort();
352 }
353 #else
354 // The UAE memory handlers will blit correctly
355 // --> no need for specialised blitters here
356 Screen_blit = Blit_Copy_Raw;
357 #endif
358
359 // If the blitter simply reduces to a copy, we don't need VOSF in DGA mode
360 // --> In that case, we return FALSE
361 return (Screen_blit != Blit_Copy_Raw);
362 }
363 #endif /* ENABLE_VOSF */