SDL  2.0
SDL_blit_N.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../SDL_internal.h"
22 
23 #include "SDL_video.h"
24 #include "SDL_endian.h"
25 #include "SDL_cpuinfo.h"
26 #include "SDL_blit.h"
27 
28 #include "SDL_assert.h"
29 
30 /* Functions to blit from N-bit surfaces to other surfaces */
31 
37 };
38 
39 #if SDL_ALTIVEC_BLITTERS
40 #ifdef HAVE_ALTIVEC_H
41 #include <altivec.h>
42 #endif
43 #ifdef __MACOSX__
44 #include <sys/sysctl.h>
45 static size_t
46 GetL3CacheSize(void)
47 {
48  const char key[] = "hw.l3cachesize";
49  u_int64_t result = 0;
50  size_t typeSize = sizeof(result);
51 
52 
53  int err = sysctlbyname(key, &result, &typeSize, NULL, 0);
54  if (0 != err)
55  return 0;
56 
57  return result;
58 }
59 #else
60 static size_t
61 GetL3CacheSize(void)
62 {
63  /* XXX: Just guess G4 */
64  return 2097152;
65 }
66 #endif /* __MACOSX__ */
67 
68 #if (defined(__MACOSX__) && (__GNUC__ < 4))
69 #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
70  (vector unsigned char) ( a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p )
71 #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
72  (vector unsigned short) ( a,b,c,d,e,f,g,h )
73 #else
74 #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
75  (vector unsigned char) { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p }
76 #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
77  (vector unsigned short) { a,b,c,d,e,f,g,h }
78 #endif
79 
80 #define UNALIGNED_PTR(x) (((size_t) x) & 0x0000000F)
81 #define VSWIZZLE32(a,b,c,d) (vector unsigned char) \
82  ( 0x00+a, 0x00+b, 0x00+c, 0x00+d, \
83  0x04+a, 0x04+b, 0x04+c, 0x04+d, \
84  0x08+a, 0x08+b, 0x08+c, 0x08+d, \
85  0x0C+a, 0x0C+b, 0x0C+c, 0x0C+d )
86 
87 #define MAKE8888(dstfmt, r, g, b, a) \
88  ( ((r<<dstfmt->Rshift)&dstfmt->Rmask) | \
89  ((g<<dstfmt->Gshift)&dstfmt->Gmask) | \
90  ((b<<dstfmt->Bshift)&dstfmt->Bmask) | \
91  ((a<<dstfmt->Ashift)&dstfmt->Amask) )
92 
93 /*
94  * Data Stream Touch...Altivec cache prefetching.
95  *
96  * Don't use this on a G5...however, the speed boost is very significant
97  * on a G4.
98  */
99 #define DST_CHAN_SRC 1
100 #define DST_CHAN_DEST 2
101 
102 /* macro to set DST control word value... */
103 #define DST_CTRL(size, count, stride) \
104  (((size) << 24) | ((count) << 16) | (stride))
105 
106 #define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \
107  ? vec_lvsl(0, src) \
108  : vec_add(vec_lvsl(8, src), vec_splat_u8(8)))
109 
110 /* Calculate the permute vector used for 32->32 swizzling */
111 static vector unsigned char
112 calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt)
113 {
114  /*
115  * We have to assume that the bits that aren't used by other
116  * colors is alpha, and it's one complete byte, since some formats
117  * leave alpha with a zero mask, but we should still swizzle the bits.
118  */
119  /* ARGB */
120  const static const struct SDL_PixelFormat default_pixel_format = {
121  0, NULL, 0, 0,
122  {0, 0},
123  0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
124  0, 0, 0, 0,
125  16, 8, 0, 24,
126  0, NULL
127  };
128  const vector unsigned char plus = VECUINT8_LITERAL(0x00, 0x00, 0x00, 0x00,
129  0x04, 0x04, 0x04, 0x04,
130  0x08, 0x08, 0x08, 0x08,
131  0x0C, 0x0C, 0x0C,
132  0x0C);
133  vector unsigned char vswiz;
134  vector unsigned int srcvec;
135  Uint32 rmask, gmask, bmask, amask;
136 
137  if (!srcfmt) {
138  srcfmt = &default_pixel_format;
139  }
140  if (!dstfmt) {
141  dstfmt = &default_pixel_format;
142  }
143 
144 #define RESHIFT(X) (3 - ((X) >> 3))
145  rmask = RESHIFT(srcfmt->Rshift) << (dstfmt->Rshift);
146  gmask = RESHIFT(srcfmt->Gshift) << (dstfmt->Gshift);
147  bmask = RESHIFT(srcfmt->Bshift) << (dstfmt->Bshift);
148 
149  /* Use zero for alpha if either surface doesn't have alpha */
150  if (dstfmt->Amask) {
151  amask =
152  ((srcfmt->Amask) ? RESHIFT(srcfmt->
153  Ashift) : 0x10) << (dstfmt->Ashift);
154  } else {
155  amask =
156  0x10101010 & ((dstfmt->Rmask | dstfmt->Gmask | dstfmt->Bmask) ^
157  0xFFFFFFFF);
158  }
159 #undef RESHIFT
160 
161  ((unsigned int *) (char *) &srcvec)[0] = (rmask | gmask | bmask | amask);
162  vswiz = vec_add(plus, (vector unsigned char) vec_splat(srcvec, 0));
163  return (vswiz);
164 }
165 
166 static void Blit_RGB888_RGB565(SDL_BlitInfo * info);
167 static void
168 Blit_RGB888_RGB565Altivec(SDL_BlitInfo * info)
169 {
170  int height = info->dst_h;
171  Uint8 *src = (Uint8 *) info->src;
172  int srcskip = info->src_skip;
173  Uint8 *dst = (Uint8 *) info->dst;
174  int dstskip = info->dst_skip;
175  SDL_PixelFormat *srcfmt = info->src_fmt;
176  vector unsigned char valpha = vec_splat_u8(0);
177  vector unsigned char vpermute = calc_swizzle32(srcfmt, NULL);
178  vector unsigned char vgmerge = VECUINT8_LITERAL(0x00, 0x02, 0x00, 0x06,
179  0x00, 0x0a, 0x00, 0x0e,
180  0x00, 0x12, 0x00, 0x16,
181  0x00, 0x1a, 0x00, 0x1e);
182  vector unsigned short v1 = vec_splat_u16(1);
183  vector unsigned short v3 = vec_splat_u16(3);
184  vector unsigned short v3f =
185  VECUINT16_LITERAL(0x003f, 0x003f, 0x003f, 0x003f,
186  0x003f, 0x003f, 0x003f, 0x003f);
187  vector unsigned short vfc =
188  VECUINT16_LITERAL(0x00fc, 0x00fc, 0x00fc, 0x00fc,
189  0x00fc, 0x00fc, 0x00fc, 0x00fc);
190  vector unsigned short vf800 = (vector unsigned short) vec_splat_u8(-7);
191  vf800 = vec_sl(vf800, vec_splat_u16(8));
192 
193  while (height--) {
194  vector unsigned char valigner;
195  vector unsigned char voverflow;
196  vector unsigned char vsrc;
197 
198  int width = info->dst_w;
199  int extrawidth;
200 
201  /* do scalar until we can align... */
202 #define ONE_PIXEL_BLEND(condition, widthvar) \
203  while (condition) { \
204  Uint32 Pixel; \
205  unsigned sR, sG, sB, sA; \
206  DISEMBLE_RGBA((Uint8 *)src, 4, srcfmt, Pixel, \
207  sR, sG, sB, sA); \
208  *(Uint16 *)(dst) = (((sR << 8) & 0x0000F800) | \
209  ((sG << 3) & 0x000007E0) | \
210  ((sB >> 3) & 0x0000001F)); \
211  dst += 2; \
212  src += 4; \
213  widthvar--; \
214  }
215 
216  ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
217 
218  /* After all that work, here's the vector part! */
219  extrawidth = (width % 8); /* trailing unaligned stores */
220  width -= extrawidth;
221  vsrc = vec_ld(0, src);
222  valigner = VEC_ALIGNER(src);
223 
224  while (width) {
225  vector unsigned short vpixel, vrpixel, vgpixel, vbpixel;
226  vector unsigned int vsrc1, vsrc2;
227  vector unsigned char vdst;
228 
229  voverflow = vec_ld(15, src);
230  vsrc = vec_perm(vsrc, voverflow, valigner);
231  vsrc1 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute);
232  src += 16;
233  vsrc = voverflow;
234  voverflow = vec_ld(15, src);
235  vsrc = vec_perm(vsrc, voverflow, valigner);
236  vsrc2 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute);
237  /* 1555 */
238  vpixel = (vector unsigned short) vec_packpx(vsrc1, vsrc2);
239  vgpixel = (vector unsigned short) vec_perm(vsrc1, vsrc2, vgmerge);
240  vgpixel = vec_and(vgpixel, vfc);
241  vgpixel = vec_sl(vgpixel, v3);
242  vrpixel = vec_sl(vpixel, v1);
243  vrpixel = vec_and(vrpixel, vf800);
244  vbpixel = vec_and(vpixel, v3f);
245  vdst =
246  vec_or((vector unsigned char) vrpixel,
247  (vector unsigned char) vgpixel);
248  /* 565 */
249  vdst = vec_or(vdst, (vector unsigned char) vbpixel);
250  vec_st(vdst, 0, dst);
251 
252  width -= 8;
253  src += 16;
254  dst += 16;
255  vsrc = voverflow;
256  }
257 
258  SDL_assert(width == 0);
259 
260  /* do scalar until we can align... */
261  ONE_PIXEL_BLEND((extrawidth), extrawidth);
262 #undef ONE_PIXEL_BLEND
263 
264  src += srcskip; /* move to next row, accounting for pitch. */
265  dst += dstskip;
266  }
267 
268 
269 }
270 
271 static void
272 Blit_RGB565_32Altivec(SDL_BlitInfo * info)
273 {
274  int height = info->dst_h;
275  Uint8 *src = (Uint8 *) info->src;
276  int srcskip = info->src_skip;
277  Uint8 *dst = (Uint8 *) info->dst;
278  int dstskip = info->dst_skip;
279  SDL_PixelFormat *srcfmt = info->src_fmt;
280  SDL_PixelFormat *dstfmt = info->dst_fmt;
281  unsigned alpha;
282  vector unsigned char valpha;
283  vector unsigned char vpermute;
284  vector unsigned short vf800;
285  vector unsigned int v8 = vec_splat_u32(8);
286  vector unsigned int v16 = vec_add(v8, v8);
287  vector unsigned short v2 = vec_splat_u16(2);
288  vector unsigned short v3 = vec_splat_u16(3);
289  /*
290  0x10 - 0x1f is the alpha
291  0x00 - 0x0e evens are the red
292  0x01 - 0x0f odds are zero
293  */
294  vector unsigned char vredalpha1 = VECUINT8_LITERAL(0x10, 0x00, 0x01, 0x01,
295  0x10, 0x02, 0x01, 0x01,
296  0x10, 0x04, 0x01, 0x01,
297  0x10, 0x06, 0x01,
298  0x01);
299  vector unsigned char vredalpha2 =
300  (vector unsigned
301  char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16))
302  );
303  /*
304  0x00 - 0x0f is ARxx ARxx ARxx ARxx
305  0x11 - 0x0f odds are blue
306  */
307  vector unsigned char vblue1 = VECUINT8_LITERAL(0x00, 0x01, 0x02, 0x11,
308  0x04, 0x05, 0x06, 0x13,
309  0x08, 0x09, 0x0a, 0x15,
310  0x0c, 0x0d, 0x0e, 0x17);
311  vector unsigned char vblue2 =
312  (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8)
313  );
314  /*
315  0x00 - 0x0f is ARxB ARxB ARxB ARxB
316  0x10 - 0x0e evens are green
317  */
318  vector unsigned char vgreen1 = VECUINT8_LITERAL(0x00, 0x01, 0x10, 0x03,
319  0x04, 0x05, 0x12, 0x07,
320  0x08, 0x09, 0x14, 0x0b,
321  0x0c, 0x0d, 0x16, 0x0f);
322  vector unsigned char vgreen2 =
323  (vector unsigned
324  char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8))
325  );
326 
327  SDL_assert(srcfmt->BytesPerPixel == 2);
328  SDL_assert(dstfmt->BytesPerPixel == 4);
329 
330  vf800 = (vector unsigned short) vec_splat_u8(-7);
331  vf800 = vec_sl(vf800, vec_splat_u16(8));
332 
333  if (dstfmt->Amask && info->a) {
334  ((unsigned char *) &valpha)[0] = alpha = info->a;
335  valpha = vec_splat(valpha, 0);
336  } else {
337  alpha = 0;
338  valpha = vec_splat_u8(0);
339  }
340 
341  vpermute = calc_swizzle32(NULL, dstfmt);
342  while (height--) {
343  vector unsigned char valigner;
344  vector unsigned char voverflow;
345  vector unsigned char vsrc;
346 
347  int width = info->dst_w;
348  int extrawidth;
349 
350  /* do scalar until we can align... */
351 #define ONE_PIXEL_BLEND(condition, widthvar) \
352  while (condition) { \
353  unsigned sR, sG, sB; \
354  unsigned short Pixel = *((unsigned short *)src); \
355  sR = (Pixel >> 8) & 0xf8; \
356  sG = (Pixel >> 3) & 0xfc; \
357  sB = (Pixel << 3) & 0xf8; \
358  ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
359  src += 2; \
360  dst += 4; \
361  widthvar--; \
362  }
363  ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
364 
365  /* After all that work, here's the vector part! */
366  extrawidth = (width % 8); /* trailing unaligned stores */
367  width -= extrawidth;
368  vsrc = vec_ld(0, src);
369  valigner = VEC_ALIGNER(src);
370 
371  while (width) {
372  vector unsigned short vR, vG, vB;
373  vector unsigned char vdst1, vdst2;
374 
375  voverflow = vec_ld(15, src);
376  vsrc = vec_perm(vsrc, voverflow, valigner);
377 
378  vR = vec_and((vector unsigned short) vsrc, vf800);
379  vB = vec_sl((vector unsigned short) vsrc, v3);
380  vG = vec_sl(vB, v2);
381 
382  vdst1 =
383  (vector unsigned char) vec_perm((vector unsigned char) vR,
384  valpha, vredalpha1);
385  vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1);
386  vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1);
387  vdst1 = vec_perm(vdst1, valpha, vpermute);
388  vec_st(vdst1, 0, dst);
389 
390  vdst2 =
391  (vector unsigned char) vec_perm((vector unsigned char) vR,
392  valpha, vredalpha2);
393  vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2);
394  vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2);
395  vdst2 = vec_perm(vdst2, valpha, vpermute);
396  vec_st(vdst2, 16, dst);
397 
398  width -= 8;
399  dst += 32;
400  src += 16;
401  vsrc = voverflow;
402  }
403 
404  SDL_assert(width == 0);
405 
406 
407  /* do scalar until we can align... */
408  ONE_PIXEL_BLEND((extrawidth), extrawidth);
409 #undef ONE_PIXEL_BLEND
410 
411  src += srcskip; /* move to next row, accounting for pitch. */
412  dst += dstskip;
413  }
414 
415 }
416 
417 
418 static void
419 Blit_RGB555_32Altivec(SDL_BlitInfo * info)
420 {
421  int height = info->dst_h;
422  Uint8 *src = (Uint8 *) info->src;
423  int srcskip = info->src_skip;
424  Uint8 *dst = (Uint8 *) info->dst;
425  int dstskip = info->dst_skip;
426  SDL_PixelFormat *srcfmt = info->src_fmt;
427  SDL_PixelFormat *dstfmt = info->dst_fmt;
428  unsigned alpha;
429  vector unsigned char valpha;
430  vector unsigned char vpermute;
431  vector unsigned short vf800;
432  vector unsigned int v8 = vec_splat_u32(8);
433  vector unsigned int v16 = vec_add(v8, v8);
434  vector unsigned short v1 = vec_splat_u16(1);
435  vector unsigned short v3 = vec_splat_u16(3);
436  /*
437  0x10 - 0x1f is the alpha
438  0x00 - 0x0e evens are the red
439  0x01 - 0x0f odds are zero
440  */
441  vector unsigned char vredalpha1 = VECUINT8_LITERAL(0x10, 0x00, 0x01, 0x01,
442  0x10, 0x02, 0x01, 0x01,
443  0x10, 0x04, 0x01, 0x01,
444  0x10, 0x06, 0x01,
445  0x01);
446  vector unsigned char vredalpha2 =
447  (vector unsigned
448  char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16))
449  );
450  /*
451  0x00 - 0x0f is ARxx ARxx ARxx ARxx
452  0x11 - 0x0f odds are blue
453  */
454  vector unsigned char vblue1 = VECUINT8_LITERAL(0x00, 0x01, 0x02, 0x11,
455  0x04, 0x05, 0x06, 0x13,
456  0x08, 0x09, 0x0a, 0x15,
457  0x0c, 0x0d, 0x0e, 0x17);
458  vector unsigned char vblue2 =
459  (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8)
460  );
461  /*
462  0x00 - 0x0f is ARxB ARxB ARxB ARxB
463  0x10 - 0x0e evens are green
464  */
465  vector unsigned char vgreen1 = VECUINT8_LITERAL(0x00, 0x01, 0x10, 0x03,
466  0x04, 0x05, 0x12, 0x07,
467  0x08, 0x09, 0x14, 0x0b,
468  0x0c, 0x0d, 0x16, 0x0f);
469  vector unsigned char vgreen2 =
470  (vector unsigned
471  char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8))
472  );
473 
474  SDL_assert(srcfmt->BytesPerPixel == 2);
475  SDL_assert(dstfmt->BytesPerPixel == 4);
476 
477  vf800 = (vector unsigned short) vec_splat_u8(-7);
478  vf800 = vec_sl(vf800, vec_splat_u16(8));
479 
480  if (dstfmt->Amask && info->a) {
481  ((unsigned char *) &valpha)[0] = alpha = info->a;
482  valpha = vec_splat(valpha, 0);
483  } else {
484  alpha = 0;
485  valpha = vec_splat_u8(0);
486  }
487 
488  vpermute = calc_swizzle32(NULL, dstfmt);
489  while (height--) {
490  vector unsigned char valigner;
491  vector unsigned char voverflow;
492  vector unsigned char vsrc;
493 
494  int width = info->dst_w;
495  int extrawidth;
496 
497  /* do scalar until we can align... */
498 #define ONE_PIXEL_BLEND(condition, widthvar) \
499  while (condition) { \
500  unsigned sR, sG, sB; \
501  unsigned short Pixel = *((unsigned short *)src); \
502  sR = (Pixel >> 7) & 0xf8; \
503  sG = (Pixel >> 2) & 0xf8; \
504  sB = (Pixel << 3) & 0xf8; \
505  ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
506  src += 2; \
507  dst += 4; \
508  widthvar--; \
509  }
510  ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
511 
512  /* After all that work, here's the vector part! */
513  extrawidth = (width % 8); /* trailing unaligned stores */
514  width -= extrawidth;
515  vsrc = vec_ld(0, src);
516  valigner = VEC_ALIGNER(src);
517 
518  while (width) {
519  vector unsigned short vR, vG, vB;
520  vector unsigned char vdst1, vdst2;
521 
522  voverflow = vec_ld(15, src);
523  vsrc = vec_perm(vsrc, voverflow, valigner);
524 
525  vR = vec_and(vec_sl((vector unsigned short) vsrc, v1), vf800);
526  vB = vec_sl((vector unsigned short) vsrc, v3);
527  vG = vec_sl(vB, v3);
528 
529  vdst1 =
530  (vector unsigned char) vec_perm((vector unsigned char) vR,
531  valpha, vredalpha1);
532  vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1);
533  vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1);
534  vdst1 = vec_perm(vdst1, valpha, vpermute);
535  vec_st(vdst1, 0, dst);
536 
537  vdst2 =
538  (vector unsigned char) vec_perm((vector unsigned char) vR,
539  valpha, vredalpha2);
540  vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2);
541  vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2);
542  vdst2 = vec_perm(vdst2, valpha, vpermute);
543  vec_st(vdst2, 16, dst);
544 
545  width -= 8;
546  dst += 32;
547  src += 16;
548  vsrc = voverflow;
549  }
550 
551  SDL_assert(width == 0);
552 
553 
554  /* do scalar until we can align... */
555  ONE_PIXEL_BLEND((extrawidth), extrawidth);
556 #undef ONE_PIXEL_BLEND
557 
558  src += srcskip; /* move to next row, accounting for pitch. */
559  dst += dstskip;
560  }
561 
562 }
563 
564 static void BlitNtoNKey(SDL_BlitInfo * info);
565 static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info);
566 static void
567 Blit32to32KeyAltivec(SDL_BlitInfo * info)
568 {
569  int height = info->dst_h;
570  Uint32 *srcp = (Uint32 *) info->src;
571  int srcskip = info->src_skip / 4;
572  Uint32 *dstp = (Uint32 *) info->dst;
573  int dstskip = info->dst_skip / 4;
574  SDL_PixelFormat *srcfmt = info->src_fmt;
575  int srcbpp = srcfmt->BytesPerPixel;
576  SDL_PixelFormat *dstfmt = info->dst_fmt;
577  int dstbpp = dstfmt->BytesPerPixel;
578  int copy_alpha = (srcfmt->Amask && dstfmt->Amask);
579  unsigned alpha = dstfmt->Amask ? info->a : 0;
580  Uint32 rgbmask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
581  Uint32 ckey = info->colorkey;
582  vector unsigned int valpha;
583  vector unsigned char vpermute;
584  vector unsigned char vzero;
585  vector unsigned int vckey;
586  vector unsigned int vrgbmask;
587  vpermute = calc_swizzle32(srcfmt, dstfmt);
588  if (info->dst_w < 16) {
589  if (copy_alpha) {
590  BlitNtoNKeyCopyAlpha(info);
591  } else {
592  BlitNtoNKey(info);
593  }
594  return;
595  }
596  vzero = vec_splat_u8(0);
597  if (alpha) {
598  ((unsigned char *) &valpha)[0] = (unsigned char) alpha;
599  valpha =
600  (vector unsigned int) vec_splat((vector unsigned char) valpha, 0);
601  } else {
602  valpha = (vector unsigned int) vzero;
603  }
604  ckey &= rgbmask;
605  ((unsigned int *) (char *) &vckey)[0] = ckey;
606  vckey = vec_splat(vckey, 0);
607  ((unsigned int *) (char *) &vrgbmask)[0] = rgbmask;
608  vrgbmask = vec_splat(vrgbmask, 0);
609 
610  while (height--) {
611 #define ONE_PIXEL_BLEND(condition, widthvar) \
612  if (copy_alpha) { \
613  while (condition) { \
614  Uint32 Pixel; \
615  unsigned sR, sG, sB, sA; \
616  DISEMBLE_RGBA((Uint8 *)srcp, srcbpp, srcfmt, Pixel, \
617  sR, sG, sB, sA); \
618  if ( (Pixel & rgbmask) != ckey ) { \
619  ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
620  sR, sG, sB, sA); \
621  } \
622  dstp = (Uint32 *) (((Uint8 *) dstp) + dstbpp); \
623  srcp = (Uint32 *) (((Uint8 *) srcp) + srcbpp); \
624  widthvar--; \
625  } \
626  } else { \
627  while (condition) { \
628  Uint32 Pixel; \
629  unsigned sR, sG, sB; \
630  RETRIEVE_RGB_PIXEL((Uint8 *)srcp, srcbpp, Pixel); \
631  if ( Pixel != ckey ) { \
632  RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \
633  ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
634  sR, sG, sB, alpha); \
635  } \
636  dstp = (Uint32 *) (((Uint8 *)dstp) + dstbpp); \
637  srcp = (Uint32 *) (((Uint8 *)srcp) + srcbpp); \
638  widthvar--; \
639  } \
640  }
641  int width = info->dst_w;
642  ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
643  SDL_assert(width > 0);
644  if (width > 0) {
645  int extrawidth = (width % 4);
646  vector unsigned char valigner = VEC_ALIGNER(srcp);
647  vector unsigned int vs = vec_ld(0, srcp);
648  width -= extrawidth;
649  SDL_assert(width >= 4);
650  while (width) {
651  vector unsigned char vsel;
652  vector unsigned int vd;
653  vector unsigned int voverflow = vec_ld(15, srcp);
654  /* load the source vec */
655  vs = vec_perm(vs, voverflow, valigner);
656  /* vsel is set for items that match the key */
657  vsel = (vector unsigned char) vec_and(vs, vrgbmask);
658  vsel = (vector unsigned char) vec_cmpeq(vs, vckey);
659  /* permute the src vec to the dest format */
660  vs = vec_perm(vs, valpha, vpermute);
661  /* load the destination vec */
662  vd = vec_ld(0, dstp);
663  /* select the source and dest into vs */
664  vd = (vector unsigned int) vec_sel((vector unsigned char) vs,
665  (vector unsigned char) vd,
666  vsel);
667 
668  vec_st(vd, 0, dstp);
669  srcp += 4;
670  width -= 4;
671  dstp += 4;
672  vs = voverflow;
673  }
674  ONE_PIXEL_BLEND((extrawidth), extrawidth);
675 #undef ONE_PIXEL_BLEND
676  srcp += srcskip;
677  dstp += dstskip;
678  }
679  }
680 }
681 
682 /* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
683 /* Use this on a G5 */
684 static void
685 ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info)
686 {
687  int height = info->dst_h;
688  Uint32 *src = (Uint32 *) info->src;
689  int srcskip = info->src_skip / 4;
690  Uint32 *dst = (Uint32 *) info->dst;
691  int dstskip = info->dst_skip / 4;
692  SDL_PixelFormat *srcfmt = info->src_fmt;
693  SDL_PixelFormat *dstfmt = info->dst_fmt;
694  vector unsigned int vzero = vec_splat_u32(0);
695  vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
696  if (dstfmt->Amask && !srcfmt->Amask) {
697  if (info->a) {
698  vector unsigned char valpha;
699  ((unsigned char *) &valpha)[0] = info->a;
700  vzero = (vector unsigned int) vec_splat(valpha, 0);
701  }
702  }
703 
704  SDL_assert(srcfmt->BytesPerPixel == 4);
705  SDL_assert(dstfmt->BytesPerPixel == 4);
706 
707  while (height--) {
708  vector unsigned char valigner;
709  vector unsigned int vbits;
710  vector unsigned int voverflow;
711  Uint32 bits;
712  Uint8 r, g, b, a;
713 
714  int width = info->dst_w;
715  int extrawidth;
716 
717  /* do scalar until we can align... */
718  while ((UNALIGNED_PTR(dst)) && (width)) {
719  bits = *(src++);
720  RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
721  if(!srcfmt->Amask)
722  a = info->a;
723  *(dst++) = MAKE8888(dstfmt, r, g, b, a);
724  width--;
725  }
726 
727  /* After all that work, here's the vector part! */
728  extrawidth = (width % 4);
729  width -= extrawidth;
730  valigner = VEC_ALIGNER(src);
731  vbits = vec_ld(0, src);
732 
733  while (width) {
734  voverflow = vec_ld(15, src);
735  src += 4;
736  width -= 4;
737  vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */
738  vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */
739  vec_st(vbits, 0, dst); /* store it back out. */
740  dst += 4;
741  vbits = voverflow;
742  }
743 
744  SDL_assert(width == 0);
745 
746  /* cover pixels at the end of the row that didn't fit in 16 bytes. */
747  while (extrawidth) {
748  bits = *(src++); /* max 7 pixels, don't bother with prefetch. */
749  RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
750  if(!srcfmt->Amask)
751  a = info->a;
752  *(dst++) = MAKE8888(dstfmt, r, g, b, a);
753  extrawidth--;
754  }
755 
756  src += srcskip;
757  dst += dstskip;
758  }
759 
760 }
761 
762 /* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
763 /* Use this on a G4 */
764 static void
765 ConvertAltivec32to32_prefetch(SDL_BlitInfo * info)
766 {
767  const int scalar_dst_lead = sizeof(Uint32) * 4;
768  const int vector_dst_lead = sizeof(Uint32) * 16;
769 
770  int height = info->dst_h;
771  Uint32 *src = (Uint32 *) info->src;
772  int srcskip = info->src_skip / 4;
773  Uint32 *dst = (Uint32 *) info->dst;
774  int dstskip = info->dst_skip / 4;
775  SDL_PixelFormat *srcfmt = info->src_fmt;
776  SDL_PixelFormat *dstfmt = info->dst_fmt;
777  vector unsigned int vzero = vec_splat_u32(0);
778  vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
779  if (dstfmt->Amask && !srcfmt->Amask) {
780  if (info->a) {
781  vector unsigned char valpha;
782  ((unsigned char *) &valpha)[0] = info->a;
783  vzero = (vector unsigned int) vec_splat(valpha, 0);
784  }
785  }
786 
787  SDL_assert(srcfmt->BytesPerPixel == 4);
788  SDL_assert(dstfmt->BytesPerPixel == 4);
789 
790  while (height--) {
791  vector unsigned char valigner;
792  vector unsigned int vbits;
793  vector unsigned int voverflow;
794  Uint32 bits;
795  Uint8 r, g, b, a;
796 
797  int width = info->dst_w;
798  int extrawidth;
799 
800  /* do scalar until we can align... */
801  while ((UNALIGNED_PTR(dst)) && (width)) {
802  vec_dstt(src + scalar_dst_lead, DST_CTRL(2, 32, 1024),
803  DST_CHAN_SRC);
804  vec_dstst(dst + scalar_dst_lead, DST_CTRL(2, 32, 1024),
805  DST_CHAN_DEST);
806  bits = *(src++);
807  RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
808  if(!srcfmt->Amask)
809  a = info->a;
810  *(dst++) = MAKE8888(dstfmt, r, g, b, a);
811  width--;
812  }
813 
814  /* After all that work, here's the vector part! */
815  extrawidth = (width % 4);
816  width -= extrawidth;
817  valigner = VEC_ALIGNER(src);
818  vbits = vec_ld(0, src);
819 
820  while (width) {
821  vec_dstt(src + vector_dst_lead, DST_CTRL(2, 32, 1024),
822  DST_CHAN_SRC);
823  vec_dstst(dst + vector_dst_lead, DST_CTRL(2, 32, 1024),
824  DST_CHAN_DEST);
825  voverflow = vec_ld(15, src);
826  src += 4;
827  width -= 4;
828  vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */
829  vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */
830  vec_st(vbits, 0, dst); /* store it back out. */
831  dst += 4;
832  vbits = voverflow;
833  }
834 
835  SDL_assert(width == 0);
836 
837  /* cover pixels at the end of the row that didn't fit in 16 bytes. */
838  while (extrawidth) {
839  bits = *(src++); /* max 7 pixels, don't bother with prefetch. */
840  RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
841  if(!srcfmt->Amask)
842  a = info->a;
843  *(dst++) = MAKE8888(dstfmt, r, g, b, a);
844  extrawidth--;
845  }
846 
847  src += srcskip;
848  dst += dstskip;
849  }
850 
851  vec_dss(DST_CHAN_SRC);
852  vec_dss(DST_CHAN_DEST);
853 }
854 
855 static enum blit_features
856 GetBlitFeatures(void)
857 {
858  static enum blit_features features = -1;
859  if (features == (enum blit_features) -1) {
860  /* Provide an override for testing .. */
861  char *override = SDL_getenv("SDL_ALTIVEC_BLIT_FEATURES");
862  if (override) {
863  unsigned int features_as_uint = 0;
864  SDL_sscanf(override, "%u", &features_as_uint);
865  features = (enum blit_features) features_as_uint;
866  } else {
867  features = (0
868  /* Feature 1 is has-MMX */
869  | ((SDL_HasMMX())? BLIT_FEATURE_HAS_MMX : 0)
870  /* Feature 2 is has-AltiVec */
872  /* Feature 4 is dont-use-prefetch */
873  /* !!!! FIXME: Check for G5 or later, not the cache size! Always prefetch on a G4. */
874  | ((GetL3CacheSize() == 0) ? BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH : 0)
875  );
876  }
877  }
878  return features;
879 }
880 
881 #if __MWERKS__
882 #pragma altivec_model off
883 #endif
884 #else
885 /* Feature 1 is has-MMX */
886 #define GetBlitFeatures() ((SDL_HasMMX() ? BLIT_FEATURE_HAS_MMX : 0) | (SDL_HasARMSIMD() ? BLIT_FEATURE_HAS_ARM_SIMD : 0))
887 #endif
888 
889 #if SDL_ARM_SIMD_BLITTERS
890 void Blit_BGR888_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride);
891 
892 static void
893 Blit_BGR888_RGB888ARMSIMD(SDL_BlitInfo * info)
894 {
895  int32_t width = info->dst_w;
896  int32_t height = info->dst_h;
897  uint32_t *dstp = (uint32_t *)info->dst;
898  int32_t dststride = width + (info->dst_skip >> 2);
899  uint32_t *srcp = (uint32_t *)info->src;
900  int32_t srcstride = width + (info->src_skip >> 2);
901 
902  Blit_BGR888_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
903 }
904 
905 void Blit_RGB444_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint16_t *src, int32_t src_stride);
906 
907 static void
908 Blit_RGB444_RGB888ARMSIMD(SDL_BlitInfo * info)
909 {
910  int32_t width = info->dst_w;
911  int32_t height = info->dst_h;
912  uint32_t *dstp = (uint32_t *)info->dst;
913  int32_t dststride = width + (info->dst_skip >> 2);
914  uint16_t *srcp = (uint16_t *)info->src;
915  int32_t srcstride = width + (info->src_skip >> 1);
916 
917  Blit_RGB444_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
918 }
919 #endif
920 
921 /* This is now endian dependent */
922 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
923 #define HI 1
924 #define LO 0
925 #else /* SDL_BYTEORDER == SDL_BIG_ENDIAN */
926 #define HI 0
927 #define LO 1
928 #endif
929 
930 /* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */
931 #define RGB888_RGB332(dst, src) { \
932  dst = (Uint8)((((src)&0x00E00000)>>16)| \
933  (((src)&0x0000E000)>>11)| \
934  (((src)&0x000000C0)>>6)); \
935 }
936 static void
938 {
939 #ifndef USE_DUFFS_LOOP
940  int c;
941 #endif
942  int width, height;
943  Uint32 *src;
944  const Uint8 *map;
945  Uint8 *dst;
946  int srcskip, dstskip;
947 
948  /* Set up some basic variables */
949  width = info->dst_w;
950  height = info->dst_h;
951  src = (Uint32 *) info->src;
952  srcskip = info->src_skip / 4;
953  dst = info->dst;
954  dstskip = info->dst_skip;
955  map = info->table;
956 
957  if (map == NULL) {
958  while (height--) {
959 #ifdef USE_DUFFS_LOOP
960  /* *INDENT-OFF* */
961  DUFFS_LOOP(
962  RGB888_RGB332(*dst++, *src);
963  , width);
964  /* *INDENT-ON* */
965 #else
966  for (c = width / 4; c; --c) {
967  /* Pack RGB into 8bit pixel */
968  ++src;
969  RGB888_RGB332(*dst++, *src);
970  ++src;
971  RGB888_RGB332(*dst++, *src);
972  ++src;
973  RGB888_RGB332(*dst++, *src);
974  ++src;
975  }
976  switch (width & 3) {
977  case 3:
978  RGB888_RGB332(*dst++, *src);
979  ++src;
980  case 2:
981  RGB888_RGB332(*dst++, *src);
982  ++src;
983  case 1:
984  RGB888_RGB332(*dst++, *src);
985  ++src;
986  }
987 #endif /* USE_DUFFS_LOOP */
988  src += srcskip;
989  dst += dstskip;
990  }
991  } else {
992  int Pixel;
993 
994  while (height--) {
995 #ifdef USE_DUFFS_LOOP
996  /* *INDENT-OFF* */
997  DUFFS_LOOP(
998  RGB888_RGB332(Pixel, *src);
999  *dst++ = map[Pixel];
1000  ++src;
1001  , width);
1002  /* *INDENT-ON* */
1003 #else
1004  for (c = width / 4; c; --c) {
1005  /* Pack RGB into 8bit pixel */
1006  RGB888_RGB332(Pixel, *src);
1007  *dst++ = map[Pixel];
1008  ++src;
1009  RGB888_RGB332(Pixel, *src);
1010  *dst++ = map[Pixel];
1011  ++src;
1012  RGB888_RGB332(Pixel, *src);
1013  *dst++ = map[Pixel];
1014  ++src;
1015  RGB888_RGB332(Pixel, *src);
1016  *dst++ = map[Pixel];
1017  ++src;
1018  }
1019  switch (width & 3) {
1020  case 3:
1021  RGB888_RGB332(Pixel, *src);
1022  *dst++ = map[Pixel];
1023  ++src;
1024  case 2:
1025  RGB888_RGB332(Pixel, *src);
1026  *dst++ = map[Pixel];
1027  ++src;
1028  case 1:
1029  RGB888_RGB332(Pixel, *src);
1030  *dst++ = map[Pixel];
1031  ++src;
1032  }
1033 #endif /* USE_DUFFS_LOOP */
1034  src += srcskip;
1035  dst += dstskip;
1036  }
1037  }
1038 }
1039 
1040 /* Special optimized blit for RGB 10-10-10 --> RGB 3-3-2 */
1041 #define RGB101010_RGB332(dst, src) { \
1042  dst = (Uint8)((((src)&0x38000000)>>22)| \
1043  (((src)&0x000E0000)>>15)| \
1044  (((src)&0x00000300)>>8)); \
1045 }
1046 static void
1048 {
1049 #ifndef USE_DUFFS_LOOP
1050  int c;
1051 #endif
1052  int width, height;
1053  Uint32 *src;
1054  const Uint8 *map;
1055  Uint8 *dst;
1056  int srcskip, dstskip;
1057 
1058  /* Set up some basic variables */
1059  width = info->dst_w;
1060  height = info->dst_h;
1061  src = (Uint32 *) info->src;
1062  srcskip = info->src_skip / 4;
1063  dst = info->dst;
1064  dstskip = info->dst_skip;
1065  map = info->table;
1066 
1067  if (map == NULL) {
1068  while (height--) {
1069 #ifdef USE_DUFFS_LOOP
1070  /* *INDENT-OFF* */
1071  DUFFS_LOOP(
1072  RGB101010_RGB332(*dst++, *src);
1073  , width);
1074  /* *INDENT-ON* */
1075 #else
1076  for (c = width / 4; c; --c) {
1077  /* Pack RGB into 8bit pixel */
1078  ++src;
1079  RGB101010_RGB332(*dst++, *src);
1080  ++src;
1081  RGB101010_RGB332(*dst++, *src);
1082  ++src;
1083  RGB101010_RGB332(*dst++, *src);
1084  ++src;
1085  }
1086  switch (width & 3) {
1087  case 3:
1088  RGB101010_RGB332(*dst++, *src);
1089  ++src;
1090  case 2:
1091  RGB101010_RGB332(*dst++, *src);
1092  ++src;
1093  case 1:
1094  RGB101010_RGB332(*dst++, *src);
1095  ++src;
1096  }
1097 #endif /* USE_DUFFS_LOOP */
1098  src += srcskip;
1099  dst += dstskip;
1100  }
1101  } else {
1102  int Pixel;
1103 
1104  while (height--) {
1105 #ifdef USE_DUFFS_LOOP
1106  /* *INDENT-OFF* */
1107  DUFFS_LOOP(
1108  RGB101010_RGB332(Pixel, *src);
1109  *dst++ = map[Pixel];
1110  ++src;
1111  , width);
1112  /* *INDENT-ON* */
1113 #else
1114  for (c = width / 4; c; --c) {
1115  /* Pack RGB into 8bit pixel */
1116  RGB101010_RGB332(Pixel, *src);
1117  *dst++ = map[Pixel];
1118  ++src;
1119  RGB101010_RGB332(Pixel, *src);
1120  *dst++ = map[Pixel];
1121  ++src;
1122  RGB101010_RGB332(Pixel, *src);
1123  *dst++ = map[Pixel];
1124  ++src;
1125  RGB101010_RGB332(Pixel, *src);
1126  *dst++ = map[Pixel];
1127  ++src;
1128  }
1129  switch (width & 3) {
1130  case 3:
1131  RGB101010_RGB332(Pixel, *src);
1132  *dst++ = map[Pixel];
1133  ++src;
1134  case 2:
1135  RGB101010_RGB332(Pixel, *src);
1136  *dst++ = map[Pixel];
1137  ++src;
1138  case 1:
1139  RGB101010_RGB332(Pixel, *src);
1140  *dst++ = map[Pixel];
1141  ++src;
1142  }
1143 #endif /* USE_DUFFS_LOOP */
1144  src += srcskip;
1145  dst += dstskip;
1146  }
1147  }
1148 }
1149 
1150 /* Special optimized blit for RGB 8-8-8 --> RGB 5-5-5 */
1151 #define RGB888_RGB555(dst, src) { \
1152  *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>9)| \
1153  (((*src)&0x0000F800)>>6)| \
1154  (((*src)&0x000000F8)>>3)); \
1155 }
1156 #ifndef USE_DUFFS_LOOP
1157 #define RGB888_RGB555_TWO(dst, src) { \
1158  *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>9)| \
1159  (((src[HI])&0x0000F800)>>6)| \
1160  (((src[HI])&0x000000F8)>>3))<<16)| \
1161  (((src[LO])&0x00F80000)>>9)| \
1162  (((src[LO])&0x0000F800)>>6)| \
1163  (((src[LO])&0x000000F8)>>3); \
1164 }
1165 #endif
1166 static void
1168 {
1169 #ifndef USE_DUFFS_LOOP
1170  int c;
1171 #endif
1172  int width, height;
1173  Uint32 *src;
1174  Uint16 *dst;
1175  int srcskip, dstskip;
1176 
1177  /* Set up some basic variables */
1178  width = info->dst_w;
1179  height = info->dst_h;
1180  src = (Uint32 *) info->src;
1181  srcskip = info->src_skip / 4;
1182  dst = (Uint16 *) info->dst;
1183  dstskip = info->dst_skip / 2;
1184 
1185 #ifdef USE_DUFFS_LOOP
1186  while (height--) {
1187  /* *INDENT-OFF* */
1188  DUFFS_LOOP(
1189  RGB888_RGB555(dst, src);
1190  ++src;
1191  ++dst;
1192  , width);
1193  /* *INDENT-ON* */
1194  src += srcskip;
1195  dst += dstskip;
1196  }
1197 #else
1198  /* Memory align at 4-byte boundary, if necessary */
1199  if ((long) dst & 0x03) {
1200  /* Don't do anything if width is 0 */
1201  if (width == 0) {
1202  return;
1203  }
1204  --width;
1205 
1206  while (height--) {
1207  /* Perform copy alignment */
1208  RGB888_RGB555(dst, src);
1209  ++src;
1210  ++dst;
1211 
1212  /* Copy in 4 pixel chunks */
1213  for (c = width / 4; c; --c) {
1214  RGB888_RGB555_TWO(dst, src);
1215  src += 2;
1216  dst += 2;
1217  RGB888_RGB555_TWO(dst, src);
1218  src += 2;
1219  dst += 2;
1220  }
1221  /* Get any leftovers */
1222  switch (width & 3) {
1223  case 3:
1224  RGB888_RGB555(dst, src);
1225  ++src;
1226  ++dst;
1227  case 2:
1228  RGB888_RGB555_TWO(dst, src);
1229  src += 2;
1230  dst += 2;
1231  break;
1232  case 1:
1233  RGB888_RGB555(dst, src);
1234  ++src;
1235  ++dst;
1236  break;
1237  }
1238  src += srcskip;
1239  dst += dstskip;
1240  }
1241  } else {
1242  while (height--) {
1243  /* Copy in 4 pixel chunks */
1244  for (c = width / 4; c; --c) {
1245  RGB888_RGB555_TWO(dst, src);
1246  src += 2;
1247  dst += 2;
1248  RGB888_RGB555_TWO(dst, src);
1249  src += 2;
1250  dst += 2;
1251  }
1252  /* Get any leftovers */
1253  switch (width & 3) {
1254  case 3:
1255  RGB888_RGB555(dst, src);
1256  ++src;
1257  ++dst;
1258  case 2:
1259  RGB888_RGB555_TWO(dst, src);
1260  src += 2;
1261  dst += 2;
1262  break;
1263  case 1:
1264  RGB888_RGB555(dst, src);
1265  ++src;
1266  ++dst;
1267  break;
1268  }
1269  src += srcskip;
1270  dst += dstskip;
1271  }
1272  }
1273 #endif /* USE_DUFFS_LOOP */
1274 }
1275 
1276 /* Special optimized blit for RGB 8-8-8 --> RGB 5-6-5 */
1277 #define RGB888_RGB565(dst, src) { \
1278  *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>8)| \
1279  (((*src)&0x0000FC00)>>5)| \
1280  (((*src)&0x000000F8)>>3)); \
1281 }
1282 #ifndef USE_DUFFS_LOOP
1283 #define RGB888_RGB565_TWO(dst, src) { \
1284  *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>8)| \
1285  (((src[HI])&0x0000FC00)>>5)| \
1286  (((src[HI])&0x000000F8)>>3))<<16)| \
1287  (((src[LO])&0x00F80000)>>8)| \
1288  (((src[LO])&0x0000FC00)>>5)| \
1289  (((src[LO])&0x000000F8)>>3); \
1290 }
1291 #endif
1292 static void
1294 {
1295 #ifndef USE_DUFFS_LOOP
1296  int c;
1297 #endif
1298  int width, height;
1299  Uint32 *src;
1300  Uint16 *dst;
1301  int srcskip, dstskip;
1302 
1303  /* Set up some basic variables */
1304  width = info->dst_w;
1305  height = info->dst_h;
1306  src = (Uint32 *) info->src;
1307  srcskip = info->src_skip / 4;
1308  dst = (Uint16 *) info->dst;
1309  dstskip = info->dst_skip / 2;
1310 
1311 #ifdef USE_DUFFS_LOOP
1312  while (height--) {
1313  /* *INDENT-OFF* */
1314  DUFFS_LOOP(
1315  RGB888_RGB565(dst, src);
1316  ++src;
1317  ++dst;
1318  , width);
1319  /* *INDENT-ON* */
1320  src += srcskip;
1321  dst += dstskip;
1322  }
1323 #else
1324  /* Memory align at 4-byte boundary, if necessary */
1325  if ((long) dst & 0x03) {
1326  /* Don't do anything if width is 0 */
1327  if (width == 0) {
1328  return;
1329  }
1330  --width;
1331 
1332  while (height--) {
1333  /* Perform copy alignment */
1334  RGB888_RGB565(dst, src);
1335  ++src;
1336  ++dst;
1337 
1338  /* Copy in 4 pixel chunks */
1339  for (c = width / 4; c; --c) {
1340  RGB888_RGB565_TWO(dst, src);
1341  src += 2;
1342  dst += 2;
1343  RGB888_RGB565_TWO(dst, src);
1344  src += 2;
1345  dst += 2;
1346  }
1347  /* Get any leftovers */
1348  switch (width & 3) {
1349  case 3:
1350  RGB888_RGB565(dst, src);
1351  ++src;
1352  ++dst;
1353  case 2:
1354  RGB888_RGB565_TWO(dst, src);
1355  src += 2;
1356  dst += 2;
1357  break;
1358  case 1:
1359  RGB888_RGB565(dst, src);
1360  ++src;
1361  ++dst;
1362  break;
1363  }
1364  src += srcskip;
1365  dst += dstskip;
1366  }
1367  } else {
1368  while (height--) {
1369  /* Copy in 4 pixel chunks */
1370  for (c = width / 4; c; --c) {
1371  RGB888_RGB565_TWO(dst, src);
1372  src += 2;
1373  dst += 2;
1374  RGB888_RGB565_TWO(dst, src);
1375  src += 2;
1376  dst += 2;
1377  }
1378  /* Get any leftovers */
1379  switch (width & 3) {
1380  case 3:
1381  RGB888_RGB565(dst, src);
1382  ++src;
1383  ++dst;
1384  case 2:
1385  RGB888_RGB565_TWO(dst, src);
1386  src += 2;
1387  dst += 2;
1388  break;
1389  case 1:
1390  RGB888_RGB565(dst, src);
1391  ++src;
1392  ++dst;
1393  break;
1394  }
1395  src += srcskip;
1396  dst += dstskip;
1397  }
1398  }
1399 #endif /* USE_DUFFS_LOOP */
1400 }
1401 
1402 
1403 /* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */
1404 #define RGB565_32(dst, src, map) (map[src[LO]*2] + map[src[HI]*2+1])
1405 static void
1407 {
1408 #ifndef USE_DUFFS_LOOP
1409  int c;
1410 #endif
1411  int width, height;
1412  Uint8 *src;
1413  Uint32 *dst;
1414  int srcskip, dstskip;
1415 
1416  /* Set up some basic variables */
1417  width = info->dst_w;
1418  height = info->dst_h;
1419  src = (Uint8 *) info->src;
1420  srcskip = info->src_skip;
1421  dst = (Uint32 *) info->dst;
1422  dstskip = info->dst_skip / 4;
1423 
1424 #ifdef USE_DUFFS_LOOP
1425  while (height--) {
1426  /* *INDENT-OFF* */
1427  DUFFS_LOOP(
1428  {
1429  *dst++ = RGB565_32(dst, src, map);
1430  src += 2;
1431  },
1432  width);
1433  /* *INDENT-ON* */
1434  src += srcskip;
1435  dst += dstskip;
1436  }
1437 #else
1438  while (height--) {
1439  /* Copy in 4 pixel chunks */
1440  for (c = width / 4; c; --c) {
1441  *dst++ = RGB565_32(dst, src, map);
1442  src += 2;
1443  *dst++ = RGB565_32(dst, src, map);
1444  src += 2;
1445  *dst++ = RGB565_32(dst, src, map);
1446  src += 2;
1447  *dst++ = RGB565_32(dst, src, map);
1448  src += 2;
1449  }
1450  /* Get any leftovers */
1451  switch (width & 3) {
1452  case 3:
1453  *dst++ = RGB565_32(dst, src, map);
1454  src += 2;
1455  case 2:
1456  *dst++ = RGB565_32(dst, src, map);
1457  src += 2;
1458  case 1:
1459  *dst++ = RGB565_32(dst, src, map);
1460  src += 2;
1461  break;
1462  }
1463  src += srcskip;
1464  dst += dstskip;
1465  }
1466 #endif /* USE_DUFFS_LOOP */
1467 }
1468 
1469 /* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */
1470 static const Uint32 RGB565_ARGB8888_LUT[512] = {
1471  0x00000000, 0xff000000, 0x00000008, 0xff002000,
1472  0x00000010, 0xff004000, 0x00000018, 0xff006100,
1473  0x00000020, 0xff008100, 0x00000029, 0xff00a100,
1474  0x00000031, 0xff00c200, 0x00000039, 0xff00e200,
1475  0x00000041, 0xff080000, 0x0000004a, 0xff082000,
1476  0x00000052, 0xff084000, 0x0000005a, 0xff086100,
1477  0x00000062, 0xff088100, 0x0000006a, 0xff08a100,
1478  0x00000073, 0xff08c200, 0x0000007b, 0xff08e200,
1479  0x00000083, 0xff100000, 0x0000008b, 0xff102000,
1480  0x00000094, 0xff104000, 0x0000009c, 0xff106100,
1481  0x000000a4, 0xff108100, 0x000000ac, 0xff10a100,
1482  0x000000b4, 0xff10c200, 0x000000bd, 0xff10e200,
1483  0x000000c5, 0xff180000, 0x000000cd, 0xff182000,
1484  0x000000d5, 0xff184000, 0x000000de, 0xff186100,
1485  0x000000e6, 0xff188100, 0x000000ee, 0xff18a100,
1486  0x000000f6, 0xff18c200, 0x000000ff, 0xff18e200,
1487  0x00000400, 0xff200000, 0x00000408, 0xff202000,
1488  0x00000410, 0xff204000, 0x00000418, 0xff206100,
1489  0x00000420, 0xff208100, 0x00000429, 0xff20a100,
1490  0x00000431, 0xff20c200, 0x00000439, 0xff20e200,
1491  0x00000441, 0xff290000, 0x0000044a, 0xff292000,
1492  0x00000452, 0xff294000, 0x0000045a, 0xff296100,
1493  0x00000462, 0xff298100, 0x0000046a, 0xff29a100,
1494  0x00000473, 0xff29c200, 0x0000047b, 0xff29e200,
1495  0x00000483, 0xff310000, 0x0000048b, 0xff312000,
1496  0x00000494, 0xff314000, 0x0000049c, 0xff316100,
1497  0x000004a4, 0xff318100, 0x000004ac, 0xff31a100,
1498  0x000004b4, 0xff31c200, 0x000004bd, 0xff31e200,
1499  0x000004c5, 0xff390000, 0x000004cd, 0xff392000,
1500  0x000004d5, 0xff394000, 0x000004de, 0xff396100,
1501  0x000004e6, 0xff398100, 0x000004ee, 0xff39a100,
1502  0x000004f6, 0xff39c200, 0x000004ff, 0xff39e200,
1503  0x00000800, 0xff410000, 0x00000808, 0xff412000,
1504  0x00000810, 0xff414000, 0x00000818, 0xff416100,
1505  0x00000820, 0xff418100, 0x00000829, 0xff41a100,
1506  0x00000831, 0xff41c200, 0x00000839, 0xff41e200,
1507  0x00000841, 0xff4a0000, 0x0000084a, 0xff4a2000,
1508  0x00000852, 0xff4a4000, 0x0000085a, 0xff4a6100,
1509  0x00000862, 0xff4a8100, 0x0000086a, 0xff4aa100,
1510  0x00000873, 0xff4ac200, 0x0000087b, 0xff4ae200,
1511  0x00000883, 0xff520000, 0x0000088b, 0xff522000,
1512  0x00000894, 0xff524000, 0x0000089c, 0xff526100,
1513  0x000008a4, 0xff528100, 0x000008ac, 0xff52a100,
1514  0x000008b4, 0xff52c200, 0x000008bd, 0xff52e200,
1515  0x000008c5, 0xff5a0000, 0x000008cd, 0xff5a2000,
1516  0x000008d5, 0xff5a4000, 0x000008de, 0xff5a6100,
1517  0x000008e6, 0xff5a8100, 0x000008ee, 0xff5aa100,
1518  0x000008f6, 0xff5ac200, 0x000008ff, 0xff5ae200,
1519  0x00000c00, 0xff620000, 0x00000c08, 0xff622000,
1520  0x00000c10, 0xff624000, 0x00000c18, 0xff626100,
1521  0x00000c20, 0xff628100, 0x00000c29, 0xff62a100,
1522  0x00000c31, 0xff62c200, 0x00000c39, 0xff62e200,
1523  0x00000c41, 0xff6a0000, 0x00000c4a, 0xff6a2000,
1524  0x00000c52, 0xff6a4000, 0x00000c5a, 0xff6a6100,
1525  0x00000c62, 0xff6a8100, 0x00000c6a, 0xff6aa100,
1526  0x00000c73, 0xff6ac200, 0x00000c7b, 0xff6ae200,
1527  0x00000c83, 0xff730000, 0x00000c8b, 0xff732000,
1528  0x00000c94, 0xff734000, 0x00000c9c, 0xff736100,
1529  0x00000ca4, 0xff738100, 0x00000cac, 0xff73a100,
1530  0x00000cb4, 0xff73c200, 0x00000cbd, 0xff73e200,
1531  0x00000cc5, 0xff7b0000, 0x00000ccd, 0xff7b2000,
1532  0x00000cd5, 0xff7b4000, 0x00000cde, 0xff7b6100,
1533  0x00000ce6, 0xff7b8100, 0x00000cee, 0xff7ba100,
1534  0x00000cf6, 0xff7bc200, 0x00000cff, 0xff7be200,
1535  0x00001000, 0xff830000, 0x00001008, 0xff832000,
1536  0x00001010, 0xff834000, 0x00001018, 0xff836100,
1537  0x00001020, 0xff838100, 0x00001029, 0xff83a100,
1538  0x00001031, 0xff83c200, 0x00001039, 0xff83e200,
1539  0x00001041, 0xff8b0000, 0x0000104a, 0xff8b2000,
1540  0x00001052, 0xff8b4000, 0x0000105a, 0xff8b6100,
1541  0x00001062, 0xff8b8100, 0x0000106a, 0xff8ba100,
1542  0x00001073, 0xff8bc200, 0x0000107b, 0xff8be200,
1543  0x00001083, 0xff940000, 0x0000108b, 0xff942000,
1544  0x00001094, 0xff944000, 0x0000109c, 0xff946100,
1545  0x000010a4, 0xff948100, 0x000010ac, 0xff94a100,
1546  0x000010b4, 0xff94c200, 0x000010bd, 0xff94e200,
1547  0x000010c5, 0xff9c0000, 0x000010cd, 0xff9c2000,
1548  0x000010d5, 0xff9c4000, 0x000010de, 0xff9c6100,
1549  0x000010e6, 0xff9c8100, 0x000010ee, 0xff9ca100,
1550  0x000010f6, 0xff9cc200, 0x000010ff, 0xff9ce200,
1551  0x00001400, 0xffa40000, 0x00001408, 0xffa42000,
1552  0x00001410, 0xffa44000, 0x00001418, 0xffa46100,
1553  0x00001420, 0xffa48100, 0x00001429, 0xffa4a100,
1554  0x00001431, 0xffa4c200, 0x00001439, 0xffa4e200,
1555  0x00001441, 0xffac0000, 0x0000144a, 0xffac2000,
1556  0x00001452, 0xffac4000, 0x0000145a, 0xffac6100,
1557  0x00001462, 0xffac8100, 0x0000146a, 0xffaca100,
1558  0x00001473, 0xffacc200, 0x0000147b, 0xfface200,
1559  0x00001483, 0xffb40000, 0x0000148b, 0xffb42000,
1560  0x00001494, 0xffb44000, 0x0000149c, 0xffb46100,
1561  0x000014a4, 0xffb48100, 0x000014ac, 0xffb4a100,
1562  0x000014b4, 0xffb4c200, 0x000014bd, 0xffb4e200,
1563  0x000014c5, 0xffbd0000, 0x000014cd, 0xffbd2000,
1564  0x000014d5, 0xffbd4000, 0x000014de, 0xffbd6100,
1565  0x000014e6, 0xffbd8100, 0x000014ee, 0xffbda100,
1566  0x000014f6, 0xffbdc200, 0x000014ff, 0xffbde200,
1567  0x00001800, 0xffc50000, 0x00001808, 0xffc52000,
1568  0x00001810, 0xffc54000, 0x00001818, 0xffc56100,
1569  0x00001820, 0xffc58100, 0x00001829, 0xffc5a100,
1570  0x00001831, 0xffc5c200, 0x00001839, 0xffc5e200,
1571  0x00001841, 0xffcd0000, 0x0000184a, 0xffcd2000,
1572  0x00001852, 0xffcd4000, 0x0000185a, 0xffcd6100,
1573  0x00001862, 0xffcd8100, 0x0000186a, 0xffcda100,
1574  0x00001873, 0xffcdc200, 0x0000187b, 0xffcde200,
1575  0x00001883, 0xffd50000, 0x0000188b, 0xffd52000,
1576  0x00001894, 0xffd54000, 0x0000189c, 0xffd56100,
1577  0x000018a4, 0xffd58100, 0x000018ac, 0xffd5a100,
1578  0x000018b4, 0xffd5c200, 0x000018bd, 0xffd5e200,
1579  0x000018c5, 0xffde0000, 0x000018cd, 0xffde2000,
1580  0x000018d5, 0xffde4000, 0x000018de, 0xffde6100,
1581  0x000018e6, 0xffde8100, 0x000018ee, 0xffdea100,
1582  0x000018f6, 0xffdec200, 0x000018ff, 0xffdee200,
1583  0x00001c00, 0xffe60000, 0x00001c08, 0xffe62000,
1584  0x00001c10, 0xffe64000, 0x00001c18, 0xffe66100,
1585  0x00001c20, 0xffe68100, 0x00001c29, 0xffe6a100,
1586  0x00001c31, 0xffe6c200, 0x00001c39, 0xffe6e200,
1587  0x00001c41, 0xffee0000, 0x00001c4a, 0xffee2000,
1588  0x00001c52, 0xffee4000, 0x00001c5a, 0xffee6100,
1589  0x00001c62, 0xffee8100, 0x00001c6a, 0xffeea100,
1590  0x00001c73, 0xffeec200, 0x00001c7b, 0xffeee200,
1591  0x00001c83, 0xfff60000, 0x00001c8b, 0xfff62000,
1592  0x00001c94, 0xfff64000, 0x00001c9c, 0xfff66100,
1593  0x00001ca4, 0xfff68100, 0x00001cac, 0xfff6a100,
1594  0x00001cb4, 0xfff6c200, 0x00001cbd, 0xfff6e200,
1595  0x00001cc5, 0xffff0000, 0x00001ccd, 0xffff2000,
1596  0x00001cd5, 0xffff4000, 0x00001cde, 0xffff6100,
1597  0x00001ce6, 0xffff8100, 0x00001cee, 0xffffa100,
1598  0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200
1599 };
1600 
1601 static void
1603 {
1605 }
1606 
1607 /* Special optimized blit for RGB 5-6-5 --> ABGR 8-8-8-8 */
1608 static const Uint32 RGB565_ABGR8888_LUT[512] = {
1609  0xff000000, 0x00000000, 0xff080000, 0x00002000,
1610  0xff100000, 0x00004000, 0xff180000, 0x00006100,
1611  0xff200000, 0x00008100, 0xff290000, 0x0000a100,
1612  0xff310000, 0x0000c200, 0xff390000, 0x0000e200,
1613  0xff410000, 0x00000008, 0xff4a0000, 0x00002008,
1614  0xff520000, 0x00004008, 0xff5a0000, 0x00006108,
1615  0xff620000, 0x00008108, 0xff6a0000, 0x0000a108,
1616  0xff730000, 0x0000c208, 0xff7b0000, 0x0000e208,
1617  0xff830000, 0x00000010, 0xff8b0000, 0x00002010,
1618  0xff940000, 0x00004010, 0xff9c0000, 0x00006110,
1619  0xffa40000, 0x00008110, 0xffac0000, 0x0000a110,
1620  0xffb40000, 0x0000c210, 0xffbd0000, 0x0000e210,
1621  0xffc50000, 0x00000018, 0xffcd0000, 0x00002018,
1622  0xffd50000, 0x00004018, 0xffde0000, 0x00006118,
1623  0xffe60000, 0x00008118, 0xffee0000, 0x0000a118,
1624  0xfff60000, 0x0000c218, 0xffff0000, 0x0000e218,
1625  0xff000400, 0x00000020, 0xff080400, 0x00002020,
1626  0xff100400, 0x00004020, 0xff180400, 0x00006120,
1627  0xff200400, 0x00008120, 0xff290400, 0x0000a120,
1628  0xff310400, 0x0000c220, 0xff390400, 0x0000e220,
1629  0xff410400, 0x00000029, 0xff4a0400, 0x00002029,
1630  0xff520400, 0x00004029, 0xff5a0400, 0x00006129,
1631  0xff620400, 0x00008129, 0xff6a0400, 0x0000a129,
1632  0xff730400, 0x0000c229, 0xff7b0400, 0x0000e229,
1633  0xff830400, 0x00000031, 0xff8b0400, 0x00002031,
1634  0xff940400, 0x00004031, 0xff9c0400, 0x00006131,
1635  0xffa40400, 0x00008131, 0xffac0400, 0x0000a131,
1636  0xffb40400, 0x0000c231, 0xffbd0400, 0x0000e231,
1637  0xffc50400, 0x00000039, 0xffcd0400, 0x00002039,
1638  0xffd50400, 0x00004039, 0xffde0400, 0x00006139,
1639  0xffe60400, 0x00008139, 0xffee0400, 0x0000a139,
1640  0xfff60400, 0x0000c239, 0xffff0400, 0x0000e239,
1641  0xff000800, 0x00000041, 0xff080800, 0x00002041,
1642  0xff100800, 0x00004041, 0xff180800, 0x00006141,
1643  0xff200800, 0x00008141, 0xff290800, 0x0000a141,
1644  0xff310800, 0x0000c241, 0xff390800, 0x0000e241,
1645  0xff410800, 0x0000004a, 0xff4a0800, 0x0000204a,
1646  0xff520800, 0x0000404a, 0xff5a0800, 0x0000614a,
1647  0xff620800, 0x0000814a, 0xff6a0800, 0x0000a14a,
1648  0xff730800, 0x0000c24a, 0xff7b0800, 0x0000e24a,
1649  0xff830800, 0x00000052, 0xff8b0800, 0x00002052,
1650  0xff940800, 0x00004052, 0xff9c0800, 0x00006152,
1651  0xffa40800, 0x00008152, 0xffac0800, 0x0000a152,
1652  0xffb40800, 0x0000c252, 0xffbd0800, 0x0000e252,
1653  0xffc50800, 0x0000005a, 0xffcd0800, 0x0000205a,
1654  0xffd50800, 0x0000405a, 0xffde0800, 0x0000615a,
1655  0xffe60800, 0x0000815a, 0xffee0800, 0x0000a15a,
1656  0xfff60800, 0x0000c25a, 0xffff0800, 0x0000e25a,
1657  0xff000c00, 0x00000062, 0xff080c00, 0x00002062,
1658  0xff100c00, 0x00004062, 0xff180c00, 0x00006162,
1659  0xff200c00, 0x00008162, 0xff290c00, 0x0000a162,
1660  0xff310c00, 0x0000c262, 0xff390c00, 0x0000e262,
1661  0xff410c00, 0x0000006a, 0xff4a0c00, 0x0000206a,
1662  0xff520c00, 0x0000406a, 0xff5a0c00, 0x0000616a,
1663  0xff620c00, 0x0000816a, 0xff6a0c00, 0x0000a16a,
1664  0xff730c00, 0x0000c26a, 0xff7b0c00, 0x0000e26a,
1665  0xff830c00, 0x00000073, 0xff8b0c00, 0x00002073,
1666  0xff940c00, 0x00004073, 0xff9c0c00, 0x00006173,
1667  0xffa40c00, 0x00008173, 0xffac0c00, 0x0000a173,
1668  0xffb40c00, 0x0000c273, 0xffbd0c00, 0x0000e273,
1669  0xffc50c00, 0x0000007b, 0xffcd0c00, 0x0000207b,
1670  0xffd50c00, 0x0000407b, 0xffde0c00, 0x0000617b,
1671  0xffe60c00, 0x0000817b, 0xffee0c00, 0x0000a17b,
1672  0xfff60c00, 0x0000c27b, 0xffff0c00, 0x0000e27b,
1673  0xff001000, 0x00000083, 0xff081000, 0x00002083,
1674  0xff101000, 0x00004083, 0xff181000, 0x00006183,
1675  0xff201000, 0x00008183, 0xff291000, 0x0000a183,
1676  0xff311000, 0x0000c283, 0xff391000, 0x0000e283,
1677  0xff411000, 0x0000008b, 0xff4a1000, 0x0000208b,
1678  0xff521000, 0x0000408b, 0xff5a1000, 0x0000618b,
1679  0xff621000, 0x0000818b, 0xff6a1000, 0x0000a18b,
1680  0xff731000, 0x0000c28b, 0xff7b1000, 0x0000e28b,
1681  0xff831000, 0x00000094, 0xff8b1000, 0x00002094,
1682  0xff941000, 0x00004094, 0xff9c1000, 0x00006194,
1683  0xffa41000, 0x00008194, 0xffac1000, 0x0000a194,
1684  0xffb41000, 0x0000c294, 0xffbd1000, 0x0000e294,
1685  0xffc51000, 0x0000009c, 0xffcd1000, 0x0000209c,
1686  0xffd51000, 0x0000409c, 0xffde1000, 0x0000619c,
1687  0xffe61000, 0x0000819c, 0xffee1000, 0x0000a19c,
1688  0xfff61000, 0x0000c29c, 0xffff1000, 0x0000e29c,
1689  0xff001400, 0x000000a4, 0xff081400, 0x000020a4,
1690  0xff101400, 0x000040a4, 0xff181400, 0x000061a4,
1691  0xff201400, 0x000081a4, 0xff291400, 0x0000a1a4,
1692  0xff311400, 0x0000c2a4, 0xff391400, 0x0000e2a4,
1693  0xff411400, 0x000000ac, 0xff4a1400, 0x000020ac,
1694  0xff521400, 0x000040ac, 0xff5a1400, 0x000061ac,
1695  0xff621400, 0x000081ac, 0xff6a1400, 0x0000a1ac,
1696  0xff731400, 0x0000c2ac, 0xff7b1400, 0x0000e2ac,
1697  0xff831400, 0x000000b4, 0xff8b1400, 0x000020b4,
1698  0xff941400, 0x000040b4, 0xff9c1400, 0x000061b4,
1699  0xffa41400, 0x000081b4, 0xffac1400, 0x0000a1b4,
1700  0xffb41400, 0x0000c2b4, 0xffbd1400, 0x0000e2b4,
1701  0xffc51400, 0x000000bd, 0xffcd1400, 0x000020bd,
1702  0xffd51400, 0x000040bd, 0xffde1400, 0x000061bd,
1703  0xffe61400, 0x000081bd, 0xffee1400, 0x0000a1bd,
1704  0xfff61400, 0x0000c2bd, 0xffff1400, 0x0000e2bd,
1705  0xff001800, 0x000000c5, 0xff081800, 0x000020c5,
1706  0xff101800, 0x000040c5, 0xff181800, 0x000061c5,
1707  0xff201800, 0x000081c5, 0xff291800, 0x0000a1c5,
1708  0xff311800, 0x0000c2c5, 0xff391800, 0x0000e2c5,
1709  0xff411800, 0x000000cd, 0xff4a1800, 0x000020cd,
1710  0xff521800, 0x000040cd, 0xff5a1800, 0x000061cd,
1711  0xff621800, 0x000081cd, 0xff6a1800, 0x0000a1cd,
1712  0xff731800, 0x0000c2cd, 0xff7b1800, 0x0000e2cd,
1713  0xff831800, 0x000000d5, 0xff8b1800, 0x000020d5,
1714  0xff941800, 0x000040d5, 0xff9c1800, 0x000061d5,
1715  0xffa41800, 0x000081d5, 0xffac1800, 0x0000a1d5,
1716  0xffb41800, 0x0000c2d5, 0xffbd1800, 0x0000e2d5,
1717  0xffc51800, 0x000000de, 0xffcd1800, 0x000020de,
1718  0xffd51800, 0x000040de, 0xffde1800, 0x000061de,
1719  0xffe61800, 0x000081de, 0xffee1800, 0x0000a1de,
1720  0xfff61800, 0x0000c2de, 0xffff1800, 0x0000e2de,
1721  0xff001c00, 0x000000e6, 0xff081c00, 0x000020e6,
1722  0xff101c00, 0x000040e6, 0xff181c00, 0x000061e6,
1723  0xff201c00, 0x000081e6, 0xff291c00, 0x0000a1e6,
1724  0xff311c00, 0x0000c2e6, 0xff391c00, 0x0000e2e6,
1725  0xff411c00, 0x000000ee, 0xff4a1c00, 0x000020ee,
1726  0xff521c00, 0x000040ee, 0xff5a1c00, 0x000061ee,
1727  0xff621c00, 0x000081ee, 0xff6a1c00, 0x0000a1ee,
1728  0xff731c00, 0x0000c2ee, 0xff7b1c00, 0x0000e2ee,
1729  0xff831c00, 0x000000f6, 0xff8b1c00, 0x000020f6,
1730  0xff941c00, 0x000040f6, 0xff9c1c00, 0x000061f6,
1731  0xffa41c00, 0x000081f6, 0xffac1c00, 0x0000a1f6,
1732  0xffb41c00, 0x0000c2f6, 0xffbd1c00, 0x0000e2f6,
1733  0xffc51c00, 0x000000ff, 0xffcd1c00, 0x000020ff,
1734  0xffd51c00, 0x000040ff, 0xffde1c00, 0x000061ff,
1735  0xffe61c00, 0x000081ff, 0xffee1c00, 0x0000a1ff,
1736  0xfff61c00, 0x0000c2ff, 0xffff1c00, 0x0000e2ff
1737 };
1738 
1739 static void
1741 {
1743 }
1744 
1745 /* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
1746 static const Uint32 RGB565_RGBA8888_LUT[512] = {
1747  0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
1748  0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
1749  0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
1750  0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
1751  0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
1752  0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
1753  0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
1754  0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
1755  0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
1756  0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
1757  0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
1758  0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
1759  0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
1760  0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
1761  0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
1762  0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
1763  0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
1764  0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
1765  0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
1766  0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
1767  0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
1768  0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
1769  0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
1770  0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
1771  0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
1772  0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
1773  0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
1774  0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
1775  0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
1776  0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
1777  0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
1778  0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
1779  0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
1780  0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
1781  0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
1782  0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
1783  0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
1784  0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
1785  0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
1786  0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
1787  0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
1788  0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
1789  0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
1790  0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
1791  0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
1792  0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
1793  0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
1794  0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
1795  0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
1796  0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
1797  0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
1798  0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
1799  0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
1800  0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
1801  0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
1802  0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
1803  0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
1804  0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
1805  0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
1806  0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
1807  0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
1808  0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
1809  0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
1810  0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
1811  0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
1812  0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
1813  0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
1814  0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
1815  0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
1816  0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
1817  0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
1818  0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
1819  0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
1820  0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
1821  0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
1822  0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
1823  0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
1824  0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
1825  0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
1826  0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
1827  0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
1828  0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
1829  0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
1830  0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
1831  0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
1832  0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
1833  0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
1834  0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
1835  0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
1836  0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
1837  0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
1838  0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
1839  0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
1840  0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
1841  0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
1842  0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
1843  0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
1844  0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
1845  0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
1846  0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
1847  0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
1848  0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
1849  0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
1850  0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
1851  0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
1852  0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
1853  0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
1854  0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
1855  0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
1856  0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
1857  0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
1858  0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
1859  0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
1860  0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
1861  0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
1862  0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
1863  0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
1864  0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
1865  0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
1866  0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
1867  0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
1868  0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
1869  0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
1870  0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
1871  0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
1872  0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
1873  0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
1874  0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
1875 };
1876 
1877 static void
1879 {
1881 }
1882 
1883 /* Special optimized blit for RGB 5-6-5 --> BGRA 8-8-8-8 */
1884 static const Uint32 RGB565_BGRA8888_LUT[512] = {
1885  0x00000000, 0x000000ff, 0x08000000, 0x002000ff,
1886  0x10000000, 0x004000ff, 0x18000000, 0x006100ff,
1887  0x20000000, 0x008100ff, 0x29000000, 0x00a100ff,
1888  0x31000000, 0x00c200ff, 0x39000000, 0x00e200ff,
1889  0x41000000, 0x000008ff, 0x4a000000, 0x002008ff,
1890  0x52000000, 0x004008ff, 0x5a000000, 0x006108ff,
1891  0x62000000, 0x008108ff, 0x6a000000, 0x00a108ff,
1892  0x73000000, 0x00c208ff, 0x7b000000, 0x00e208ff,
1893  0x83000000, 0x000010ff, 0x8b000000, 0x002010ff,
1894  0x94000000, 0x004010ff, 0x9c000000, 0x006110ff,
1895  0xa4000000, 0x008110ff, 0xac000000, 0x00a110ff,
1896  0xb4000000, 0x00c210ff, 0xbd000000, 0x00e210ff,
1897  0xc5000000, 0x000018ff, 0xcd000000, 0x002018ff,
1898  0xd5000000, 0x004018ff, 0xde000000, 0x006118ff,
1899  0xe6000000, 0x008118ff, 0xee000000, 0x00a118ff,
1900  0xf6000000, 0x00c218ff, 0xff000000, 0x00e218ff,
1901  0x00040000, 0x000020ff, 0x08040000, 0x002020ff,
1902  0x10040000, 0x004020ff, 0x18040000, 0x006120ff,
1903  0x20040000, 0x008120ff, 0x29040000, 0x00a120ff,
1904  0x31040000, 0x00c220ff, 0x39040000, 0x00e220ff,
1905  0x41040000, 0x000029ff, 0x4a040000, 0x002029ff,
1906  0x52040000, 0x004029ff, 0x5a040000, 0x006129ff,
1907  0x62040000, 0x008129ff, 0x6a040000, 0x00a129ff,
1908  0x73040000, 0x00c229ff, 0x7b040000, 0x00e229ff,
1909  0x83040000, 0x000031ff, 0x8b040000, 0x002031ff,
1910  0x94040000, 0x004031ff, 0x9c040000, 0x006131ff,
1911  0xa4040000, 0x008131ff, 0xac040000, 0x00a131ff,
1912  0xb4040000, 0x00c231ff, 0xbd040000, 0x00e231ff,
1913  0xc5040000, 0x000039ff, 0xcd040000, 0x002039ff,
1914  0xd5040000, 0x004039ff, 0xde040000, 0x006139ff,
1915  0xe6040000, 0x008139ff, 0xee040000, 0x00a139ff,
1916  0xf6040000, 0x00c239ff, 0xff040000, 0x00e239ff,
1917  0x00080000, 0x000041ff, 0x08080000, 0x002041ff,
1918  0x10080000, 0x004041ff, 0x18080000, 0x006141ff,
1919  0x20080000, 0x008141ff, 0x29080000, 0x00a141ff,
1920  0x31080000, 0x00c241ff, 0x39080000, 0x00e241ff,
1921  0x41080000, 0x00004aff, 0x4a080000, 0x00204aff,
1922  0x52080000, 0x00404aff, 0x5a080000, 0x00614aff,
1923  0x62080000, 0x00814aff, 0x6a080000, 0x00a14aff,
1924  0x73080000, 0x00c24aff, 0x7b080000, 0x00e24aff,
1925  0x83080000, 0x000052ff, 0x8b080000, 0x002052ff,
1926  0x94080000, 0x004052ff, 0x9c080000, 0x006152ff,
1927  0xa4080000, 0x008152ff, 0xac080000, 0x00a152ff,
1928  0xb4080000, 0x00c252ff, 0xbd080000, 0x00e252ff,
1929  0xc5080000, 0x00005aff, 0xcd080000, 0x00205aff,
1930  0xd5080000, 0x00405aff, 0xde080000, 0x00615aff,
1931  0xe6080000, 0x00815aff, 0xee080000, 0x00a15aff,
1932  0xf6080000, 0x00c25aff, 0xff080000, 0x00e25aff,
1933  0x000c0000, 0x000062ff, 0x080c0000, 0x002062ff,
1934  0x100c0000, 0x004062ff, 0x180c0000, 0x006162ff,
1935  0x200c0000, 0x008162ff, 0x290c0000, 0x00a162ff,
1936  0x310c0000, 0x00c262ff, 0x390c0000, 0x00e262ff,
1937  0x410c0000, 0x00006aff, 0x4a0c0000, 0x00206aff,
1938  0x520c0000, 0x00406aff, 0x5a0c0000, 0x00616aff,
1939  0x620c0000, 0x00816aff, 0x6a0c0000, 0x00a16aff,
1940  0x730c0000, 0x00c26aff, 0x7b0c0000, 0x00e26aff,
1941  0x830c0000, 0x000073ff, 0x8b0c0000, 0x002073ff,
1942  0x940c0000, 0x004073ff, 0x9c0c0000, 0x006173ff,
1943  0xa40c0000, 0x008173ff, 0xac0c0000, 0x00a173ff,
1944  0xb40c0000, 0x00c273ff, 0xbd0c0000, 0x00e273ff,
1945  0xc50c0000, 0x00007bff, 0xcd0c0000, 0x00207bff,
1946  0xd50c0000, 0x00407bff, 0xde0c0000, 0x00617bff,
1947  0xe60c0000, 0x00817bff, 0xee0c0000, 0x00a17bff,
1948  0xf60c0000, 0x00c27bff, 0xff0c0000, 0x00e27bff,
1949  0x00100000, 0x000083ff, 0x08100000, 0x002083ff,
1950  0x10100000, 0x004083ff, 0x18100000, 0x006183ff,
1951  0x20100000, 0x008183ff, 0x29100000, 0x00a183ff,
1952  0x31100000, 0x00c283ff, 0x39100000, 0x00e283ff,
1953  0x41100000, 0x00008bff, 0x4a100000, 0x00208bff,
1954  0x52100000, 0x00408bff, 0x5a100000, 0x00618bff,
1955  0x62100000, 0x00818bff, 0x6a100000, 0x00a18bff,
1956  0x73100000, 0x00c28bff, 0x7b100000, 0x00e28bff,
1957  0x83100000, 0x000094ff, 0x8b100000, 0x002094ff,
1958  0x94100000, 0x004094ff, 0x9c100000, 0x006194ff,
1959  0xa4100000, 0x008194ff, 0xac100000, 0x00a194ff,
1960  0xb4100000, 0x00c294ff, 0xbd100000, 0x00e294ff,
1961  0xc5100000, 0x00009cff, 0xcd100000, 0x00209cff,
1962  0xd5100000, 0x00409cff, 0xde100000, 0x00619cff,
1963  0xe6100000, 0x00819cff, 0xee100000, 0x00a19cff,
1964  0xf6100000, 0x00c29cff, 0xff100000, 0x00e29cff,
1965  0x00140000, 0x0000a4ff, 0x08140000, 0x0020a4ff,
1966  0x10140000, 0x0040a4ff, 0x18140000, 0x0061a4ff,
1967  0x20140000, 0x0081a4ff, 0x29140000, 0x00a1a4ff,
1968  0x31140000, 0x00c2a4ff, 0x39140000, 0x00e2a4ff,
1969  0x41140000, 0x0000acff, 0x4a140000, 0x0020acff,
1970  0x52140000, 0x0040acff, 0x5a140000, 0x0061acff,
1971  0x62140000, 0x0081acff, 0x6a140000, 0x00a1acff,
1972  0x73140000, 0x00c2acff, 0x7b140000, 0x00e2acff,
1973  0x83140000, 0x0000b4ff, 0x8b140000, 0x0020b4ff,
1974  0x94140000, 0x0040b4ff, 0x9c140000, 0x0061b4ff,
1975  0xa4140000, 0x0081b4ff, 0xac140000, 0x00a1b4ff,
1976  0xb4140000, 0x00c2b4ff, 0xbd140000, 0x00e2b4ff,
1977  0xc5140000, 0x0000bdff, 0xcd140000, 0x0020bdff,
1978  0xd5140000, 0x0040bdff, 0xde140000, 0x0061bdff,
1979  0xe6140000, 0x0081bdff, 0xee140000, 0x00a1bdff,
1980  0xf6140000, 0x00c2bdff, 0xff140000, 0x00e2bdff,
1981  0x00180000, 0x0000c5ff, 0x08180000, 0x0020c5ff,
1982  0x10180000, 0x0040c5ff, 0x18180000, 0x0061c5ff,
1983  0x20180000, 0x0081c5ff, 0x29180000, 0x00a1c5ff,
1984  0x31180000, 0x00c2c5ff, 0x39180000, 0x00e2c5ff,
1985  0x41180000, 0x0000cdff, 0x4a180000, 0x0020cdff,
1986  0x52180000, 0x0040cdff, 0x5a180000, 0x0061cdff,
1987  0x62180000, 0x0081cdff, 0x6a180000, 0x00a1cdff,
1988  0x73180000, 0x00c2cdff, 0x7b180000, 0x00e2cdff,
1989  0x83180000, 0x0000d5ff, 0x8b180000, 0x0020d5ff,
1990  0x94180000, 0x0040d5ff, 0x9c180000, 0x0061d5ff,
1991  0xa4180000, 0x0081d5ff, 0xac180000, 0x00a1d5ff,
1992  0xb4180000, 0x00c2d5ff, 0xbd180000, 0x00e2d5ff,
1993  0xc5180000, 0x0000deff, 0xcd180000, 0x0020deff,
1994  0xd5180000, 0x0040deff, 0xde180000, 0x0061deff,
1995  0xe6180000, 0x0081deff, 0xee180000, 0x00a1deff,
1996  0xf6180000, 0x00c2deff, 0xff180000, 0x00e2deff,
1997  0x001c0000, 0x0000e6ff, 0x081c0000, 0x0020e6ff,
1998  0x101c0000, 0x0040e6ff, 0x181c0000, 0x0061e6ff,
1999  0x201c0000, 0x0081e6ff, 0x291c0000, 0x00a1e6ff,
2000  0x311c0000, 0x00c2e6ff, 0x391c0000, 0x00e2e6ff,
2001  0x411c0000, 0x0000eeff, 0x4a1c0000, 0x0020eeff,
2002  0x521c0000, 0x0040eeff, 0x5a1c0000, 0x0061eeff,
2003  0x621c0000, 0x0081eeff, 0x6a1c0000, 0x00a1eeff,
2004  0x731c0000, 0x00c2eeff, 0x7b1c0000, 0x00e2eeff,
2005  0x831c0000, 0x0000f6ff, 0x8b1c0000, 0x0020f6ff,
2006  0x941c0000, 0x0040f6ff, 0x9c1c0000, 0x0061f6ff,
2007  0xa41c0000, 0x0081f6ff, 0xac1c0000, 0x00a1f6ff,
2008  0xb41c0000, 0x00c2f6ff, 0xbd1c0000, 0x00e2f6ff,
2009  0xc51c0000, 0x0000ffff, 0xcd1c0000, 0x0020ffff,
2010  0xd51c0000, 0x0040ffff, 0xde1c0000, 0x0061ffff,
2011  0xe61c0000, 0x0081ffff, 0xee1c0000, 0x00a1ffff,
2012  0xf61c0000, 0x00c2ffff, 0xff1c0000, 0x00e2ffff
2013 };
2014 
2015 static void
2017 {
2019 }
2020 
2021 static void
2023 {
2024 #ifndef USE_DUFFS_LOOP
2025  int c;
2026 #endif
2027  int width, height;
2028  Uint8 *src;
2029  const Uint8 *map;
2030  Uint8 *dst;
2031  int srcskip, dstskip;
2032  int srcbpp;
2033  Uint32 Pixel;
2034  int sR, sG, sB;
2035  SDL_PixelFormat *srcfmt;
2036 
2037  /* Set up some basic variables */
2038  width = info->dst_w;
2039  height = info->dst_h;
2040  src = info->src;
2041  srcskip = info->src_skip;
2042  dst = info->dst;
2043  dstskip = info->dst_skip;
2044  map = info->table;
2045  srcfmt = info->src_fmt;
2046  srcbpp = srcfmt->BytesPerPixel;
2047 
2048  if (map == NULL) {
2049  while (height--) {
2050 #ifdef USE_DUFFS_LOOP
2051  /* *INDENT-OFF* */
2052  DUFFS_LOOP(
2053  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
2054  sR, sG, sB);
2055  if ( 1 ) {
2056  /* Pack RGB into 8bit pixel */
2057  *dst = ((sR>>5)<<(3+2))|
2058  ((sG>>5)<<(2)) |
2059  ((sB>>6)<<(0)) ;
2060  }
2061  dst++;
2062  src += srcbpp;
2063  , width);
2064  /* *INDENT-ON* */
2065 #else
2066  for (c = width; c; --c) {
2067  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
2068  if (1) {
2069  /* Pack RGB into 8bit pixel */
2070  *dst = ((sR >> 5) << (3 + 2)) |
2071  ((sG >> 5) << (2)) | ((sB >> 6) << (0));
2072  }
2073  dst++;
2074  src += srcbpp;
2075  }
2076 #endif
2077  src += srcskip;
2078  dst += dstskip;
2079  }
2080  } else {
2081  while (height--) {
2082 #ifdef USE_DUFFS_LOOP
2083  /* *INDENT-OFF* */
2084  DUFFS_LOOP(
2085  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
2086  sR, sG, sB);
2087  if ( 1 ) {
2088  /* Pack RGB into 8bit pixel */
2089  *dst = map[((sR>>5)<<(3+2))|
2090  ((sG>>5)<<(2)) |
2091  ((sB>>6)<<(0)) ];
2092  }
2093  dst++;
2094  src += srcbpp;
2095  , width);
2096  /* *INDENT-ON* */
2097 #else
2098  for (c = width; c; --c) {
2099  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
2100  if (1) {
2101  /* Pack RGB into 8bit pixel */
2102  *dst = map[((sR >> 5) << (3 + 2)) |
2103  ((sG >> 5) << (2)) | ((sB >> 6) << (0))];
2104  }
2105  dst++;
2106  src += srcbpp;
2107  }
2108 #endif /* USE_DUFFS_LOOP */
2109  src += srcskip;
2110  dst += dstskip;
2111  }
2112  }
2113 }
2114 
2115 /* blits 32 bit RGB<->RGBA with both surfaces having the same R,G,B fields */
2116 static void
2118 {
2119  int width = info->dst_w;
2120  int height = info->dst_h;
2121  Uint32 *src = (Uint32 *) info->src;
2122  int srcskip = info->src_skip;
2123  Uint32 *dst = (Uint32 *) info->dst;
2124  int dstskip = info->dst_skip;
2125  SDL_PixelFormat *srcfmt = info->src_fmt;
2126  SDL_PixelFormat *dstfmt = info->dst_fmt;
2127 
2128  if (dstfmt->Amask) {
2129  /* RGB->RGBA, SET_ALPHA */
2130  Uint32 mask = (info->a >> dstfmt->Aloss) << dstfmt->Ashift;
2131 
2132  while (height--) {
2133  /* *INDENT-OFF* */
2134  DUFFS_LOOP(
2135  {
2136  *dst = *src | mask;
2137  ++dst;
2138  ++src;
2139  },
2140  width);
2141  /* *INDENT-ON* */
2142  src = (Uint32 *) ((Uint8 *) src + srcskip);
2143  dst = (Uint32 *) ((Uint8 *) dst + dstskip);
2144  }
2145  } else {
2146  /* RGBA->RGB, NO_ALPHA */
2147  Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
2148 
2149  while (height--) {
2150  /* *INDENT-OFF* */
2151  DUFFS_LOOP(
2152  {
2153  *dst = *src & mask;
2154  ++dst;
2155  ++src;
2156  },
2157  width);
2158  /* *INDENT-ON* */
2159  src = (Uint32 *) ((Uint8 *) src + srcskip);
2160  dst = (Uint32 *) ((Uint8 *) dst + dstskip);
2161  }
2162  }
2163 }
2164 
2165 /* blits 32 bit RGBA<->RGBA with both surfaces having the same R,G,B,A fields */
2166 static void
2168 {
2169  int width = info->dst_w;
2170  int height = info->dst_h;
2171  Uint32 *src = (Uint32 *) info->src;
2172  int srcskip = info->src_skip;
2173  Uint32 *dst = (Uint32 *) info->dst;
2174  int dstskip = info->dst_skip;
2175 
2176  /* RGBA->RGBA, COPY_ALPHA */
2177  while (height--) {
2178  /* *INDENT-OFF* */
2179  DUFFS_LOOP(
2180  {
2181  *dst = *src;
2182  ++dst;
2183  ++src;
2184  },
2185  width);
2186  /* *INDENT-ON* */
2187  src = (Uint32 *) ((Uint8 *) src + srcskip);
2188  dst = (Uint32 *) ((Uint8 *) dst + dstskip);
2189  }
2190 }
2191 
2192 static void
2194 {
2195  int width = info->dst_w;
2196  int height = info->dst_h;
2197  Uint8 *src = info->src;
2198  int srcskip = info->src_skip;
2199  Uint8 *dst = info->dst;
2200  int dstskip = info->dst_skip;
2201  SDL_PixelFormat *srcfmt = info->src_fmt;
2202  int srcbpp = srcfmt->BytesPerPixel;
2203  SDL_PixelFormat *dstfmt = info->dst_fmt;
2204  int dstbpp = dstfmt->BytesPerPixel;
2205  unsigned alpha = dstfmt->Amask ? info->a : 0;
2206 
2207  while (height--) {
2208  /* *INDENT-OFF* */
2209  DUFFS_LOOP(
2210  {
2211  Uint32 Pixel;
2212  unsigned sR;
2213  unsigned sG;
2214  unsigned sB;
2215  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
2216  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
2217  dst += dstbpp;
2218  src += srcbpp;
2219  },
2220  width);
2221  /* *INDENT-ON* */
2222  src += srcskip;
2223  dst += dstskip;
2224  }
2225 }
2226 
2227 static void
2229 {
2230  int width = info->dst_w;
2231  int height = info->dst_h;
2232  Uint8 *src = info->src;
2233  int srcskip = info->src_skip;
2234  Uint8 *dst = info->dst;
2235  int dstskip = info->dst_skip;
2236  SDL_PixelFormat *srcfmt = info->src_fmt;
2237  int srcbpp = srcfmt->BytesPerPixel;
2238  SDL_PixelFormat *dstfmt = info->dst_fmt;
2239  int dstbpp = dstfmt->BytesPerPixel;
2240  int c;
2241 
2242  while (height--) {
2243  for (c = width; c; --c) {
2244  Uint32 Pixel;
2245  unsigned sR, sG, sB, sA;
2246  DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
2247  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
2248  dst += dstbpp;
2249  src += srcbpp;
2250  }
2251  src += srcskip;
2252  dst += dstskip;
2253  }
2254 }
2255 
2256 static void
2258 {
2259  int width = info->dst_w;
2260  int height = info->dst_h;
2261  Uint8 *src = info->src;
2262  int srcskip = info->src_skip;
2263  Uint8 *dst = info->dst;
2264  int dstskip = info->dst_skip;
2265  SDL_PixelFormat *srcfmt = info->src_fmt;
2266  const Uint8 *palmap = info->table;
2267  Uint32 ckey = info->colorkey;
2268  Uint32 rgbmask = ~srcfmt->Amask;
2269  int srcbpp;
2270  Uint32 Pixel;
2271  unsigned sR, sG, sB;
2272 
2273  /* Set up some basic variables */
2274  srcbpp = srcfmt->BytesPerPixel;
2275  ckey &= rgbmask;
2276 
2277  if (palmap == NULL) {
2278  while (height--) {
2279  /* *INDENT-OFF* */
2280  DUFFS_LOOP(
2281  {
2282  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
2283  sR, sG, sB);
2284  if ( (Pixel & rgbmask) != ckey ) {
2285  /* Pack RGB into 8bit pixel */
2286  *dst = (Uint8)(((sR>>5)<<(3+2))|
2287  ((sG>>5)<<(2)) |
2288  ((sB>>6)<<(0)));
2289  }
2290  dst++;
2291  src += srcbpp;
2292  },
2293  width);
2294  /* *INDENT-ON* */
2295  src += srcskip;
2296  dst += dstskip;
2297  }
2298  } else {
2299  while (height--) {
2300  /* *INDENT-OFF* */
2301  DUFFS_LOOP(
2302  {
2303  DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
2304  sR, sG, sB);
2305  if ( (Pixel & rgbmask) != ckey ) {
2306  /* Pack RGB into 8bit pixel */
2307  *dst = (Uint8)palmap[((sR>>5)<<(3+2))|
2308  ((sG>>5)<<(2)) |
2309  ((sB>>6)<<(0)) ];
2310  }
2311  dst++;
2312  src += srcbpp;
2313  },
2314  width);
2315  /* *INDENT-ON* */
2316  src += srcskip;
2317  dst += dstskip;
2318  }
2319  }
2320 }
2321 
2322 static void
2324 {
2325  int width = info->dst_w;
2326  int height = info->dst_h;
2327  Uint16 *srcp = (Uint16 *) info->src;
2328  int srcskip = info->src_skip;
2329  Uint16 *dstp = (Uint16 *) info->dst;
2330  int dstskip = info->dst_skip;
2331  Uint32 ckey = info->colorkey;
2332  Uint32 rgbmask = ~info->src_fmt->Amask;
2333 
2334  /* Set up some basic variables */
2335  srcskip /= 2;
2336  dstskip /= 2;
2337  ckey &= rgbmask;
2338 
2339  while (height--) {
2340  /* *INDENT-OFF* */
2341  DUFFS_LOOP(
2342  {
2343  if ( (*srcp & rgbmask) != ckey ) {
2344  *dstp = *srcp;
2345  }
2346  dstp++;
2347  srcp++;
2348  },
2349  width);
2350  /* *INDENT-ON* */
2351  srcp += srcskip;
2352  dstp += dstskip;
2353  }
2354 }
2355 
2356 static void
2358 {
2359  int width = info->dst_w;
2360  int height = info->dst_h;
2361  Uint8 *src = info->src;
2362  int srcskip = info->src_skip;
2363  Uint8 *dst = info->dst;
2364  int dstskip = info->dst_skip;
2365  Uint32 ckey = info->colorkey;
2366  SDL_PixelFormat *srcfmt = info->src_fmt;
2367  SDL_PixelFormat *dstfmt = info->dst_fmt;
2368  int srcbpp = srcfmt->BytesPerPixel;
2369  int dstbpp = dstfmt->BytesPerPixel;
2370  unsigned alpha = dstfmt->Amask ? info->a : 0;
2371  Uint32 rgbmask = ~srcfmt->Amask;
2372 
2373  /* Set up some basic variables */
2374  ckey &= rgbmask;
2375 
2376  /* Fastpath: same source/destination format, no Amask, bpp 32, loop is vectorized. ~10x faster */
2377  if (srcfmt->format == dstfmt->format &&
2378  (srcfmt->format == SDL_PIXELFORMAT_RGB888 || srcfmt->format == SDL_PIXELFORMAT_BGR888)) {
2379  Uint32 *src32 = (Uint32*)src;
2380  Uint32 *dst32 = (Uint32*)dst;
2381  srcskip /= sizeof(Uint32);
2382  dstskip /= sizeof(Uint32);
2383  while (height--) {
2384  /* *INDENT-OFF* */
2385  DUFFS_LOOP(
2386  {
2387  if (*src32 != ckey) {
2388  *dst32 = *src32;
2389  }
2390  ++src32;
2391  ++dst32;
2392  },
2393  width);
2394  /* *INDENT-ON* */
2395  src32 += srcskip;
2396  dst32 += dstskip;
2397  }
2398  return;
2399  }
2400 
2401  while (height--) {
2402  /* *INDENT-OFF* */
2403  DUFFS_LOOP(
2404  {
2405  Uint32 Pixel;
2406  unsigned sR;
2407  unsigned sG;
2408  unsigned sB;
2409  RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel);
2410  if ( (Pixel & rgbmask) != ckey ) {
2411  RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB);
2412  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
2413  }
2414  dst += dstbpp;
2415  src += srcbpp;
2416  },
2417  width);
2418  /* *INDENT-ON* */
2419  src += srcskip;
2420  dst += dstskip;
2421  }
2422 }
2423 
2424 static void
2426 {
2427  int width = info->dst_w;
2428  int height = info->dst_h;
2429  Uint8 *src = info->src;
2430  int srcskip = info->src_skip;
2431  Uint8 *dst = info->dst;
2432  int dstskip = info->dst_skip;
2433  Uint32 ckey = info->colorkey;
2434  SDL_PixelFormat *srcfmt = info->src_fmt;
2435  SDL_PixelFormat *dstfmt = info->dst_fmt;
2436  Uint32 rgbmask = ~srcfmt->Amask;
2437 
2438  Uint8 srcbpp;
2439  Uint8 dstbpp;
2440  Uint32 Pixel;
2441  unsigned sR, sG, sB, sA;
2442 
2443  /* Set up some basic variables */
2444  srcbpp = srcfmt->BytesPerPixel;
2445  dstbpp = dstfmt->BytesPerPixel;
2446  ckey &= rgbmask;
2447 
2448  /* Fastpath: same source/destination format, with Amask, bpp 32, loop is vectorized. ~10x faster */
2449  if (srcfmt->format == dstfmt->format &&
2450  (srcfmt->format == SDL_PIXELFORMAT_ARGB8888 ||
2451  srcfmt->format == SDL_PIXELFORMAT_ABGR8888 ||
2452  srcfmt->format == SDL_PIXELFORMAT_BGRA8888 ||
2453  srcfmt->format == SDL_PIXELFORMAT_RGBA8888)) {
2454  Uint32 *src32 = (Uint32*)src;
2455  Uint32 *dst32 = (Uint32*)dst;
2456  srcskip /= sizeof(Uint32);
2457  dstskip /= sizeof(Uint32);
2458  while (height--) {
2459  /* *INDENT-OFF* */
2460  DUFFS_LOOP(
2461  {
2462  if ((*src32 & rgbmask) != ckey) {
2463  *dst32 = *src32;
2464  }
2465  ++src32;
2466  ++dst32;
2467  },
2468  width);
2469  /* *INDENT-ON* */
2470  src32 += srcskip;
2471  dst32 += dstskip;
2472  }
2473  return;
2474  }
2475 
2476  while (height--) {
2477  /* *INDENT-OFF* */
2478  DUFFS_LOOP(
2479  {
2480  DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
2481  if ( (Pixel & rgbmask) != ckey ) {
2482  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
2483  }
2484  dst += dstbpp;
2485  src += srcbpp;
2486  },
2487  width);
2488  /* *INDENT-ON* */
2489  src += srcskip;
2490  dst += dstskip;
2491  }
2492 }
2493 
2494 /* Special optimized blit for ARGB 2-10-10-10 --> RGBA */
2495 static void
2497 {
2498  int width = info->dst_w;
2499  int height = info->dst_h;
2500  Uint8 *src = info->src;
2501  int srcskip = info->src_skip;
2502  Uint8 *dst = info->dst;
2503  int dstskip = info->dst_skip;
2504  SDL_PixelFormat *dstfmt = info->dst_fmt;
2505  int dstbpp = dstfmt->BytesPerPixel;
2506  Uint32 Pixel;
2507  unsigned sR, sG, sB, sA;
2508 
2509  while (height--) {
2510  /* *INDENT-OFF* */
2511  DUFFS_LOOP(
2512  {
2513  Pixel = *(Uint32 *)src;
2514  RGBA_FROM_ARGB2101010(Pixel, sR, sG, sB, sA);
2515  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
2516  dst += dstbpp;
2517  src += 4;
2518  },
2519  width);
2520  /* *INDENT-ON* */
2521  src += srcskip;
2522  dst += dstskip;
2523  }
2524 }
2525 
2526 /* Special optimized blit for RGBA --> ARGB 2-10-10-10 */
2527 static void
2529 {
2530  int width = info->dst_w;
2531  int height = info->dst_h;
2532  Uint8 *src = info->src;
2533  int srcskip = info->src_skip;
2534  Uint8 *dst = info->dst;
2535  int dstskip = info->dst_skip;
2536  SDL_PixelFormat *srcfmt = info->src_fmt;
2537  int srcbpp = srcfmt->BytesPerPixel;
2538  Uint32 Pixel;
2539  unsigned sR, sG, sB, sA;
2540 
2541  while (height--) {
2542  /* *INDENT-OFF* */
2543  DUFFS_LOOP(
2544  {
2545  DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
2546  ARGB2101010_FROM_RGBA(Pixel, sR, sG, sB, sA);
2547  *(Uint32 *)dst = Pixel;
2548  dst += 4;
2549  src += srcbpp;
2550  },
2551  width);
2552  /* *INDENT-ON* */
2553  src += srcskip;
2554  dst += dstskip;
2555  }
2556 }
2557 
2558 /* Normal N to N optimized blitters */
2559 #define NO_ALPHA 1
2560 #define SET_ALPHA 2
2561 #define COPY_ALPHA 4
2563 {
2565  int dstbpp;
2569  Uint32 alpha; /* bitwise NO_ALPHA, SET_ALPHA, COPY_ALPHA */
2570 };
2571 static const struct blit_table normal_blit_1[] = {
2572  /* Default for 8-bit RGB source, never optimized */
2573  {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
2574 };
2575 
2576 static const struct blit_table normal_blit_2[] = {
2577 #if SDL_ALTIVEC_BLITTERS
2578  /* has-altivec */
2579  {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
2580  BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
2581  {0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
2582  BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
2583 #endif
2584 #if SDL_ARM_SIMD_BLITTERS
2585  {0x00000F00, 0x000000F0, 0x0000000F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
2586  BLIT_FEATURE_HAS_ARM_SIMD, Blit_RGB444_RGB888ARMSIMD, NO_ALPHA | COPY_ALPHA},
2587 #endif
2588  {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
2590  {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
2592  {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000, 0x0000FF00,
2594  {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000,
2596 
2597  /* Default for 16-bit RGB source, used if no other blitter matches */
2598  {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
2599 };
2600 
2601 static const struct blit_table normal_blit_3[] = {
2602  /* Default for 24-bit RGB source, never optimized */
2603  {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
2604 };
2605 
2606 static const struct blit_table normal_blit_4[] = {
2607 #if SDL_ALTIVEC_BLITTERS
2608  /* has-altivec | dont-use-prefetch */
2609  {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000,
2611  /* has-altivec */
2612  {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000,
2613  BLIT_FEATURE_HAS_ALTIVEC, ConvertAltivec32to32_prefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
2614  /* has-altivec */
2615  {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, 0x0000001F,
2616  BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB888_RGB565Altivec, NO_ALPHA},
2617 #endif
2618 #if SDL_ARM_SIMD_BLITTERS
2619  {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
2620  BLIT_FEATURE_HAS_ARM_SIMD, Blit_BGR888_RGB888ARMSIMD, NO_ALPHA | COPY_ALPHA },
2621 #endif
2622  {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, 0x0000001F,
2623  0, Blit_RGB888_RGB565, NO_ALPHA},
2624  {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, 0x0000001F,
2625  0, Blit_RGB888_RGB555, NO_ALPHA},
2626  /* Default for 32-bit RGB source, used if no other blitter matches */
2627  {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
2628 };
2629 
2630 static const struct blit_table *const normal_blit[] = {
2631  normal_blit_1, normal_blit_2, normal_blit_3, normal_blit_4
2632 };
2633 
2634 /* Mask matches table, or table entry is zero */
2635 #define MASKOK(x, y) (((x) == (y)) || ((y) == 0x00000000))
2636 
2639 {
2640  SDL_PixelFormat *srcfmt;
2641  SDL_PixelFormat *dstfmt;
2642  const struct blit_table *table;
2643  int which;
2644  SDL_BlitFunc blitfun;
2645 
2646  /* Set up data for choosing the blit */
2647  srcfmt = surface->format;
2648  dstfmt = surface->map->dst->format;
2649 
2650  /* We don't support destinations less than 8-bits */
2651  if (dstfmt->BitsPerPixel < 8) {
2652  return (NULL);
2653  }
2654 
2655  switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
2656  case 0:
2657  blitfun = NULL;
2658  if (dstfmt->BitsPerPixel == 8) {
2659  if ((srcfmt->BytesPerPixel == 4) &&
2660  (srcfmt->Rmask == 0x00FF0000) &&
2661  (srcfmt->Gmask == 0x0000FF00) &&
2662  (srcfmt->Bmask == 0x000000FF)) {
2663  blitfun = Blit_RGB888_index8;
2664  } else if ((srcfmt->BytesPerPixel == 4) &&
2665  (srcfmt->Rmask == 0x3FF00000) &&
2666  (srcfmt->Gmask == 0x000FFC00) &&
2667  (srcfmt->Bmask == 0x000003FF)) {
2668  blitfun = Blit_RGB101010_index8;
2669  } else {
2670  blitfun = BlitNto1;
2671  }
2672  } else {
2673  /* Now the meat, choose the blitter we want */
2674  int a_need = NO_ALPHA;
2675  if (dstfmt->Amask)
2676  a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA;
2677  table = normal_blit[srcfmt->BytesPerPixel - 1];
2678  for (which = 0; table[which].dstbpp; ++which) {
2679  if (MASKOK(srcfmt->Rmask, table[which].srcR) &&
2680  MASKOK(srcfmt->Gmask, table[which].srcG) &&
2681  MASKOK(srcfmt->Bmask, table[which].srcB) &&
2682  MASKOK(dstfmt->Rmask, table[which].dstR) &&
2683  MASKOK(dstfmt->Gmask, table[which].dstG) &&
2684  MASKOK(dstfmt->Bmask, table[which].dstB) &&
2685  dstfmt->BytesPerPixel == table[which].dstbpp &&
2686  (a_need & table[which].alpha) == a_need &&
2687  ((table[which].blit_features & GetBlitFeatures()) ==
2688  table[which].blit_features))
2689  break;
2690  }
2691  blitfun = table[which].blitfunc;
2692 
2693  if (blitfun == BlitNtoN) { /* default C fallback catch-all. Slow! */
2694  if (srcfmt->format == SDL_PIXELFORMAT_ARGB2101010) {
2695  blitfun = Blit2101010toN;
2696  } else if (dstfmt->format == SDL_PIXELFORMAT_ARGB2101010) {
2697  blitfun = BlitNto2101010;
2698  } else if (srcfmt->BytesPerPixel == 4 &&
2699  dstfmt->BytesPerPixel == 4 &&
2700  srcfmt->Rmask == dstfmt->Rmask &&
2701  srcfmt->Gmask == dstfmt->Gmask &&
2702  srcfmt->Bmask == dstfmt->Bmask) {
2703  if (a_need == COPY_ALPHA) {
2704  if (srcfmt->Amask == dstfmt->Amask) {
2705  /* Fastpath C fallback: 32bit RGBA<->RGBA blit with matching RGBA */
2706  blitfun = Blit4to4CopyAlpha;
2707  } else {
2708  blitfun = BlitNtoNCopyAlpha;
2709  }
2710  } else {
2711  /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */
2712  blitfun = Blit4to4MaskAlpha;
2713  }
2714  } else if (a_need == COPY_ALPHA) {
2715  blitfun = BlitNtoNCopyAlpha;
2716  }
2717  }
2718  }
2719  return (blitfun);
2720 
2721  case SDL_COPY_COLORKEY:
2722  /* colorkey blit: Here we don't have too many options, mostly
2723  because RLE is the preferred fast way to deal with this.
2724  If a particular case turns out to be useful we'll add it. */
2725 
2726  if (srcfmt->BytesPerPixel == 2 && surface->map->identity)
2727  return Blit2to2Key;
2728  else if (dstfmt->BytesPerPixel == 1)
2729  return BlitNto1Key;
2730  else {
2731 #if SDL_ALTIVEC_BLITTERS
2732  if ((srcfmt->BytesPerPixel == 4) && (dstfmt->BytesPerPixel == 4)
2733  && SDL_HasAltiVec()) {
2734  return Blit32to32KeyAltivec;
2735  } else
2736 #endif
2737  if (srcfmt->Amask && dstfmt->Amask) {
2738  return BlitNtoNKeyCopyAlpha;
2739  } else {
2740  return BlitNtoNKey;
2741  }
2742  }
2743  }
2744 
2745  return NULL;
2746 }
2747 
2748 /* vi: set ts=4 sw=4 expandtab: */
SDL_BlitFunc blitfunc
Definition: SDL_blit_N.c:2568
Uint8 * table
Definition: SDL_blit.h:67
#define SDL_HasAltiVec
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
Uint32 srcG
Definition: SDL_blit_N.c:2564
Uint32 srcB
Definition: SDL_blit_N.c:2564
static const struct blit_table normal_blit_2[]
Definition: SDL_blit_N.c:2576
static void Blit_RGB565_32(SDL_BlitInfo *info, const Uint32 *map)
Definition: SDL_blit_N.c:1406
#define MASKOK(x, y)
Definition: SDL_blit_N.c:2635
GLenum GLsizei GLenum GLenum const void * table
GLuint64EXT * result
#define SDL_COPY_COLORKEY
Definition: SDL_blit.h:39
int src_skip
Definition: SDL_blit.h:60
#define RETRIEVE_RGB_PIXEL(buf, bpp, Pixel)
Definition: SDL_blit.h:146
#define RGB888_RGB332(dst, src)
Definition: SDL_blit_N.c:931
GLenum GLenum dst
signed int int32_t
Uint32 dstB
Definition: SDL_blit_N.c:2566
Uint32 dstR
Definition: SDL_blit_N.c:2566
unsigned short uint16_t
#define RGB888_RGB565(dst, src)
Definition: SDL_blit_N.c:1277
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
GLfloat GLfloat v1
#define NO_ALPHA
Definition: SDL_blit_N.c:2559
GLfloat GLfloat GLfloat GLfloat h
SDL_PixelFormat * src_fmt
Definition: SDL_blit.h:65
static void BlitNto2101010(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2528
EGLSurface surface
Definition: eglext.h:248
#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)
Definition: SDL_blit.h:402
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
static const Uint32 RGB565_RGBA8888_LUT[512]
Definition: SDL_blit_N.c:1746
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
uint16_t Uint16
Definition: SDL_stdinc.h:191
#define SDL_COPY_RLE_MASK
Definition: SDL_blit.h:44
#define RGBA_FROM_ARGB2101010(Pixel, r, g, b, a)
Definition: SDL_blit.h:346
static const struct blit_table normal_blit_3[]
Definition: SDL_blit_N.c:2601
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
int dst_skip
Definition: SDL_blit.h:64
static const Uint32 RGB565_ABGR8888_LUT[512]
Definition: SDL_blit_N.c:1608
GLenum src
enum blit_features blit_features
Definition: SDL_blit_N.c:2567
static void Blit_RGB565_ARGB8888(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1602
GLfloat GLfloat GLfloat alpha
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
Uint32 colorkey
Definition: SDL_blit.h:69
static const struct blit_table normal_blit_1[]
Definition: SDL_blit_N.c:2571
Uint8 * dst
Definition: SDL_blit.h:61
Uint32 srcR
Definition: SDL_blit_N.c:2564
static void BlitNtoNCopyAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2228
GLfloat GLfloat GLfloat v2
struct SDL_BlitMap * map
Definition: SDL_surface.h:88
static const Uint32 RGB565_ARGB8888_LUT[512]
Definition: SDL_blit_N.c:1470
static const Uint32 RGB565_BGRA8888_LUT[512]
Definition: SDL_blit_N.c:1884
#define SET_ALPHA
Definition: SDL_blit_N.c:2560
#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a)
Definition: SDL_blit.h:353
Uint32 dstG
Definition: SDL_blit_N.c:2566
GLuint64 key
Definition: gl2ext.h:2192
#define RGB101010_RGB332(dst, src)
Definition: SDL_blit_N.c:1041
static void Blit2to2Key(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2323
uint8_t Uint8
Definition: SDL_stdinc.h:179
#define RGB_FROM_PIXEL(Pixel, fmt, r, g, b)
Definition: SDL_blit.h:122
Uint8 BitsPerPixel
Definition: SDL_pixels.h:319
static void Blit4to4MaskAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2117
static const struct blit_table normal_blit_4[]
Definition: SDL_blit_N.c:2606
static void BlitNto1Key(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2257
GLenum GLint GLuint mask
#define DUFFS_LOOP(pixel_copy_increment, width)
Definition: SDL_blit.h:500
static void Blit_RGB888_index8(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:937
const GLubyte * c
GLubyte GLubyte GLubyte GLubyte w
static void Blit_RGB565_RGBA8888(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1878
#define SDL_sscanf
static void Blit_RGB565_BGRA8888(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2016
#define SDL_HasMMX
Uint8 * src
Definition: SDL_blit.h:57
SDL_PixelFormat * dst_fmt
Definition: SDL_blit.h:66
#define SDL_getenv
#define RGB565_32(dst, src, map)
Definition: SDL_blit_N.c:1404
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_Surface * dst
Definition: SDL_blit.h:88
#define NULL
Definition: begin_code.h:164
unsigned int uint32_t
SDL_PixelFormat * format
Definition: SDL_surface.h:72
static const struct blit_table *const normal_blit[]
Definition: SDL_blit_N.c:2630
static void BlitNtoNKey(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2357
#define COPY_ALPHA
Definition: SDL_blit_N.c:2561
static void Blit2101010toN(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2496
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2425
#define GetBlitFeatures()
Definition: SDL_blit_N.c:886
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface *surface)
Definition: SDL_blit_N.c:2638
void(* SDL_BlitFunc)(SDL_BlitInfo *info)
Definition: SDL_blit.h:73
Uint32 alpha
Definition: SDL_blit_N.c:2569
#define DISEMBLE_RGB(buf, bpp, fmt, Pixel, r, g, b)
Definition: SDL_blit.h:177
static void Blit_RGB101010_index8(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1047
#define ARGB2101010_FROM_RGBA(Pixel, r, g, b, a)
Definition: SDL_blit.h:253
blit_features
Definition: SDL_blit_N.c:32
static void Blit4to4CopyAlpha(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2167
static void BlitNtoN(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2193
#define RGBA_FROM_8888(Pixel, fmt, r, g, b, a)
Definition: SDL_blit.h:311
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint GLint GLint j2 GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum GLenum GLint *params GLenum GLenum GLint *params GLenum GLenum GLint *params GLenum GLenum GLfloat *params GLenum GLint GLenum GLenum GLvoid *pixels GLenum GLint GLenum GLint *params GLenum GLenum GLint *params GLenum GLsizei const GLvoid *pointer GLenum GLenum const GLint *params GLenum GLfloat GLfloat GLint GLint const GLfloat *points GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat *points GLint GLfloat GLfloat GLint GLfloat GLfloat v2 GLenum GLenum const GLint *params GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum map
Definition: SDL_glfuncs.h:290
GLfloat GLfloat GLfloat GLfloat v3
GLboolean GLboolean GLboolean GLboolean a
static void Blit_RGB565_ABGR8888(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1740
GLboolean GLboolean g
GLboolean GLboolean GLboolean b
int identity
Definition: SDL_blit.h:89
static void Blit_RGB888_RGB555(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1167
SDL_BlitInfo info
Definition: SDL_blit.h:92
static void Blit_RGB888_RGB565(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:1293
#define RGB888_RGB555(dst, src)
Definition: SDL_blit_N.c:1151
Uint8 a
Definition: SDL_blit.h:70
static void BlitNto1(SDL_BlitInfo *info)
Definition: SDL_blit_N.c:2022