ddblt.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxcom.h"
  36. #include "hxtypes.h"
  37. #include "hxwintyp.h"
  38. #include "ddblt.h"
  39. #ifdef __cplusplus
  40. extern "C"
  41. #endif
  42. #if 0
  43. static void MovePlain(
  44.     UCHAR *srcPtr, int srcPitch, UCHAR *destPtr, int destPitch,
  45.     int plainWidth, int plainHeight)
  46. {
  47.     register int i;
  48.     for (i = 0; i < plainHeight; i ++)
  49.     {
  50.         /* must be done using MMX movqs,
  51.          * but this is a simple test app, not a production code: */
  52.         memcpy(destPtr, srcPtr, plainWidth); /* Flawfinder: ignore */
  53.         srcPtr += srcPitch;
  54.         destPtr += destPitch;
  55.     }
  56. }
  57. #endif //0
  58. CDDBlt::CDDBlt()
  59.  :  CWinBlt()
  60.  ,  m_pDD(NULL)
  61.  ,  m_pPrimary(NULL)
  62.  ,  m_pOffscreen(NULL)
  63. {
  64. }
  65. CDDBlt::~CDDBlt()
  66. {
  67.     DestroySurface(0);
  68. }
  69. HX_RESULT CDDBlt::CreateSurface(int cidIn, int& cidOut,
  70.                                 int nWidth, int nHeight,
  71.                                 int nFlags, HWND hWnd,
  72.                                 int nCountIn, int& nCountOut)
  73. {
  74.     HRESULT hr;
  75.     if (!m_pDD)
  76.     {
  77.         hr = DirectDrawCreate(NULL, &m_pDD, NULL);
  78.         if (hr)
  79.             return HXR_FAIL;
  80.     }
  81.     IDirectDraw2 *pDD2 = NULL;
  82.     hr = m_pDD->QueryInterface(IID_IDirectDraw2, (void **)&pDD2);
  83.     if (!pDD2)
  84.     {
  85. HX_RELEASE(m_pDD);
  86. return HXR_FAIL;
  87.     }
  88.     m_hWnd = hWnd;
  89.     hr = pDD2->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
  90.     if (!m_pPrimary)
  91.     {
  92. // Create primary surface
  93. DDSURFACEDESC ddsd;
  94. ZeroMemory(&ddsd, sizeof(ddsd));
  95. ddsd.dwSize = sizeof(ddsd);
  96. ddsd.dwFlags = DDSD_CAPS;
  97. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  98.     
  99. pDD2->CreateSurface (&ddsd, &m_pPrimary, NULL);
  100. if (!m_pPrimary)
  101. {
  102.     HX_RELEASE(m_pDD);
  103.     HX_RELEASE(pDD2);
  104.     return HXR_FAIL;
  105. }
  106. IDirectDrawClipper *pDDclip;
  107. if (DD_OK == pDD2->CreateClipper(0, &pDDclip, NULL))
  108. {
  109.     pDDclip->SetHWnd(0, m_hWnd);
  110.     m_pPrimary->SetClipper(pDDclip);
  111.     HX_RELEASE(pDDclip);
  112. }
  113.     }
  114.     // Create offscreen surface
  115.     DDSURFACEDESC ddsd;
  116.     memset(&ddsd, 0, sizeof(ddsd));
  117.     ddsd.dwSize = sizeof(ddsd);
  118.     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; 
  119.     ddsd.dwWidth = nWidth;
  120.     ddsd.dwHeight = nHeight;
  121.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  122.     ddsd.dwFlags |= DDSD_PIXELFORMAT;
  123.     ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  124.     const int nOutputFormats = 6;
  125.     UINT32 fourCC[nOutputFormats];
  126.     UINT32 bbp[nOutputFormats];
  127.     UINT32 rbm[nOutputFormats];
  128.     UINT32 gbm[nOutputFormats];
  129.     UINT32 bbm[nOutputFormats];
  130.     UINT32 flags[nOutputFormats];
  131.     int    cid[nOutputFormats];
  132.     memset(&rbm, 0, sizeof(rbm));
  133.     memset(&gbm, 0, sizeof(gbm));
  134.     memset(&bbm, 0, sizeof(bbm));
  135.     memset(&flags, 0, sizeof(flags));
  136.     int nOutputTypes = 0;
  137. #if defined (HELIX_FEATURE_CC_I420out)
  138.     fourCC[nOutputTypes] = MAKEFOURCC('I', '4', '2', '0');
  139.     bbp[nOutputTypes] = 12;
  140.     cid[nOutputTypes] = CID_I420;
  141.     flags[nOutputTypes] = DDPF_FOURCC;
  142.     ++nOutputTypes;
  143. #endif //HELIX_FEATURE_CC_I420out
  144. #if defined (HELIX_FEATURE_CC_YV12out)
  145.     fourCC[nOutputTypes] = MAKEFOURCC('Y', 'V', '1', '2');
  146.     bbp[nOutputTypes] = 12;
  147.     cid[nOutputTypes] = CID_YV12;
  148.     flags[nOutputTypes] = DDPF_FOURCC;
  149.     ++nOutputTypes;
  150. #endif //HELIX_FEATURE_CC_YV12out
  151. #if defined (HELIX_FEATURE_CC_YUY2out)
  152.     fourCC[nOutputTypes] = MAKEFOURCC('Y', 'U', 'Y', '2');
  153.     bbp[nOutputTypes] = 16;
  154.     cid[nOutputTypes] = CID_YUY2;
  155.     flags[nOutputTypes] = DDPF_FOURCC;
  156.     ++nOutputTypes;
  157. #endif //HELIX_FEATURE_CC_YUY2out
  158. #if defined (HELIX_FEATURE_CC_UYVYout)
  159.     fourCC[nOutputTypes] = MAKEFOURCC('U', 'Y', 'V', 'Y');
  160.     bbp[nOutputTypes] = 16;
  161.     cid[nOutputTypes] = CID_UYVY;
  162.     flags[nOutputTypes] = DDPF_FOURCC;
  163.     ++nOutputTypes;
  164. #endif //HELIX_FEATURE_CC_UYVYout
  165. #if defined (HELIX_FEATURE_CC_RGB32out)
  166.     fourCC[nOutputTypes] = BI_RGB;
  167.     bbp[nOutputTypes] = 32;
  168.     cid[nOutputTypes] = CID_RGB32;
  169.     rbm[nOutputTypes] = 0xFF0000;
  170.     gbm[nOutputTypes] = 0x00FF00;
  171.     bbm[nOutputTypes] = 0x0000FF;
  172.     flags[nOutputTypes] = DDPF_RGB;
  173.     ++nOutputTypes;
  174. #endif //HELIX_FEATURE_CC_RGB32out
  175. #if defined (HELIX_FEATURE_CC_RGB565out)
  176.     fourCC[nOutputTypes] = BI_RGB;
  177.     bbp[nOutputTypes] = 16;
  178.     cid[nOutputTypes] = CID_RGB565;
  179.     rbm[nOutputTypes] = 0x7C00;
  180.     gbm[nOutputTypes] = 0x03E0;
  181.     bbm[nOutputTypes] = 0x001F;
  182.     flags[nOutputTypes] = DDPF_RGB;
  183.     ++nOutputTypes;
  184. #endif //HELIX_FEATURE_CC_RGB565out
  185.     for (int i=0; i<nOutputTypes; i++)
  186.     {
  187.         ddsd.ddpfPixelFormat.dwFourCC       = fourCC[i];
  188.         ddsd.ddpfPixelFormat.dwRGBBitCount  = bbp[i];                                                                   
  189.         ddsd.ddpfPixelFormat.dwRBitMask     = rbm[i];
  190.         ddsd.ddpfPixelFormat.dwGBitMask     = gbm[i];
  191.         ddsd.ddpfPixelFormat.dwBBitMask     = bbm[i];
  192.         ddsd.ddpfPixelFormat.dwFlags        = flags[i];                                                                
  193.         if (DD_OK == pDD2->CreateSurface (&ddsd, &m_pOffscreen, NULL))
  194.         {
  195.             m_nCID = cid[i];
  196.             break;
  197.         }
  198.     }
  199.     
  200.     pDD2->Release();
  201.     // Don't use DirectDraw
  202.     if (!m_pOffscreen)
  203.     {
  204.         HX_RELEASE(m_pPrimary);                  
  205.         HX_RELEASE(m_pDD);
  206.         return HXR_FAIL;
  207.     }
  208.     return HXR_OK;
  209. }
  210. HX_RESULT CDDBlt::LockSurface(UCHAR** ppDestPtr,
  211.                               LONG32* pnDestPitch,
  212.                               int& cid,
  213.                               REF(HXxSize) dstSize,
  214.                               int nIndex)
  215. {
  216.     DDSURFACEDESC ddsd;
  217.     memset(&ddsd, 0, sizeof(ddsd));
  218.     ddsd.dwSize = sizeof(ddsd);
  219.     HRESULT hr;
  220.     for (int i=0; i<3; i++)
  221.     {
  222. hr = m_pOffscreen->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
  223.         if (DDERR_SURFACELOST == hr)
  224. {
  225.     m_pOffscreen->Restore();
  226.     m_pPrimary->Restore();
  227. }
  228. else if (DD_OK == hr)
  229. {
  230.     *ppDestPtr = (UCHAR*)ddsd.lpSurface;
  231.     *pnDestPitch = ddsd.lPitch;
  232.     break;
  233. }
  234. else
  235. {
  236.     return HXR_FAIL;
  237. }
  238.     }
  239.     
  240.     return HXR_OK;
  241. }
  242. HX_RESULT CDDBlt::FillSurface(int cidIn,
  243.                               UCHAR* pSrcBuffer,
  244.                               HXxSize* pSrcSize,
  245.                               HXxRect* prSrcRect,
  246.                               UCHAR* pDstBuffer,
  247.                               LONG32 nDstPitch,
  248.                               HXxRect* prDestRect)
  249. {
  250. #if 1
  251.     return HXR_FAIL;
  252. #else
  253.     // If input and output are both planar, just copy each plane
  254.     if (CID_YV12 != m_nCID || 
  255.         (cidIn != CID_I420 && cidIn != CID_XING))
  256.         return HXR_FAIL;
  257.     INT32 yPitch = pSrcSize->cx;
  258.     INT32 uvPitch = pSrcSize->cx/2;
  259.     UCHAR *pU = pSrcBuffer + pSrcSize->cy*yPitch;
  260.     UCHAR *pV = pU + pSrcSize->cy/2*uvPitch;
  261.     if (cidIn == CID_XING)
  262.     {
  263.         yPitch = 768;
  264.         uvPitch = 768;
  265.         pU = pSrcBuffer + pSrcSize->cy*yPitch;
  266.         pV = pU + yPitch/2;
  267.     }
  268.     
  269.     // We only support YV12
  270.     UCHAR *pDestV = pDstBuffer + pSrcSize->cy*nDstPitch;
  271.     UCHAR *pDestU = pDestV + pSrcSize->cy*nDstPitch/4;
  272.     MovePlain(pSrcBuffer, yPitch, pDstBuffer, nDstPitch,
  273.               pSrcSize->cx,pSrcSize->cy);
  274.     MovePlain(pU, uvPitch, pDestU, nDstPitch/2,
  275.               pSrcSize->cx/2,pSrcSize->cy/2);
  276.     MovePlain(pV, uvPitch, pDestV, nDstPitch/2,
  277.               pSrcSize->cx/2,pSrcSize->cy/2);
  278.     
  279. #endif //1
  280.     return HXR_OK;
  281. }
  282. HX_RESULT CDDBlt::UnlockSurface(UCHAR* pSurfPtr, int nIndex)
  283. {
  284.     m_pOffscreen->Unlock(NULL);
  285.     return HXR_OK;
  286. }
  287. HX_RESULT CDDBlt::RenderSurface(HXxSize* pSrcSize,
  288.                                 HXxRect* prSrcRect,
  289.                                 HXxRect* prDestRect,
  290.                                 int nIndex)
  291. {
  292.     // Map to screen coordinates
  293.     POINT   po = {0,0};
  294.     ClientToScreen(m_hWnd, &po);
  295.     
  296.     RECT rc;
  297.     GetClientRect(m_hWnd, &rc);
  298.     
  299.     rc.left += po.x;
  300.     rc.right += po.x;
  301.     rc.top += po.y;
  302.     rc.bottom += po.y;
  303.     
  304.     DDBLTFX ddbltfx;
  305.     memset(&ddbltfx, 0, sizeof(ddbltfx));
  306.     ddbltfx.dwSize = sizeof(ddbltfx);
  307.     ddbltfx.dwDDFX = DDBLTFX_NOTEARING; 
  308.     HRESULT hr = m_pPrimary->Blt(&rc, m_pOffscreen, NULL, DDBLT_WAIT, &ddbltfx);
  309.     if (DD_OK == hr)
  310.         return HXR_OK;
  311.     else
  312.         return HXR_FAIL;
  313. }
  314. HX_RESULT CDDBlt::DestroySurface(int cid)
  315. {
  316.     HX_RELEASE(m_pPrimary);
  317.     HX_RELEASE(m_pOffscreen);
  318.     HX_RELEASE(m_pDD);
  319.     
  320.     return HXR_OK;
  321. }