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

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_rgb16.c 339 2005-11-15 11:22:45Z 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. #if defined(ARM) 
  27. // R0..R6 temporary
  28. // R7 Pos(when Stretch)
  29. // R8 Src2SrcLast (when Diff)
  30. // R8 Src0 (when Stretch)
  31. // R9 Src
  32. // R10 EndOfLine 
  33. // R11 Dst
  34. // R12 DstPitch
  35. // R14 SrcPitch 
  36. // R14 Src1 (when Stretch)
  37. typedef struct stack
  38. {
  39. int EndOfRect; 
  40. int DstNext; 
  41. int SrcNext;
  42. void* Palette;
  43. int StackFrame[STACKFRAME];
  44. //void* this   R0
  45. //char* Dst    R1
  46. //char* Src    R2
  47. //int DstPitch R3 can be signed
  48. int SrcPitch;
  49. int Width; 
  50. int Height;
  51. int Src2SrcLast;
  52. } stack;
  53. void RGB_4X2(blit_soft* p)
  54. {
  55. if (p->RealOnlyDiff)
  56. {
  57. p->Skip = Label(0);
  58. I3(LDR,R4,R9,R8);
  59. I3(LDR_POST,R0,R9,R14);
  60. I3(LDR,R6,R9,R8);
  61. I2C(LDR_POST,R2,R9,4);
  62. I3(LDR,R5,R9,R8);
  63. I3(LDR_POSTSUB,R3,R9,R14);
  64. I3(CMP,NONE,R0,R4);
  65. C(EQ); I3(CMP,NONE,R2,R6);
  66. I3(LDR,R6,R9,R8);
  67. I2C(LDR_POST,R1,R9,4);
  68. C(EQ); I3(CMP,NONE,R3,R5);
  69. C(EQ); I3(CMP,NONE,R1,R6);
  70. C(EQ);
  71. if (p->SwapXY)
  72. I3S(ADD,R11,R11,R12,LSL,2+p->DstDoubleY);
  73. else
  74. I2C(ADD,R11,R11,(2*4*p->DirX)<<p->DstDoubleX);
  75. I0P(B,EQ,p->Skip);
  76. }
  77. if (p->DstDoubleX && p->DstDoubleY)
  78. {
  79. //todo...
  80. }
  81. else
  82. {
  83. if (p->SwapXY)
  84. {
  85. if (p->RealOnlyDiff)
  86. I2C(SUB,R9,R9,8);
  87. Half(); I3(LDR_POST,R0,R9,R14);
  88. Half(); I2C(LDR_POST,R1,R9,2);
  89. Half(); I3(LDR_POSTSUB,R3,R9,R14);
  90. Half(); I2C(LDR_POST,R2,R9,2);
  91. if (p->DirX>0)
  92. {
  93. I3S(ORR,R4,R0,R1,LSL,16);
  94. I3S(ORR,R5,R2,R3,LSL,16);
  95. }
  96. else
  97. {
  98. I3S(ORR,R4,R1,R0,LSL,16);
  99. I3S(ORR,R5,R3,R2,LSL,16);
  100. }
  101. MB(); Half(); I3(LDR_POST,R0,R9,R14);
  102. MB(); Half(); I2C(LDR_POST,R1,R9,2);
  103. MB(); Half(); I3(LDR_POSTSUB,R3,R9,R14);
  104. MB(); Half(); I2C(LDR_POST,R2,R9,2);
  105. if (p->DirX>0)
  106. {
  107. I3S(ORR,R1,R0,R1,LSL,16);
  108. I3S(ORR,R3,R2,R3,LSL,16);
  109. }
  110. else
  111. {
  112. I3S(ORR,R1,R1,R0,LSL,16);
  113. I3S(ORR,R3,R3,R2,LSL,16);
  114. }
  115. I3(STR_POST,R4,R11,R12);
  116. I3(STR_POST,R5,R11,R12);
  117. I3(STR_POST,R1,R11,R12);
  118. I3(STR_POST,R3,R11,R12);
  119. }
  120. else
  121. {
  122. if (!p->RealOnlyDiff)
  123. {
  124. I3(LDR_POST,R0,R9,R14);
  125. I2C(LDR_POST,R2,R9,4);
  126. I3(LDR_POSTSUB,R3,R9,R14);
  127. I2C(LDR_POST,R1,R9,4);
  128. }
  129. if (p->DirX<0)
  130. {
  131. I3S(MOV,R0,NONE,R0,ROR,16);
  132. I3S(MOV,R1,NONE,R1,ROR,16);
  133. I3S(MOV,R2,NONE,R2,ROR,16);
  134. I3S(MOV,R3,NONE,R3,ROR,16);
  135. }
  136. I3(STR_POST,R0,R11,R12);
  137. I2C(STR_POST,R2,R11,4*p->DirX);
  138. I3(STR_POSTSUB,R3,R11,R12);
  139. I2C(STR_POST,R1,R11,4*p->DirX);
  140. }
  141. }
  142. if (p->RealOnlyDiff)
  143. InstPost(p->Skip);
  144. }
  145. void RGB_Read(blit_soft* p,reg RGB,reg Src,int Inc)
  146. {
  147. int Type[4];
  148. int IncByte[4];
  149. reg Tmp = R6;
  150. int i,j;
  151. bool_t First;
  152. if (p->Src.BitCount==p->Dst.BitCount && (p->Src.BitCount!=8 || !p->LookUp) &&
  153. p->Src.BitMask[0] == p->Dst.BitMask[0] &&
  154. p->Src.BitMask[1] == p->Dst.BitMask[1] &&
  155. p->Src.BitMask[2] == p->Dst.BitMask[2])
  156. {
  157. switch (p->Src.BitCount)
  158. {
  159. case 8:
  160. Byte(); I2C(LDR_POST,RGB,Src,Inc); 
  161. break;
  162. case 16:
  163. Half(); I2C(LDR_POST,RGB,Src,Inc*2); 
  164. break;
  165. case 32:
  166. I2C(LDR_POST,RGB,Src,Inc*4); 
  167. break;
  168. }
  169. }
  170. else
  171. {
  172. switch (p->Src.BitCount)
  173. {
  174. case 8:
  175. if (p->LookUp)
  176. {
  177. I1P(MOV,Tmp,p->LookUp,0);
  178. Byte(); I2C(LDR_POST,RGB,Src,Inc);
  179. switch (p->Dst.BitCount)
  180. {
  181. case 8:
  182. Byte(); I3(LDR,RGB,Tmp,RGB); 
  183. break;
  184. case 16:
  185. I3(ADD,RGB,RGB,RGB);
  186. Half(); I3(LDR,RGB,Tmp,RGB);
  187. break;
  188. case 32:
  189. I3S(LDR,RGB,Tmp,RGB,LSL,2);
  190. break;
  191. }
  192. }
  193. break;
  194. case 16:
  195. Half(); I2C(LDR_POST,RGB,Src,Inc*2);
  196. for (i=0;i<3;++i)
  197. {
  198. j = min(p->DstSize[i],p->SrcSize[i]);
  199. I2C(AND,Tmp,RGB,((1<<j)-1) << (p->SrcSize[i]+p->SrcPos[i]-j));
  200. I3S(ORR,RGB,RGB,Tmp,LSL,16-p->SrcSize[i]-p->SrcPos[i]+p->DstSize[i]+p->DstPos[i]);
  201. }
  202. I3S(MOV,RGB,NONE,RGB,LSR,16);
  203. break;
  204. case 32:
  205. case 24:
  206. for (j=0;j<3;++j)
  207. IncByte[j] = 1;
  208. IncByte[3] = (Inc-1) * (p->SrcBPP/8) + (p->Src.BitCount==32);
  209. for (j=0;j<4;++j)
  210. {
  211. Type[j] = -1;
  212. for (i=0;i<3;++i)
  213. if (p->SrcPos[i]==j*8)
  214. Type[j] = i;
  215. if (Type[j]<0)
  216. {
  217. // merge IncByte to previous
  218. for (i=j-1;i>=0;--i)
  219. if (Type[i]>=0 || IncByte[i])
  220. {
  221. IncByte[i] += IncByte[j];
  222. IncByte[j] = 0;
  223. break;
  224. }
  225. }
  226. }
  227. First = 1;
  228. for (j=0;j<4;++j)
  229. {
  230. i = Type[j];
  231. if (i>=0)
  232. {
  233. Byte(); I2C(LDR_POST,Tmp,Src,IncByte[j]);
  234. I2C(AND,Tmp,Tmp,((1 << p->DstSize[i])-1) << (8-p->DstSize[i]));
  235. if (First)
  236. {
  237. I3S(MOV,RGB,NONE,Tmp,LSR,8-p->DstPos[i]-p->DstSize[i]);
  238. First = 0;
  239. }
  240. else
  241. I3S(ORR,RGB,RGB,Tmp,LSR,8-p->DstPos[i]-p->DstSize[i]);
  242. }
  243. else if (IncByte[j]>0)
  244. I2C(ADD,Src,Src,IncByte[j]);
  245. }
  246. break;
  247. }
  248. }
  249. }
  250. void RGB_4X2S(blit_soft* p,int* Inc)
  251. {
  252. if (p->SwapXY)
  253. {
  254. RGB_Read(p,R0,R8,Inc[0]);
  255. RGB_Read(p,R1,R14,Inc[0]);
  256. RGB_Read(p,R2,R8,Inc[1]);
  257. RGB_Read(p,R3,R14,Inc[1]);
  258. if (p->DirX>0)
  259. {
  260. I3S(ORR,R4,R0,R1,LSL,16);
  261. I3S(ORR,R5,R2,R3,LSL,16);
  262. }
  263. else
  264. {
  265. I3S(ORR,R4,R1,R0,LSL,16);
  266. I3S(ORR,R5,R3,R2,LSL,16);
  267. }
  268. RGB_Read(p,R0,R8,Inc[2]);
  269. RGB_Read(p,R1,R14,Inc[2]);
  270. RGB_Read(p,R2,R8,Inc[3]);
  271. RGB_Read(p,R3,R14,Inc[3]);
  272. if (p->DirX>0)
  273. {
  274. I3S(ORR,R1,R0,R1,LSL,16);
  275. I3S(ORR,R3,R2,R3,LSL,16);
  276. }
  277. else
  278. {
  279. I3S(ORR,R1,R1,R0,LSL,16);
  280. I3S(ORR,R3,R3,R2,LSL,16);
  281. }
  282. I3(STR_POST,R4,R11,R12);
  283. I3(STR_POST,R5,R11,R12);
  284. I3(STR_POST,R1,R11,R12);
  285. I3(STR_POST,R3,R11,R12);
  286. }
  287. else
  288. {
  289. RGB_Read(p,R0,R8,Inc[0]);
  290. RGB_Read(p,R1,R8,Inc[1]);
  291. RGB_Read(p,R2,R8,Inc[2]);
  292. RGB_Read(p,R3,R8,Inc[3]);
  293. if (p->DirX>0)
  294. {
  295. I3S(ORR,R4,R0,R1,LSL,16);
  296. I3S(ORR,R5,R2,R3,LSL,16);
  297. }
  298. else
  299. {
  300. I3S(ORR,R4,R1,R0,LSL,16);
  301. I3S(ORR,R5,R3,R2,LSL,16);
  302. }
  303. RGB_Read(p,R0,R14,Inc[0]);
  304. RGB_Read(p,R1,R14,Inc[1]);
  305. RGB_Read(p,R2,R14,Inc[2]);
  306. RGB_Read(p,R3,R14,Inc[3]);
  307. if (p->DirX>0)
  308. {
  309. I3S(ORR,R1,R0,R1,LSL,16);
  310. I3S(ORR,R3,R2,R3,LSL,16);
  311. }
  312. else
  313. {
  314. I3S(ORR,R1,R1,R0,LSL,16);
  315. I3S(ORR,R3,R3,R2,LSL,16);
  316. }
  317. I3(STR_POST,R4,R11,R12);
  318. I2C(STR_POST,R1,R11,4*p->DirX);
  319. I3(STR_POSTSUB,R3,R11,R12);
  320. I2C(STR_POST,R5,R11,4*p->DirX);
  321. }
  322. }
  323. void Any_RGB_RGB(blit_soft* p)
  324. {
  325. dyninst* LoopX;
  326. dyninst* LoopY;
  327. dyninst* EndOfLine;
  328. bool_t Stretch;
  329. bool_t Same = 
  330. p->Src.BitCount==p->Dst.BitCount && 
  331. p->Src.BitMask[0] == p->Dst.BitMask[0] &&
  332. p->Src.BitMask[1] == p->Dst.BitMask[1] &&
  333. p->Src.BitMask[2] == p->Dst.BitMask[2];
  334. Stretch = p->RScaleX!=16 || p->RScaleY!=16 || !Same;
  335. p->RealOnlyDiff = (boolmem_t)(p->OnlyDiff && !Stretch);
  336. p->Caps = 0;
  337. p->DstAlignSize = 4;
  338. if (p->SrcDoubleX && !Stretch)
  339. p->DstAlignSize = 8;
  340. p->LookUp = NULL;
  341. if (p->Src.Palette)
  342. CalcPalRGBLookUp(p);
  343. if (p->LookUp_Data)
  344. {
  345. p->LookUp = InstCreate(p->LookUp_Data,p->LookUp_Size,NONE,NONE,NONE,0,0);
  346. free(p->LookUp_Data);
  347. p->LookUp_Data = NULL;
  348. }
  349. CodeBegin();
  350. I2C(SUB,SP,SP,OFS(stack,StackFrame));
  351. I2C(LDR,R11,R1,0);//Dst[0]
  352. I2C(LDR,R9,R2,0); //Src[0]
  353. if (p->DirX<0)
  354. {
  355. //adjust reversed destination for block size
  356. I2C(SUB,R11,R11,2);
  357. }
  358. I3(MOV,R12,NONE,R3); //DstPitch
  359. I2C(LDR,R2,SP,OFS(stack,Height));
  360. I2C(LDR,R1,SP,OFS(stack,Width));
  361. if (!Stretch)
  362. {
  363. //SrcNext = 2*Src->Pitch - SrcWidth << (SrcBPP2+SrcDoubleX)
  364. I2C(LDR,R14,SP,OFS(stack,SrcPitch));
  365. I3S(MOV,R3,NONE,R1,LSL,p->SrcDoubleX+p->SrcBPP2);
  366. I3S(RSB,R0,R3,R14,LSL,1); 
  367. I2C(STR,R0,SP,OFS(stack,SrcNext));
  368. }
  369. if (p->SwapXY)
  370. {
  371. //EndOfRect = Dst + Height*2*DirX
  372. I3S(p->DirX<0?SUB:ADD,R0,R11,R2,LSL,p->DstBPP2);
  373. I2C(STR,R0,SP,OFS(stack,EndOfRect));
  374. //DstNext = 2*(DstBPP/8)*DirX - Width*Dst->Pitch
  375. I3(MUL,R3,R1,R12);
  376. I2C(MOV,R0,NONE,2*p->DirX*(p->DstBPP/8));
  377. I3(SUB,R0,R0,R3);
  378. I2C(STR,R0,SP,OFS(stack,DstNext));
  379. }
  380. else
  381. {
  382. I3(MUL,R0,R12,R2); //DstPitch * Height
  383. I3(ADD,R0,R11,R0);
  384. I2C(STR,R0,SP,OFS(stack,EndOfRect));
  385. //DstNext = 2*Dst->Pitch - DirX*Width*(DstBPP/8)
  386. I3(ADD,R3,R1,R1);
  387. I3S(p->DirX<0?ADD:RSB,R0,R3,R12,LSL,p->DstBPP2); 
  388. I2C(STR,R0,SP,OFS(stack,DstNext));
  389. }
  390. if (p->RealOnlyDiff)
  391. I2C(LDR,R8,SP,OFS(stack,Src2SrcLast));
  392. if (Stretch)
  393. I2C(MOV,R7,NONE,0); //Pos
  394. I2C(LDR,R0,SP,OFS(stack,Width));
  395. LoopY = Label(1);
  396. //R0 width
  397. if (p->SwapXY)
  398. {
  399. I3(MUL,R10,R12,R0); //R12=DstPitch
  400. I3(ADD,R10,R11,R10);
  401. }
  402. else
  403. I3S(p->DirX>0?ADD:SUB,R10,R11,R0,LSL,1);
  404. if (Stretch)
  405. {
  406. int Col,i,ColCount;
  407. I3(MOV,R8,NONE,R9); //Src0
  408. I2C(LDR,R6,SP,OFS(stack,SrcPitch));
  409. I3S(MOV,R4,NONE,R7,LSR,4);
  410. I2C(ADD,R0,R7,p->RScaleY);
  411. I3S(RSB,R4,R4,R0,LSR,4);
  412. I3(MUL,R4,R6,R4);
  413. I3(ADD,R14,R9,R4); //Src1
  414. EndOfLine = Label(0);
  415. LoopX = Label(1);
  416. ColCount = 16;
  417. for (i=1;i<4 && !(p->RScaleX & i);i<<=1)
  418. ColCount >>= 1;
  419. for (Col=0;Col<ColCount;Col+=4)
  420. {
  421. int Inc[4];
  422. for (i=0;i<4;++i)
  423. Inc[i] = (((Col+i+1) * p->RScaleX) >> 4) - (((Col+i) * p->RScaleX) >> 4);
  424. RGB_4X2S(p,Inc);
  425. I3(CMP,NONE,R10,R11);
  426. if (Col+4 >= ColCount) 
  427. I0P(B,NE,LoopX);
  428. else
  429. I0P(B,EQ,EndOfLine);
  430. }
  431. InstPost(EndOfLine);
  432. I2C(LDR,R6,SP,OFS(stack,SrcPitch));
  433. I3S(MOV,R4,NONE,R7,LSR,4);
  434. I2C(ADD,R7,R7,2*p->RScaleY);
  435. I3S(RSB,R4,R4,R7,LSR,4);
  436. I3(MUL,R4,R6,R4);
  437. I3(ADD,R9,R9,R4); //add 2 lines
  438. }
  439. else
  440. {
  441. LoopX = Label(1);
  442. RGB_4X2(p);
  443. I3(CMP,NONE,R10,R11);
  444. I0P(B,NE,LoopX);
  445. I2C(LDR,R0,SP,OFS(stack,SrcNext));
  446. I3(ADD,R9,R9,R0);
  447. }
  448. I2C(LDR,R1,SP,OFS(stack,DstNext));
  449. I2C(LDR,R2,SP,OFS(stack,EndOfRect));
  450. I2C(LDR,R0,SP,OFS(stack,Width)); // needed for next EndOfLine
  451. I3(ADD,R11,R11,R1);
  452. I3(CMP,NONE,R2,R11);
  453. I0P(B,NE,LoopY);
  454. I2C(ADD,SP,SP,OFS(stack,StackFrame));
  455. CodeEnd();
  456. if (p->LookUp)
  457. {
  458. Align(16);
  459. InstPost(p->LookUp);
  460. }
  461. }
  462. #endif