SDL_blit_N.c 108 KB

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