blit_arm_yuv.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:19k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: blit_arm_yuv.c 375 2005-12-02 09:34:27Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common.h"
  24. #include "../dyncode/dyncode.h"
  25. #include "blit_soft.h"
  26. // DstAlignSize 8
  27. // DstAlignPos  8
  28. // SrcAlignPos  8
  29. #if defined(ARM) 
  30. // R0..R4 temporary
  31. // R5 DiffMask (when Diff)
  32. // R6 Src2SrcLast (when Diff)
  33. // R5 7F7F7F7F (when !Diff and HalfY and !HalfX)
  34. // R7 Src
  35. // R8 MaskCarry (when Brightness != 0)
  36. // R9 Add32 (when Brightness != 0)
  37. // R10 EndOfLine (Src)
  38. // R11 Dst
  39. // R12 DstPitch
  40. // R14 SrcPitch
  41. typedef struct stack
  42. {
  43. int Dst[3];
  44. int Src[3];
  45. int EndOfRect;
  46. int DstNext[2]; 
  47. int SrcNext[2];
  48. int SaveR0;
  49. int StackFrame[STACKFRAME];
  50. //void* this   R0
  51. //char* Dst    R1
  52. //char* Src    R2
  53. //int DstPitch R3 can be signed
  54. int SrcPitch;
  55. int Width; 
  56. int Height;
  57. int Src2SrcLast;
  58. } stack;
  59. static void NOINLINE SetDither(blit_soft* p,int Pos,int Part,int Plane)
  60. {
  61. if (Plane==0 && (p->FX.Flags & BLITFX_DITHER) && p->SrcYUV)
  62. {
  63. // dither matrix:
  64. // 0 2
  65. // 3 1
  66. int Ofs;
  67. if (Pos & 8)
  68. Ofs = Part?2:0;
  69. else
  70. Ofs = Part?1:3;
  71. if (Ofs != p->LookUpOfs)
  72. {
  73. I2C(ADD,R8,R8,Ofs-p->LookUpOfs);
  74. p->LookUpOfs = Ofs;
  75. }
  76. }
  77. }
  78. static NOINLINE int YUV_4(blit_soft* p, int Reg,int Pos,int Plane)
  79. {
  80. reg RA = (reg)Reg;
  81. reg RB = R4;
  82. reg RC = R0;
  83. reg RD = R9;
  84. if (p->SwapXY)
  85. {
  86. if (Reg != R0)
  87. {
  88. if (!p->SrcYUV || (Plane!=0 && (p->HalfX || p->HalfY)))
  89. I2C(LDR,R0,SP,OFS(stack,SaveR0));
  90. else
  91. I2(LDR,R0,R7);
  92. }
  93. if (p->LookUp)
  94. {
  95. I2C(AND,RB,R2,0xFF << Pos);
  96. I2C(AND,RC,R0,0xFF << Pos);
  97. SetDither(p,Pos,1,Plane);
  98. Byte(); I3S(LDR,RB,R8,RB,LSR,Pos);
  99. I2C(AND,RD,R1,0xFF << Pos);
  100. Byte(); I3S(LDR,RC,R8,RC,LSR,Pos);
  101. I3S(MOV,RB,NONE,RB,LSR,-(p->DirX<0?8:16));
  102. I3S(ORR,RB,RB,RC,LSR,-(p->DirX<0?24:0));
  103. I2C(AND,RC,R3,0xFF << Pos);
  104. SetDither(p,Pos,0,Plane);
  105. Byte(); I3S(LDR,RD,R8,RD,LSR,Pos);
  106. Byte(); I3S(LDR,RC,R8,RC,LSR,Pos);
  107. I3S(ORR,RB,RB,RD,LSR,-(p->DirX<0?16:8));
  108. I3S(ORR,RB,RB,RC,LSR,-(p->DirX<0?0:24));
  109. }
  110. else
  111. {
  112. I2C(AND,RB,R2,0xFF << Pos);
  113. I3S(MOV,RB,NONE,RB,LSR,Pos-(p->DirX<0?8:16));
  114. I2C(AND,RC,R0,0xFF << Pos);
  115. I3S(ORR,RB,RB,RC,LSR,Pos-(p->DirX<0?24:0));
  116. I2C(AND,RC,R1,0xFF << Pos);
  117. I3S(ORR,RB,RB,RC,LSR,Pos-(p->DirX<0?16:8));
  118. I2C(AND,RC,R3,0xFF << Pos);
  119. I3S(ORR,RB,RB,RC,LSR,Pos-(p->DirX<0?0:24));
  120. }
  121. RA=RB;
  122. }
  123. else
  124. if (p->DirX<0)
  125. {
  126. if (p->LookUp)
  127. {
  128. I2C(AND,RB,RA,0xFF00);
  129. SetDither(p,Pos,1,Plane);
  130. Byte(); I3S(LDR,RD,R8,RA,LSR,24);
  131. Byte(); I3S(LDR,RB,R8,RB,LSR,8);
  132. I3S(MOV,RA,NONE,RA,ROR,24);
  133. I3S(ORR,RD,RD,RB,LSL,16);
  134. SetDither(p,Pos,0,Plane);
  135. Byte(); I3S(LDR,RB,R8,RA,LSR,24);
  136. I2C(AND,RA,RA,0xFF00);
  137. Byte(); I3S(LDR,RA,R8,RA,LSR,8);
  138. I3S(ORR,RD,RD,RB,LSL,8);
  139. I3S(ORR,RD,RD,RA,LSL,24);
  140. RA = RD;
  141. }
  142. else
  143. if (RA == RC)
  144. {
  145. // only RA and RB
  146. I3S(MOV,RB,NONE,RA,LSR,24);
  147. I3S(ORR,RB,RB,RA,LSL,24);
  148. I3S(MOV,RA,NONE,RA,ROR,16);
  149. I3S(MOV,RB,NONE,RB,ROR,16);
  150. I3S(ORR,RB,RB,RA,LSR,24);
  151. I3S(ORR,RB,RB,RA,LSL,24);
  152. I3S(MOV,RA,NONE,RB,ROR,16);
  153. }
  154. else
  155. {
  156. I2C(AND,RC,RA,0xFF00);
  157. I3S(MOV,RB,NONE,RA,LSL,24);
  158. I3S(ORR,RB,RB,RC,LSL,8);
  159. I2C(AND,RC,RA,0xFF0000);
  160. I3S(ORR,RB,RB,RA,LSR,24);
  161. I3S(ORR,RA,RB,RC,LSR,8);
  162. }
  163. }
  164. else
  165. {
  166. if (p->LookUp)
  167. {
  168. I2C(AND,RB,RA,0xFF00);
  169. SetDither(p,Pos,1,Plane);
  170. Byte(); I3S(LDR,RD,R8,RA,LSR,24);
  171. Byte(); I3S(LDR,RB,R8,RB,LSR,8);
  172. I3S(MOV,RA,NONE,RA,ROR,24);
  173. I3S(ORR,RB,RB,RD,LSL,16);
  174. SetDither(p,Pos,0,Plane);
  175. Byte(); I3S(LDR,RD,R8,RA,LSR,24);
  176. I2C(AND,RA,RA,0xFF00);
  177. Byte(); I3S(LDR,RA,R8,RA,LSR,8);
  178. I3S(ORR,RB,RB,RD,LSL,8);
  179. I3S(ORR,RA,RA,RB,LSL,8);
  180. }
  181. else
  182. {
  183. RB = R0;
  184. RC = R4;
  185. }
  186. }
  187. if (Plane==0 && p->FX.Brightness && !p->LookUp && p->SrcYUV)
  188. {
  189. if (p->FX.Brightness < 0)
  190. {
  191. I3(MVN,RB,NONE,RA);
  192. RA=RB;
  193. }
  194. I3(ADD,RC,RA,R9); //add32
  195. I3(BIC,RB,RA,RC);
  196. I3(AND,RB,RB,R8); //maskcarry
  197. I3S(MOV,RB,NONE,RB,LSR,7);
  198. I3S(SUB,RC,RC,RB,LSL,8);
  199. I3S(RSB,RB,RB,RB,LSL,8);
  200. I3(ORR,RB,RB,RC);
  201. if (p->FX.Brightness < 0)
  202. I3(MVN,RB,NONE,RB);
  203. RA=RB;
  204. }
  205. return RA;
  206. }
  207. static NOINLINE void YUV_4X4(blit_soft* p, int Plane)
  208. {
  209. int y;
  210. int UV = Plane != 0;
  211. int Rows = 2;
  212. int HalfX = UV ? p->HalfX:0;
  213. int HalfY = UV ? p->HalfY:0;
  214. int SrcUVX = UV?p->SrcUVX2:0;
  215. int SrcUVPitch = UV?p->SrcUVPitch2:0;
  216. int DstUVPitch = UV?p->DstUVPitch2:0;
  217. if (UV) Rows >>= p->SrcUVY2+p->HalfY;
  218. I2C(LDR,R7,SP,OFS(stack,Src[Plane]));
  219. I2C(LDR,R11,SP,OFS(stack,Dst[Plane]));
  220. for (y=0;y<Rows;++y)
  221. {
  222. reg RA,RWidth=R0;
  223. dyninst* LoopX = Label(0);
  224. MB(); I2C(LDR,R0,SP,OFS(stack,Width));
  225. if (p->SrcBPP2>0)
  226. {
  227. IMul(R1,R0,p->SrcBPP/8);
  228. RWidth = R1;
  229. }
  230. I3S(ADD,R10,R7,RWidth,LSR,SrcUVX); //end of line
  231. //preload
  232. if (!p->Slices)
  233. {
  234. dyninst* PreLoad1;
  235. dyninst* PreLoad2;
  236. dyninst* PreLoad3;
  237. dyninst* PreLoad4;
  238. I2C(ADD,R0,R7,32);
  239. I3(CMP,NONE,R0,R10);
  240. I0P(B,CS,LoopX);
  241. PreLoad1 = Label(1);
  242. Byte(); I2C(LDR,R2,R0,-32);
  243. I2C(ADD,R0,R0,64);
  244. I3(CMP,NONE,R0,R10);
  245. Byte(); I2C(LDR,R3,R0,-64);
  246. I0P(B,CC,PreLoad1);
  247. I3S(ADD,R7,R7,R14,ASR,SrcUVPitch-1);
  248. I3S(ADD,R10,R10,R14,ASR,SrcUVPitch-1);
  249. I2C(ADD,R0,R7,32);
  250. PreLoad2 = Label(1);
  251. Byte(); I2C(LDR,R2,R0,-32);
  252. I2C(ADD,R0,R0,64);
  253. I3(CMP,NONE,R0,R10);
  254. Byte(); I2C(LDR,R3,R0,-64);
  255. I0P(B,CC,PreLoad2);
  256. I3S(ADD,R7,R7,R14,ASR,SrcUVPitch);
  257. I3S(ADD,R10,R10,R14,ASR,SrcUVPitch);
  258. I2C(ADD,R0,R7,32);
  259. PreLoad3 = Label(1);
  260. Byte(); I2C(LDR,R2,R0,-32);
  261. I2C(ADD,R0,R0,64);
  262. I3(CMP,NONE,R0,R10);
  263. Byte(); I2C(LDR,R3,R0,-64);
  264. I0P(B,CC,PreLoad3);
  265. I3S(SUB,R7,R7,R14,ASR,SrcUVPitch-1);
  266. I3S(SUB,R10,R10,R14,ASR,SrcUVPitch-1);
  267. I2C(ADD,R0,R7,32);
  268. PreLoad4 = Label(1);
  269. Byte(); I2C(LDR,R2,R0,-32);
  270. I2C(ADD,R0,R0,64);
  271. I3(CMP,NONE,R0,R10);
  272. Byte(); I2C(LDR,R3,R0,-64);
  273. I0P(B,CC,PreLoad4);
  274. I3S(SUB,R7,R7,R14,ASR,SrcUVPitch);
  275. I3S(SUB,R10,R10,R14,ASR,SrcUVPitch);
  276. }
  277. else
  278. if (p->ARM5)
  279. {
  280. //preload next
  281. I3S(ADD,R0,R7,R14,ASR,SrcUVPitch-2);
  282. I3S(ADD,R1,R0,R14,ASR,SrcUVPitch-1);
  283. I2(PLD,NONE,R0);
  284. I2(PLD,NONE,R1);
  285. I3S(PLD,NONE,R0,R14,ASR,SrcUVPitch);
  286. I3S(PLD,NONE,R1,R14,ASR,SrcUVPitch);
  287. }
  288. InstPost(LoopX);
  289. if (p->RealOnlyDiff)
  290. {
  291. p->Skip = Label(0);
  292. I3(LDR,R4,R7,R6);
  293. I3S(LDR_POST,R0,R7,R14,ASR,SrcUVPitch-1);
  294. I3(LDR,R1,R7,R6);
  295. I3S(LDR_POST,R2,R7,R14,ASR,SrcUVPitch);
  296. I3(EOR,R4,R4,R0);
  297. S(); I3(BIC,R4,R4,R5);
  298. I3(LDR,R0,R7,R6);
  299. I3S(LDR_POSTSUB,R3,R7,R14,ASR,SrcUVPitch-1);
  300. I3(EOR,R1,R1,R2);
  301. S(); C(EQ); I3(BIC,R1,R1,R5);
  302. I3(LDR,R4,R7,R6);
  303. I3S(LDR_POSTSUB,R1,R7,R14,ASR,SrcUVPitch);
  304. I3(EOR,R0,R0,R3);
  305. S(); C(EQ); I3(BIC,R0,R0,R5);
  306. I2(LDR,R0,R7);
  307. I3(EOR,R4,R4,R1);
  308. S(); C(EQ); I3(BIC,R4,R4,R5);
  309. I0P(B,EQ,p->Skip);
  310. }
  311. else
  312. if (!p->SrcYUV && !p->LookUp)
  313. {
  314. int x,y;
  315. // r0,r2,r3,r1 (tmp r4,r5,r6)
  316. for (y=0;y<4;++y)
  317. {
  318. reg Out;
  319. switch (y)
  320. {
  321. case 1: Out = R1; break;
  322. case 2: Out = R2; break;
  323. case 3: Out = R3; break;
  324. default:Out = R0; break;
  325. }
  326. for (x=0;x<4;++x)
  327. {
  328. reg Val = (reg)(x?R4:Out);
  329. int ofs = ((p->SrcBPP/8) << HalfX)*x;
  330. switch (p->SrcBPP)
  331. {
  332. // 8bit handled by lookup (with normal YUV blitting)
  333. case 16:
  334. Half(); I2C(LDR,R4,R7,ofs);
  335. I2C(MOV,R5,NONE,((1 << p->SrcSize[1])-1) << (8-p->SrcSize[1]));
  336. I2C(MOV,R6,NONE,((1 << p->SrcSize[2])-1) << (8-p->SrcSize[2]));
  337. I3S(AND,R5,R5,R4,LSR,p->SrcPos[1]+p->SrcSize[1]-8);
  338. I3S(AND,R6,R6,R4,LSR,p->SrcPos[2]+p->SrcSize[2]-8);
  339. I2C(AND,R4,R4,p->Src.BitMask[0]);
  340. I3S(MOV,R4,NONE,R4,LSR,p->SrcPos[0]+p->SrcSize[0]-8);
  341. break;
  342. case 24:
  343. case 32:
  344. Byte(); I2C(LDR,R6,R7,ofs+(p->SrcPos[2]>>3));
  345. Byte(); I2C(LDR,R4,R7,ofs+(p->SrcPos[0]>>3));
  346. Byte(); I2C(LDR,R5,R7,ofs+(p->SrcPos[1]>>3));
  347. break;
  348. }
  349. // R4,R5,R6 r,g,b
  350. // Y = (2105*R + 4128*G + 802*B)/0x2000 + 16;
  351. // U = (-1212*R - 2384*G + 3596*B)/0x2000 + 128;
  352. // V = (3596*R - 3015*G - 582*B)/0x2000 + 128;
  353. switch (Plane)
  354. {
  355. case 0:
  356. // Y = (8*R + 16*G + 3*B)/32 + 16;
  357. I3S(ADD,R6,R6,R6,LSL,1);
  358. I3S(ADD,R4,R6,R4,LSL,3);
  359. I3S(ADD,R4,R4,R5,LSL,4);
  360. I3S(MOV,R4,NONE,R4,ASR,5);
  361. S(); I2C(ADD,Val,R4,16+p->FX.Brightness);
  362. if (p->FX.Brightness+16<0)
  363. C(MI);I2C(MOV,Val,NONE,0x00); 
  364. }
  365. if (p->FX.Brightness+16+215>=255)
  366. {
  367. I2C(CMP,NONE,Val,0xFF);
  368. C(GT);I2C(MOV,Val,NONE,0xFF);
  369. }
  370. break;
  371. case 1:
  372. // U = (-5*R - 9*G + 14*B)/32 + 128;
  373. I3S(RSB,R6,R6,R6,LSL,3);
  374. I3(ADD,R6,R6,R6);
  375. I3S(ADD,R4,R4,R4,LSL,2);
  376. I3S(ADD,R5,R5,R5,LSL,3);
  377. I3(SUB,R4,R6,R4);
  378. I3(SUB,R4,R4,R5);
  379. I3S(MOV,R4,NONE,R4,ASR,5);
  380. I2C(ADD,Val,R4,128);
  381. break;
  382. case 2:
  383. // V = (14*R - 12*G - 2*B)/32 + 128;
  384. I3(ADD,R6,R6,R6);
  385. I3S(RSB,R4,R4,R4,LSL,3);
  386. I3S(ADD,R5,R5,R5,LSL,1);
  387. I3S(RSB,R4,R6,R4,LSL,1);
  388. I3S(SUB,R4,R4,R5,LSL,2);
  389. I3S(MOV,R4,NONE,R4,ASR,5);
  390. I2C(ADD,Val,R4,128);
  391. break;
  392. }
  393. if (x>0)
  394. I3S(ORR,Out,Out,Val,LSL,x*8);
  395. }
  396. I3S(ADD,R7,R7,R14,ASR,SrcUVPitch-HalfY);
  397. }
  398. I3S(SUB,R7,R7,R14,ASR,SrcUVPitch-2-HalfY);
  399. }
  400. else
  401. {
  402. int mode = HalfX + 2*HalfY;
  403. int x = 2;
  404. if (!p->SrcYUV && mode==0)
  405. {
  406. //possible alignment problems...
  407. mode = 1;
  408. x = 1;
  409. }
  410. switch (mode)
  411. {
  412. case 0:
  413. I3S(LDR_POST,R0,R7,R14,ASR,SrcUVPitch-1);
  414. I3S(LDR_POST,R2,R7,R14,ASR,SrcUVPitch);
  415. I3S(LDR_POSTSUB,R3,R7,R14,ASR,SrcUVPitch-1);
  416. I3S(LDR_POSTSUB,R1,R7,R14,ASR,SrcUVPitch);
  417. break;
  418. case 1: // halfx (not average...)
  419. Byte(); I2C(LDR,R0,R7,3*x);
  420. Byte(); I2C(LDR,R4,R7,2*x);
  421. Byte(); I2C(LDR,R5,R7,1*x);
  422. Byte(); I3S(LDR_POST,R6,R7,R14,ASR,SrcUVPitch-1);
  423. I3S(ORR,R0,R4,R0,LSL,8);
  424. I3S(ORR,R0,R5,R0,LSL,8);
  425. I3S(ORR,R0,R6,R0,LSL,8);
  426. Byte(); I2C(LDR,R2,R7,3*x);
  427. Byte(); I2C(LDR,R4,R7,2*x);
  428. Byte(); I2C(LDR,R5,R7,1*x);
  429. Byte(); I3S(LDR_POST,R6,R7,R14,ASR,SrcUVPitch);
  430. I3S(ORR,R2,R4,R2,LSL,8);
  431. I3S(ORR,R2,R5,R2,LSL,8);
  432. I3S(ORR,R2,R6,R2,LSL,8);
  433. Byte(); I2C(LDR,R3,R7,3*x);
  434. Byte(); I2C(LDR,R4,R7,2*x);
  435. Byte(); I2C(LDR,R5,R7,1*x);
  436. Byte(); I3S(LDR_POSTSUB,R6,R7,R14,ASR,SrcUVPitch-1);
  437. I3S(ORR,R3,R4,R3,LSL,8);
  438. I3S(ORR,R3,R5,R3,LSL,8);
  439. I3S(ORR,R3,R6,R3,LSL,8);
  440. Byte(); I2C(LDR,R1,R7,3*x);
  441. Byte(); I2C(LDR,R4,R7,2*x);
  442. Byte(); I2C(LDR,R5,R7,1*x);
  443. Byte(); I3S(LDR_POSTSUB,R6,R7,R14,ASR,SrcUVPitch);
  444. I3S(ORR,R1,R4,R1,LSL,8);
  445. I3S(ORR,R1,R5,R1,LSL,8);
  446. I3S(ORR,R1,R6,R1,LSL,8);
  447. break;
  448. case 2: // halfy
  449. I3S(LDR,R4,R7,R14,ASR,SrcUVPitch);
  450. I3S(LDR_POST,R0,R7,R14,ASR,SrcUVPitch-1-1);
  451. I3S(LDR,R6,R7,R14,ASR,SrcUVPitch);
  452. I3S(LDR_POST,R2,R7,R14,ASR,SrcUVPitch-1);
  453. I3S(AND,R4,R5,R4,LSR,1);
  454. I3S(AND,R0,R5,R0,LSR,1);
  455. I3(ADD,R0,R0,R4);
  456. I3S(AND,R6,R5,R6,LSR,1);
  457. I3S(AND,R2,R5,R2,LSR,1);
  458. I3(ADD,R2,R2,R6);
  459. I3S(LDR,R4,R7,R14,ASR,SrcUVPitch);
  460. I3S(LDR_POSTSUB,R3,R7,R14,ASR,SrcUVPitch-1-1);
  461. I3S(LDR,R6,R7,R14,ASR,SrcUVPitch);
  462. I3S(LDR_POSTSUB,R1,R7,R14,ASR,SrcUVPitch-1);
  463. I3S(AND,R4,R5,R4,LSR,1);
  464. I3S(AND,R3,R5,R3,LSR,1);
  465. I3(ADD,R3,R3,R4);
  466. I3S(AND,R6,R5,R6,LSR,1);
  467. I3S(AND,R1,R5,R1,LSR,1);
  468. I3(ADD,R1,R1,R4);
  469. break;
  470. case 3: // halfx + halfy (no average..., used by palette mode as well)
  471. Byte(); I2C(LDR,R0,R7,6);
  472. Byte(); I2C(LDR,R4,R7,4);
  473. Byte(); I2C(LDR,R5,R7,2);
  474. Byte(); I3S(LDR_POST,R6,R7,R14,ASR,SrcUVPitch-1-1);
  475. I3S(ORR,R0,R4,R0,LSL,8);
  476. I3S(ORR,R0,R5,R0,LSL,8);
  477. I3S(ORR,R0,R6,R0,LSL,8);
  478. Byte(); I2C(LDR,R2,R7,6);
  479. Byte(); I2C(LDR,R4,R7,4);
  480. Byte(); I2C(LDR,R5,R7,2);
  481. Byte(); I3S(LDR_POST,R6,R7,R14,ASR,SrcUVPitch-1);
  482. I3S(ORR,R2,R4,R2,LSL,8);
  483. I3S(ORR,R2,R5,R2,LSL,8);
  484. I3S(ORR,R2,R6,R2,LSL,8);
  485. Byte(); I2C(LDR,R3,R7,6);
  486. Byte(); I2C(LDR,R4,R7,4);
  487. Byte(); I2C(LDR,R5,R7,2);
  488. Byte(); I3S(LDR_POSTSUB,R6,R7,R14,ASR,SrcUVPitch-1-1);
  489. I3S(ORR,R3,R4,R3,LSL,8);
  490. I3S(ORR,R3,R5,R3,LSL,8);
  491. I3S(ORR,R3,R6,R3,LSL,8);
  492. Byte(); I2C(LDR,R1,R7,6);
  493. Byte(); I2C(LDR,R4,R7,4);
  494. Byte(); I2C(LDR,R5,R7,2);
  495. Byte(); I3S(LDR_POSTSUB,R6,R7,R14,ASR,SrcUVPitch-1);
  496. I3S(ORR,R1,R4,R1,LSL,8);
  497. I3S(ORR,R1,R5,R1,LSL,8);
  498. I3S(ORR,R1,R6,R1,LSL,8);
  499. break;
  500. }
  501. }
  502. if (p->SwapXY && (HalfX || HalfY || !p->SrcYUV))
  503. I2C(STR,R0,SP,OFS(stack,SaveR0));
  504. RA = (reg)YUV_4(p,R0,0,Plane);
  505. I3S(STR_POST,RA,R11,R12,ASR,DstUVPitch-1);
  506. RA = (reg)YUV_4(p,R2,16,Plane);
  507. I3S(STR_POST,RA,R11,R12,ASR,DstUVPitch);
  508. RA = (reg)YUV_4(p,R3,24,Plane);
  509. I3S(STR_POSTSUB,RA,R11,R12,ASR,DstUVPitch-1);
  510. RA = (reg)YUV_4(p,R1,8,Plane);
  511. I3S(STR_POSTSUB,RA,R11,R12,ASR,DstUVPitch);
  512. if (p->LookUp && p->LookUpOfs)
  513. {
  514. I2C(SUB,R8,R8,p->LookUpOfs);
  515. p->LookUpOfs = 0;
  516. }
  517. if (p->RealOnlyDiff)
  518. InstPost(p->Skip);
  519. I2C(ADD,R7,R7,(4 << HalfX)*(p->SrcBPP/8));
  520. if (p->SwapXY)
  521. I3S(ADD,R11,R11,R12,ASR,DstUVPitch-2);
  522. else
  523. I2C(ADD,R11,R11,4*p->DirX);
  524. I3(CMP,NONE,R7,R10);
  525. I0P(B,NE,LoopX);
  526. I2C(LDR,R0,SP,OFS(stack,SrcNext[UV]));
  527. I2C(LDR,R1,SP,OFS(stack,DstNext[UV]));
  528. I3(ADD,R7,R7,R0);
  529. I3(ADD,R11,R11,R1);
  530. }
  531. I2C(STR,R7,SP,OFS(stack,Src[Plane]));
  532. I2C(STR,R11,SP,OFS(stack,Dst[Plane]));
  533. }
  534. void Fix_Any_YUV(blit_soft* p)
  535. {
  536. dyninst* Add32 = NULL;
  537. dyninst* MaskCarry = NULL;
  538. dyninst* LoopY;
  539. reg RSrcWidth;
  540. p->SrcAlignPos = p->DstAlignPos = p->DstAlignSize = 8;
  541. CodeBegin();
  542. I2C(SUB,SP,SP,OFS(stack,StackFrame));
  543. p->DiffMask = NULL;
  544. I2C(LDR,R6,R1,0);//Dst[0] U
  545. I2C(LDR,R7,R1,4);//Dst[1] V
  546. I2C(LDR,R8,R1,8);//Dst[2] Y
  547. I2C(LDR,R10,R2,0); //Src[0] U
  548. if (!p->SrcYUV)
  549. {
  550. I3(MOV,R11,NONE,R10);
  551. I3(MOV,R12,NONE,R10);
  552. p->SrcUVX2 = 0;
  553. p->SrcUVY2 = 0;
  554. p->SrcUVPitch2 = 0;
  555. p->Caps = VC_BRIGHTNESS;
  556. }
  557. else
  558. {
  559. I2C(LDR,R11,R2,4); //Src[1] V
  560. I2C(LDR,R12,R2,8); //Src[2] Y
  561. }
  562. if (p->DirX<0)
  563. {
  564. //adjust reversed destination for block size
  565. I2C(SUB,R6,R6,3);
  566. I2C(SUB,R7,R7,3);
  567. I2C(SUB,R8,R8,3);
  568. }
  569. I2C(STR,R6,SP,OFS(stack,Dst[0]));
  570. I2C(STR,R7,SP,OFS(stack,Dst[1]));
  571. I2C(STR,R8,SP,OFS(stack,Dst[2]));
  572. I2C(STR,R10,SP,OFS(stack,Src[0]));
  573. I2C(STR,R11,SP,OFS(stack,Src[1]));
  574. I2C(STR,R12,SP,OFS(stack,Src[2]));
  575. I3(MOV,R12,NONE,R3);  //DstPitch
  576. I2C(LDR,R14,SP,OFS(stack,SrcPitch));
  577. I2C(LDR,R2,SP,OFS(stack,Height));
  578. I2C(LDR,R1,SP,OFS(stack,Width));
  579. p->RealOnlyDiff = p->OnlyDiff;
  580. p->HalfX = (boolmem_t)(p->SrcUVX2+1 == p->DstUVX2);
  581. p->HalfY = (boolmem_t)(p->SrcUVY2+1 == p->DstUVY2);
  582. if (p->HalfX || p->HalfY)
  583. p->RealOnlyDiff = 0;
  584. if (p->RealOnlyDiff)
  585. {
  586. int Mask = 0x03030303;
  587. p->DiffMask = InstCreate32(Mask,NONE,NONE,NONE,0,0);
  588. I1P(LDR,R5,p->DiffMask,0);
  589. I2C(LDR,R6,SP,OFS(stack,Src2SrcLast));
  590. }
  591. else
  592. if ((p->HalfX + 2*p->HalfY)==2)
  593. {
  594. int Mask = 0x7F7F7F7F;
  595. p->DiffMask = InstCreate32(Mask,NONE,NONE,NONE,0,0);
  596. I1P(LDR,R5,p->DiffMask,0);
  597. }
  598. p->LookUp = NULL;
  599. if (p->SrcYUV)
  600. CalcYUVLookUp(p);
  601. else if (p->Src.Palette)
  602. CalcPalYUVLookUp(p);
  603. if (p->LookUp_Data)
  604. {
  605. p->LookUp = InstCreate(p->LookUp_Data,p->LookUp_Size,NONE,NONE,NONE,0,0);
  606. free(p->LookUp_Data);
  607. p->LookUp_Data = NULL;
  608. I1P(MOV,R8,p->LookUp,0);
  609. p->LookUpOfs = 0;
  610. }
  611. else
  612. if (p->FX.Brightness)
  613. {
  614. int i = p->FX.Brightness;
  615. if (i<0) i=-i;
  616. if (i>127) i=127;
  617. MaskCarry = InstCreate32(0x80808080U,NONE,NONE,NONE,0,0);
  618. Add32 = InstCreate32(0x01010101U * (uint8_t)i,NONE,NONE,NONE,0,0);
  619. I1P(LDR,R8,MaskCarry,0);
  620. I1P(LDR,R9,Add32,0);
  621. }
  622. //EndOfRect
  623. //DstNext[2] 
  624. //SrcNext[2]
  625. RSrcWidth = R1;
  626. if (p->SrcBPP2>0)
  627. {
  628. IMul(R3,R1,p->SrcBPP/8);
  629. RSrcWidth = R3;
  630. }
  631. //SrcYNext = 4*Src->Pitch - Width
  632. I3S(RSB,R0,RSrcWidth,R14,LSL,2); 
  633. I2C(STR,R0,SP,OFS(stack,SrcNext[0]));
  634. //SrcUVNext = (4 << HalfY)*(Src->Pitch >> SrcUVPitch2) - (Width >> SrcUVX)
  635. I3S(MOV,R0,NONE,R14,LSL,2+p->HalfY-p->SrcUVPitch2); 
  636. I3S(SUB,R0,R0,RSrcWidth,LSR,p->SrcUVX2); 
  637. I2C(STR,R0,SP,OFS(stack,SrcNext[1]));
  638. //EndOfRect = Src + Src->Pitch * Height
  639. I3(MUL,R0,R14,R2);
  640. I3(ADD,R0,R0,R10);
  641. I2C(STR,R0,SP,OFS(stack,EndOfRect));
  642. if (p->SwapXY)
  643. {
  644. //DstYNext = 4*DirX - Width*Dst->Pitch
  645. I3(MUL,R3,R1,R12);
  646. I2C(MOV,R0,NONE,4*p->DirX);
  647. I3(SUB,R0,R0,R3);
  648. I2C(STR,R0,SP,OFS(stack,DstNext[0]));
  649. //DstUVNext = 4*DirX - (Width >> DstUVY2)*(Dst->Pitch >> DstUVPitch2)
  650. if (p->DstUVY2+p->DstUVPitch2) I3S(MOV,R3,NONE,R3,ASR,p->DstUVY2+p->DstUVPitch2);
  651. I2C(MOV,R0,NONE,4*p->DirX);
  652. I3(SUB,R0,R0,R3);
  653. I2C(STR,R0,SP,OFS(stack,DstNext[1]));
  654. }
  655. else
  656. {
  657. //DstYNext = 4*Dst->Pitch - DirX * Width
  658. I3S(p->DirX<0?ADD:RSB,R0,R1,R12,LSL,2); 
  659. I2C(STR,R0,SP,OFS(stack,DstNext[0]));
  660. //DstUVNext = 4*Dst->Pitch >> DstUVPitch2 - DirX * (Width >> DstUVX2)
  661. I3S(MOV,R0,NONE,R12,LSL,2-p->DstUVPitch2);
  662. I3S(p->DirX<0?ADD:SUB,R0,R0,R1,LSR,p->DstUVX2); 
  663. I2C(STR,R0,SP,OFS(stack,DstNext[1]));
  664. }
  665. LoopY = Label(0);
  666. I0P(B,AL,LoopY);
  667. if (p->DiffMask) InstPost(p->DiffMask);
  668. if (Add32) InstPost(Add32);
  669. if (MaskCarry) InstPost(MaskCarry);
  670. if (p->LookUp)
  671. {
  672. Align(16);
  673. InstPost(p->LookUp);
  674. }
  675. InstPost(LoopY);
  676. {
  677. if (p->LookUp)
  678. I2C(ADD,R8,R8,256+4);
  679. YUV_4X4(p,1);
  680. if (p->LookUp)
  681. I2C(ADD,R8,R8,256);
  682. YUV_4X4(p,2);
  683. if (p->LookUp)
  684. I2C(SUB,R8,R8,256+256+4);
  685. YUV_4X4(p,0);
  686. MB(); I2C(LDR,R2,SP,OFS(stack,EndOfRect));
  687. I3(CMP,NONE,R2,R7);
  688. I0P(B,NE,LoopY);
  689. }
  690. I2C(ADD,SP,SP,OFS(stack,StackFrame));
  691. CodeEnd();
  692. }
  693. #endif