ge2d.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: ge2d.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.  * Big thanks to Mobile Stream (http://www.mobile-stream.com)
  23.  * for reverse enginerring the GE2D interface
  24.  *
  25.  ****************************************************************************/
  26. #include "../common/common.h"
  27. #if defined(TARGET_PALMOS)
  28. #include "../common/palmos/pace.h"
  29. #if defined(_M_IX86)
  30. //#define GE2DEMU
  31. #endif
  32. #define GE2D_ID FOURCC('G','E','2','D')
  33. #define sonyGE2DLibType 'aexo'
  34. #define sonyGE2DLibCreator 'SeGE'
  35. enum {
  36. sonyGE2DFormatYCbCr422 = 1,
  37. sonyGE2DFormatYCbCr422Planar,
  38. sonyGE2DFormatYCbCr420Planar
  39. };
  40. #define sonyGE2DBlitPixelCoord 0x2
  41. typedef UInt32 GE2DInsnType;
  42. typedef struct GE2DBitmapType
  43. {
  44. UInt8 format; /* 0x00 */
  45. UInt8 zero; /* 0x01 */
  46. UInt16 pitch; /* 0x02 */
  47. UInt16 chromaPitch;/* 0x04 */
  48. UInt16 width; /* 0x06 */
  49. UInt16 height; /* 0x08 */
  50. UInt16 unused; /* 0x0a */
  51. void * plane1P; /* 0x0c: Y */
  52. void * plane2P; /* 0x10: Cb */
  53. void * plane3P; /* 0x14: Cr */
  54. } GE2DBitmapType;
  55. typedef struct GE2DLibAPIType
  56. {
  57. Err (*GE2DLibOpen)();
  58. Err (*GE2DLibClose)();
  59. Err (*GE2DProgramBlit)(GE2DInsnType *,
  60. void *, UInt16,
  61. const void *, UInt16,
  62. UInt16, UInt16, UInt8);
  63. Err (*GE2DBlitWithAlpha)(void *, UInt16,
  64. const void *, UInt16,
  65. UInt16, UInt16, UInt8);
  66. Err (*GE2DBlit)(void *dstBitsP, UInt16 dstPitch,
  67. const void *srcBitsP, UInt16 srcPitch,
  68. UInt16 srcWidth, UInt16 srcHeight, UInt8 ff);
  69. Err (*GE2DBlitWithMask)(void *dstBitsP, UInt16 dstPitch,
  70. const void *srcBitsP, UInt16 srcPitch,
  71. UInt16 srcWidth, UInt16 srcHeight,
  72. UInt8 ff, const void *maskBitsP);
  73. Err (*GE2DBlitBitmap)(void *dstP, Coord left, Coord top,
  74. UInt16 dstWidth, UInt16 dstHeight, GE2DBitmapType *);
  75. Err (*GE2DConvertBitmap)(GE2DBitmapType *, GE2DBitmapType *);
  76. Err (*GE2DProgramBlitBitmapWithMask)(GE2DInsnType *programP,
  77. void *dstP, Coord left, Coord top,
  78. UInt16 dstWidth, UInt16 dstHeight,
  79. GE2DBitmapType *bmpP, const void *p7);
  80. Err (*GE2DProgramBlitBitmap)(GE2DInsnType *programP,
  81. void *dstP, Coord left, Coord top,
  82. UInt16 dstWidth, UInt16 dstHeight, GE2DBitmapType *bmpP);
  83. Err (*GE2DScaleBitmap)(GE2DBitmapType *dstBmpP, GE2DBitmapType *srcBmpP);
  84. Err (*GE2DShowOverlay)(Coord left, Coord top, GE2DBitmapType *);
  85. Err (*GE2DHideOverlay)();
  86. Err (*GE2DRunProgram)(const GE2DInsnType *programP);
  87. Err (*GE2DRunProgram2)(const GE2DInsnType *programP);
  88. Err (*GE2D_60)(UInt16 x, UInt16 y);
  89. Err (*GE2D_64)();
  90. Err (*GE2D_68)(void *);
  91. Err (*GE2D_72)(RectangleType *);
  92. Err (*GE2D_76)(FormType *);
  93. Err (*GE2D_80)(Boolean);
  94. Err (*GE2D_84)();
  95. Err (*GE2DSetLock)(Boolean lock);
  96. } GE2DLibAPIType;
  97. typedef struct ge2d
  98. {
  99. overlay p;
  100. point Offset;
  101. GE2DBitmapType Buffer;
  102. GE2DBitmapType Scale;
  103. int BufferSize;
  104. int ScaleSize;
  105. rect OverlayRect;
  106. blitfx SoftFX;
  107. char* Bits;
  108. } ge2d;
  109. static UInt32 LibRef = 0;
  110. #if defined(GE2DEMU)
  111. #include "ge2demu.c"
  112. #else
  113. static GE2DLibAPIType API;
  114. #endif
  115. extern char* QueryScreen(video* Video,int* Offset,int* Mode);
  116. static void FreeBuffer(GE2DBitmapType* p,int* Allocated)
  117. {
  118. free(p->plane1P);
  119. free(p->plane2P);
  120. free(p->plane3P);
  121. memset(p,0,sizeof(GE2DBitmapType));
  122. *Allocated = 0;
  123. }
  124. static bool_t AllocBuffer(GE2DBitmapType* p,int w,int h,int* Allocated)
  125. {
  126. int size;
  127. w = (w+1) & ~1;
  128. h = (h+1) & ~1;
  129. size = w*h;
  130. p->format = sonyGE2DFormatYCbCr420Planar;
  131. p->zero = 0;
  132. p->pitch = (UInt16)w;
  133. p->chromaPitch = (UInt16)(w >> 1);
  134. p->width = (UInt16)w;
  135. p->height = (UInt16)h;
  136. p->unused = 0;
  137. if (*Allocated < size)
  138. {
  139. free(p->plane1P);
  140. free(p->plane2P);
  141. free(p->plane3P);
  142. p->plane1P = malloc(size);
  143. p->plane2P = malloc(size/4);
  144. p->plane3P = malloc(size/4);
  145. if (!p->plane1P || !p->plane2P || !p->plane3P)
  146. {
  147. FreeBuffer(p,Allocated);
  148. return 0;
  149. }
  150. *Allocated = size;
  151. }
  152. memset(p->plane1P,0,size);
  153. memset(p->plane2P,128,size/4);
  154. memset(p->plane2P,128,size/4);
  155. return 1;
  156. }
  157. static int GetMode(ge2d* p)
  158. {
  159. int Offset;
  160. p->Bits = QueryScreen(&p->p.Output.Format.Video,&Offset,NULL);
  161. if (!p->p.Output.Format.Video.Pitch || !p->p.Output.Format.Video.Pixel.BitCount)
  162. return ERR_INVALID_PARAM;
  163. p->Offset.x = (Offset % p->p.Output.Format.Video.Pitch) / (p->p.Output.Format.Video.Pixel.BitCount/8);
  164. p->Offset.y = Offset / p->p.Output.Format.Video.Pitch;
  165. return ERR_NONE;
  166. }
  167. static int Init(ge2d* p)
  168. {
  169. //p->p.SetFX = BLITFX_AVOIDTEARING;
  170. p->p.Overlay = 0;
  171. if (GetMode(p) != ERR_NONE)
  172. return ERR_INVALID_PARAM;
  173. if (!AllocBuffer(&p->Buffer,p->p.Input.Format.Video.Width,p->p.Input.Format.Video.Height,&p->BufferSize))
  174. return ERR_OUT_OF_MEMORY;
  175. return ERR_NONE;
  176. }
  177. static void Done(ge2d* p)
  178. {
  179. FreeBuffer(&p->Buffer,&p->BufferSize);
  180. FreeBuffer(&p->Scale,&p->ScaleSize);
  181. }
  182. static int UpdateOverlay(ge2d* p)
  183. {
  184. if (p->p.Overlay)
  185. {
  186. if (p->p.Show)
  187. {
  188. int x = p->p.DstAlignedRect.x;
  189. int y = p->p.DstAlignedRect.y;
  190. x += p->Offset.x;
  191. y += p->Offset.y;
  192. PALMCALL3(API.GE2DShowOverlay,(Coord)x,(Coord)y,p->Scale.format? &p->Scale : &p->Buffer);
  193. }
  194. else
  195. PALMCALL0(API.GE2DHideOverlay);
  196. }
  197. return ERR_NONE;
  198. }
  199. static int Update(ge2d* p)
  200. {
  201. blitfx OvlFX = p->p.FX;
  202. video Buffer;
  203. if (p->p.Overlay)
  204. PALMCALL0(API.GE2DHideOverlay);
  205. p->SoftFX = p->p.FX;
  206. p->SoftFX.ScaleX = SCALE_ONE; // scale handled by hardware
  207. p->SoftFX.ScaleY = SCALE_ONE;
  208. OvlFX.Direction = 0;
  209. //align to 100%
  210. if (OvlFX.ScaleX > SCALE_ONE-(SCALE_ONE/16) && OvlFX.ScaleX < SCALE_ONE+(SCALE_ONE/16) &&
  211. OvlFX.ScaleY > SCALE_ONE-(SCALE_ONE/16) && OvlFX.ScaleY < SCALE_ONE+(SCALE_ONE/16))
  212. {
  213. OvlFX.ScaleX = SCALE_ONE;
  214. OvlFX.ScaleY = SCALE_ONE;
  215. }
  216. if (p->SoftFX.Direction & DIR_SWAPXY)
  217. SwapInt(&OvlFX.ScaleX,&OvlFX.ScaleY);
  218. memset(&Buffer,0,sizeof(Buffer));
  219. Buffer.Pixel.Flags = PF_YUV420;
  220. Buffer.Width = p->p.Input.Format.Video.Width;
  221. Buffer.Height = p->p.Input.Format.Video.Height;
  222. Buffer.Direction = CombineDir(p->p.InputDirection,p->p.OrigFX.Direction,p->p.Output.Format.Video.Direction);
  223. if (Buffer.Direction & DIR_SWAPXY)
  224. SwapInt(&Buffer.Width,&Buffer.Height);
  225. Buffer.Pitch = Buffer.Width;
  226. for (;;)
  227. {
  228. VirtToPhy(&p->p.Viewport,&p->p.DstAlignedRect,&p->p.Output.Format.Video);
  229. VirtToPhy(NULL,&p->OverlayRect,&Buffer);
  230. AnyAlign(&p->p.DstAlignedRect, &p->OverlayRect, &OvlFX, 2, 1, SCALE_ONE/256, SCALE_ONE*256);
  231. if ((OvlFX.ScaleX != SCALE_ONE || OvlFX.ScaleY != SCALE_ONE) && 
  232. (p->p.DstAlignedRect.Width != p->OverlayRect.Width && p->p.DstAlignedRect.Height != p->OverlayRect.Height))
  233. {
  234. if (!AllocBuffer(&p->Scale,p->p.DstAlignedRect.Width,p->p.DstAlignedRect.Height,&p->ScaleSize))
  235. {
  236. // fallback to 100%
  237. OvlFX.ScaleX = SCALE_ONE;
  238. OvlFX.ScaleY = SCALE_ONE;
  239. continue;
  240. }
  241. }
  242. else
  243. FreeBuffer(&p->Scale,&p->ScaleSize);
  244. break;
  245. }
  246. VirtToPhy(NULL,&p->p.SrcAlignedRect,&p->p.Input.Format.Video);
  247. BlitRelease(p->p.Soft);
  248. p->p.Soft = BlitCreate(&Buffer,&p->p.Input.Format.Video,&p->SoftFX,&p->p.Caps);
  249. BlitAlign(p->p.Soft,&p->OverlayRect,&p->p.SrcAlignedRect);
  250. if (!AllocBuffer(&p->Buffer,p->OverlayRect.Width,p->OverlayRect.Height,&p->BufferSize))
  251. return ERR_OUT_OF_MEMORY;
  252. Buffer.Width = p->OverlayRect.Width;
  253. Buffer.Height = p->OverlayRect.Height;
  254. Buffer.Pitch = Buffer.Width;
  255. p->OverlayRect.x = 0;
  256. p->OverlayRect.y = 0;
  257. BlitRelease(p->p.Soft);
  258. p->p.Soft = BlitCreate(&Buffer,&p->p.Input.Format.Video,&p->SoftFX,&p->p.Caps);
  259. BlitAlign(p->p.Soft,&p->OverlayRect,&p->p.SrcAlignedRect);
  260. if (!p->Scale.format) // no scaling -> adjust dst rectangle with soft yuv blitting alignement
  261. {
  262. p->p.DstAlignedRect.x += (p->p.DstAlignedRect.Width - p->OverlayRect.Width) >> 1;
  263. p->p.DstAlignedRect.y += (p->p.DstAlignedRect.Height - p->OverlayRect.Height) >> 1;
  264. p->p.DstAlignedRect.Width = p->OverlayRect.Width;
  265. p->p.DstAlignedRect.Height = p->OverlayRect.Height;
  266. }
  267. PhyToVirt(&p->p.DstAlignedRect,&p->p.GUIAlignedRect,&p->p.Output.Format.Video);
  268. return UpdateOverlay(p);
  269. }
  270. static INLINE void FlushDCache(void *p, int n)
  271. {
  272. SonyCleanDCache(p,n);
  273. SonyInvalidateDCache(p,n);
  274. }
  275. static int Blit(ge2d* p, const constplanes Data, const constplanes DataLast )
  276. {
  277. int n;
  278. planes Planes;
  279. Planes[0] = p->Buffer.plane1P;
  280. Planes[1] = p->Buffer.plane3P;
  281. Planes[2] = p->Buffer.plane2P;
  282. BlitImage(p->p.Soft,Planes,Data,DataLast,-1,-1);
  283. n = p->Buffer.width * p->Buffer.height;
  284. FlushDCache(Planes[0],n);
  285. FlushDCache(Planes[1],n/4);
  286. FlushDCache(Planes[2],n/4);
  287. if (p->Scale.format)
  288. PALMCALL2(API.GE2DScaleBitmap,&p->Scale,&p->Buffer);
  289. if (!p->p.Overlay)
  290. {
  291. PALMCALL6(API.GE2DBlitBitmap,p->Bits,
  292. (Coord)(p->p.DstAlignedRect.x + p->Offset.x),
  293. (Coord)(p->p.DstAlignedRect.y + p->Offset.y),
  294. (Coord)(p->p.Output.Format.Video.Pitch>>1),(Coord)p->p.Output.Format.Video.Height,
  295. p->Scale.format? &p->Scale : &p->Buffer);
  296. }
  297. return ERR_NONE;
  298. }
  299. static int Reset(ge2d* p)
  300. {
  301. return GetMode(p);
  302. }
  303. static int Create(ge2d* p)
  304. {
  305. p->p.Init = (ovlfunc)Init;
  306. p->p.Done = (ovldone)Done;
  307. p->p.Reset = (ovlfunc)Reset;
  308. p->p.Blit = (ovlblit)Blit;
  309. p->p.Update = (ovlfunc)Update;
  310. p->p.UpdateShow = (ovlfunc)UpdateOverlay;
  311. QueryDesktop(&p->p.Output.Format.Video);
  312. return ERR_NONE;
  313. }
  314. static const nodedef GE2D = 
  315. {
  316. sizeof(ge2d)|CF_GLOBAL,
  317. GE2D_ID,
  318. OVERLAY_CLASS,
  319. PRI_DEFAULT+50,
  320. (nodecreate)Create,
  321. };
  322. void GE2D_Init() 
  323. {
  324. #if !defined(GE2DEMU)
  325. Err err;
  326. // UInt32 CompanyID;
  327. // FtrGet(sysFtrCreator, sysFtrNumOEMCompanyID, &CompanyID);
  328. // if (CompanyID != 'sony')
  329. // return;
  330. err = SysFindModule(sonyGE2DLibType, sonyGE2DLibCreator, 0, 0, &LibRef);
  331. if (err) 
  332. err = SysLoadModule(sonyGE2DLibType, sonyGE2DLibCreator, 0, 0, &LibRef);
  333. if (err)
  334. return;
  335. if (SysGetEntryAddresses(LibRef, 0, 22, (void **)(void *)&API) != errNone)
  336. return;
  337. #endif
  338. PALMCALL0(API.GE2DLibOpen);
  339. NodeRegisterClass(&GE2D);
  340. }
  341. void GE2D_Done() 
  342. {
  343. NodeUnRegisterClass(GE2D_ID);
  344. if (LibRef)
  345. {
  346. PALMCALL0(API.GE2DLibClose);
  347. //SysUnloadModule(LibRef);
  348. LibRef = 0;
  349. }
  350. }
  351. #else
  352. void GE2D_Init() {}
  353. void GE2D_Done() {}
  354. #endif