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