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

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: intel2700g.c 607 2006-01-22 20:58:29Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "stdafx.h"
  24. #include "gxvadd.h"
  25. #if defined(ARM)
  26. #define VSYNC_WORKAROUND
  27. typedef struct pvr
  28. {
  29. overlay p;
  30. idct IdctVMT;
  31. // idct
  32. int mx,my;
  33. int SubPos;
  34. int ImageWrite[3];
  35. int MCompType;
  36. int FetchA[2][2];
  37. int Width16;
  38. int Height16;
  39. // vsync
  40. #ifdef VSYNC_WORKAROUND
  41. bool_t SetupVSync;
  42. bool_t DisableVSync;
  43. int* VSyncPtr;
  44. int VSyncTotal; // total units
  45. int VSyncBottom;   // start of vsync
  46. int VSyncLimit; // units per 1msec
  47. tick_t VSyncRefresh;
  48. #endif
  49. GXVAError (*M24VA_FrameDimensions)(gx_uint32 ui32Height, gx_uint32 ui32Width);
  50. GXVAError (*M24VA_FrameAllocate)(SMSurface *phFrames, gx_uint32 ui32FrameCnt);
  51. GXVAError (*M24VA_FrameFree)(SMSurface *phFrames, gx_uint32 ui32FrameCnt);
  52. GXVAError (*M24VA_BeginFrame)(SMSurface hOutputSurface, gx_bool bEnableIDCT);
  53. GXVAError (*M24VA_EndFrame)(gx_bool bSyncHardware);
  54. GXVAError (*M24VA_SetReferenceFrameAddress)(gx_uint32 ui32FrameNo, SMSurface hSurface);
  55. GXVAError (*M24VA_FrameBeginAccess)(SMSurface hSurface, gx_uint8 **ppuint8FrameAddress, gx_uint32 *pui32FrameStride, gx_bool bSyncHardware);
  56. GXVAError (*M24VA_FrameEndAccess)(SMSurface hSurface);
  57. GXVAError (*M24VA_WriteIZZBlock)(gx_int32 *pi32Data, gx_uint32 ui32Count);
  58. GXVAError (*M24VA_WriteIZZData)(gx_int32 i32Coeff, gx_uint32 ui32Index, gx_bool bEOB);
  59. GXVAError (*M24VA_SetIZZMode)(GXVA_IZZMODE eMode);
  60. GXVAError (*M24VA_WriteResidualDifferenceData)(gx_int16 *pi16Data, gx_uint32 ui32Count); 
  61. GXVAError (*M24VA_WriteMCCmdData)(gx_uint32 ui32Data);
  62. GXVAError (*M24VA_FCFrameAllocate)(SMSurface *phFrame, GXVA_SURF_FORMAT eFormat);
  63. GXVAError (*M24VA_FrameConvert)(SMSurface hDestSurface, SMSurface hSourSurface);                                        
  64. GXVAError (*M24VA_Initialise)(void*);
  65. GXVAError (*M24VA_Deinitialise)();
  66. GXVAError (*M24VA_Reset)();
  67. VDISPError (*VDISP_Initialise)(void*);
  68. VDISPError (*VDISP_Deinitialise)();
  69. VDISPError (*VDISP_OverlaySetAttributes)(PVDISP_OVERLAYATTRIBS psOverlayAttributes, SMSurface hSurface);
  70. VDISPError (*VDISP_OverlayFlipSurface)(SMSurface hSurfaceFlipTo, VDISP_DEINTERLACE eDeinterlace);
  71. VDISPError (*VDISP_OverlayContrast)(gx_uint32 ui32Contrast);
  72. VDISPError (*VDISP_OverlayGamma)(gx_uint32 ui32Gamma);
  73. VDISPError (*VDISP_OverlayBrightness)(gx_uint32 ui32Brightness);
  74. VDISPError (*VDISP_OverlaySetColorspaceConversion)(PVDISP_CSCCoeffs psCoeffs);
  75. int16_t IZZ[2*(64+8)];
  76. VDISP_OVERLAYATTRIBS Attribs;
  77. uint8_t* RegBase;
  78. bool_t CloseWMP;
  79. bool_t SetupIDCTRotate;
  80. bool_t M24VA;
  81. bool_t VDISP;
  82. bool_t IDCT;
  83. bool_t YUV422;
  84. bool_t Empty;
  85. bool_t IDCTInit;
  86. bool_t Initing;
  87. bool_t FirstUpdate;
  88. int FirstUpdateTime;
  89. int IDCTMemInit;
  90. int IDCTWidth;
  91. int IDCTHeight;
  92. int AllCount;
  93. int BufCount;
  94. int TempCount;
  95. int ShowNext;
  96. int ShowCurr;
  97. int ShowLast;
  98. int FlipLastTime;
  99. int NativeDirection;
  100. video Overlay;
  101. rect OverlayRect;
  102. blitfx OvlFX;
  103. blitfx SoftFX;
  104. pin IDCTOutput;
  105. bool_t IDCTRounding;
  106. int Brightness;
  107. int Contrast;
  108. int Saturation;
  109. int RGBAdjust[3];
  110. SMSurface Buf[MAXIDCTBUF]; 
  111. planes BufMem[MAXIDCTBUF];
  112. int BufFrameNo[MAXIDCTBUF];
  113. } pvr;
  114. #define PVR(p) ((pvr*)((char*)(p)-(int)&(((pvr*)0)->IdctVMT)))
  115. //------------------------------------------------------------
  116. #define MID 0x3FE0FF0
  117. #define DVT01 0x3FE2164
  118. #define DVT02 0x3FE2168
  119. #define DVT03 0x3FE216C
  120. #define DVLNUM 0x3FE2308
  121. static void GetMode(pvr* p)
  122. {
  123. RawFrameBufferInfo Info;
  124. HDC DC= GetDC(NULL);
  125. memset(&Info,0,sizeof(Info));
  126. ExtEscape(DC, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char*)&Info);
  127. ReleaseDC(NULL,DC);
  128. p->NativeDirection = 0;
  129. #ifdef VSYNC_WORKAROUND
  130. p->VSyncPtr = NULL;
  131. #endif
  132. if (Info.pFramePointer)
  133. {
  134. if (abs(Info.cyStride) < abs(Info.cxPixels * Info.cxStride))
  135. SwapInt(&Info.cxPixels,&Info.cyPixels); // correct possible orientation error
  136. if (abs(Info.cyStride) < abs(Info.cxStride))
  137. {
  138. p->NativeDirection |= DIR_SWAPXY;
  139. if (Info.cxStride<0) 
  140. p->NativeDirection |= DIR_MIRRORUPDOWN;
  141. if (Info.cyStride<0) 
  142. p->NativeDirection |= DIR_MIRRORLEFTRIGHT;
  143. }
  144. else
  145. {
  146. if (Info.cxStride<0) 
  147. p->NativeDirection |= DIR_MIRRORLEFTRIGHT;
  148. if (Info.cyStride<0) 
  149. p->NativeDirection |= DIR_MIRRORUPDOWN;
  150. }
  151. p->NativeDirection = CombineDir(0,p->NativeDirection,GetOrientation());
  152. p->RegBase = (uint8_t*)((uint32_t)Info.pFramePointer & ~(1024*1024-1)); // align to 1MB
  153. #ifdef VSYNC_WORKAROUND
  154. {
  155. int VSyncTop = 0;
  156. p->VSyncTotal = -1;
  157. p->VSyncBottom = 0;
  158. TRY_BEGIN
  159. if ((*(uint32_t*)(p->RegBase+MID) & 0xFFFFFF) == 0x727189) // Intel 2700G ?
  160. {
  161. p->VSyncRefresh = TICKSPERSEC / 60; // todo: find a way to get lcd refresh rate
  162. p->VSyncTotal = *(uint32_t*)(p->RegBase+DVT01) & 4095;
  163. VSyncTop = *(uint32_t*)(p->RegBase+DVT02) & 4095;
  164. p->VSyncBottom = *(uint32_t*)(p->RegBase+DVT03) & 4095;
  165. p->VSyncLimit = Scale(p->VSyncTotal,TICKSPERSEC,p->VSyncRefresh*1000);
  166. }
  167. TRY_END
  168. if (p->VSyncTotal >= p->VSyncBottom && (p->VSyncBottom  - VSyncTop) >= Info.cyPixels)
  169. {
  170. p->VSyncBottom -= 16; // adjust a little
  171. p->VSyncPtr = (int*)(p->RegBase+DVLNUM);
  172. }
  173. }
  174. #endif
  175. }
  176. QueryDesktop(&p->p.Output.Format.Video);
  177. }
  178. static void BufferFormat(pvr* p,video* Format)
  179. {
  180. *Format = p->Overlay;
  181. DefaultPitch(Format);
  182. }
  183. static void ClearIMC4(uint8_t* Ptr,const video* Format)
  184. {
  185. FillColor(Ptr,
  186. Format->Pitch,0,0,Format->Width,Format->Height,8,0);
  187. FillColor(Ptr+Format->Pitch*Format->Height,
  188. Format->Pitch,0,0,Format->Width>>1,Format->Height>>1,8,128);
  189. FillColor(Ptr+Format->Pitch*Format->Height+(Format->Pitch >> 1),
  190. Format->Pitch,0,0,Format->Width>>1,Format->Height>>1,8,128);
  191. }
  192. static int UpdateAlloc(pvr* p,int BufCount,int TempCount,int MemCount)
  193. {
  194. int Result = ERR_NONE;
  195. int AllCount;
  196. if (BufCount && BufCount+TempCount<2)
  197. ++TempCount;
  198. AllCount = BufCount + TempCount;
  199. if (AllCount > MAXIDCTBUF)
  200. return ERR_INVALID_PARAM;
  201. if (p->AllCount > AllCount)
  202. {
  203. p->M24VA_FrameFree(&p->Buf[AllCount],p->AllCount-AllCount);
  204. p->AllCount = AllCount;
  205. p->BufCount = BufCount;
  206. p->TempCount = TempCount;
  207. }
  208. else
  209. {
  210. p->BufCount = min(p->AllCount,BufCount);
  211. p->TempCount = p->AllCount - p->BufCount;
  212. while (p->AllCount < AllCount)
  213. {
  214. gx_uint8* Ptr;
  215. bool_t Clear = !p->IDCT || MemCount <= p->AllCount;
  216. if (p->IDCT && MemCount <= p->AllCount)
  217. {
  218. video Buffer;
  219. BufferFormat(p,&Buffer);
  220. if (SurfaceAlloc(p->BufMem[p->AllCount],&Buffer) != ERR_NONE)
  221. {
  222. Result = ERR_OUT_OF_MEMORY;
  223. break;
  224. }
  225. ++MemCount;
  226. }
  227. if (p->M24VA_FrameAllocate(&p->Buf[p->AllCount],1) != GXVAError_OK)
  228. {
  229. Result = ERR_OUT_OF_MEMORY;
  230. break;
  231. }
  232. if (Clear && p->M24VA_FrameBeginAccess(p->Buf[p->AllCount],&Ptr,(gx_uint32*)&p->Overlay.Pitch,1) == GXVAError_OK)
  233. {
  234. ClearIMC4(Ptr,&p->Overlay);
  235. p->M24VA_FrameEndAccess(p->Buf[p->AllCount]);
  236. }
  237. p->BufFrameNo[p->AllCount] = -1;
  238. p->AllCount++;
  239. p->BufCount = min(p->AllCount,BufCount);
  240. p->TempCount = p->AllCount - p->BufCount;
  241. }
  242. }
  243. while (MemCount > p->AllCount)
  244. SurfaceFree(p->BufMem[--MemCount]);
  245. return Result;
  246. }
  247. static int16_t Sat11(int x,int Adjust)
  248. x = (x * (Adjust + 256)) >> 8;
  249. return (int16_t)(x>1023?1023:(x<-1024?-1024:x));
  250. }
  251. static int SatUV(pvr* p,int v)
  252. {
  253. int m = p->Saturation;
  254. if (m<0) m >>= 1; // adjust negtive interval: -128..0 -> -64..0
  255. m = 4*m+256;
  256. v = (v*m) >> 8;
  257. return v;
  258. }
  259. static void UpdateColorSpace(pvr* p)
  260. {
  261. VDISP_CSCCoeffs Color;
  262. p->VDISP_OverlayBrightness(p->Brightness+128);
  263. p->VDISP_OverlayContrast(p->Contrast+128);
  264. //R = 1.164(Y - 16) + 1.596(V - 128)
  265. //G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
  266. //B = 1.164(Y - 16)                  + 2.018(U - 128)
  267. Color.ui16RyCoeff = Sat11(298,p->RGBAdjust[0]);
  268. Color.ui16RuCoeff = Sat11(SatUV(p,0),p->RGBAdjust[0]);
  269. Color.ui16RvCoeff = Sat11(SatUV(p,408),p->RGBAdjust[0]);
  270. Color.ui16GyCoeff = Sat11(298,p->RGBAdjust[1]);
  271. Color.ui16GuCoeff = Sat11(SatUV(p,-100),p->RGBAdjust[1]);
  272. Color.ui16GvCoeff = Sat11(SatUV(p,-208),p->RGBAdjust[1]);
  273. Color.ui16ByCoeff = Sat11(298,p->RGBAdjust[2]);
  274. Color.ui16BuCoeff = Sat11(SatUV(p,517),p->RGBAdjust[2]);
  275. Color.ui16BvCoeff = Sat11(SatUV(p,0),p->RGBAdjust[2]);
  276. p->VDISP_OverlaySetColorspaceConversion(&Color);
  277. }
  278. static void ReInit(pvr* p);
  279. static int Lock(pvr* p,int No,planes Planes,bool_t UseReInit);
  280. static void Unlock(pvr* p,int No);
  281. static bool_t UpdateDirection(pvr* p)
  282. {
  283. int No;
  284. video New = p->Overlay;
  285. p->OvlFX = p->p.FX;
  286. memset(&p->SoftFX,0,sizeof(blitfx));
  287. p->SoftFX.Flags = p->p.FX.Flags & BLITFX_DITHER;
  288. p->SoftFX.ScaleX = SCALE_ONE;
  289. p->SoftFX.ScaleY = SCALE_ONE;
  290. if (p->IDCT && (!p->SetupIDCTRotate || p->YUV422))
  291. {
  292. p->SoftFX.Direction = 0;
  293. p->OvlFX.Direction = CombineDir(p->p.InputDirection,p->p.OrigFX.Direction,p->p.Output.Format.Video.Direction);
  294. }
  295. else
  296. {
  297. p->SoftFX.Direction = CombineDir(p->p.InputDirection,p->p.OrigFX.Direction,p->NativeDirection);
  298. p->OvlFX.Direction = CombineDir(p->NativeDirection,0,p->p.Output.Format.Video.Direction);
  299. }
  300. if (p->SoftFX.Direction & DIR_SWAPXY)
  301. SwapInt(&p->OvlFX.ScaleX,&p->OvlFX.ScaleY);
  302. #ifdef VSYNC_WORKAROUND
  303. // hwrotation is used? no vsync needed
  304. p->DisableVSync = !p->SetupVSync || ((p->OvlFX.Direction ^ p->NativeDirection ^ p->p.Output.Format.Video.Direction) & DIR_SWAPXY) != 0;
  305. #endif
  306. New.Width = p->Width16+16;
  307. New.Height = p->Height16+16;
  308. New.Direction = CombineDir(p->p.Input.Format.Video.Direction,p->SoftFX.Direction,0);
  309. if (New.Direction & DIR_SWAPXY)
  310. SwapInt(&New.Width,&New.Height);
  311. New.Pitch = New.Width;
  312. // DEBUG_MSG6(-1,T("UpdateDirection w:%d h:%d dir:%d native:%d softfx:%d ovlfx:%d"),
  313. // New.Width,New.Height,New.Direction,p->NativeDirection,p->SoftFX.Direction,p->OvlFX.Direction);
  314. if (New.Direction != p->Overlay.Direction)
  315. {
  316. planes Planes;
  317. int Rotate;
  318. planes BufMem = { NULL };
  319. int BufCount = p->BufCount;
  320. int TempCount = p->TempCount;
  321. video Buffer;
  322. BufferFormat(p,&Buffer);
  323. if (p->Attribs.ui16ValidFlags)
  324. {
  325. Sleep(50); // be sure last flipping finished
  326. p->Attribs.bOverlayOn = 0;
  327. p->VDISP_OverlaySetAttributes(&p->Attribs,p->Buf[0]);
  328. p->VDISP_OverlaySetAttributes(&p->Attribs,p->Buf[1]);
  329. Sleep(20); //wait for overlay turn off
  330. }
  331. // save old surfaces
  332. if (p->IDCT)
  333. {
  334. for (No=0;No<p->BufCount;++No)
  335. if (p->BufMem[No][0] && Lock(p,No,Planes,0)==ERR_NONE)
  336. {
  337. SurfaceCopy(&p->Overlay,&Buffer,Planes,p->BufMem[No],NULL);
  338. Unlock(p,No);
  339. }
  340. }
  341. else
  342. {
  343. // only ShowCurr
  344. if (Lock(p,p->ShowCurr,Planes,0)==ERR_NONE)
  345. {
  346. if (SurfaceAlloc(BufMem,&Buffer) == ERR_NONE)
  347. SurfaceCopy(&p->Overlay,&Buffer,Planes,BufMem,NULL);
  348. Unlock(p,p->ShowCurr);
  349. }
  350. }
  351. if (p->AllCount)
  352. p->M24VA_FrameFree(p->Buf,p->AllCount);
  353. p->AllCount = 0;
  354. p->TempCount = 0;
  355. p->BufCount = 0;
  356. p->Empty = 1;
  357. p->ShowLast = -1;
  358. if (p->ShowNext >= 0)
  359. p->ShowCurr = p->ShowNext;
  360. if (p->ShowCurr<0 || p->ShowCurr>=BufCount)
  361. p->ShowCurr = 0;
  362. if (p->M24VA_FrameDimensions(New.Height,New.Width) == GXVAError_HardwareNotAvailable && !p->Initing)
  363. {
  364. ReInit(p);
  365. return 1;
  366. }
  367. p->Overlay = New;
  368. UpdateAlloc(p,BufCount,TempCount,BufCount+TempCount);
  369. // restore old surfaces (rotated)
  370. Rotate = CombineDir(Buffer.Direction,0,New.Direction);
  371. if (p->IDCT)
  372. {
  373. for (No=0;No<p->BufCount;++No)
  374. if (p->BufMem[No][0] && Lock(p,No,Planes,1)==ERR_NONE)
  375. {
  376. SurfaceRotate(&Buffer,&p->Overlay,p->BufMem[No],Planes,Rotate);
  377. Unlock(p,No);
  378. }
  379. }
  380. else
  381. if (BufMem[0])
  382. {
  383. if (Lock(p,p->ShowCurr,Planes,1)==ERR_NONE)
  384. {
  385. SurfaceRotate(&Buffer,&p->Overlay,BufMem,Planes,Rotate);
  386. Unlock(p,p->ShowCurr);
  387. }
  388. SurfaceFree(BufMem);
  389. }
  390. return 1;
  391. }
  392. return 0;
  393. }
  394. static const datatable PVRParams[] = 
  395. {
  396. #ifdef VSYNC_WORKAROUND
  397. { INTEL2700G_VSYNC, TYPE_BOOL, DF_SETUP|DF_CHECKLIST },
  398. #endif
  399. { INTEL2700G_IDCTROTATE, TYPE_BOOL, DF_SETUP|DF_CHECKLIST },
  400. { INTEL2700G_CLOSE_WMP, TYPE_BOOL, DF_SETUP|DF_CHECKLIST },
  401. DATATABLE_END(INTEL2700G_ID)
  402. };
  403. static int Enum(pvr* p, int* No, datadef* Param)
  404. {
  405. if (OverlayEnum(&p->p,No,Param)==ERR_NONE)
  406. return ERR_NONE;
  407. return NodeEnumTable(No,Param,PVRParams);
  408. }
  409. static void Done(pvr* p);
  410. static int Set(pvr* p,int No,const void* Data,int Size)
  411. {
  412. int Result = OverlaySet(&p->p,No,Data,Size);
  413. switch (No)
  414. {
  415. #ifdef VSYNC_WORKAROUND
  416. case INTEL2700G_VSYNC: SETVALUE(p->SetupVSync,bool_t,OverlayUpdateFX(&p->p,0)); break;
  417. #endif
  418. case INTEL2700G_CLOSE_WMP: SETVALUE(p->CloseWMP,bool_t,ERR_NONE); break;
  419. case INTEL2700G_IDCTROTATE: SETVALUE(p->SetupIDCTRotate,bool_t,OverlayUpdateFX(&p->p,0)); break;
  420. case NODE_CRASH:
  421. memset(p->BufMem,0,sizeof(p->BufMem)); // heap could be corrupted
  422. Done(p);
  423. break;
  424. }
  425. return Result;
  426. }
  427. static int Get(pvr* p,int No,void* Data,int Size)
  428. {
  429. int Result = OverlayGet(&p->p,No,Data,Size);
  430. switch (No)
  431. {
  432. #ifdef VSYNC_WORKAROUND
  433. case INTEL2700G_VSYNC: GETVALUE(p->SetupVSync,bool_t); break;
  434. #endif
  435. case INTEL2700G_CLOSE_WMP: GETVALUE(p->CloseWMP,bool_t); break;
  436. case INTEL2700G_IDCTROTATE: GETVALUE(p->SetupIDCTRotate,bool_t); break;
  437. }
  438. return Result;
  439. }
  440. static int Update(pvr* p);
  441. static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
  442. {
  443. if (!(GetWindowLong(hWnd,GWL_STYLE) & WS_POPUP))
  444. {
  445. tchar_t Name[64];
  446. if (GetWindowText(hWnd,Name,64)>0 && tcscmp(Name,T("Windows Media"))==0)
  447. *(HWND*)lParam = hWnd;
  448. }
  449. return TRUE;
  450. }
  451. static HWND FindWMP()
  452. {
  453. HWND Result = NULL;
  454. EnumWindows(EnumWindowsProc,(LPARAM)&Result);
  455. return Result;
  456. }
  457. static bool_t InitM24VA(pvr* p)
  458. {
  459. HWND WMP = NULL;
  460. int ReTry;
  461. for (;;)
  462. {
  463. for (ReTry=0;ReTry<4;++ReTry)
  464. {
  465. if (ReTry)
  466. ThreadSleep(50);
  467. if (p->M24VA_Initialise(NULL) == GXVAError_OK)
  468. {
  469. p->M24VA = 1;
  470. return 1;
  471. }
  472. }
  473. if (!p->CloseWMP || WMP || (WMP = FindWMP())==NULL)
  474. break;
  475. PostMessage(WMP,WM_CLOSE,0,0);
  476. }
  477. ShowError(INTEL2700G_ID,INTEL2700G_ID,INTEL2700G_LOCKED);
  478. return 0;
  479. }
  480. static void ReInit(pvr* p)
  481. {
  482. int BufCount = p->BufCount;
  483. int TempCount = p->TempCount;
  484. if (p->VDISP)
  485. {
  486. p->VDISP_Deinitialise();
  487. p->VDISP = 0;
  488. }
  489. // keep p->BufMem[]
  490. if (p->AllCount)
  491. p->M24VA_FrameFree(p->Buf,p->AllCount);
  492. p->AllCount = 0;
  493. p->TempCount = 0;
  494. p->BufCount = 0;
  495. if (p->M24VA)
  496. {
  497. p->M24VA_Deinitialise();
  498. p->M24VA = 0;
  499. }
  500. p->Initing = 1;
  501. if (InitM24VA(p))
  502. {
  503. if (p->VDISP_Initialise(NULL) == VDISPError_OK)
  504. {
  505. p->VDISP = 1;
  506. memset(&p->Attribs,0,sizeof(p->Attribs)); // force new udpate
  507. p->Overlay.Direction = -1; // force update in UpdateDirection
  508. p->FirstUpdate = 1;
  509. p->FirstUpdateTime = GetTimeTick() - 10000;
  510. UpdateColorSpace(p);
  511. UpdateDirection(p);
  512. UpdateAlloc(p,BufCount,TempCount,BufCount+TempCount);
  513. Update(p);
  514. }
  515. else
  516. {
  517. p->M24VA_Deinitialise();
  518. p->M24VA = 0;
  519. }
  520. }
  521. p->Initing = 0;
  522. }
  523. static void Done(pvr* p)
  524. {
  525. int No;
  526. if (p->VDISP)
  527. {
  528. p->VDISP_Deinitialise();
  529. p->VDISP = 0;
  530. }
  531. if (p->AllCount)
  532. p->M24VA_FrameFree(p->Buf,p->AllCount);
  533. for (No=0;No<p->AllCount;++No)
  534. SurfaceFree(p->BufMem[No]);
  535. p->AllCount = 0;
  536. p->TempCount = 0;
  537. p->BufCount = 0;
  538. if (p->M24VA)
  539. {
  540. p->M24VA_Deinitialise();
  541. p->M24VA = 0;
  542. }
  543. }
  544. static int Init(pvr* p)
  545. {
  546. int Result = ERR_DEVICE_ERROR;
  547. p->BufCount = 0;
  548. p->AllCount = 0;
  549. p->TempCount = 0;
  550. p->YUV422 = 0;
  551. #ifdef VSYNC_WORKAROUND
  552. p->DisableVSync = !p->SetupVSync;
  553. #endif
  554. if (p->IDCTInit)
  555. {
  556. if (!PlanarYUV420(&p->p.Input.Format.Video.Pixel))
  557. {
  558. if (PlanarYUV422(&p->p.Input.Format.Video.Pixel))
  559. p->YUV422 = 1;
  560. else
  561. return ERR_NOT_SUPPORTED;
  562. }
  563. }
  564. p->Initing = 1;
  565. if (InitM24VA(p))
  566. {
  567. if (p->VDISP_Initialise(NULL) == VDISPError_OK)
  568. {
  569. p->VDISP = 1;
  570. p->IDCT = p->IDCTInit;
  571. p->FirstUpdate = 1;
  572. memset(&p->Attribs,0,sizeof(p->Attribs));
  573. p->Brightness = 0;
  574. p->Contrast = 0;
  575. p->Saturation = 0;
  576. p->RGBAdjust[0] = 0;
  577. p->RGBAdjust[1] = 0;
  578. p->RGBAdjust[2] = 0;
  579. p->FlipLastTime = GetTimeTick();
  580. p->RegBase = NULL;
  581. p->IDCTOutput.Node = (node*)p;
  582. p->IDCTOutput.No = OUT_INPUT;
  583. p->IDCTRounding = 0;
  584. p->Width16 = ALIGN16(p->IDCT ? p->IDCTWidth:p->p.Input.Format.Video.Width)-16;
  585. if (p->Width16<0) p->Width16=0;
  586. p->Height16 = ALIGN16(p->IDCT ? p->IDCTHeight:p->p.Input.Format.Video.Height)-16;
  587. if (p->Height16<0) p->Height16=0;
  588. if (p->IDCT)
  589. {
  590. if (p->p.Input.Format.Video.Direction & DIR_SWAPXY)
  591. SwapInt(&p->p.Input.Format.Video.Width,&p->p.Input.Format.Video.Height);
  592. p->p.Input.Format.Video.Direction = 0;
  593. }
  594. else
  595. if (p->p.Input.Format.Video.Direction & DIR_SWAPXY)
  596. SwapInt(&p->Width16,&p->Height16);
  597. p->ShowCurr = 0;
  598. p->ShowNext = -1;
  599. p->ShowLast = -1;
  600. GetMode(p);
  601. p->Overlay = p->p.Input.Format.Video;
  602. p->Overlay.Pitch = 0;
  603. p->Overlay.Pixel.Flags = PF_FOURCC;
  604. p->Overlay.Pixel.FourCC = FOURCC_IMC4;
  605. p->Overlay.Aspect = ASPECT_ONE;
  606. p->Overlay.Direction = -1; // force update in UpdateDirection
  607. p->Overlay.Width = 0;
  608. p->Overlay.Height = 0;
  609. UpdateColorSpace(p);
  610. UpdateDirection(p);
  611. Result = UpdateAlloc(p,max(3-p->IDCT,p->IDCTMemInit),0,p->IDCTMemInit);
  612. }
  613. }
  614. else
  615. Result = ERR_NOT_SUPPORTED;
  616. p->Initing = 0;
  617. if (Result != ERR_NONE)
  618. Done(p);
  619. return Result;
  620. }
  621. static int Update(pvr* p)
  622. {
  623. int NativeFX;
  624. rect FullScreen;
  625. VDISP_OVERLAYATTRIBS Attribs;
  626. bool_t Slept = UpdateDirection(p);
  627. if (p->Brightness != p->p.FX.Brightness ||
  628. p->Contrast != p->p.FX.Contrast ||
  629. p->Saturation != p->p.FX.Saturation ||
  630. p->RGBAdjust[0] != p->p.FX.RGBAdjust[0] ||
  631. p->RGBAdjust[1] != p->p.FX.RGBAdjust[1] ||
  632. p->RGBAdjust[2] != p->p.FX.RGBAdjust[2])
  633. {
  634. p->Brightness = p->p.FX.Brightness;
  635. p->Contrast = p->p.FX.Contrast;
  636. p->Saturation = p->p.FX.Saturation;
  637. p->RGBAdjust[0] = p->p.FX.RGBAdjust[0];
  638. p->RGBAdjust[1] = p->p.FX.RGBAdjust[1];
  639. p->RGBAdjust[2] = p->p.FX.RGBAdjust[2];
  640. UpdateColorSpace(p);
  641. }
  642. NativeFX = CombineDir(p->p.InputDirection,p->p.OrigFX.Direction,p->NativeDirection);
  643. p->p.PrefDirection = CombineDir(NativeFX,0,p->p.Input.Format.Video.Direction);
  644. PhyToVirt(NULL,&FullScreen,&p->p.Output.Format.Video);
  645. p->p.ColorKey = COLORKEY; 
  646. VirtToPhy(&p->p.Viewport,&p->p.DstAlignedRect,&p->p.Output.Format.Video);
  647. VirtToPhy(NULL,&p->p.SrcAlignedRect,&p->p.Input.Format.Video);
  648. if (p->IDCT)
  649. {
  650. p->OverlayRect = p->p.SrcAlignedRect;
  651. if (p->SoftFX.Direction & DIR_SWAPXY)
  652. SwapInt(&p->OverlayRect.Width,&p->OverlayRect.Height);
  653. if (p->SoftFX.Direction & DIR_MIRRORLEFTRIGHT)
  654. p->OverlayRect.x += p->Overlay.Width - p->OverlayRect.Width;
  655. if (p->SoftFX.Direction & DIR_MIRRORUPDOWN)
  656. p->OverlayRect.y += p->Overlay.Height - p->OverlayRect.Height;
  657. p->p.Caps = 0; // no dither
  658. }
  659. else
  660. {
  661. VirtToPhy(NULL,&p->OverlayRect,&p->Overlay);
  662. BlitRelease(p->p.Soft);
  663. p->p.Soft = BlitCreate(&p->Overlay,&p->p.Input.Format.Video,&p->SoftFX,&p->p.Caps);
  664. BlitAlign(p->p.Soft, &p->OverlayRect, &p->p.SrcAlignedRect);
  665. }
  666. p->p.Caps |= VC_BRIGHTNESS|VC_SATURATION|VC_CONTRAST|VC_RGBADJUST;
  667. AnyAlign(&p->p.DstAlignedRect, &p->OverlayRect, &p->OvlFX, 2, 2, SCALE_ONE/4, SCALE_ONE*8);
  668. PhyToVirt(&p->p.DstAlignedRect,&p->p.GUIAlignedRect,&p->p.Output.Format.Video);
  669. OverlayUpdateShow(&p->p,1);
  670. if (p->p.ColorKey != RGB_NULL)
  671. WinInvalidate(&p->p.Viewport,1);
  672. // setup overlay attributes
  673. if (p->AllCount>=2)
  674. {
  675. bool_t Show = p->p.Show && (!p->IDCT || (p->IDCTWidth>0 && p->IDCTHeight>0));
  676. memset(&Attribs,0,sizeof(Attribs));
  677. Attribs.bDisableRotation = 0;
  678. if (p->OvlFX.Direction & DIR_SWAPXY)
  679. Attribs.ui16RotateDegree = (gx_uint16)((p->OvlFX.Direction & DIR_MIRRORUPDOWN) ? 90:270);
  680. else
  681. Attribs.ui16RotateDegree = (gx_uint16)((p->OvlFX.Direction & DIR_MIRRORUPDOWN) ? 180:0);
  682. Attribs.bCKeyOn = 1;//p->p.ColorKey != RGB_NULL;
  683. Attribs.ui32CKeyValue = RGBToFormat(p->p.ColorKey,&p->p.Output.Format.Video.Pixel); 
  684. Attribs.bOverlayOn = Show;
  685. Attribs.i16Left = (gx_int16)p->p.DstAlignedRect.x;
  686. Attribs.i16Top = (gx_int16)p->p.DstAlignedRect.y;
  687. Attribs.i16Right = (gx_int16)(p->p.DstAlignedRect.Width + p->p.DstAlignedRect.x);
  688. Attribs.i16Bottom = (gx_int16)(p->p.DstAlignedRect.Height + p->p.DstAlignedRect.y);
  689. Attribs.ui16SrcX1 = (gx_uint16)p->OverlayRect.x;
  690. Attribs.ui16SrcY1 = (gx_uint16)p->OverlayRect.y;
  691. Attribs.ui16SrcX2 = (gx_uint16)(p->OverlayRect.Width + p->OverlayRect.x);
  692. Attribs.ui16SrcY2 = (gx_uint16)(p->OverlayRect.Height + p->OverlayRect.y);
  693. Attribs.ui16ValidFlags = 
  694. VDISP_OVERLAYATTRIB_VALID_CKEY | VDISP_OVERLAYATTRIB_VALID_VISIBILITY |
  695. VDISP_OVERLAYATTRIB_VALID_DSTPOSITION | VDISP_OVERLAYATTRIB_VALID_SRCPOSITION | 0x20 | 0x40;
  696. if (memcmp(&p->Attribs,&Attribs,sizeof(Attribs))!=0)
  697. {
  698. if (!Slept && !p->FirstUpdate)
  699. Sleep(50); // be sure last flipping finished
  700. if (Show)
  701. {
  702. if (!p->FirstUpdate) // already updated?
  703. {
  704. if (p->Attribs.bOverlayOn || p->Attribs.ui16RotateDegree != Attribs.ui16RotateDegree)
  705. {
  706. // we don't want to trash the screen when the new rotation attributes are set
  707. // disable overlay first and flip the current surface with the new settings
  708. // with X50v A03 ROM setting attribs when the overlay is on seem to make them move
  709. // let's turn overlay off before setting new src/dst rectangles 
  710. Attribs.bOverlayOn = 0;
  711. p->VDISP_OverlaySetAttributes(&Attribs,p->Buf[0]);
  712. p->VDISP_OverlaySetAttributes(&Attribs,p->Buf[1]);
  713. p->Empty = 1;
  714. }
  715. if (p->Empty)
  716. {
  717. p->VDISP_OverlayFlipSurface(p->Buf[p->ShowCurr],VDISP_NONE);
  718. Sleep(50); //wait flipping
  719. }
  720. Attribs.bOverlayOn = 1;
  721. p->VDISP_OverlaySetAttributes(&Attribs,p->Buf[0]);
  722. p->VDISP_OverlaySetAttributes(&Attribs,p->Buf[1]);
  723. }
  724. else
  725. {
  726. int Time = GetTimeTick();
  727. p->FirstUpdate = 0;
  728. if (p->FirstUpdateTime+500 < Time) // avoid this step if it was done recently
  729. {
  730. // first create a 100% (without this the overlay stais black after sleep mode)
  731. p->FirstUpdateTime = Time;
  732. p->Attribs = Attribs;
  733. p->Attribs.i16Left = 0;
  734. p->Attribs.i16Top = 0;
  735. p->Attribs.i16Right = 16;
  736. p->Attribs.i16Bottom = 16;
  737. p->Attribs.ui16SrcX1 = 0;
  738. p->Attribs.ui16SrcY1 = 0;
  739. p->Attribs.ui16SrcX2 = 16;
  740. p->Attribs.ui16SrcY2 = 16;
  741. p->Attribs.bOverlayOn = QueryPlatform(PLATFORM_VER) >= 500;
  742. p->VDISP_OverlaySetAttributes(&p->Attribs,p->Buf[0]);
  743. p->VDISP_OverlaySetAttributes(&p->Attribs,p->Buf[1]);
  744. p->VDISP_OverlayFlipSurface(p->Buf[p->ShowCurr],VDISP_NONE);
  745. Sleep(50);
  746. }
  747. p->VDISP_OverlaySetAttributes(&Attribs,p->Buf[0]);
  748. p->VDISP_OverlaySetAttributes(&Attribs,p->Buf[1]);
  749. }
  750. Sleep(20); //wait for overlay turn on
  751. p->Empty = 0;
  752. }
  753. else
  754. {
  755. p->VDISP_OverlaySetAttributes(&Attribs,p->Buf[0]);
  756. p->VDISP_OverlaySetAttributes(&Attribs,p->Buf[1]);
  757. Sleep(20); //wait for overlay turn off
  758. }
  759. p->Attribs = Attribs;
  760. }
  761. }
  762. return ERR_NONE;
  763. }
  764. static int Lock(pvr* p,int No,planes Planes,bool_t UseReInit)
  765. {
  766. GXVAError Result;
  767. Planes[1] = NULL;
  768. Planes[2] = NULL;
  769. if (No<0 || No>=p->AllCount)
  770. {
  771. Planes[0] = NULL;
  772. return ERR_INVALID_PARAM;
  773. }
  774. Result = p->M24VA_FrameBeginAccess(p->Buf[No],(gx_uint8**) &Planes[0],(gx_uint32*)&p->Overlay.Pitch,1);
  775. if (Result == GXVAError_HardwareNotAvailable && UseReInit && !p->Initing)
  776. {
  777. ReInit(p);
  778. if (p->M24VA) 
  779. Result = p->M24VA_FrameBeginAccess(p->Buf[No],(gx_uint8**) &Planes[0],(gx_uint32*)&p->Overlay.Pitch,1);
  780. }
  781. return (Result == GXVAError_OK) ? ERR_NONE : ERR_DEVICE_ERROR;
  782. }
  783. static void Unlock(pvr* p,int No)
  784. {
  785. p->M24VA_FrameEndAccess(p->Buf[No]);
  786. }
  787. static int Blit(pvr* p, const constplanes Data, const constplanes DataLast )
  788. {
  789. planes Planes;
  790. int Result;
  791. if (!p->M24VA)
  792. return ERR_DEVICE_ERROR;
  793. p->ShowLast = p->ShowCurr;
  794. if (++p->ShowCurr == p->AllCount)
  795. p->ShowCurr = 0;
  796. Result = Lock(p,p->ShowCurr,Planes,1);
  797. if (Result == ERR_NONE)
  798. {
  799. BlitImage(p->p.Soft,Planes,Data,DataLast,p->Overlay.Pitch,-1);
  800. Unlock(p,p->ShowCurr);
  801. if (p->p.CurrTime<0 && p->p.LastTime>=0)
  802. {
  803. int t = GetTimeTick();
  804. if (t-p->FlipLastTime<16) // it would just stall unneccessary the benchmark
  805. return ERR_NONE;
  806. p->FlipLastTime = t;
  807. }
  808. if (p->Attribs.bOverlayOn)
  809. p->VDISP_OverlayFlipSurface(p->Buf[p->ShowCurr],VDISP_NONE);
  810. }
  811. return Result;
  812. }
  813. static int UpdateShow(pvr* p)
  814. {
  815. Update(p);
  816. return ERR_NONE;
  817. }
  818. static int Reset(pvr* p)
  819. {
  820. GetMode(p);
  821. return ERR_NONE;
  822. }
  823. //------------------------------------------------------------
  824. static const uint8_t ScanTable[3][64] = {
  825. {
  826.  0,  1,  8, 16,  9,  2,  3, 10, 
  827. 17, 24, 32, 25, 18, 11,  4,  5,
  828. 12, 19, 26, 33, 40, 48, 41, 34, 
  829. 27, 20, 13,  6,  7, 14, 21, 28, 
  830. 35, 42, 49, 56, 57, 50, 43, 36, 
  831. 29, 22, 15, 23, 30, 37, 44, 51, 
  832. 58, 59, 52, 45, 38, 31, 39, 46, 
  833. 53, 60, 61, 54, 47, 55, 62, 63
  834. },
  835. {
  836.    0,  1,  2,  3,  8,  9, 16, 17, 
  837. 10, 11,  4,  5,  6,  7, 15, 14,
  838. 13, 12, 19, 18, 24, 25, 32, 33, 
  839. 26, 27, 20, 21, 22, 23, 28, 29,
  840. 30, 31, 34, 35, 40, 41, 48, 49, 
  841. 42, 43, 36, 37, 38, 39, 44, 45,
  842. 46, 47, 50, 51, 56, 57, 58, 59, 
  843. 52, 53, 54, 55, 60, 61, 62, 63
  844. },
  845. {
  846.  0,  8, 16, 24,  1,  9,  2, 10, 
  847. 17, 25, 32, 40, 48, 56, 57, 49,
  848. 41, 33, 26, 18,  3, 11,  4, 12, 
  849. 19, 27, 34, 42, 50, 58, 35, 43,
  850. 51, 59, 20, 28,  5, 13,  6, 14, 
  851. 21, 29, 36, 44, 52, 60, 37, 45,
  852. 53, 61, 22, 30,  7, 15, 23, 31, 
  853. 38, 46, 54, 62, 39, 47, 55, 63
  854. }};
  855. static const uint8_t ScanTable8x4[3][64*2] = {
  856. {
  857. // source
  858.  0,  1,  8, 16,  9,  2,  3, 10, 
  859. 17, 24, 32, 25, 18, 11,  4,  5,
  860. 12, 19, 26, 33, 40, 48, 41, 34, 
  861. 27, 20, 13,  6,  7, 14, 21, 28, 
  862. 35, 42, 49, 56, 57, 50, 43, 36, 
  863. 29, 22, 15, 23, 30, 37, 44, 51, 
  864. 58, 59, 52, 45, 38, 31, 39, 46, 
  865. 53, 60, 61, 54, 47, 55, 62, 63,
  866. // dest
  867.  0,  1, 16, 32, 17,  2,  3, 18, 
  868. 33, 48, 64, 49, 34, 19,  4,  5,
  869. 20, 35, 50, 64, 64, 64, 64, 64, 
  870. 51, 36, 21,  6,  7, 22, 37, 52, 
  871. 64, 64, 64, 64, 64, 64, 64, 64, 
  872. 53, 38, 23, 39, 54, 64, 64, 64, 
  873. 64, 64, 64, 64, 64, 55, 64, 64, 
  874. 64, 64, 64, 64, 64, 64, 64, 64
  875. }};
  876. //------------------------------------------------------------
  877. #define FUNC(x) x##_0
  878. #define FA_XMASK GXVA_FETCH_A_PREDX_MASK
  879. #define FA_YMASK GXVA_FETCH_A_PREDY_MASK
  880. #define FA_XSHIFT GXVA_FETCH_A_PREDX_SHIFT
  881. #define FA_YSHIFT GXVA_FETCH_A_PREDY_SHIFT
  882. #define IW_XSHIFT GXVA_IMAGE_WRITE_X_SHIFT
  883. #define IW_YSHIFT GXVA_IMAGE_WRITE_Y_SHIFT
  884. #define MIRRORXY
  885. #define IZZDATA   v <<= 1;
  886. #define MVDIRX +
  887. #define MVDIRY +
  888. #define MVPOS_00 GXVA_FETCH_B_ACC_Y_POS_0|GXVA_FETCH_B_ACC_X_POS_0
  889. #define MVIDX_00 0
  890. #define MVPOS_01 GXVA_FETCH_B_ACC_Y_POS_0|GXVA_FETCH_B_ACC_X_POS_8
  891. #define MVIDX_01 2
  892. #define MVPOS_10 GXVA_FETCH_B_ACC_Y_POS_8|GXVA_FETCH_B_ACC_X_POS_0
  893. #define MVIDX_10 4
  894. #define MVPOS_11 GXVA_FETCH_B_ACC_Y_POS_8|GXVA_FETCH_B_ACC_X_POS_8
  895. #define MVIDX_11 6
  896. #define IDCT_00 GXVA_IDCT_MODE_BLK_TOP_LEFT
  897. #define IDCT_01 GXVA_IDCT_MODE_BLK_TOP_RGHT
  898. #define IDCT_10 GXVA_IDCT_MODE_BLK_BOT_LEFT
  899. #define IDCT_11 GXVA_IDCT_MODE_BLK_BOT_RGHT
  900. #include "intel2700g_idct420.h"
  901. #define FUNC(x) x##_90
  902. #define FA_XMASK GXVA_FETCH_A_PREDY_MASK
  903. #define FA_YMASK GXVA_FETCH_A_PREDX_MASK
  904. #define FA_XSHIFT GXVA_FETCH_A_PREDY_SHIFT
  905. #define FA_YSHIFT GXVA_FETCH_A_PREDX_SHIFT
  906. #define IW_XSHIFT GXVA_IMAGE_WRITE_Y_SHIFT
  907. #define IW_YSHIFT GXVA_IMAGE_WRITE_X_SHIFT
  908. #define MIRRORXY x=PVR(p)->Width16-x;
  909. #define IZZDATA   if (v & 1) { d=-d; } v = ((v & 7) << 4)|((v & 56) >> 2);
  910. #define MVDIRX -
  911. #define MVDIRY +
  912. #define MVPOS_00 GXVA_FETCH_B_ACC_Y_POS_0|GXVA_FETCH_B_ACC_X_POS_0
  913. #define MVIDX_00 2
  914. #define MVPOS_01 GXVA_FETCH_B_ACC_Y_POS_8|GXVA_FETCH_B_ACC_X_POS_0
  915. #define MVIDX_01 0
  916. #define MVPOS_10 GXVA_FETCH_B_ACC_Y_POS_0|GXVA_FETCH_B_ACC_X_POS_8
  917. #define MVIDX_10 6
  918. #define MVPOS_11 GXVA_FETCH_B_ACC_Y_POS_8|GXVA_FETCH_B_ACC_X_POS_8
  919. #define MVIDX_11 4
  920. #define IDCT_00 GXVA_IDCT_MODE_BLK_BOT_LEFT
  921. #define IDCT_01 GXVA_IDCT_MODE_BLK_TOP_LEFT
  922. #define IDCT_10 GXVA_IDCT_MODE_BLK_BOT_RGHT
  923. #define IDCT_11 GXVA_IDCT_MODE_BLK_TOP_RGHT
  924. #include "intel2700g_idct420.h"
  925. #define FUNC(x) x##_180
  926. #define FA_XMASK GXVA_FETCH_A_PREDX_MASK
  927. #define FA_YMASK GXVA_FETCH_A_PREDY_MASK
  928. #define FA_XSHIFT GXVA_FETCH_A_PREDX_SHIFT
  929. #define FA_YSHIFT GXVA_FETCH_A_PREDY_SHIFT
  930. #define IW_XSHIFT GXVA_IMAGE_WRITE_X_SHIFT
  931. #define IW_YSHIFT GXVA_IMAGE_WRITE_Y_SHIFT
  932. #define MIRRORXY x=PVR(p)->Width16-x; y=PVR(p)->Height16-y;
  933. #define IZZDATA   if ((v ^ (v >> 3)) & 1) { d=-d; } v <<= 1;
  934. #define MVDIRX -
  935. #define MVDIRY -
  936. #define MVPOS_00 GXVA_FETCH_B_ACC_Y_POS_0|GXVA_FETCH_B_ACC_X_POS_0
  937. #define MVIDX_00 6
  938. #define MVPOS_01 GXVA_FETCH_B_ACC_Y_POS_0|GXVA_FETCH_B_ACC_X_POS_8
  939. #define MVIDX_01 4
  940. #define MVPOS_10 GXVA_FETCH_B_ACC_Y_POS_8|GXVA_FETCH_B_ACC_X_POS_0
  941. #define MVIDX_10 2
  942. #define MVPOS_11 GXVA_FETCH_B_ACC_Y_POS_8|GXVA_FETCH_B_ACC_X_POS_8
  943. #define MVIDX_11 0
  944. #define IDCT_00 GXVA_IDCT_MODE_BLK_BOT_RGHT
  945. #define IDCT_01 GXVA_IDCT_MODE_BLK_BOT_LEFT
  946. #define IDCT_10 GXVA_IDCT_MODE_BLK_TOP_RGHT
  947. #define IDCT_11 GXVA_IDCT_MODE_BLK_TOP_LEFT
  948. #include "intel2700g_idct420.h"
  949. #define FUNC(x) x##_270
  950. #define FA_XMASK GXVA_FETCH_A_PREDY_MASK
  951. #define FA_YMASK GXVA_FETCH_A_PREDX_MASK
  952. #define FA_XSHIFT GXVA_FETCH_A_PREDY_SHIFT
  953. #define FA_YSHIFT GXVA_FETCH_A_PREDX_SHIFT
  954. #define IW_XSHIFT GXVA_IMAGE_WRITE_Y_SHIFT
  955. #define IW_YSHIFT GXVA_IMAGE_WRITE_X_SHIFT
  956. #define MIRRORXY y=PVR(p)->Height16-y;
  957. #define IZZDATA   if (v & 8) { d=-d; } v = ((v & 7) << 4)|((v & 56) >> 2);
  958. #define MVDIRX +
  959. #define MVDIRY -
  960. #define MVPOS_00 GXVA_FETCH_B_ACC_Y_POS_0|GXVA_FETCH_B_ACC_X_POS_0
  961. #define MVIDX_00 4
  962. #define MVPOS_01 GXVA_FETCH_B_ACC_Y_POS_8|GXVA_FETCH_B_ACC_X_POS_0
  963. #define MVIDX_01 6
  964. #define MVPOS_10 GXVA_FETCH_B_ACC_Y_POS_0|GXVA_FETCH_B_ACC_X_POS_8
  965. #define MVIDX_10 0
  966. #define MVPOS_11 GXVA_FETCH_B_ACC_Y_POS_8|GXVA_FETCH_B_ACC_X_POS_8
  967. #define MVIDX_11 2
  968. #define IDCT_00 GXVA_IDCT_MODE_BLK_TOP_RGHT
  969. #define IDCT_01 GXVA_IDCT_MODE_BLK_BOT_RGHT
  970. #define IDCT_10 GXVA_IDCT_MODE_BLK_TOP_LEFT
  971. #define IDCT_11 GXVA_IDCT_MODE_BLK_BOT_LEFT
  972. #include "intel2700g_idct420.h"
  973. //------------------------------------------------------------
  974. #include "intel2700g_idct422.h"
  975. //------------------------------------------------------------
  976. static idctmcomp const IDCTMComp16x16[2][4] =
  977. {{
  978. (idctmcomp)IDCTMComp16x16Back_0,
  979. (idctmcomp)IDCTMComp16x16Back_90,
  980. (idctmcomp)IDCTMComp16x16Back_180,
  981. (idctmcomp)IDCTMComp16x16Back_270
  982. },{
  983. (idctmcomp)IDCTMComp16x16BackFwd_0,
  984. (idctmcomp)IDCTMComp16x16BackFwd_90,
  985. (idctmcomp)IDCTMComp16x16BackFwd_180,
  986. (idctmcomp)IDCTMComp16x16BackFwd_270
  987. }};
  988. static idctmcomp const IDCTMComp8x8[2][4] =
  989. {{
  990. (idctmcomp)IDCTMComp8x8Back_0,
  991. (idctmcomp)IDCTMComp8x8Back_90,
  992. (idctmcomp)IDCTMComp8x8Back_180,
  993. (idctmcomp)IDCTMComp8x8Back_270
  994. },{
  995. (idctmcomp)IDCTMComp8x8BackFwd_0,
  996. (idctmcomp)IDCTMComp8x8BackFwd_90,
  997. (idctmcomp)IDCTMComp8x8BackFwd_180,
  998. (idctmcomp)IDCTMComp8x8BackFwd_270
  999. }};
  1000. static idctinter const IDCTInter8x8[2][4] =
  1001. {{
  1002. (idctinter) IDCTInter8x8Back_0,
  1003. (idctinter) IDCTInter8x8Back_90,
  1004. (idctinter) IDCTInter8x8Back_180,
  1005. (idctinter) IDCTInter8x8Back_270
  1006. },{
  1007. (idctinter) IDCTInter8x8BackFwd_0,
  1008. (idctinter) IDCTInter8x8BackFwd_90,
  1009. (idctinter) IDCTInter8x8BackFwd_180,
  1010. (idctinter) IDCTInter8x8BackFwd_270
  1011. }};
  1012. static idctprocess const IDCTProcess[4] = 
  1013. (idctprocess)IDCTProcess_0,
  1014. (idctprocess)IDCTProcess_90,
  1015. (idctprocess)IDCTProcess_180,
  1016. (idctprocess)IDCTProcess_270 
  1017. };
  1018. static idctcopy const IDCTCopy16x16[4] = 
  1019. (idctcopy)IDCTCopy16x16_0,
  1020. (idctcopy)IDCTCopy16x16_90,
  1021. (idctcopy)IDCTCopy16x16_180,
  1022. (idctcopy)IDCTCopy16x16_270 
  1023. };
  1024. static idctintra const IDCTIntra8x8[4] = 
  1025. (idctintra)IDCTIntra8x8_0,
  1026. (idctintra)IDCTIntra8x8_90,
  1027. (idctintra)IDCTIntra8x8_180,
  1028. (idctintra)IDCTIntra8x8_270 
  1029. };
  1030. //------------------------------------------------------------
  1031. static int IDCTOutputFormat(pvr* p, const void* Data, int Size )
  1032. {
  1033. packetformat Format;
  1034. int Result;
  1035. p->IDCTInit = 1;
  1036. if (Size == sizeof(video))
  1037. {
  1038. memset(&Format,0,sizeof(Format));
  1039. Format.Type = PACKET_VIDEO;
  1040. Format.Format.Video = *(const video*)Data;
  1041. Data = &Format;
  1042. Size = sizeof(packetformat);
  1043. //IDCTWidth or IDCTHeight could have changes so invalidate current input format
  1044. memset(&p->p.Input.Format.Video,0,sizeof(video));
  1045. }
  1046. Result = p->p.Node.Set((node*)p,OUT_INPUT|PIN_FORMAT,Data,Size);
  1047. if (Size && Result != ERR_NONE)
  1048. p->p.Node.Set((node*)p,OUT_INPUT|PIN_FORMAT,NULL,0);
  1049. p->IDCTInit = 0;
  1050. return Result;
  1051. }
  1052. static int IDCTSend(void* p,tick_t RefTime,const flowstate* State);
  1053. static int IDCTPVRRestore(pvr* p, idctbackup* Backup)
  1054. {
  1055. int No;
  1056. if (p && Backup->Format.Pixel.Flags)
  1057. {
  1058. planes Planes;
  1059. blitfx FX;
  1060. memset(&FX,0,sizeof(FX));
  1061. FX.ScaleX = SCALE_ONE;
  1062. FX.ScaleY = SCALE_ONE;
  1063. p->IDCTWidth = Backup->Width;
  1064. p->IDCTHeight = Backup->Height;
  1065. for (No=0;No<Backup->Count;++No)
  1066. {
  1067. idctbufferbackup* Buffer = Backup->Buffer+No;
  1068. if (Buffer->Buffer[0] && Buffer->Format.Pixel.FourCC==FOURCC_IMC4)
  1069. p->BufMem[No][0] = Buffer->Buffer[0];
  1070. else
  1071. {
  1072. video Format;
  1073. memset(&Format,0,sizeof(Format));
  1074. Format.Pixel.Flags = PF_FOURCC;
  1075. Format.Pixel.FourCC = FOURCC_IMC4;
  1076. Format.Aspect = ASPECT_ONE;
  1077. Format.Width = p->IDCTWidth;
  1078. Format.Height = p->IDCTHeight;
  1079. DefaultPitch(&Format);
  1080. SurfaceAlloc(p->BufMem[No],&Format);
  1081. }
  1082. }
  1083. p->IDCTMemInit = Backup->Count;
  1084. IDCTOutputFormat(p,&Backup->Format,sizeof(video));
  1085. p->IDCTMemInit = 0;
  1086. for (No=0;No<Backup->Count;++No)
  1087. {
  1088. idctbufferbackup* Buffer = Backup->Buffer+No;
  1089. p->BufFrameNo[No] = Buffer->FrameNo;
  1090. if (Buffer->Buffer[0] && Lock(p,No,Planes,1) == ERR_NONE)
  1091. {
  1092. FX.Direction = CombineDir(Buffer->Format.Direction, 0, p->Overlay.Direction);
  1093. FX.Brightness = -Buffer->Brightness;
  1094. SurfaceCopy(&Buffer->Format,&p->Overlay,Buffer->Buffer,Planes,&FX);
  1095. Unlock(p,No);
  1096. }
  1097. if (Buffer->Buffer[0] == p->BufMem[No][0])
  1098. memset(Buffer->Buffer,0,sizeof(planes));
  1099. }
  1100. p->FirstUpdate = 1;
  1101. p->ShowNext = Backup->Show;
  1102. if (p->ShowNext >= p->BufCount)
  1103. p->ShowNext = -1;
  1104. }
  1105. for (No=0;No<Backup->Count;++No)
  1106. SurfaceFree(Backup->Buffer[No].Buffer);
  1107. memset(Backup,0,sizeof(idctbackup));
  1108. return ERR_NONE;
  1109. }
  1110. static int IDCTPVRBackup(pvr* p, idctbackup* Backup)
  1111. {
  1112. int No;
  1113. planes Planes;
  1114. memset(Backup,0,sizeof(idctbackup));
  1115. if (!p->IDCT)
  1116. return ERR_INVALID_DATA;
  1117. Backup->Format = p->p.Input.Format.Video;
  1118. Backup->Width = p->IDCTWidth;
  1119. Backup->Height = p->IDCTHeight;
  1120. Backup->Count = p->BufCount;
  1121. Backup->Show = p->ShowNext;
  1122. p->Initing = 1; // do not ReInit here
  1123. for (No=0;No<Backup->Count;++No)
  1124. {
  1125. idctbufferbackup* Buffer = Backup->Buffer+No;
  1126. Buffer->FrameNo = p->BufFrameNo[No];
  1127. BufferFormat(p,&Buffer->Format);
  1128. Buffer->Buffer[0] = p->BufMem[No][0];
  1129. memset(p->BufMem[No],0,sizeof(planes));
  1130. if (Buffer->Buffer[0])
  1131. if (Lock(p,No,Planes,0)==ERR_NONE)
  1132. {
  1133. SurfaceCopy(&p->Overlay,&Buffer->Format,Planes,Buffer->Buffer,NULL);
  1134. Unlock(p,No);
  1135. }
  1136. else
  1137. ClearIMC4(Buffer->Buffer[0],&Buffer->Format);
  1138. }
  1139. p->Initing = 0;
  1140. IDCTOutputFormat(p,NULL,0);
  1141. return ERR_NONE;
  1142. }
  1143. static int IDCTSet(void* p, int No, const void* Data, int Size )
  1144. {
  1145. flowstate State;
  1146. int Result = ERR_INVALID_PARAM;
  1147. switch (No)
  1148. {
  1149. case IDCT_BACKUP: 
  1150. if (Size == sizeof(idctbackup))
  1151. Result = IDCTPVRRestore(PVR(p),(idctbackup*)Data);
  1152. break;
  1153. case IDCT_MODE: if (*(int*)Data==0) Result = ERR_NONE; break;
  1154. case IDCT_BUFFERWIDTH: SETVALUE(PVR(p)->IDCTWidth,int,ERR_NONE); break;
  1155. case IDCT_BUFFERHEIGHT: SETVALUE(PVR(p)->IDCTHeight,int,ERR_NONE); break;
  1156. case IDCT_FORMAT:
  1157. assert(Size == sizeof(video) || !Data);
  1158. Result = IDCTOutputFormat(PVR(p),Data,Size);
  1159. break;
  1160. case IDCT_ROUNDING: SETVALUE(PVR(p)->IDCTRounding,bool_t,ERR_NONE); break;
  1161. case IDCT_SHOW: 
  1162. SETVALUE(PVR(p)->ShowNext,int,ERR_NONE); 
  1163. if (PVR(p)->ShowNext >= PVR(p)->BufCount) PVR(p)->ShowNext = -1;
  1164. break;
  1165. case IDCT_BUFFERCOUNT:
  1166. assert(Size == sizeof(int));
  1167. Result = ERR_NONE;
  1168. if (PVR(p)->BufCount != *(const int*)Data)
  1169. Result = UpdateAlloc(PVR(p),*(const int*)Data,0,PVR(p)->AllCount);
  1170. break;
  1171. case FLOW_FLUSH:
  1172. PVR(p)->ShowNext = -1;
  1173. Result = ERR_NONE;
  1174. break;
  1175. case FLOW_RESEND:
  1176. State.CurrTime = TIME_RESEND;
  1177. State.DropLevel = 0;
  1178. Result = IDCTSend(p,-1,&State);
  1179. Sleep(20);
  1180. break;
  1181. }
  1182. if (No>=IDCT_FRAMENO && No<IDCT_FRAMENO+PVR(p)->AllCount)
  1183. SETVALUE(PVR(p)->BufFrameNo[No-IDCT_FRAMENO],int,ERR_NONE);
  1184. return Result;
  1185. }
  1186. static int IDCTEnumPVR(void* p, int* No, datadef* Param)
  1187. {
  1188. int Result = IDCTEnum(p,No,Param);
  1189. if (Result == ERR_NONE && Param->No == IDCT_OUTPUT)
  1190. Param->Flags |= DF_RDONLY;
  1191. return Result;
  1192. }
  1193. static int IDCTGet(void* p, int No, void* Data, int Size )
  1194. {
  1195. int Result = ERR_INVALID_PARAM;
  1196. switch (No)
  1197. {
  1198. case FLOW_BUFFERED: GETVALUE(1,bool_t); break;
  1199. case NODE_PARTOF: GETVALUE(PVR(p),pvr*); break;
  1200. case IDCT_FORMAT: GETVALUECOND(PVR(p)->p.Input.Format.Video,video,PVR(p)->IDCT); break;
  1201. case IDCT_OUTPUT|PIN_FORMAT: GETVALUECOND(PVR(p)->p.Input,packetformat,PVR(p)->IDCT); break;
  1202. case IDCT_OUTPUT|PIN_PROCESS: GETVALUE(NULL,packetprocess); break;
  1203. case IDCT_OUTPUT: GETVALUE(PVR(p)->IDCTOutput,pin); break;
  1204. case IDCT_ROUNDING: GETVALUE(PVR(p)->IDCTRounding,bool_t); break;
  1205. case IDCT_MODE: GETVALUE(0,int); break;
  1206. case IDCT_BUFFERCOUNT: GETVALUE(PVR(p)->BufCount,int); break;
  1207. case IDCT_BUFFERWIDTH: GETVALUE(PVR(p)->IDCTWidth,int); break;
  1208. case IDCT_BUFFERHEIGHT: GETVALUE(PVR(p)->IDCTHeight,int); break;
  1209. case IDCT_SHOW: GETVALUE(PVR(p)->ShowNext,int); break;
  1210. case IDCT_BACKUP: 
  1211. assert(Size == sizeof(idctbackup));
  1212. Result = IDCTPVRBackup(PVR(p),(idctbackup*)Data);
  1213. break;
  1214. }
  1215. if (No>=IDCT_FRAMENO && No<IDCT_FRAMENO+PVR(p)->AllCount)
  1216. GETVALUE(PVR(p)->BufFrameNo[No-IDCT_FRAMENO],int);
  1217. return Result;
  1218. }
  1219. static int IDCTNull(void* p,const flowstate* State,bool_t Empty)
  1220. {
  1221. if (Empty)
  1222. ++PVR(p)->p.Total;
  1223. if (!State || State->DropLevel)
  1224. ++PVR(p)->p.Dropped;
  1225. return ERR_NONE;
  1226. }
  1227. static int IDCTLock(void* p,int No,planes Planes,int* Brightness,video* Format)
  1228. {
  1229. if (Brightness)
  1230. *Brightness = 0;
  1231. if (Format)
  1232. *Format = PVR(p)->Overlay;
  1233. return Lock(PVR(p),No,Planes,1);
  1234. }
  1235. static void IDCTUnlock(void* p,int No)
  1236. {
  1237. Unlock(PVR(p),No);
  1238. }
  1239. static void SwapPtr(pvr* p,int a,int b,int SwapShow)
  1240. {
  1241. SMSurface t;
  1242. void* u;
  1243. t = p->Buf[a];
  1244. p->Buf[a] = p->Buf[b];
  1245. p->Buf[b] = t;
  1246. u = p->BufMem[a][0];
  1247. p->BufMem[a][0] = p->BufMem[b][0];
  1248. p->BufMem[b][0] = u;
  1249. if (SwapShow)
  1250. {
  1251. SwapInt(&p->BufFrameNo[a],&p->BufFrameNo[b]);
  1252. if (p->ShowNext == a)
  1253. p->ShowNext = b;
  1254. else
  1255. if (p->ShowNext == b)
  1256. p->ShowNext = a;
  1257. if (p->ShowLast == a)
  1258. p->ShowLast = b;
  1259. else
  1260. if (p->ShowLast == b)
  1261. p->ShowLast = a;
  1262. if (p->ShowCurr == a)
  1263. p->ShowCurr = b;
  1264. else
  1265. if (p->ShowCurr == b)
  1266. p->ShowCurr = a;
  1267. }
  1268. }
  1269. static int IDCTFrameStart(void* p,int FrameNo,int* OldFrameNo,int DstNo,int BackNo,int FwdNo,int ShowNo,bool_t Drop)
  1270. {
  1271. bool_t ReTry = 0;
  1272. GXVAError Result;
  1273. retry:
  1274. if (!PVR(p)->M24VA)
  1275. return ERR_DEVICE_ERROR;
  1276. // we will try to avoid overwrite currently displayed buffers:
  1277. //   ShowCurr currently displayed
  1278. //   ShowLast may be still on screen (because flip occurs only during vblank)
  1279. if (PVR(p)->ShowLast == DstNo || PVR(p)->ShowCurr == DstNo)
  1280. {
  1281. // try to find a free buffer
  1282. int SwapNo;
  1283. for (SwapNo=0;SwapNo<PVR(p)->AllCount;++SwapNo)
  1284. if (SwapNo != PVR(p)->ShowLast && SwapNo != PVR(p)->ShowCurr && 
  1285. SwapNo != BackNo && SwapNo != FwdNo && SwapNo != ShowNo)
  1286. break; 
  1287. if (SwapNo < PVR(p)->AllCount || UpdateAlloc(PVR(p),PVR(p)->BufCount,PVR(p)->TempCount+1,PVR(p)->AllCount)==ERR_NONE)
  1288. {
  1289. // use free buffer
  1290. SwapPtr(PVR(p),SwapNo,DstNo,1);
  1291. }
  1292. else
  1293. if (PVR(p)->ShowLast >= 0 && PVR(p)->ShowCurr != PVR(p)->ShowLast &&
  1294. PVR(p)->ShowLast != BackNo && PVR(p)->ShowLast != FwdNo) 
  1295. {
  1296. // no free buffer found and couldn't allocate new temp buffer
  1297. // so we wait for vblank and use ShowLast
  1298. if (DstNo != PVR(p)->ShowLast)
  1299. SwapPtr(PVR(p),PVR(p)->ShowLast,DstNo,1);
  1300. }
  1301. }
  1302. Result = PVR(p)->M24VA_BeginFrame(PVR(p)->Buf[DstNo],1);
  1303. if (Result == GXVAError_OK)
  1304. {
  1305. if (BackNo >= 0)
  1306. Result = PVR(p)->M24VA_SetReferenceFrameAddress(1,PVR(p)->Buf[BackNo]);
  1307. if (FwdNo >= 0 && Result == GXVAError_OK)
  1308. Result = PVR(p)->M24VA_SetReferenceFrameAddress(2,PVR(p)->Buf[FwdNo]);
  1309. if (Result != GXVAError_OK)
  1310. PVR(p)->M24VA_EndFrame(1);
  1311. }
  1312. if (Result == GXVAError_HardwareNotAvailable && !ReTry)
  1313. {
  1314. ReInit(PVR(p));
  1315. ReTry = 1;
  1316. goto retry;
  1317. }
  1318. else
  1319. if (Result == GXVAError_OK)
  1320. {
  1321. if (PVR(p)->YUV422)
  1322. {
  1323. PVR(p)->IdctVMT.Process = IDCTProcess_422;
  1324. PVR(p)->IdctVMT.Intra8x8 = (idctintra)IDCTIntra8x8_422;
  1325. PVR(p)->IdctVMT.Copy16x16 = NULL;
  1326. PVR(p)->IdctVMT.MComp16x16 = NULL;
  1327. PVR(p)->IdctVMT.MComp8x8 = NULL;
  1328. PVR(p)->IdctVMT.Inter8x8 = NULL;
  1329. }
  1330. else
  1331. {
  1332. int Degree;
  1333. if (PVR(p)->SoftFX.Direction & DIR_SWAPXY)
  1334. Degree = (PVR(p)->SoftFX.Direction & DIR_MIRRORUPDOWN) ? 1:3;
  1335. else
  1336. Degree = (PVR(p)->SoftFX.Direction & DIR_MIRRORUPDOWN) ? 2:0;
  1337. PVR(p)->IdctVMT.Process = IDCTProcess[Degree];
  1338. PVR(p)->IdctVMT.Copy16x16 = IDCTCopy16x16[Degree];
  1339. PVR(p)->IdctVMT.MComp16x16 = (idctmcomp)IDCTMComp16x16[FwdNo>=0][Degree];
  1340. PVR(p)->IdctVMT.MComp8x8 = (idctmcomp)IDCTMComp8x8[FwdNo>=0][Degree];
  1341. PVR(p)->IdctVMT.Intra8x8 = IDCTIntra8x8[Degree];
  1342. PVR(p)->IdctVMT.Inter8x8 = IDCTInter8x8[FwdNo>=0][Degree];
  1343. }
  1344. }
  1345. else
  1346. return ERR_DEVICE_ERROR;
  1347. PVR(p)->ShowNext = ShowNo;
  1348. if (OldFrameNo)
  1349. *OldFrameNo = PVR(p)->BufFrameNo[DstNo];
  1350. PVR(p)->BufFrameNo[DstNo] = FrameNo;
  1351. PVR(p)->MCompType = GXVA_CMD_MC_OPP_TYPE;
  1352. if (PVR(p)->IDCTRounding)
  1353. PVR(p)->MCompType |= GXVA_MC_TYPE_INTR_RND_MODE;
  1354. PVR(p)->GXVA_SetIZZMode(GXVA_RasterScanOrder);
  1355. return ERR_NONE;
  1356. }
  1357. static void IDCTFrameEnd(void* p)
  1358. {
  1359. PVR(p)->M24VA_EndFrame(1);
  1360. }
  1361. static void IDCTDrop(void* p)
  1362. {
  1363. int No;
  1364. for (No=0;No<PVR(p)->AllCount;++No)
  1365. PVR(p)->BufFrameNo[No] = -1;
  1366. }
  1367. static bool_t IDCTTiming(pvr* p, tick_t CurrTime, tick_t RefTime)
  1368. {
  1369. if (CurrTime >= 0)
  1370. {
  1371. tick_t Diff;
  1372. if (!p->p.Play && CurrTime == p->p.LastTime)
  1373. return 0;
  1374. Diff = RefTime - (CurrTime + SHOWAHEAD);
  1375. if (Diff >= 0)
  1376. {
  1377. #ifdef VSYNC_WORKAROUND
  1378. bool_t Tried;
  1379. int Last;
  1380. int Same;
  1381. int Start;
  1382. if (p->DisableVSync || !p->VSyncPtr || Diff>(TICKSPERSEC*20/1000))
  1383. return 0;
  1384. Start = *p->VSyncPtr & 4095;
  1385. if (Scale(p->VSyncRefresh,p->VSyncBottom - Start,p->VSyncTotal) > (TICKSPERSEC*8/1000))
  1386. return 0;
  1387. // wait for vsync
  1388. Tried = 0;
  1389. Last = -1;
  1390. Same = 0;
  1391. for (;;)
  1392. {
  1393. int Pos = *p->VSyncPtr & 4095;
  1394. // fail safe for stuck scanline counter
  1395. if (Pos == Last)
  1396. {
  1397. if (++Same == 10000000)
  1398. break;
  1399. }
  1400. else
  1401. {
  1402. Last = Pos;
  1403. Same = 0;
  1404. }
  1405. // we got interrupted and missed the vsync. 
  1406. if (Pos < Start) 
  1407. {
  1408. if (Tried) 
  1409. break;
  1410. Start = Pos;
  1411. Tried = 1; // try again, but only one more time
  1412. }
  1413. Pos = p->VSyncBottom - Pos;
  1414. if (Pos <= 0) 
  1415. break;
  1416. if (Pos >= 2*p->VSyncLimit) 
  1417. Sleep(Pos/p->VSyncLimit-1); // sleep few msec
  1418. }
  1419. #else
  1420. return 0;
  1421. #endif
  1422. }
  1423. p->p.LastTime = CurrTime;
  1424. }
  1425. else
  1426. p->p.LastTime = RefTime;
  1427. p->p.CurrTime = CurrTime;
  1428. return 1;
  1429. }
  1430. static int IDCTSend(void* p,tick_t RefTime,const flowstate* State)
  1431. {
  1432. // no dropping check, because flipping costs no time
  1433. if (PVR(p)->ShowNext < 0)
  1434. return ERR_NEED_MORE_DATA;
  1435. if (!IDCTTiming(PVR(p),State->CurrTime,RefTime))
  1436. return ERR_BUFFER_FULL;
  1437. if (State->CurrTime != TIME_RESEND)
  1438. ++PVR(p)->p.Total;
  1439. if (State->CurrTime<0 && RefTime>=0)
  1440. {
  1441. // it would just stall unneccessary the benchmark and
  1442. // can crash the 2700G driver with too frequent flipping
  1443. int t = GetTimeTick();
  1444. if (t-PVR(p)->FlipLastTime<16)  
  1445. return ERR_NONE;
  1446. PVR(p)->FlipLastTime = t;
  1447. }
  1448. PVR(p)->ShowLast = PVR(p)->ShowCurr;
  1449. PVR(p)->ShowCurr = PVR(p)->ShowNext;
  1450. if (PVR(p)->Attribs.bOverlayOn)
  1451. PVR(p)->VDISP_OverlayFlipSurface(PVR(p)->Buf[PVR(p)->ShowCurr],VDISP_NONE);
  1452. return ERR_NONE;
  1453. }
  1454. //------------------------------------------------------------
  1455. static int Create(pvr* p)
  1456. {
  1457. p->p.Module = LoadLibrary(T("PVRVADD.DLL"));
  1458. GetProc(&p->p.Module,&p->M24VA_FrameDimensions,T("M24VA_FrameDimensions"),0);
  1459. GetProc(&p->p.Module,&p->M24VA_FrameAllocate,T("M24VA_FrameAllocate"),0);
  1460. GetProc(&p->p.Module,&p->M24VA_FrameFree,T("M24VA_FrameFree"),0);
  1461. GetProc(&p->p.Module,&p->M24VA_BeginFrame,T("M24VA_BeginFrame"),0);
  1462. GetProc(&p->p.Module,&p->M24VA_EndFrame,T("M24VA_EndFrame"),0);
  1463. GetProc(&p->p.Module,&p->M24VA_SetReferenceFrameAddress,T("M24VA_SetReferenceFrameAddress"),0);
  1464. GetProc(&p->p.Module,&p->M24VA_FCFrameAllocate,T("M24VA_FCFrameAllocate"),0);
  1465. GetProc(&p->p.Module,&p->M24VA_FrameConvert,T("M24VA_FrameConvert"),0);
  1466. GetProc(&p->p.Module,&p->M24VA_FrameBeginAccess,T("M24VA_FrameBeginAccess"),0);
  1467. GetProc(&p->p.Module,&p->M24VA_FrameEndAccess,T("M24VA_FrameEndAccess"),0);
  1468. GetProc(&p->p.Module,&p->M24VA_WriteIZZBlock,T("M24VA_WriteIZZBlock"),0);
  1469. GetProc(&p->p.Module,&p->M24VA_WriteIZZData,T("M24VA_WriteIZZData"),0);
  1470. GetProc(&p->p.Module,&p->M24VA_SetIZZMode,T("M24VA_SetIZZMode"),0);
  1471. GetProc(&p->p.Module,&p->M24VA_WriteResidualDifferenceData,T("M24VA_WriteResidualDifferenceData"),0);
  1472. GetProc(&p->p.Module,&p->M24VA_WriteMCCmdData,T("M24VA_WriteMCCmdData"),0);
  1473. GetProc(&p->p.Module,&p->M24VA_Initialise,T("M24VA_Initialise"),0);
  1474. GetProc(&p->p.Module,&p->M24VA_Deinitialise,T("M24VA_Deinitialise"),0);
  1475. GetProc(&p->p.Module,&p->M24VA_Reset,T("M24VA_Reset"),0);
  1476. GetProc(&p->p.Module,&p->VDISP_Initialise,T("VDISP_Initialise"),0);
  1477. GetProc(&p->p.Module,&p->VDISP_Deinitialise,T("VDISP_Deinitialise"),0);
  1478. GetProc(&p->p.Module,&p->VDISP_OverlaySetAttributes,T("VDISP_OverlaySetAttributes"),0);
  1479. GetProc(&p->p.Module,&p->VDISP_OverlayFlipSurface,T("VDISP_OverlayFlipSurface"),0);
  1480. GetProc(&p->p.Module,&p->VDISP_OverlayContrast,T("VDISP_OverlayContrast"),0);
  1481. GetProc(&p->p.Module,&p->VDISP_OverlayGamma,T("VDISP_OverlayGamma"),0);
  1482. GetProc(&p->p.Module,&p->VDISP_OverlayBrightness,T("VDISP_OverlayBrightness"),0);
  1483. GetProc(&p->p.Module,&p->VDISP_OverlaySetColorspaceConversion,T("VDISP_OverlaySetColorspaceConversion"),0);
  1484. if (!p->p.Module)
  1485. return ERR_NOT_SUPPORTED;
  1486. #ifdef VSYNC_WORKAROUND
  1487. {
  1488. tchar_t Path[MAXPATH];
  1489. GetModuleFileName(p->p.Module,Path,MAXPATH);
  1490. if (FileDate(Path) < 20041205) // just guessing when vsync was corrected
  1491. p->SetupVSync = 1;
  1492. }
  1493. #endif
  1494. p->p.Node.Enum = (nodeenum)Enum;
  1495. p->p.Node.Get = (nodeget)Get;
  1496. p->p.Node.Set = (nodeset)Set;
  1497. p->p.Init = (ovlfunc)Init;
  1498. p->p.Done = (ovldone)Done;
  1499. p->p.Blit = (ovlblit)Blit;
  1500. p->p.Update = (ovlfunc)Update;
  1501. p->p.UpdateShow = (ovlfunc)UpdateShow;
  1502. p->p.Reset = (ovlfunc)Reset;
  1503. p->IdctVMT.Class = INTEL2700G_IDCT_ID;
  1504. p->IdctVMT.Enum = IDCTEnumPVR;
  1505. p->IdctVMT.Get = IDCTGet;
  1506. p->IdctVMT.Set = IDCTSet;
  1507. p->IdctVMT.Send = IDCTSend;
  1508. p->IdctVMT.Null = IDCTNull;
  1509. p->IdctVMT.Drop = IDCTDrop;
  1510. p->IdctVMT.Lock = IDCTLock;
  1511. p->IdctVMT.Unlock = IDCTUnlock;
  1512. p->IdctVMT.FrameStart = IDCTFrameStart;
  1513. p->IdctVMT.FrameEnd = IDCTFrameEnd;
  1514. p->p.AccelIDCT = &p->IdctVMT;
  1515. p->p.Overlay = 1;
  1516. p->p.DoPowerOff = 1;
  1517. p->FirstUpdateTime = GetTimeTick() - 10000;
  1518. p->SetupIDCTRotate = 1;
  1519. p->CloseWMP = 1;
  1520. return ERR_NONE;
  1521. }
  1522. static const nodedef PVR =
  1523. {
  1524. sizeof(pvr)|CF_GLOBAL|CF_SETTINGS,
  1525. INTEL2700G_ID,
  1526. OVERLAY_CLASS,
  1527. PRI_DEFAULT+210,
  1528. (nodecreate)Create,
  1529. };
  1530. static const nodedef PVRIDCT =
  1531. {
  1532. CF_ABSTRACT,
  1533. INTEL2700G_IDCT_ID,
  1534. IDCT_CLASS,
  1535. PRI_DEFAULT+50,
  1536. };
  1537. void Intel2700G_Init()
  1538. {
  1539. NodeRegisterClass(&PVR);
  1540. NodeRegisterClass(&PVRIDCT);
  1541. }
  1542. void Intel2700G_Done()
  1543. {
  1544. NodeUnRegisterClass(INTEL2700G_ID);
  1545. NodeUnRegisterClass(INTEL2700G_IDCT_ID);
  1546. }
  1547. #else
  1548. void Intel2700G_Init() {}
  1549. void Intel2700G_Done() {}
  1550. #endif