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

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: overlay_hires.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. #if defined(TARGET_PALMOS)
  25. #include "../palmos/pace.h"
  26. #ifdef HAVE_PALMONE_SDK
  27. #include <68K/System/PalmDisplayExtent.h>
  28. static UInt16 DEX = sysInvalidRefNum;
  29. #endif
  30. #undef CPU_TYPE
  31. #define CPU_TYPE CPU_68K
  32. #include "RotationMgrLib.h"
  33. static UInt16 RotM = sysInvalidRefNum;
  34. typedef struct xscaledesc
  35. {
  36. uint32_t Next;
  37. uint32_t Base;
  38. uint32_t Id;
  39. uint32_t Cmd;
  40. } xscaledesc;
  41. typedef struct hiresbuffer
  42. {
  43. block Buffer;
  44. uint32_t DescPhy;
  45. xscaledesc* Desc;
  46. uint32_t SurfacePhy;
  47. uint8_t* Surface;
  48. } hiresbuffer;
  49. #define MAGIC 0xBABE0000
  50. #define XSCALE_LCD_BASE 0x44000000
  51. #define LCCR0 (0x000/4)
  52. #define LCCR1 (0x004/4)
  53. #define LCCR2 (0x008/4)
  54. #define LCCR3 (0x00C/4)
  55. #define LCCR4 (0x010/4)
  56. #define LCCR5 (0x014/4)
  57. #define LCSR0 (0x038/4)
  58. #define LCSR1 (0x034/4)
  59. #define FBR0 (0x020/4)
  60. #define FDADR0 (0x200/4)
  61. #define FSADR0 (0x204/4)
  62. #define FIDR0 (0x208/4)
  63. #define OMAP_LCD_BASE 0xfffec000
  64. #define OMAP_DMA_BASE 0xfffedb00
  65. #define OMAP_PAL_SIZE 32
  66. #define OMAP_CONTROL 0
  67. #define OMAP_TIMING0 1
  68. #define OMAP_TIMING1 2
  69. #define OMAP_TIMING2 3
  70. #define OMAP_STATUS  4
  71. #define OMAP_DMA_CONTROL 0
  72. #define OMAP_DMA_TOP_L 1
  73. #define OMAP_DMA_TOP_U 2
  74. #define OMAP_DMA_BOTTOM_L 3
  75. #define OMAP_DMA_BOTTOM_U 4
  76. typedef struct hires hires;
  77. typedef int (*hiresfunc)(hires* This);
  78. struct hires
  79. {
  80. overlay Overlay;
  81. bool_t UseLocking;
  82. bool_t Locked;
  83. char* Bits;
  84. int Offset;
  85. int BufferCount;
  86. hiresbuffer Buffer[3];
  87. int Next;
  88. int PhyWidth;
  89. int PhyHeight;
  90. int SurfaceSize;
  91. int SurfaceOffset;
  92. int OrigPitch;
  93. uint32_t OrigPhy;
  94. uint32_t OrigPhyEnd;
  95. int Border[4];
  96. volatile uint32_t* Regs;
  97. volatile uint16_t* Regs2;
  98. int Caps;
  99. int Model;
  100. bool_t UseBorder;
  101. bool_t TripleBuffer;
  102. bool_t LowLevelFailed;
  103. hiresfunc LowLevelAlloc;
  104. hiresfunc LowLevelGet;
  105. hiresfunc LowLevelGetOrig;
  106. hiresfunc LowLevelSetOrig;
  107. hiresfunc LowLevelFlip;
  108. };
  109. static char* GetBits()
  110. {
  111. BitmapType* Bitmap;
  112. WinHandle Win = WinGetDisplayWindow();
  113. if (!Win)
  114. return NULL;
  115. Bitmap = WinGetBitmap(Win);
  116. if (!Bitmap)
  117. return NULL;
  118. return BmpGetBits(Bitmap);
  119. }
  120. static bool_t ProcessRawInfo(video* Video,char* Bits,char* RawBits,int Width,int Height,int Pitch,int* Offset,bool_t MovedSIP)
  121. {
  122. int Dir = GetOrientation();
  123. Video->Pitch = Pitch;
  124. if (Width > Height) // native landscape device
  125. Dir = CombineDir(Dir,DIR_SWAPXY|DIR_MIRRORUPDOWN,0);
  126. // trust GetBits() if it's inside the Raw buffer
  127. if (Bits >= RawBits && Bits < RawBits + Height*Pitch) 
  128. return 0; 
  129. if (!MovedSIP && Dir==0) // assuming working GetBits() with RotM in native mode
  130. return 0; 
  131. if (Dir & DIR_SWAPXY)
  132. SwapInt(&Video->Width,&Video->Height);
  133. if (Width > Height) // native landscape device
  134. {
  135. if ((Dir & DIR_SWAPXY)==0 ? GetHandedness() : (Dir & DIR_MIRRORLEFTRIGHT)!=0)
  136. *Offset = (Width-Video->Width)*(Video->Pixel.BitCount >> 3);
  137. }
  138. else 
  139. {
  140. // native portrait device
  141. if ((Dir & DIR_SWAPXY) && MovedSIP) // don't adjust for RotM (SIP stays on native bottom)
  142. {
  143. // assuming taskbar and SIP is in the upper part of the screen in landscape mode
  144. if (Height > 320+32 && Video->Height <= 320+32 && DIASupported() && !DIAGet(DIA_SIP))
  145. Height = 320+32; // closed slider on Tungsten T3
  146. *Offset = (Height-Video->Height)*Pitch;
  147. }
  148. }
  149. Video->Direction = Dir;
  150. return 1;
  151. }
  152. char* QueryScreen(video* Video,int* Offset,int* Mode)
  153. {
  154. char* Bits = GetBits(); 
  155. QueryDesktop(Video);
  156. *Offset = 0;
  157. if (Mode) *Mode = 0;
  158. #ifdef HAVE_PALMONE_SDK
  159. if (DEX != sysInvalidRefNum)
  160. {
  161. UInt16 Pitch;
  162. Coord Width,Height;
  163. char* RawBits = DexGetDisplayAddress(DEX);
  164. if (RawBits)
  165. {
  166. DexGetDisplayDimensions(DEX,&Width,&Height,&Pitch);
  167. if (ProcessRawInfo(Video,Bits,RawBits,Width,Height,Pitch,Offset,1))
  168. {
  169. if (Mode) *Mode = 1;
  170. return RawBits;
  171. }
  172. }
  173. }
  174. #endif
  175. if (RotM != sysInvalidRefNum)
  176. {
  177. UInt32 RawBits;
  178. UInt32 Width,Height,Pitch;
  179. if (RotationMgrAttributeGet(RotM,kRotationMgrAttrDisplayAddress,&RawBits)==errNone && RawBits &&
  180. RotationMgrAttributeGet(RotM,kRotationMgrAttrDisplayWidth,&Width)==errNone &&
  181. RotationMgrAttributeGet(RotM,kRotationMgrAttrDisplayHeight,&Height)==errNone &&
  182. RotationMgrAttributeGet(RotM,kRotationMgrAttrDisplayRowBytes,&Pitch)==errNone &&
  183. ProcessRawInfo(Video,Bits,(char*)RawBits,Width,Height,Pitch,Offset,0))
  184. {
  185. if (Mode) *Mode = 2;
  186. return (char*)RawBits;
  187. }
  188. }
  189. if (Video->Pitch < Video->Width*(Video->Pixel.BitCount/8))
  190. return NULL;
  191. return Bits;
  192. }
  193. static int BufferFree(hires* p)
  194. {
  195. int n;
  196. for (n=0;n<p->BufferCount;++n)
  197. FreeBlock(&p->Buffer[n].Buffer);
  198. p->BufferCount = 0;
  199. memset(&p->Buffer,0,sizeof(p->Buffer));
  200. return ERR_NONE;
  201. }
  202. static int Init(hires* p)
  203. {
  204. int Mode;
  205. p->Overlay.SetFX = BLITFX_AVOIDTEARING;
  206. p->UseLocking = 0;
  207. if (QueryPlatform(PLATFORM_MODEL)==MODEL_ZODIAC)
  208. {
  209. int Dir = GetOrientation();
  210. if (Dir & DIR_SWAPXY)
  211. {
  212. p->Overlay.SetFX |= BLITFX_VMEMROTATED;
  213. if (Dir & DIR_MIRRORLEFTRIGHT)
  214. p->Overlay.SetFX |= BLITFX_VMEMUPDOWN;
  215. }
  216. }
  217. p->Bits = QueryScreen(&p->Overlay.Output.Format.Video,&p->Offset,&Mode);
  218. if (!p->Bits)
  219. return ERR_INVALID_PARAM;
  220. if (!Mode)
  221. p->Bits = NULL; // use GetBits() during Lock()
  222. p->OrigPitch = p->Overlay.Output.Format.Video.Pitch;
  223. p->Next = 0;
  224. p->LowLevelFailed = 0;
  225. return ERR_NONE;
  226. }
  227. static void Hide(hires* p)
  228. {
  229. if (p->Overlay.Overlay)
  230. {
  231. p->LowLevelSetOrig(p);
  232. p->Overlay.Overlay = 0;
  233. p->Overlay.Output.Format.Video.Pitch = p->OrigPitch;
  234. }
  235. }
  236. static void Done(hires* p)
  237. {
  238. Hide(p);
  239. BufferFree(p);
  240. }
  241. static int UpdateAlloc(hires* p)
  242. {
  243. int MaxCount = 1;
  244. if (p->TripleBuffer)
  245. MaxCount = 3;
  246. if (p->UseBorder)
  247. {
  248. p->SurfaceSize = (p->PhyWidth+p->Border[0]+p->Border[1])*(p->PhyHeight+p->Border[2]+p->Border[3])*2;
  249. p->SurfaceOffset = ((p->PhyWidth+p->Border[0]+p->Border[1])*p->Border[2]+p->Border[0])*2;
  250. }
  251. else
  252. {
  253. p->SurfaceSize = p->PhyWidth*p->PhyHeight*2;
  254. p->SurfaceOffset = 0;
  255. }
  256. while (p->BufferCount<MaxCount)
  257. if (p->LowLevelAlloc(p) == ERR_NONE)
  258. ++p->BufferCount;
  259. else
  260. break;
  261. if (p->BufferCount==2)
  262. {
  263. FreeBlock(&p->Buffer[1].Buffer);
  264. --p->BufferCount;
  265. }
  266. if (!p->BufferCount)
  267. return ERR_OUT_OF_MEMORY;
  268. return ERR_NONE;
  269. }
  270. static int Update(hires* p)
  271. {
  272. if (p->Overlay.FullScreenViewport && (p->UseBorder || p->TripleBuffer) && 
  273. !p->LowLevelFailed && (p->Overlay.Overlay || (p->LowLevelGetOrig && p->LowLevelGetOrig(p)==ERR_NONE)))
  274. {
  275. p->Overlay.Overlay = 1;
  276. if (UpdateAlloc(p)!=ERR_NONE || (p->BufferCount<3 && !p->UseBorder))
  277. {
  278. Hide(p);
  279. p->LowLevelFailed = 1;
  280. BufferFree(p);
  281. }
  282. else
  283. {
  284. int n;
  285. for (n=0;n<p->BufferCount;++n)
  286. memset(p->Buffer[n].Surface,0,p->SurfaceSize);
  287. }
  288. }
  289. else
  290. Hide(p);
  291. p->Overlay.DoPowerOff = p->Overlay.Overlay;
  292. return OverlayUpdateAlign(&p->Overlay);
  293. }
  294. static int Show(hires* p)
  295. {
  296. if (!p->Overlay.Show && p->Overlay.Overlay)
  297. {
  298. p->LowLevelSetOrig(p);
  299. p->Next = 0;
  300. }
  301. return ERR_NONE;
  302. }
  303. static int Reset(hires* p)
  304. {
  305. int Pitch = p->Overlay.Output.Format.Video.Pitch;
  306. Init(p);
  307. if (p->Overlay.Overlay)
  308. p->Overlay.Output.Format.Video.Pitch = Pitch;
  309. return ERR_NONE;
  310. }
  311. static int Lock(hires* p, planes Planes, bool_t OnlyAligned)
  312. {
  313. if (p->Overlay.Overlay)
  314. {
  315. int Next = p->Next+1;
  316. if (Next == p->BufferCount) 
  317. Next = 0;
  318. // use new buffer only if it's not the current
  319. if (p->LowLevelGet(p) != Next) 
  320. p->Next = Next;
  321. Planes[0] = p->Buffer[p->Next].Surface + p->SurfaceOffset;
  322. }
  323. else
  324. if (p->UseLocking && p->Overlay.CurrTime>=0 &&  // don't use locking with benchmark
  325. (Planes[0] = WinScreenLock(p->Overlay.Dirty?winLockCopy:winLockDontCare)) != NULL)
  326. p->Locked = 1;
  327. else
  328. if (p->Bits)
  329. Planes[0] = p->Bits + p->Offset;
  330. else
  331. {
  332. char* Bits = GetBits();
  333. if (!Bits)
  334. return ERR_DEVICE_ERROR;
  335. Planes[0] = Bits;
  336. }
  337. return ERR_NONE;
  338. }
  339. static int Unlock(hires* p)
  340. {
  341. if (p->Overlay.Overlay)
  342. return p->LowLevelFlip(p);
  343. else
  344. if (p->Locked)
  345. WinScreenUnlock();
  346. return ERR_NONE;
  347. }
  348. //-------------------------------------------------------------------------------
  349. static int XScaleGetOrig(hires* p)
  350. {
  351. int ReTry = 0;
  352. do
  353. {
  354. ThreadSleep(2);
  355. if (++ReTry == 5) return ERR_NOT_SUPPORTED;
  356. }
  357. while (!(p->Regs[LCCR0] & 1)); // again if lcd disabled
  358. p->PhyWidth = (p->Regs[LCCR1] & 0x3FF)+1;
  359. p->PhyHeight = (p->Regs[LCCR2] & 0x3FF)+1;
  360. if (p->Overlay.Output.Format.Video.Width > p->PhyWidth ||
  361. p->Overlay.Output.Format.Video.Height > p->PhyHeight)
  362. return ERR_NOT_SUPPORTED; // this shouldn't happen
  363. p->OrigPhy = p->Regs[FDADR0];
  364. if (!p->OrigPhy)
  365. return ERR_NOT_SUPPORTED; // this shouldn't happen
  366. // assuming physical direction and size is already correct
  367. p->Overlay.Output.Format.Video.Pitch = p->PhyWidth*2;
  368. if (p->UseBorder)
  369. p->Overlay.Output.Format.Video.Pitch += (p->Border[0]+p->Border[1])*2;
  370. return ERR_NONE;
  371. }
  372. static int XScaleAlloc(hires* p)
  373. {
  374. hiresbuffer* Buffer = p->Buffer+p->BufferCount;
  375. if (!AllocBlock(16+sizeof(xscaledesc)+256+p->SurfaceSize,&Buffer->Buffer,0,HEAP_ANYWR))
  376. return ERR_OUT_OF_MEMORY;
  377. Buffer->Desc = (xscaledesc*)ALIGN16((uintptr_t)Buffer->Buffer.Ptr);
  378. Buffer->DescPhy = MemVirtToPhy(Buffer->Desc);
  379. if (!Buffer->DescPhy)
  380. {
  381. FreeBlock(&Buffer->Buffer);
  382. return ERR_NOT_SUPPORTED;
  383. }
  384. Buffer->Surface = (uint8_t*)Buffer->Desc+sizeof(xscaledesc)+256;
  385. Buffer->SurfacePhy = Buffer->DescPhy+sizeof(xscaledesc)+256; 
  386. Buffer->Desc->Base = Buffer->SurfacePhy;
  387. Buffer->Desc->Id = MAGIC|(p->BufferCount << 4); 
  388. Buffer->Desc->Next = Buffer->DescPhy; 
  389. Buffer->Desc->Cmd = p->SurfaceSize | (1<<21);
  390. return ERR_NONE;
  391. }
  392. static int XScaleGet(hires* p)
  393. {
  394. int Id = p->Regs[FIDR0] & ~15;
  395. uint32_t Phy = p->Regs[FDADR0] & ~15;
  396. if ((Id & 0xFFFF0000) == MAGIC)
  397. return (Id >> 4) & 0xFF;
  398. if (Phy == p->OrigPhy || Phy == p->OrigPhy+sizeof(xscaledesc))
  399. return -1;
  400. p->OrigPhy = Phy; // changed...
  401. return -1; 
  402. }
  403. static void XScaleQuickDisable(hires* p)
  404. {
  405. int n = p->Regs[LCCR0];
  406. n &= ~(1<<10); //DIS
  407. n &= ~1;    //ENB
  408. p->Regs[LCCR0] = n;
  409. ThreadSleep(1);
  410. }
  411. static void XScaleDisable(hires* p)
  412. {
  413. int i;
  414. int n = p->Regs[LCCR0];
  415. if (n & 1)
  416. {
  417. n |= 1<<10; //DIS
  418. p->Regs[LCCR0] = n;
  419. for (i=0;i<30;++i)
  420. {
  421. if (!(p->Regs[LCCR0] & 1)) 
  422. break;
  423. ThreadSleep(1);
  424. }
  425. if (i==30)
  426. XScaleQuickDisable(p);
  427. }
  428. }
  429. static void XScaleEnable(hires* p,uint32_t Phy)
  430. {
  431. int n = p->Regs[LCCR0];
  432. n &= ~(1<<10); //DIS
  433. n |= 1; //EN;
  434. p->Regs[FBR0] = 0;
  435. p->Regs[FDADR0] = Phy;
  436. p->Regs[LCCR0] = n;
  437. ThreadSleep(1);
  438. }
  439. static NOINLINE bool_t TimeAdjust(volatile uint32_t* p,int x,int left,int right,bool_t UseBorder)
  440. {
  441. int o1,o2;
  442. uint32_t n;
  443. uint32_t v = *p;
  444. if (UseBorder)
  445. x += left+right;
  446. --x;
  447. n = v & 0x3FF;
  448. if ((int)n == x)
  449. return 0;
  450. v &= ~0x3FF;
  451. v |= x;
  452. x -= n;
  453. if (x>=left)
  454. o1 = left;
  455. else
  456. if (x<=-left)
  457. o1 = -left;
  458. else
  459. o1 = x >> 1;
  460. o2 = x - o1;
  461. n = (v >> 16) & 0xFF;
  462. v &= ~0xFF0000;
  463. v |= (n-o2) << 16; 
  464. n = (v >> 24) & 0xFF;
  465. v &= ~0xFF000000;
  466. v |= (n-o1) << 24; 
  467. *p = v;
  468. return 1;
  469. }
  470. static NOINLINE bool_t Adjust(hires* p,volatile uint32_t* p1,volatile uint32_t* p2,bool_t UseBorder)
  471. {
  472. bool_t Changed;
  473. Changed = TimeAdjust(p1,p->PhyWidth,p->Border[0],p->Border[1],UseBorder);
  474. Changed = TimeAdjust(p2,p->PhyHeight,p->Border[2],p->Border[3],UseBorder) || Changed;
  475. return Changed;
  476. }
  477. static void XScaleChange(hires* p,uint32_t Phy,bool_t UseBorder)
  478. {
  479. XScaleDisable(p);
  480. if (Adjust(p,&p->Regs[LCCR1],&p->Regs[LCCR2],UseBorder))
  481. {
  482. // PXA270 bug. need to enable/disable twice
  483. XScaleEnable(p,Phy);
  484. XScaleDisable(p);
  485. }
  486. XScaleEnable(p,Phy);
  487. }
  488. static int XScaleSetOrig(hires* p)
  489. {
  490. if (XScaleGet(p)>=0)
  491. XScaleChange(p,p->OrigPhy,0);
  492. return ERR_NONE;
  493. }
  494. static int XScaleFlip(hires* p)
  495. {
  496. uint32_t DescPhy = p->Buffer[p->Next].DescPhy;
  497. p->Buffer[p->Next].Desc->Next = DescPhy; // close chain
  498. if (!(p->Regs[LCCR0] & 1)) // is lcd enabled?
  499. return ERR_DEVICE_ERROR;
  500. if (XScaleGet(p)<0)
  501. XScaleChange(p,DescPhy,p->UseBorder);
  502. else
  503. {
  504. // modify last frames tail to new frame
  505. int Current = p->Next-1;
  506. if (Current<0)
  507. Current = p->BufferCount-1;
  508. p->Buffer[Current].Desc->Next = DescPhy;
  509. }
  510. return ERR_NONE;
  511. }
  512. //-------------------------------------------------------------------------------
  513. static int OMAPGetOrig(hires* p)
  514. {
  515. int ReTry = 0;
  516. do
  517. {
  518. ThreadSleep(1);
  519. if (++ReTry == 5) return ERR_NOT_SUPPORTED;
  520. }
  521. while (!(p->Regs[OMAP_CONTROL] & 1)); // again if lcd disabled
  522. p->PhyWidth = (p->Regs[OMAP_TIMING0] & 0x3FF)+1;
  523. p->PhyHeight = (p->Regs[OMAP_TIMING1] & 0x3FF)+1;
  524. if (p->Overlay.Output.Format.Video.Width > p->PhyWidth ||
  525. p->Overlay.Output.Format.Video.Height > p->PhyHeight)
  526. return ERR_NOT_SUPPORTED; // this shouldn't happen
  527. p->OrigPhy = (p->Regs2[OMAP_DMA_TOP_U] << 16) | p->Regs2[OMAP_DMA_TOP_L];
  528. p->OrigPhyEnd = (p->Regs2[OMAP_DMA_BOTTOM_U] << 16) | p->Regs2[OMAP_DMA_BOTTOM_L];
  529. if (!p->OrigPhy)
  530. return ERR_NOT_SUPPORTED; // this shouldn't happen
  531. // assuming physical direction and size is already correct
  532. p->Overlay.Output.Format.Video.Pitch = p->PhyWidth*2;
  533. if (p->UseBorder)
  534. p->Overlay.Output.Format.Video.Pitch += (p->Border[0]+p->Border[1])*2;
  535. return ERR_NONE;
  536. }
  537. static int OMAPAlloc(hires* p)
  538. {
  539. hiresbuffer* Buffer = p->Buffer+p->BufferCount;
  540. if (!AllocBlock(p->SurfaceSize+16+OMAP_PAL_SIZE,&Buffer->Buffer,0,HEAP_ANYWR))
  541. return ERR_OUT_OF_MEMORY;
  542. Buffer->Surface = (uint8_t*)ALIGN16((uintptr_t)Buffer->Buffer.Ptr)+OMAP_PAL_SIZE;
  543. memset(Buffer->Surface-OMAP_PAL_SIZE,0,OMAP_PAL_SIZE); //clear palette
  544. Buffer->Surface[-OMAP_PAL_SIZE+1] = 0x40; //set 16bit mode framebuffer
  545. Buffer->SurfacePhy = MemVirtToPhy(Buffer->Surface);
  546. if (!Buffer->SurfacePhy)
  547. {
  548. FreeBlock(&Buffer->Buffer);
  549. return ERR_NOT_SUPPORTED;
  550. }
  551. return ERR_NONE;
  552. }
  553. static int OMAPGet(hires* p)
  554. {
  555. uint32_t Phy = p->Regs2[OMAP_DMA_TOP_L] | (p->Regs2[OMAP_DMA_TOP_U] << 16);
  556. int n;
  557. for (n=0;n<p->BufferCount;++n)
  558. if (Phy == p->Buffer[n].SurfacePhy-OMAP_PAL_SIZE)
  559. return 0;
  560. p->OrigPhy = Phy;
  561. return -1; 
  562. }
  563. static void OMAPDisable(hires* p)
  564. {
  565. int i;
  566. int n = p->Regs[OMAP_CONTROL];
  567. if (n & 1)
  568. {
  569. n &= ~1;
  570. p->Regs[OMAP_CONTROL] = n;
  571. for (i=0;i<50;++i)
  572. {
  573. if (p->Regs[OMAP_STATUS] & 1) 
  574. break;
  575. ThreadSleep(1);
  576. }
  577. }
  578. }
  579. static void OMAPEnable(hires* p)
  580. {
  581. int v = p->Regs[OMAP_CONTROL];
  582. v |= 1;
  583. p->Regs[OMAP_CONTROL] = v;
  584. ThreadSleep(1);
  585. }
  586. static void OMAPChange(hires* p,uint32_t Phy,uint32_t PhyEnd,bool_t UseBorder)
  587. {
  588. bool_t Old = (p->Regs[OMAP_CONTROL] & 1);
  589. OMAPDisable(p);
  590. Adjust(p,&p->Regs[OMAP_TIMING0],&p->Regs[OMAP_TIMING1],UseBorder);
  591. p->Regs2[OMAP_DMA_TOP_U] = (uint16_t)(Phy >> 16);
  592. p->Regs2[OMAP_DMA_TOP_L] = (uint16_t)(Phy);
  593. p->Regs2[OMAP_DMA_BOTTOM_U] = (uint16_t)(PhyEnd >> 16);
  594. p->Regs2[OMAP_DMA_BOTTOM_L] = (uint16_t)(PhyEnd);
  595. if (Old) OMAPEnable(p);
  596. }
  597. static int OMAPSetOrig(hires* p)
  598. {
  599. if (OMAPGet(p)>=0)
  600. OMAPChange(p,p->OrigPhy,p->OrigPhyEnd,0);
  601. return ERR_NONE;
  602. }
  603. static int OMAPFlip(hires* p)
  604. {
  605. if (!(p->Regs[OMAP_CONTROL] & 1)) // is lcd enabled?
  606. return ERR_DEVICE_ERROR;
  607. if (OMAPGet(p)<0)
  608. OMAPChange(p,p->Buffer[0].SurfacePhy-OMAP_PAL_SIZE,p->Buffer[0].SurfacePhy+p->SurfaceSize-2,p->UseBorder);
  609. return ERR_NONE;
  610. }
  611. //-------------------------------------------------------------------------------
  612. static const datatable Params[] = 
  613. {
  614. { HIRES_TRIPLEBUFFER, TYPE_BOOL, DF_SETUP|DF_CHECKLIST },
  615. { HIRES_USEBORDER, TYPE_BOOL, DF_SETUP|DF_CHECKLIST },
  616. { HIRES_USEBORDER_INFO, TYPE_LABEL, DF_SETUP },
  617. DATATABLE_END(HIRES_ID)
  618. };
  619. static int Enum(hires* p, int* No, datadef* Param)
  620. {
  621. int Result;
  622. if (OverlayEnum(&p->Overlay,No,Param)==ERR_NONE)
  623. return ERR_NONE;
  624. Result = NodeEnumTable(No,Param,Params);
  625. if (Result==ERR_NONE)
  626. {
  627. if (Param->No == HIRES_TRIPLEBUFFER && (!p->Regs || !(p->Caps & CAPS_ARM_XSCALE)))
  628. Param->Flags |= DF_HIDDEN;
  629. if (Param->No == HIRES_USEBORDER && !p->Regs)
  630. Param->Flags |= DF_HIDDEN;
  631. }
  632. return Result;
  633. }
  634. static int Get(hires* p,int No,void* Data,int Size)
  635. {
  636. int Result = OverlayGet(&p->Overlay,No,Data,Size);
  637. switch (No) 
  638. {
  639. case HIRES_TRIPLEBUFFER: GETVALUE(p->TripleBuffer,bool_t); break;
  640. case HIRES_USEBORDER: GETVALUE(p->UseBorder,bool_t); break;
  641. }
  642. return Result;
  643. }
  644. static int UpdateLowLevel(hires* p)
  645. {
  646. p->LowLevelFailed = 0;
  647. Hide(p);
  648. BufferFree(p);
  649. OverlayUpdateFX(&p->Overlay,1);
  650. return ERR_NONE;
  651. }
  652. static int Set(hires* p,int No,const void* Data,int Size)
  653. {
  654. int Result = OverlaySet(&p->Overlay,No,Data,Size);
  655. switch (No)
  656. {
  657. case HIRES_TRIPLEBUFFER: SETVALUECMP(p->TripleBuffer,bool_t,UpdateLowLevel(p),EqBool); break;
  658. case HIRES_USEBORDER: SETVALUECMP(p->UseBorder,bool_t,UpdateLowLevel(p),EqBool); break;
  659. }
  660. return Result;
  661. }
  662. extern bool_t SwapLandscape;
  663. static int Create(hires* p)
  664. {
  665. p->Overlay.Node.Enum = (nodeenum)Enum;
  666. p->Overlay.Node.Get = (nodeget)Get;
  667. p->Overlay.Node.Set = (nodeset)Set;
  668. p->Overlay.Init = (ovlfunc)Init;
  669. p->Overlay.Done = (ovldone)Done;
  670. p->Overlay.Reset = (ovlfunc)Reset;
  671. p->Overlay.Lock = (ovllock)Lock;
  672. p->Overlay.Unlock = (ovlfunc)Unlock;
  673. p->Overlay.UpdateShow = (ovlfunc)Show;
  674. p->Overlay.Update = (ovlfunc)Update;
  675. p->Caps = QueryPlatform(PLATFORM_CAPS);
  676. if (p->Caps & CAPS_ARM_XSCALE)
  677. {
  678. p->Regs = (volatile uint32_t*)MemPhyToVirt(XSCALE_LCD_BASE);
  679. if (p->Regs)
  680. {
  681. p->LowLevelGet = XScaleGet;
  682. p->LowLevelGetOrig = XScaleGetOrig;
  683. p->LowLevelSetOrig = XScaleSetOrig;
  684. p->LowLevelFlip = XScaleFlip;
  685. p->LowLevelAlloc = XScaleAlloc;
  686. p->Border[0] = 2;
  687. p->Border[1] = 2;
  688. p->Border[2] = p->Border[3] = 2;
  689. }
  690. }
  691. else
  692. {
  693. p->Regs = (volatile uint32_t*)MemPhyToVirt(OMAP_LCD_BASE);
  694. p->Regs2 = (volatile uint16_t*)MemPhyToVirt(OMAP_DMA_BASE);
  695. if (!p->Regs || !p->Regs2)
  696. {
  697. p->Regs = NULL;
  698. p->Regs2 = NULL;
  699. }
  700. else
  701. {
  702. p->LowLevelGet = OMAPGet;
  703. p->LowLevelGetOrig = OMAPGetOrig;
  704. p->LowLevelSetOrig = OMAPSetOrig;
  705. p->LowLevelFlip = OMAPFlip;
  706. p->LowLevelAlloc = OMAPAlloc;
  707. p->Border[0] = 14; // OMAP width has to be multiple of 16
  708. p->Border[1] = 2;
  709. p->Border[2] = p->Border[3] = 2;
  710. }
  711. }
  712. p->Model = QueryPlatform(PLATFORM_MODEL);
  713. // don't use triple buffering on 320x320 devices by default
  714. p->TripleBuffer = (Context()->StartUpMemory > 3*1024*1024) &&
  715. (p->Model==MODEL_TUNGSTEN_T3 ||
  716. p->Model==MODEL_TUNGSTEN_T5 ||
  717. p->Model==MODEL_PALM_TX ||
  718. p->Model==MODEL_LIFEDRIVE);
  719. // only device always supporting borderless mode is LifeDrive (?)
  720. p->UseBorder = 
  721. p->Model==MODEL_LIFEDRIVE ||
  722. p->Model==MODEL_PALM_TX;
  723. return ERR_NONE;
  724. }
  725. static const nodedef HIRES = 
  726. {
  727. sizeof(hires)|CF_GLOBAL|CF_SETTINGS,
  728. HIRES_ID,
  729. OVERLAY_CLASS,
  730. PRI_DEFAULT+10,
  731. (nodecreate)Create,
  732. };
  733. void OverlayHIRES_Init() 
  734. {
  735. #ifdef HAVE_PALMONE_SDK
  736. if (SysLibFind(dexLibName, &DEX) == sysErrLibNotFound)
  737. SysLibLoad(dexLibType, dexLibCreator, &DEX);
  738. if (DEX != sysInvalidRefNum && SysLibOpen(DEX)!=errNone)
  739. DEX = sysInvalidRefNum;
  740. #endif
  741. if (SysLibFind(kRotationMgrLibName, &RotM) == sysErrLibNotFound)
  742. SysLibLoad(kRotationMgrLibType, kRotationMgrLibCreator, &RotM);
  743. if (RotM != sysInvalidRefNum && SysLibOpen(RotM)!=errNone)
  744. RotM = sysInvalidRefNum;
  745. if (RotM != sysInvalidRefNum)
  746. {
  747. UInt32 Width,Height;
  748. if (RotationMgrAttributeGet(RotM,kRotationMgrAttrDisplayWidth,&Width)==errNone &&
  749. RotationMgrAttributeGet(RotM,kRotationMgrAttrDisplayHeight,&Height)==errNone &&
  750. Width < Height) // native portrait -> landscape modes are swapped by Mobile Stream
  751. SwapLandscape = 1;
  752. }
  753. NodeRegisterClass(&HIRES);
  754. }
  755. void OverlayHIRES_Done() 
  756. {
  757. NodeUnRegisterClass(HIRES_ID);
  758. #ifdef HAVE_PALMONE_SDK
  759. if (DEX != sysInvalidRefNum)
  760. {
  761. SysLibClose(DEX);
  762. DEX = sysInvalidRefNum;
  763. }
  764. #endif
  765. if (RotM != sysInvalidRefNum)
  766. {
  767. SysLibClose(RotM);
  768. RotM = sysInvalidRefNum;
  769. }
  770. }
  771. #endif