📄 ddblt.cpp
字号:
/* ***** 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 __cplusplusextern "C"#endif#if 0static 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 //0CDDBlt::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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -