📄 halsurf.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// -----------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// -----------------------------------------------------------------------------
#include "precomp.h"
#define HAL_ZONE_ERROR 0
#define HAL_ZONE_INFO 0
#define HAL_ZONE_WARNING 0
#define GDI_SCREEN_WIDTH (g_pGPE->ScreenWidth())
#define GDI_SCREEN_HEIGHT (g_pGPE->ScreenHeight())
#define DDRAW_SCREEN_WIDTH ( (g_pDDrawPrimarySurface != NULL) \
? (g_pDDrawPrimarySurface->Width()) \
: GDI_SCREEN_WIDTH )
#define DDRAW_SCREEN_HEIGHT ( (g_pDDrawPrimarySurface != NULL) \
? (g_pDDrawPrimarySurface->Height()) \
: GDI_SCREEN_HEIGHT )
// Retrieve pFormat and pPixelFormat based on pDDPF
SCODE DetectSupportPixelFormat(DDPIXELFORMAT *pDDPF,
EGPEFormat *pFormat,
EDDGPEPixelFormat *pPixelFormat)
{
if( pDDPF->dwFlags & DDPF_RGB)
{
if( pDDPF->dwRGBBitCount == 8 )
{
#if 0
*pPixelFormat = ddgpePixelFormat_8bpp;
*pFormat = gpe8Bpp;
#else
DDHAL_ERR((_T("[DDHAL:ERR] DetectSupportPixelFormat() : Unsupported 8-bit RGB format\n\r")));
return DDERR_UNSUPPORTEDFORMAT;
#endif
}
else if( pDDPF->dwRGBBitCount == 16 )
{
if(pDDPF->dwRBitMask == 0xF800
&& pDDPF->dwGBitMask == 0x07E0
&& pDDPF->dwBBitMask == 0x001F)
{
DDHAL_MSG((_T("[DDHAL] DetectSupportPixelFormat() : ddgpePixelFormat_565\n\r")));
*pPixelFormat = ddgpePixelFormat_565;
*pFormat = gpe16Bpp;
}
else
{
DDHAL_ERR((_T("[DDHAL:ERR] DetectSupportPixelFormat() : Unsupported 16-bit RGB format\n\r")));
return DDERR_UNSUPPORTEDFORMAT;
}
}
else if( pDDPF->dwRGBBitCount == 24 )
{
DDHAL_ERR((_T("[DDHAL:ERR] DetectSupportPixelFormat() : Unsupported 24-bit RGB format : Use 32-bit RGB format (X888)\n\r")));
return DDERR_UNSUPPORTEDFORMAT;
}
else if( pDDPF->dwRGBBitCount == 32 )
{
if(pDDPF->dwRBitMask == 0x00FF0000
&& pDDPF->dwGBitMask == 0x0000FF00
&& pDDPF->dwBBitMask == 0x000000FF)
{
DDHAL_MSG((_T("[DDHAL] DetectSupportPixelFormat() : ddgpePixelFormat_8888\n\r")));
*pPixelFormat = ddgpePixelFormat_8888;
*pFormat = gpe32Bpp;
}
else
{
DDHAL_ERR((_T("[DDHAL:ERR] DetectSupportPixelFormat() : Unsupported 32-bit RGB format\n\r")));
return DDERR_UNSUPPORTEDFORMAT;
}
}
else
{
DDHAL_ERR((_T("[DDHAL:ERR] DetectSupportPixelFormat() : Unsupported bit depth %d RGB format\n\r"), pDDPF->dwRGBBitCount));
return DDERR_UNSUPPORTEDFORMAT;
}
}
else if( pDDPF->dwFlags & DDPF_FOURCC )
{
if( pDDPF->dwFourCC == FOURCC_I420 )
{
DDHAL_MSG((_T("[DDHAL] DetectSupportPixelFormat() : ddgpePixelFormat_I420\n\r")));
*pPixelFormat = (EDDGPEPixelFormat)ddgpePixelFormat_I420;
*pFormat = gpeUndefined; // 12 bit is not defined in GPE
}
else if( pDDPF->dwFourCC == FOURCC_YV12 )
{
DDHAL_MSG((_T("[DDHAL] DetectSupportPixelFormat() : ddgpePixelFormat_YV12\n\r")));
*pPixelFormat = (EDDGPEPixelFormat)ddgpePixelFormat_YV12;
*pFormat = gpeUndefined; // 12 bit is not defined in GPE
}
else if( pDDPF->dwFourCC == FOURCC_YUYV )
{
DDHAL_MSG((_T("[DDHAL] DetectSupportPixelFormat() : ddgpePixelFormat_YUYV\n\r")));
*pPixelFormat = ddgpePixelFormat_YUYV;
*pFormat = gpe16YCrCb;
}
else if( pDDPF->dwFourCC == FOURCC_YUY2 )
{
DDHAL_MSG((_T("[DDHAL] DetectSupportPixelFormat() : ddgpePixelFormat_YUY2\n\r")));
*pPixelFormat = ddgpePixelFormat_YUY2;
*pFormat = gpe16YCrCb;
}
else if( pDDPF->dwFourCC == FOURCC_UYVY )
{
DDHAL_MSG((_T("[DDHAL] DetectSupportPixelFormat() : ddgpePixelFormat_UYVY\n\r")));
*pPixelFormat = ddgpePixelFormat_UYVY;
*pFormat = gpe16YCrCb;
}
else if( pDDPF->dwFourCC == FOURCC_YVYU )
{
DDHAL_MSG((_T("[DDHAL] DetectSupportPixelFormat() : ddgpePixelFormat_YVYU\n\r")));
*pPixelFormat = (EDDGPEPixelFormat)ddgpePixelFormat_YVYU;
*pFormat = gpe16YCrCb;
}
else if( pDDPF->dwFourCC == FOURCC_VYUY )
{
DDHAL_MSG((_T("[DDHAL] DetectSupportPixelFormat() : ddgpePixelFormat_VYUY\n\r")));
*pPixelFormat = (EDDGPEPixelFormat)ddgpePixelFormat_VYUY;
*pFormat = gpe16YCrCb;
}
else
{
DDHAL_ERR((_T("[DDHAL:ERR] DetectSupportPixelFormat() : Unsupported FourCC 0x%08x format\n\r"), pDDPF->dwFourCC));
return DDERR_UNSUPPORTEDFORMAT;
}
}
else
{
DDHAL_ERR((_T("[DDHAL:ERR] DetectSupportPixelFormat() : Unsupported Non-RGB, Non-FOURCC format\n\r")));
return DDERR_UNSUPPORTEDFORMAT;
}
return DD_OK;
}
DWORD
WINAPI
HalCreateSurface(LPDDHAL_CREATESURFACEDATA lpcsd)
{
DEBUGENTER( HalCreateSurface );
/*
typedef struct _DDHAL_CREATESURFACEDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD;
LPDDSURFACEDESC lpDDSurfaceDesc;
LPDDRAWI_DDRAWSURFACE_LCL lplpSList;
DWORD dwSCnt;
HRESULT ddRVal;
} DDHAL_CREATESURFACEDATA;
*/
S3C6400Disp *pDDGPE;
LPDDRAWI_DDRAWSURFACE_LCL pSurf;
DDGPESurf *pTmpSurf;
EGPEFormat format;
EDDGPEPixelFormat pixelFormat;
EDDGPEPixelFormat primaryPixelFormat;
SCODE sc;
DWORD dwFlags;
DWORD dwCaps;
DWORD dwSurfCaps;
unsigned int iSurf;
DDHAL_MSG((_T("[DDHAL] ++HalCreateSurface()\n\r")));
pDDGPE = (S3C6400Disp *)GetDDGPE();
dwFlags = lpcsd->lpDDSurfaceDesc->dwFlags;
dwCaps = lpcsd->lpDDSurfaceDesc->ddsCaps.dwCaps;
// Driver do Not allow Primary Surface in System Memory
if ((dwCaps & DDSCAPS_PRIMARYSURFACE) && (dwCaps & DDSCAPS_SYSTEMMEMORY))
{
DDHAL_ERR((_T("[DDHAL:ERR] HalCreateSurface() : Can Not create Primary Surface in System Memory\n\r")));
lpcsd->ddRVal = DDERR_UNSUPPORTEDFORMAT;
return DDHAL_DRIVER_HANDLED;
}
// Driver do Not allow Overlay Surface in System Memory
if ((dwCaps & DDSCAPS_OVERLAY) && (dwCaps & DDSCAPS_SYSTEMMEMORY))
{
DDHAL_ERR((_T("[DDHAL:ERR] HalCreateSurface() : Can Not create Overlay Surface in System Memory\n\r")));
lpcsd->ddRVal = DDERR_UNSUPPORTEDFORMAT;
return DDHAL_DRIVER_HANDLED;
}
// Non-Primary, Non-Overlay and Non-Video Memory Surface (Maybe Offscreen Surface) is handled by DDGPE function
if (!(dwCaps & (DDSCAPS_PRIMARYSURFACE|DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY)))
{
DDHAL_MSG((_T("[DDHAL] HalCreateSurface() : Pass to DDGPECreateSurface()\n\r")));
return DDGPECreateSurface(lpcsd);
}
//-------------------------------------
// Get the pixel format of the Primary surface
//-------------------------------------
GPEMode modeInfo;
sc = pDDGPE->GetModeInfo(&modeInfo, 0);
if (FAILED(sc))
{
DDHAL_ERR((_T("[DDHAL:ERR] HalCreateSurface() : GetModeInfo() Failed\n\r")));
lpcsd->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_HANDLED;
}
GPEModeEx modeInfoEx;
sc = pDDGPE->GetModeInfoEx(&modeInfoEx, 0);
if (FAILED(sc))
{
primaryPixelFormat = EGPEFormatToEDDGPEPixelFormat[modeInfo.format];
}
else
{
primaryPixelFormat = modeInfoEx.ePixelFormat;
}
//------------------------------------------
// Get the pixel format for the surface to be created
//------------------------------------------
if (dwFlags & DDSD_PIXELFORMAT)
{
lpcsd->ddRVal = DetectSupportPixelFormat(&lpcsd->lpDDSurfaceDesc->ddpfPixelFormat, &format, &pixelFormat);
if (FAILED(lpcsd->ddRVal))
{
DDHAL_ERR((_T("[DDHAL:ERR] HalCreateSurface() : Unsupported format\n\r")));
return DDHAL_DRIVER_HANDLED;
}
}
else
{
pixelFormat = primaryPixelFormat;
}
// Primary Surface must have same format as Primary Surface
if ((dwCaps & DDSCAPS_PRIMARYSURFACE) && (pixelFormat != primaryPixelFormat))
{
DDHAL_ERR((_T("[DDHAL:ERR] HalCreateSurface() : Primary Surface must have same format as Current Pixel Format\n\r")));
lpcsd->ddRVal = DDERR_UNSUPPORTEDFORMAT;
return DDHAL_DRIVER_HANDLED;
}
#if 1
for(iSurf = 0; iSurf < lpcsd->dwSCnt; iSurf++)
{
pSurf = lpcsd->lplpSList[iSurf];
dwSurfCaps = pSurf->ddsCaps.dwCaps;
if(dwSurfCaps & DDSCAPS_OVERLAY)
{
sc = pDDGPE->AllocSurface((DDGPESurf **)(&pTmpSurf),
lpcsd->lpDDSurfaceDesc->dwWidth, lpcsd->lpDDSurfaceDesc->dwHeight,
format, pixelFormat, GPE_REQUIRE_VIDEO_MEMORY);
if (FAILED(sc) || pTmpSurf == NULL)
{
// AllocSurface() Failed
if(iSurf > 0)
{
// Remove Partially Allocated Surface
for(int j=iSurf -1; j >= 0; j--)
{
if(lpcsd->lplpSList[j]->dwReserved1)
{
if (!(lpcsd->lplpSList[j]->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
{
delete (S3C6400Disp *)(lpcsd->lplpSList[j]->dwReserved1);
}
lpcsd->lplpSList[j]->dwReserved1 = NULL;
}
}
}
DDHAL_ERR((_T("[DDHAL:ERR] HalCreateSurface() : Create Failed -> Out of Video Memory\n\r")));
lpcsd->ddRVal = DDERR_OUTOFVIDEOMEMORY;
return DDHAL_DRIVER_HANDLED;
}
pTmpSurf->SetOverlay();
pSurf->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
pSurf->dwReserved1 = (ULONG_PTR)pTmpSurf;
lpcsd->lpDDSurfaceDesc->lPitch = pTmpSurf->Stride();
lpcsd->lpDDSurfaceDesc->dwSurfaceSize = pTmpSurf->SurfaceSize();
lpcsd->lpDDSurfaceDesc->ddsCaps.dwCaps |= (DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY);
lpcsd->lpDDSurfaceDesc->dwFlags |= (DDSD_PITCH|DDSD_SURFACESIZE|DDSD_CAPS);
lpcsd->ddRVal = DD_OK;
}
else
{
DDHAL_MSG((_T("[DDHAL] --HalCreateSurface() : Non-Overlay Surface pass to DDGPECreateSurface()\n\r")));
return DDGPECreateSurface(lpcsd);
}
}
DDHAL_MSG((_T("[DDHAL] --HalCreateSurface() : Overlay Surface\n\r")));
return DDHAL_DRIVER_HANDLED;
#else
// Custom pixel Format
if ((pixelFormat == ddgpePixelFormat_I420)
|| (pixelFormat == ddgpePixelFormat_YV12)
|| ((pixelFormat == ddgpePixelFormat_8888) && (primaryPixelFormat != ddgpePixelFormat_8888)) // Just in case of create RGB888 overlay surface when Primary is not RGB888
|| (pixelFormat == ddgpePixelFormat_YUYV)
|| (pixelFormat == ddgpePixelFormat_YUY2)
|| (pixelFormat == ddgpePixelFormat_YVYU)
|| (pixelFormat == ddgpePixelFormat_UYVY)
|| (pixelFormat == ddgpePixelFormat_VYUY))
{
LPDDRAWI_DDRAWSURFACE_LCL pSurf;
DWORD dwCaps;
unsigned int iSurf;
for(iSurf = 0; iSurf < lpcsd->dwSCnt; iSurf++)
{
pSurf = lpcsd->lplpSList[iSurf];
dwCaps = pSurf->ddsCaps.dwCaps;
if(dwCaps & DDSCAPS_OVERLAY)
{
DDGPESurf *pTmpSurf;
SCODE sc;
sc = pDDGPE->AllocSurface((DDGPESurf **)(&pTmpSurf),
lpcsd->lpDDSurfaceDesc->dwWidth, lpcsd->lpDDSurfaceDesc->dwHeight,
format, pixelFormat, GPE_REQUIRE_VIDEO_MEMORY);
if (FAILED(sc) || pTmpSurf == NULL)
{
// AllocSurface() Failed
if(iSurf > 0)
{
// Remove Partially Allocated Surface
for(int j=iSurf -1; j >= 0; j--)
{
if(lpcsd->lplpSList[j]->dwReserved1)
{
if (!(lpcsd->lplpSList[j]->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
{
delete (S3C6400Disp *)(lpcsd->lplpSList[j]->dwReserved1);
}
lpcsd->lplpSList[j]->dwReserved1 = NULL;
}
}
}
DDHAL_ERR((_T("[DDHAL:ERR] HalCreateSurface() : Create Failed -> Out of Video Memory\n\r")));
lpcsd->ddRVal = DDERR_OUTOFVIDEOMEMORY;
return DDHAL_DRIVER_HANDLED;
}
pTmpSurf->SetOverlay();
pSurf->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
pSurf->dwReserved1 = (ULONG_PTR)pTmpSurf;
lpcsd->lpDDSurfaceDesc->lPitch = pTmpSurf->Stride();
lpcsd->lpDDSurfaceDesc->dwSurfaceSize = pTmpSurf->SurfaceSize();
lpcsd->lpDDSurfaceDesc->ddsCaps.dwCaps |= (DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY);
lpcsd->lpDDSurfaceDesc->dwFlags |= (DDSD_PITCH|DDSD_SURFACESIZE|DDSD_CAPS);
lpcsd->ddRVal = DD_OK;
}
else
{
// Custom pixel Format can support Only Overlay Surface
lpcsd->ddRVal = DDERR_UNSUPPORTEDFORMAT;
return DDHAL_DRIVER_HANDLED;
}
}
return DDHAL_DRIVER_HANDLED;
}
else
{
DDHAL_MSG((_T("[DDHAL] --HalCreateSurface()\n\r")));
return DDGPECreateSurface(lpcsd);
}
#endif
}
DWORD WINAPI HalCanCreateSurface(LPDDHAL_CANCREATESURFACEDATA lpccsd)
{
DEBUGENTER( HalCanCreateSurface );
/*
typedef struct _DDHAL_CANCREATESURFACEDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD;
LPDDSURFACEDESC lpDDSurfaceDesc;
DWORD bIsDifferentPixelFormat;
HRESULT ddRVal;
} DDHAL_CANCREATESURFACEDATA;
*/
// Implementation
DDPIXELFORMAT *pddpf = &lpccsd->lpDDSurfaceDesc->ddpfPixelFormat;
DWORD width = lpccsd->lpDDSurfaceDesc->dwWidth;
DWORD height = lpccsd->lpDDSurfaceDesc->dwHeight;
DWORD caps = lpccsd->lpDDSurfaceDesc->ddsCaps.dwCaps;
// We do Not allow Primary Surface in System Memory
if ((caps & DDSCAPS_PRIMARYSURFACE) && (caps & DDSCAPS_SYSTEMMEMORY))
{
DDHAL_ERR((_T("[DDHAL:ERR] HalCanCreateSurface() : Can Not create Primary Surface in System Memory\n\r")));
goto CannotCreate;
}
if ((caps & DDSCAPS_OVERLAY) && (caps & DDSCAPS_SYSTEMMEMORY))
{
DDHAL_ERR((_T("[DDHAL:ERR] HalCanCreateSurface() : Can Not create Overlay Surface in System Memory\n\r")));
goto CannotCreate;
}
if (caps & DDSCAPS_PRIMARYSURFACE)
{
if (lpccsd->bIsDifferentPixelFormat)
{
goto CannotCreate;
}
else
{
if (pddpf->dwFlags & DDPF_RGB)
{
if (pddpf->dwRGBBitCount == 16
&& pddpf->dwRBitMask == 0xF800
&& pddpf->dwGBitMask == 0x07E0
&& pddpf->dwBBitMask == 0x001F)
{
// RGB16
if (width%2) // Word Align
{
goto CannotCreate;
}
else
{
goto CanCreate;
}
}
else if (pddpf->dwRGBBitCount == 32
&& pddpf->dwRBitMask == 0x00FF0000
&& pddpf->dwGBitMask == 0x0000FF00
&& pddpf->dwBBitMask == 0x000000FF)
{
// RGB32
goto CanCreate;
}
else
{
goto CannotCreate;
}
}
else
{
goto CanCreate;
}
}
}
else if (caps & DDSCAPS_OVERLAY)
{
if (pddpf->dwFlags & DDPF_RGB)
{
if (pddpf->dwRGBBitCount == 16
&& pddpf->dwRBitMask == 0xF800
&& pddpf->dwGBitMask == 0x07E0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -