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

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_half.c 543 2006-01-07 22:06:24Z 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 4
  27. // DstAlignPos  4
  28. // SrcAlignPos  2
  29. #if defined(ARM) 
  30. typedef struct stack
  31. {
  32. int EndOfLine;
  33. int EndOfRect;
  34. int DstPitch; 
  35. int DstNext;
  36. int SrcNext;
  37. int UVNext;
  38. int StackFrame[STACKFRAME];
  39. //void* this   R0
  40. //char* Dst    R1
  41. //char* Src    R2
  42. //int DstPitch R3 can be signed
  43. int SrcPitch; //can be signed
  44. int Width; 
  45. int Height;
  46. int Src2SrcLast;
  47. } stack;
  48. // R0 result RGB
  49. // R1..R3 R,G,B accumulator
  50. // R4..R6 temporary
  51. // R7 EndOfLine
  52. // R8 DstPitch
  53. // R9 Dst
  54. // R10 U
  55. // R11 V
  56. // R12 Y
  57. // R14 UVPitch (same as YPitch/2)
  58. static NOINLINE void Half_RGB_UV_Pixel(blit_soft* p, int No)
  59. {
  60. bool_t NextSub;
  61. bool_t NextX;
  62. int SatBit = p->QAdd ? 32 : 24;
  63. int RPos = p->DstPos[0];
  64. int GPos = p->DstPos[1];
  65. int BPos = p->DstPos[2];
  66. int NextLoad;
  67. // 3 <- 2
  68. // |    ^
  69. // v |
  70. // 0 -> 1
  71. switch (No)
  72. {
  73. default:
  74. case 0: NextSub = 0; NextX = 1; p->Upper = 0; break;
  75. case 1: NextSub = 1; NextX = 0; p->Upper = 1; break;
  76. case 2: NextSub = 1; NextX = 1; p->Upper = 1; break;
  77. case 3: NextSub = 0; NextX = 0; p->Upper = 0; break;
  78. }
  79. if (p->DirX<0)
  80. p->Upper = !p->Upper;
  81. if (p->SwapXY)
  82. {
  83. if (!NextX) NextSub = !NextSub;
  84. NextX = !NextX;
  85. }
  86. if (p->Upper && p->DstBPP<=16)
  87. {
  88. RPos += p->DstBPP;
  89. GPos += p->DstBPP;
  90. BPos += p->DstBPP;
  91. }
  92. if (p->FX.Flags & BLITFX_DITHER)
  93. {
  94. IConst(R4,p->_RAdd);
  95. IConst(R5,p->_GAdd);
  96. IConst(R6,p->_BAdd);
  97. I3S(ADD,R1,R4,R1,LSR,32-SatBit+p->DstSize[0]);
  98. I3S(ADD,R2,R5,R2,LSR,32-SatBit+p->DstSize[1]);
  99. I3S(ADD,R3,R6,R3,LSR,32-SatBit+p->DstSize[2]);
  100. }
  101. else
  102. {
  103. IConst(R1,p->_RAdd);
  104. IConst(R2,p->_GAdd);
  105. IConst(R3,p->_BAdd);
  106. }
  107. NextLoad = NextSub ? LDR_POSTSUB : LDR_POST;
  108. if (p->ArithStretch)
  109. {
  110. // sum a 2x2 block of Y
  111. if (NextX)
  112. {
  113. MB(); Byte(); I3S(LDR_POST,R4,R12,R14,LSL,1);   //y00
  114. MB(); Byte(); I2C(LDR_POST,R6,R12,1);   //y10
  115. MB(); Byte(); I3S(LDR_POSTSUB,R5,R12,R14,LSL,1);  //y11
  116. I3(ADD,R4,R4,R6);
  117. Byte(); I2C(NextLoad,R6,R12,NextSub?3:1);   //y01
  118. I3(ADD,R4,R4,R5);
  119. I3(ADD,R4,R4,R6);
  120. }
  121. else
  122. {
  123. MB(); Byte(); I2C(LDR_POST,R4,R12,1); //y00
  124. MB(); Byte(); I3S(LDR_POST,R6,R12,R14,LSL,1); //y01
  125. MB(); Byte(); I2C(LDR_POSTSUB,R5,R12,1); //y11
  126. I3(ADD,R4,R4,R6);
  127. Byte(); I3S(NextLoad,R6,R12,R14,LSL,1);     //y10
  128. I3(ADD,R4,R4,R5);
  129. if (NextSub) I3S(SUB,R12,R12,R14,LSL,2);
  130. I3(ADD,R4,R4,R6);
  131. }
  132. MB(); IConst(R5,p->_YMul >> 2);
  133. }
  134. else
  135. {
  136. MB(); Byte(); 
  137. if (NextX)
  138. I2C(NextLoad,R4,R12,2);   //y
  139. else
  140. I3S(NextLoad,R4,R12,R14,LSL,2); //y
  141. IConst(R5,p->_YMul);
  142. }
  143. I4(MLA,R1,R5,R4,R1);
  144. I4(MLA,R2,R5,R4,R2);
  145. I4(MLA,R3,R5,R4,R3);
  146. if (NextX)
  147. {
  148. MB(); Byte(); I2C(NextLoad,R6,R11,1); //v
  149. MB(); Byte(); I2C(NextLoad,R4,R10,1); //u
  150. }
  151. else
  152. {
  153. MB(); Byte(); I3(NextLoad,R6,R11,R14); //v
  154. MB(); Byte(); I3(NextLoad,R4,R10,R14); //u
  155. }
  156. IConst(R5,p->_GVMul);
  157. I4(MLA,R2,R5,R6,R2);
  158. IConst(R5,p->_RVMul);
  159. I4(MLA,R1,R5,R6,R1);
  160. IConst(R5,p->_GUMul);
  161. I4(MLA,R2,R5,R4,R2);
  162. IConst(R5,p->_BUMul);
  163. I4(MLA,R3,R5,R4,R3);
  164. if (p->QAdd)
  165. {
  166. I3(QDADD,R1,R1,R1);
  167. I3(QDADD,R2,R2,R2);
  168. I3(QDADD,R3,R3,R3);
  169. }
  170. else
  171. {
  172. I2C(TST,NONE,R1,0xFF000000);
  173. C(NE);I2C(MVN,R1,NONE,0xFF000000);
  174. C(MI);I2C(MOV,R1,NONE,0x00000000);
  175. I2C(TST,NONE,R2,0xFF000000);
  176. C(NE);I2C(MVN,R2,NONE,0xFF000000);
  177. C(MI);I2C(MOV,R2,NONE,0x00000000);
  178. I2C(TST,NONE,R3,0xFF000000);
  179. C(NE);I2C(MVN,R3,NONE,0xFF000000);
  180. C(MI);I2C(MOV,R3,NONE,0x00000000);
  181. }
  182. if (p->InvertMask && p->Pos<0)
  183. {
  184. p->Pos = RPos;
  185. MB(); I1P(LDR,R0,p->InvertMask,0);
  186. }
  187. if (p->Pos!=RPos && p->Pos>=0) I3S(MOV,R0,NONE,R0,ROR,RPos-p->Pos);
  188. I3S(p->Pos<0?MOV:EOR,R0,(reg)(p->Pos<0?NONE:R0),R1,LSR,SatBit-p->DstSize[0]);
  189. I3S(MOV,R5,NONE,R2,LSR,SatBit-p->DstSize[1]);
  190. I3S(MOV,R0,NONE,R0,ROR,BPos-RPos);
  191. I3S(EOR,R0,R0,R5,ROR,BPos-GPos);
  192. I3S(EOR,R0,R0,R3,LSR,SatBit-p->DstSize[2]);
  193. p->Pos = BPos;
  194. if (p->FX.Flags & BLITFX_DITHER)
  195. {
  196. MB(); I3S(MOV,R1,NONE,R1,LSL,32-SatBit+p->DstSize[0]);
  197. MB(); I3S(MOV,R2,NONE,R2,LSL,32-SatBit+p->DstSize[1]);
  198. MB(); I3S(MOV,R3,NONE,R3,LSL,32-SatBit+p->DstSize[2]);
  199. }
  200. }
  201. void Half_RGB_UV(blit_soft* p)
  202. {
  203. dyninst* LoopY;
  204. dyninst* LoopX;
  205. int Invert = 0;
  206. int Mask = 0;
  207. p->DstAlignPos = p->DstAlignSize = 4;
  208. p->DstStepX = p->DirX * ((p->DstBPP*2) >> 3);
  209. p->PalPtr = NULL;
  210. p->DiffMask = NULL;
  211. p->InvertMask = NULL;
  212. if (p->Dst.Flags & PF_INVERTED)
  213. Invert = -1;
  214. if (p->QAdd)
  215. {
  216. int Mask2;
  217. int i,Shift;
  218. for (i=0;i<3;++i)
  219. Mask |= 1 << (p->DstPos[i] + p->DstSize[i] - 1);
  220. Mask2 = Mask;
  221. Shift = 0;
  222. if (p->DstBPP <= 16)
  223. {
  224. if (p->DirX<0) Shift = p->DstBPP;
  225. Mask2 |= Mask << p->DstBPP;
  226. }
  227. Invert ^= RotateRight(Mask2,Shift+p->DstPos[0]);
  228. }
  229. if (Invert)
  230. p->InvertMask = InstCreate32(Invert,NONE,NONE,NONE,0,0);
  231. if (p->OnlyDiff)
  232. {
  233. int Mask = 0x03030303;
  234. if (!p->ArithStretch)
  235. Mask &= ~0x00FF0000; //lose Y3
  236. p->DiffMask = InstCreate32(Mask,NONE,NONE,NONE,0,0);
  237. }
  238. CodeBegin();
  239. I2C(SUB,SP,SP,OFS(stack,StackFrame));
  240. I2C(LDR,R9,R1,0);  //Dst[0] RGB
  241. I2C(LDR,R10,R2,4); //Src[1] U
  242. I2C(LDR,R11,R2,8); //Src[2] V
  243. I2C(LDR,R12,R2,0); //Src[0] Y
  244. I2C(STR,R3,SP,OFS(stack,DstPitch));
  245. I3(MOV,R8,NONE,R3); //DstPitch
  246. I2C(LDR,R14,SP,OFS(stack,SrcPitch));
  247. I2C(LDR,R0,SP,OFS(stack,Height));
  248. I2C(LDR,R4,SP,OFS(stack,Width));
  249. //SrcNext = 4*Src->Pitch - (Width << 1)
  250. I3S(MOV,R1,NONE,R14,LSL,2);
  251. I3S(SUB,R1,R1,R4,LSL,1); 
  252. I2C(STR,R1,SP,OFS(stack,SrcNext));
  253. //UVNext = (Src->Pitch) - (Width << 1 >> 1);
  254. I3(SUB,R2,R14,R4); 
  255. I2C(STR,R2,SP,OFS(stack,UVNext));
  256. I3S(MOV,R14,NONE,R14,ASR,1);
  257. if (p->DirX<0 && p->DstBPP==16) //adjust reversed destination for block size
  258. I2C(SUB,R9,R9,-p->DstStepX-(p->DstBPP >> 3));
  259. if (p->SwapXY)
  260. {
  261. //EndOfRect = Dst + (Height * DstBPP * DirX) >> 3;
  262. I2C(MOV,R1,NONE,p->DstBPP * p->DirX);
  263. I3(MUL,R0,R1,R0);
  264. I3S(ADD,R0,R9,R0,ASR,3);
  265. I2C(STR,R0,SP,OFS(stack,EndOfRect));
  266. //DstNext = DstStepX - Width*DstPitch;
  267. MB(); I3(MUL,R2,R8,R4);
  268. I2C(MOV,R0,NONE,p->DstStepX);
  269. I3(SUB,R0,R0,R2); 
  270. I2C(STR,R0,SP,OFS(stack,DstNext));
  271. }
  272. else
  273. {
  274. //EndOfRect = Dst + DstPitch * Height
  275. I3(MUL,R0,R8,R0);
  276. I3(ADD,R0,R9,R0);
  277. I2C(STR,R0,SP,OFS(stack,EndOfRect));
  278. //DstNext = DstPitch*2 - DirX * Width << DstBPP2;
  279. I3S(MOV,R2,NONE,R8,LSL,1);
  280. I3S(p->DirX>0?SUB:ADD,R2,R2,R4,LSL,p->DstBPP2); 
  281. I2C(STR,R2,SP,OFS(stack,DstNext));
  282. }
  283. if (p->FX.Flags & BLITFX_DITHER)
  284. {
  285. I2C(MVN,R1,NONE,0x80000000);
  286. I2C(MVN,R2,NONE,0x80000000);
  287. I2C(MVN,R3,NONE,0x80000000);
  288. }
  289. if (!p->SwapXY) // starting in second row
  290. {
  291. I3(ADD,R10,R10,R14);
  292. I3(ADD,R11,R11,R14);
  293. I3S(ADD,R12,R12,R14,LSL,2);
  294. }
  295. // R8 DstPitch
  296. // R4 Width
  297. LoopY = Label(1);
  298. if (p->SwapXY)
  299. {
  300. I3(MUL,R4,R8,R4); //R8=dstpitch
  301. I3(ADD,R7,R9,R4);
  302. }
  303. else
  304. {
  305. if (p->DirX > 0)
  306. I3S(ADD,R7,R9,R4,LSL,p->DstBPP2);
  307. else
  308. I3S(SUB,R7,R9,R4,LSL,p->DstBPP2);
  309. }
  310.     if (p->OnlyDiff)
  311. {
  312. if (p->FX.Flags & BLITFX_DITHER)
  313. I2C(STR,R7,SP,OFS(stack,EndOfLine)); //needed for restoring
  314. MB(); I1P(LDR,R5,p->DiffMask,0);
  315. MB(); I2C(LDR,R6,SP,OFS(stack,Src2SrcLast));
  316. p->Skip = Label(0);
  317. }
  318. LoopX = Label(1);
  319. {
  320. if (p->OnlyDiff)
  321. {
  322. // R0 temp
  323. // R1..R3 R,G,B accumulator (if dither)
  324. // R4 temp
  325. // R5 DiffMask
  326. // R6 Src2SrcLast
  327. // R7 EndOfLine
  328. // R8 DstPitch
  329. // R9 Dst
  330. // R10 U (second row when not SwapXY)
  331. // R11 V (second row when not SwapXY)
  332. // R12 Y (second double row when not SwapXY)
  333. // R14 UVPitch (same as YPitch/2)
  334. int LoadSub = p->SwapXY?LDR_POST:LDR_POSTSUB;
  335. int LoadAdd = p->SwapXY?LDR_POSTSUB:LDR_POST;
  336. reg RA=R0,RB=R4,RC,RD;
  337. if (p->FX.Flags & BLITFX_DITHER)
  338. {
  339. RC=R7; //will be restored
  340. RD=R8; //will be restored
  341. }
  342. else
  343. {
  344. RC=R1;
  345. RD=R2;
  346. }
  347. I3(LDR,RA,R12,R6);
  348. I3S(LoadSub,RB,R12,R14,LSL,2);
  349. I3(EOR,RA,RA,RB);
  350. if (p->ArithStretch)
  351. {
  352. MB(); I3(LDR,RC,R12,R6);
  353. MB(); I3S(LDR_POST,RD,R12,R14,LSL,1);
  354. I3(EOR,RC,RC,RD);
  355. I3(ORR,RA,RA,RC);
  356. MB(); I3(LDR,RB,R12,R6);
  357. MB(); I3S(LoadAdd,RD,R12,R14,LSL,2);
  358. I3(EOR,RB,RB,RD);
  359. I3(ORR,RA,RA,RB);
  360. MB(); I3(LDR,RC,R12,R6);
  361. MB(); I3S(LDR_POSTSUB,RD,R12,R14,LSL,1);
  362. I3(EOR,RC,RC,RD);
  363. I3(ORR,RA,RA,RC);
  364. I3S(BIC,RA,RA,R5,LSL,1); //lose 1 bit from Y (additionaly to DiffMask)
  365. }
  366. else
  367. {
  368. MB(); I3(LDR,RC,R12,R6);
  369. MB(); I3S(LoadAdd,RD,R12,R14,LSL,2);
  370. I3(EOR,RC,RC,RD);
  371. I3(ORR,RA,RA,RC);
  372. I2C(BIC,RA,RA,0xFF00); //lose Y1 (Y3 is masked out in DiffMask already)
  373. }
  374. MB(); Half(); I3(LDR,RB,R10,R6);
  375. MB(); Half(); I3(LoadSub,RD,R10,R14);
  376. I3(EOR,RB,RB,RD);
  377. I3(ORR,RA,RA,RB);
  378. MB(); Half(); I3(LDR,RC,R10,R6);
  379. MB(); Half(); I3(LoadAdd,RD,R10,R14);
  380. I3(EOR,RC,RC,RD);
  381. I3(ORR,RA,RA,RC);
  382. MB(); Half(); I3(LDR,RB,R11,R6);
  383. MB(); Half(); I3(LoadSub,RD,R11,R14);
  384. I3(EOR,RB,RB,RD);
  385. I3(ORR,RA,RA,RB);
  386. MB(); Half(); I3(LDR,RC,R11,R6);
  387. MB(); Half(); I3(LoadAdd,RD,R11,R14);
  388. I3(EOR,RC,RC,RD);
  389. I3(ORR,RA,RA,RC);
  390. S(); I3(BIC,RA,RA,R5);
  391. if (p->FX.Flags & BLITFX_DITHER) // restore R7,R8
  392. {
  393. MB(); I2C(LDR,R8,SP,OFS(stack,DstPitch));
  394. MB(); I2C(LDR,R7,SP,OFS(stack,EndOfLine));
  395. }
  396. if (p->SwapXY)
  397. {
  398. C(EQ); I3S(ADD,R9,R9,R8,LSL,1);
  399. }
  400. else
  401. {
  402. C(EQ); I2C(ADD,R9,R9,p->DstStepX);
  403. }
  404. I0P(B,EQ,p->Skip);
  405. }
  406. p->Pos = -1;
  407. Half_RGB_UV_Pixel(p,0);
  408. Half_RGB_UV_Pixel(p,1);
  409. if (p->Pos) 
  410. I3S(MOV,R0,NONE,R0,ROR,-p->Pos);
  411. if (p->DstBPP==8) Half();
  412. if (p->SwapXY)
  413. I3(STR_POST,R0,R9,R8);
  414. else
  415. I3(STR,R0,R9,R8);
  416. p->Pos = -1;
  417. Half_RGB_UV_Pixel(p,2);
  418. Half_RGB_UV_Pixel(p,3);
  419. if (p->Pos) 
  420. I3S(MOV,R0,NONE,R0,ROR,-p->Pos);
  421. if (p->DstBPP==8) Half();
  422. if (p->SwapXY)
  423. I3(STR_POST,R0,R9,R8);
  424. else
  425. I2C(STR_POST,R0,R9,p->DstStepX);
  426. if (p->OnlyDiff)
  427. {
  428. MB(); I1P(LDR,R5,p->DiffMask,0);
  429. MB(); I2C(LDR,R6,SP,OFS(stack,Src2SrcLast));
  430. InstPost(p->Skip);
  431. }
  432. I3(CMP,NONE,R9,R7);
  433. I2C(ADD,R12,R12,4);
  434. I2C(ADD,R10,R10,2);
  435. I2C(ADD,R11,R11,2);
  436. I0P(B,NE,LoopX);
  437. }
  438. I2C(LDR,R0,SP,OFS(stack,SrcNext));
  439. I2C(LDR,R4,SP,OFS(stack,DstNext));
  440. I2C(LDR,R6,SP,OFS(stack,UVNext));
  441. I2C(LDR,R5,SP,OFS(stack,EndOfRect));
  442. //increment pointers
  443. I3(ADD,R12,R12,R0);
  444. I3(ADD,R9,R9,R4);
  445. I3(ADD,R10,R10,R6);
  446. I3(ADD,R11,R11,R6);
  447. //prepare registers for next row
  448. I2C(LDR,R4,SP,OFS(stack,Width));
  449. I3(CMP,NONE,R9,R5);
  450. I0P(B,NE,LoopY);
  451. I2C(ADD,SP,SP,OFS(stack,StackFrame));
  452. CodeEnd();
  453. if (p->InvertMask) InstPost(p->InvertMask);
  454. if (p->DiffMask) InstPost(p->DiffMask);
  455. if (p->PalPtr) InstPost(p->PalPtr);
  456. }
  457. #endif