ddblt.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:12k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: ddblt.cpp,v 1.3.34.2 2004/07/09 01:59:19 hubbe Exp $
- *
- * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file,
- * are subject to the current version of the RealNetworks Public
- * Source License (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (the "RCSL") available at
- * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
- * will apply. You may also obtain the license terms directly from
- * RealNetworks. You may not use this file except in compliance with
- * the RPSL or, if you have a valid RCSL with RealNetworks applicable
- * to this file, the RCSL. Please see the applicable RPSL or RCSL for
- * the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the
- * portions it created.
- *
- * This file, and the files included with this file, is distributed
- * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
- * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
- * ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- #include "hxcom.h"
- #include "hxtypes.h"
- #include "hxwintyp.h"
- #include "ddblt.h"
- #ifdef __cplusplus
- extern "C"
- #endif
- #if 0
- static void MovePlain(
- UCHAR *srcPtr, int srcPitch, UCHAR *destPtr, int destPitch,
- int plainWidth, int plainHeight)
- {
- register int i;
- for (i = 0; i < plainHeight; i ++)
- {
- /* must be done using MMX movqs,
- * but this is a simple test app, not a production code: */
- memcpy(destPtr, srcPtr, plainWidth); /* Flawfinder: ignore */
- srcPtr += srcPitch;
- destPtr += destPitch;
- }
- }
- #endif //0
- CDDBlt::CDDBlt()
- : CWinBlt()
- , m_pDD(NULL)
- , m_pPrimary(NULL)
- , m_pOffscreen(NULL)
- {
- }
- CDDBlt::~CDDBlt()
- {
- DestroySurface(0);
- }
- HX_RESULT CDDBlt::CreateSurface(int cidIn, int& cidOut,
- int nWidth, int nHeight,
- int nFlags, HWND hWnd,
- int nCountIn, int& nCountOut)
- {
- HRESULT hr;
- if (!m_pDD)
- {
- hr = DirectDrawCreate(NULL, &m_pDD, NULL);
- if (hr)
- return HXR_FAIL;
- }
- IDirectDraw2 *pDD2 = NULL;
- hr = m_pDD->QueryInterface(IID_IDirectDraw2, (void **)&pDD2);
- if (!pDD2)
- {
- HX_RELEASE(m_pDD);
- return HXR_FAIL;
- }
- m_hWnd = hWnd;
- hr = pDD2->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
- if (hr)
- {
- HX_RELEASE(pDD2);
- return HXR_FAIL;
- }
- if (!m_pPrimary)
- {
- // Create primary surface
- DDSURFACEDESC ddsd;
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- hr = pDD2->CreateSurface (&ddsd, &m_pPrimary, NULL);
- if (!m_pPrimary || hr != DD_OK)
- {
- HX_RELEASE(m_pDD);
- HX_RELEASE(pDD2);
- return HXR_FAIL;
- }
- IDirectDrawClipper *pDDclip;
- if (DD_OK == pDD2->CreateClipper(0, &pDDclip, NULL))
- {
- pDDclip->SetHWnd(0, m_hWnd);
- m_pPrimary->SetClipper(pDDclip);
- HX_RELEASE(pDDclip);
- }
- }
- // Create offscreen surface
- DDSURFACEDESC ddsd;
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
- ddsd.dwWidth = nWidth;
- ddsd.dwHeight = nHeight;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- #ifndef HELIX_FEATURE_DD_AUTOPIXELFORMAT
- ddsd.dwFlags |= DDSD_PIXELFORMAT;
- ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
- #endif //!HELIX_FEATURE_DD_AUTOPIXELFORMAT
- const int nOutputFormats = 6;
- UINT32 fourCC[nOutputFormats];
- UINT32 bbp[nOutputFormats];
- UINT32 rbm[nOutputFormats];
- UINT32 gbm[nOutputFormats];
- UINT32 bbm[nOutputFormats];
- UINT32 flags[nOutputFormats];
- int cid[nOutputFormats];
- memset(&rbm, 0, sizeof(rbm));
- memset(&gbm, 0, sizeof(gbm));
- memset(&bbm, 0, sizeof(bbm));
- memset(&flags, 0, sizeof(flags));
- int nOutputTypes = 0;
- #if defined (HELIX_FEATURE_CC_I420out)
- fourCC[nOutputTypes] = MAKEFOURCC('I', '4', '2', '0');
- bbp[nOutputTypes] = 12;
- cid[nOutputTypes] = CID_I420;
- flags[nOutputTypes] = DDPF_FOURCC;
- ++nOutputTypes;
- #endif //HELIX_FEATURE_CC_I420out
- #if defined (HELIX_FEATURE_CC_YV12out)
- fourCC[nOutputTypes] = MAKEFOURCC('Y', 'V', '1', '2');
- bbp[nOutputTypes] = 12;
- cid[nOutputTypes] = CID_YV12;
- flags[nOutputTypes] = DDPF_FOURCC;
- ++nOutputTypes;
- #endif //HELIX_FEATURE_CC_YV12out
- #if defined (HELIX_FEATURE_CC_YUY2out)
- fourCC[nOutputTypes] = MAKEFOURCC('Y', 'U', 'Y', '2');
- bbp[nOutputTypes] = 16;
- cid[nOutputTypes] = CID_YUY2;
- flags[nOutputTypes] = DDPF_FOURCC;
- ++nOutputTypes;
- #endif //HELIX_FEATURE_CC_YUY2out
- #if defined (HELIX_FEATURE_CC_UYVYout)
- fourCC[nOutputTypes] = MAKEFOURCC('U', 'Y', 'V', 'Y');
- bbp[nOutputTypes] = 16;
- cid[nOutputTypes] = CID_UYVY;
- flags[nOutputTypes] = DDPF_FOURCC;
- ++nOutputTypes;
- #endif //HELIX_FEATURE_CC_UYVYout
- #if defined (HELIX_FEATURE_CC_RGB32out)
- fourCC[nOutputTypes] = BI_RGB;
- bbp[nOutputTypes] = 32;
- cid[nOutputTypes] = CID_RGB32;
- rbm[nOutputTypes] = 0xFF0000;
- gbm[nOutputTypes] = 0x00FF00;
- bbm[nOutputTypes] = 0x0000FF;
- #if defined (HELIX_FEATURE_DD_AUTOPIXELFORMAT)
- flags[nOutputTypes] = DDPF_RGB|DDPF_ALPHAPREMULT|DDPF_ALPHAPIXELS;
- #else
- flags[nOutputTypes] = DDPF_RGB;
- #endif //HELIX_FEATURE_DD_AUTOPIXELFORMAT
- ++nOutputTypes;
- #endif //HELIX_FEATURE_CC_RGB32out
- #if defined (HELIX_FEATURE_CC_RGB565out)
- fourCC[nOutputTypes] = BI_RGB;
- bbp[nOutputTypes] = 16;
- cid[nOutputTypes] = CID_RGB565;
- rbm[nOutputTypes] = 0x7C00;
- gbm[nOutputTypes] = 0x03E0;
- bbm[nOutputTypes] = 0x001F;
- flags[nOutputTypes] = DDPF_RGB;
- ++nOutputTypes;
- #endif //HELIX_FEATURE_CC_RGB565out
- for (int i=0; i<nOutputTypes; i++)
- {
- ddsd.ddpfPixelFormat.dwFourCC = fourCC[i];
- ddsd.ddpfPixelFormat.dwRGBBitCount = bbp[i];
- ddsd.ddpfPixelFormat.dwRBitMask = rbm[i];
- ddsd.ddpfPixelFormat.dwGBitMask = gbm[i];
- ddsd.ddpfPixelFormat.dwBBitMask = bbm[i];
- ddsd.ddpfPixelFormat.dwFlags = flags[i];
- #ifdef _DEBUG
- HX_TRACE( "CDDBlt::CreateSurface: BEFORE CreateSurface(Offscreen) returned: n");
- HX_TRACE( " CCFormat: 0x%08X n", ddsd.ddpfPixelFormat.dwFourCC );
- HX_TRACE( " RGBBitCount (bbp): %d n", ddsd.ddpfPixelFormat.dwRGBBitCount );
- HX_TRACE( " Flags: 0x%08X n", ddsd.ddpfPixelFormat.dwFlags );
- HX_TRACE( " RBitMask: 0x%08X n", ddsd.ddpfPixelFormat.dwRBitMask );
- HX_TRACE( " GBitMask: 0x%08X n", ddsd.ddpfPixelFormat.dwGBitMask );
- HX_TRACE( " BBitMask: 0x%08X n", ddsd.ddpfPixelFormat.dwBBitMask );
- #endif //_DEBUG
- hr = pDD2->CreateSurface (&ddsd, &m_pOffscreen, NULL);
- if (DD_OK == hr)
- {
- m_nCID = cid[i];
- #ifdef _DEBUG
- memset( &(ddsd.ddpfPixelFormat), 0, sizeof(ddsd.ddpfPixelFormat) );
- ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
- hr = m_pOffscreen->GetPixelFormat( &(ddsd.ddpfPixelFormat) );
- if (FAILED(hr))
- {
- }
- else
- {
- HX_TRACE( "CDDBlt::CreateSurface: AFTER CreateSurface(Offscreen) returned: n");
- HX_TRACE( " CCFormat: 0x%08X n", ddsd.ddpfPixelFormat.dwFourCC );
- HX_TRACE( " RGBBitCount (bbp): %d n", ddsd.ddpfPixelFormat.dwRGBBitCount );
- HX_TRACE( " Flags: 0x%08X n", ddsd.ddpfPixelFormat.dwFlags );
- HX_TRACE( " RBitMask: 0x%08X n", ddsd.ddpfPixelFormat.dwRBitMask );
- HX_TRACE( " GBitMask: 0x%08X n", ddsd.ddpfPixelFormat.dwGBitMask );
- HX_TRACE( " BBitMask: 0x%08X n", ddsd.ddpfPixelFormat.dwBBitMask );
- }
- #endif //_DEBUG
- break;
- }
- }
- HX_RELEASE(pDD2);
- // Don't use DirectDraw
- if (!m_pOffscreen)
- {
- HX_RELEASE(m_pPrimary);
- HX_RELEASE(m_pDD);
- return HXR_FAIL;
- }
- return HXR_OK;
- }
- HX_RESULT CDDBlt::LockSurface(UCHAR** ppDestPtr,
- LONG32* pnDestPitch,
- int& cid,
- REF(HXxSize) dstSize,
- int nIndex)
- {
- if (!m_pPrimary || !m_pOffscreen)
- return HXR_FAIL;
- DDSURFACEDESC ddsd;
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- HRESULT hr;
- for (int i=0; i<3; i++)
- {
- hr = m_pOffscreen->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
- if (DDERR_SURFACELOST == hr)
- {
- m_pOffscreen->Restore();
- m_pPrimary->Restore();
- }
- else if (DD_OK == hr)
- {
- *ppDestPtr = (UCHAR*)ddsd.lpSurface;
- *pnDestPitch = ddsd.lPitch;
- break;
- }
- else
- {
- return HXR_FAIL;
- }
- }
- return HXR_OK;
- }
- HX_RESULT CDDBlt::FillSurface(int cidIn,
- UCHAR* pSrcBuffer,
- HXxSize* pSrcSize,
- HXxRect* prSrcRect,
- UCHAR* pDstBuffer,
- LONG32 nDstPitch,
- HXxRect* prDestRect)
- {
- #if 1
- return HXR_FAIL;
- #else
- // If input and output are both planar, just copy each plane
- if (CID_YV12 != m_nCID ||
- (cidIn != CID_I420 && cidIn != CID_XING))
- return HXR_FAIL;
- INT32 yPitch = pSrcSize->cx;
- INT32 uvPitch = pSrcSize->cx/2;
- UCHAR *pU = pSrcBuffer + pSrcSize->cy*yPitch;
- UCHAR *pV = pU + pSrcSize->cy/2*uvPitch;
- if (cidIn == CID_XING)
- {
- yPitch = 768;
- uvPitch = 768;
- pU = pSrcBuffer + pSrcSize->cy*yPitch;
- pV = pU + yPitch/2;
- }
- // We only support YV12
- UCHAR *pDestV = pDstBuffer + pSrcSize->cy*nDstPitch;
- UCHAR *pDestU = pDestV + pSrcSize->cy*nDstPitch/4;
- MovePlain(pSrcBuffer, yPitch, pDstBuffer, nDstPitch,
- pSrcSize->cx,pSrcSize->cy);
- MovePlain(pU, uvPitch, pDestU, nDstPitch/2,
- pSrcSize->cx/2,pSrcSize->cy/2);
- MovePlain(pV, uvPitch, pDestV, nDstPitch/2,
- pSrcSize->cx/2,pSrcSize->cy/2);
- #endif //1
- return HXR_OK;
- }
- HX_RESULT CDDBlt::UnlockSurface(UCHAR* pSurfPtr, int nIndex)
- {
- m_pOffscreen->Unlock(NULL);
- return HXR_OK;
- }
- HX_RESULT CDDBlt::RenderSurface(HXxSize* pSrcSize,
- HXxRect* prSrcRect,
- HXxRect* prDestRect,
- int nIndex)
- {
- // Map to screen coordinates
- POINT po = {0,0};
- ClientToScreen(m_hWnd, &po);
- RECT rc;
- GetClientRect(m_hWnd, &rc);
- rc.left += po.x;
- rc.right += po.x;
- rc.top += po.y;
- rc.bottom += po.y;
- DDBLTFX ddbltfx;
- memset(&ddbltfx, 0, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(ddbltfx);
- ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
- HRESULT hr = m_pPrimary->Blt(&rc, m_pOffscreen, NULL, DDBLT_WAIT, &ddbltfx);
- if (DD_OK == hr)
- return HXR_OK;
- else
- return HXR_FAIL;
- }
- HX_RESULT CDDBlt::DestroySurface(int cid)
- {
- HX_RELEASE(m_pPrimary);
- HX_RELEASE(m_pOffscreen);
- HX_RELEASE(m_pDD);
- return HXR_OK;
- }