ddblt.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 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
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (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.
- *
- * 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 (!m_pPrimary)
- {
- // Create primary surface
- DDSURFACEDESC ddsd;
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
- pDD2->CreateSurface (&ddsd, &m_pPrimary, NULL);
- if (!m_pPrimary)
- {
- 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;
- ddsd.dwFlags |= DDSD_PIXELFORMAT;
- ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
- 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;
- flags[nOutputTypes] = DDPF_RGB;
- ++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];
- if (DD_OK == pDD2->CreateSurface (&ddsd, &m_pOffscreen, NULL))
- {
- m_nCID = cid[i];
- break;
- }
- }
-
- pDD2->Release();
- // 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)
- {
- 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;
- }