📄 surf.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.
Module Name: surface allocation/manipulation/free routines
Abstract:
Functions:
Notes:
--*/
#include "precomp.h"
static DWORD dwSurfaceCount = 0;
// This method is called for all normal surface allocations from ddgpe and gpe
SCODE S3C6400Disp::AllocSurface(GPESurf **ppSurf, INT width, INT height, EGPEFormat format, int surfaceFlags)
{
#if 1
//DISPDRV_MSG((_T("[DISPDRV] S3C6400Disp::AllocSurface(%d, %d, %d, 0x%08x)\n\r"), width, height, format, surfaceFlags));
*ppSurf = new GPESurf(width, height, format);
if (*ppSurf == NULL)
{
DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : Surface allocate Failed -> Out of Memory\n\r")));
return E_OUTOFMEMORY;
}
else if ((*ppSurf)->Buffer() == NULL)
{
delete *ppSurf;
*ppSurf = NULL;
DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : Surface Buffer is NULL -> Out of Memory\n\r")));
return E_OUTOFMEMORY;
}
//DISPDRV_MSG((_T("[DISPDRV] AllocSurface() : GPESurf() Allocated in System Memory\n\r")));
return S_OK;
#else
return AllocSurface((DDGPESurf**)ppSurf,
width,
height,
format,
EGPEFormatToEDDGPEPixelFormat[format],
surfaceFlags);
#endif
}
// This method is used to allocate DirectDraw enabled surfaces
SCODE
S3C6400Disp::AllocSurface(DDGPESurf **ppSurf, int width, int height,
EGPEFormat format, EDDGPEPixelFormat pixelFormat, int surfaceFlags)
{
DWORD bpp;
DWORD stride;
DISPDRV_MSG((_T("[DISPDRV] S3C6400Disp::AllocSurface(%d, %d, %d, %d, 0x%08x)\n\r"), width, height, format, pixelFormat, surfaceFlags));
if (pixelFormat == ddgpePixelFormat_I420 || pixelFormat == ddgpePixelFormat_YV12)
{
// in this case, stride can't be calculated. because of planar format (non-interleaved...)
bpp = 12;
}
else if (pixelFormat == ddgpePixelFormat_YVYU || pixelFormat == ddgpePixelFormat_VYUY)
{
bpp = 16;
}
else
{
bpp = EGPEFormatToBpp[format];
}
stride = (width*bpp/8);
if ((surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
|| ((surfaceFlags & GPE_PREFER_VIDEO_MEMORY) && (format == m_pMode->format))
|| ((surfaceFlags & GPE_BACK_BUFFER) && (format == m_pMode->format)))
{
DWORD dwVideoMemoryOffset;
DWORD dwSize;
if (pixelFormat == ddgpePixelFormat_I420 || pixelFormat == ddgpePixelFormat_YV12)
{
dwSize = width*height*bpp/8; // 12 bpp, stride is no meaning
}
else
{
dwSize = stride*height;
}
// Attempt to allocate from video memory
SurfaceHeap *pHeap = m_pVideoMemoryHeap->Alloc(dwSize);
if (pHeap != NULL)
{
dwVideoMemoryOffset = pHeap->Address() - (DWORD)m_VideoMemoryVirtualBase;
DISPDRV_MSG((_T("[DISPDRV] AllocSurface() : Allocated PA = 0x%08x\n\r"), dwVideoMemoryOffset+m_VideoMemoryPhysicalBase));
*ppSurf = new S3C6400Surf(width, height, dwVideoMemoryOffset, (PVOID)pHeap->Address(), stride, format, pixelFormat, pHeap);
if (*ppSurf == NULL)
{
DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : S3C6400Surf() Allocate Failed\n\r")));
pHeap->Free();
return E_OUTOFMEMORY;
}
DISPDRV_MSG((_T("[DISPDRV] AllocSurface() : S3C6400Surf() Allocated in Video Memory\n\r")));
return S_OK;
}
else if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
{
DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : Failed -> Out of Video Memory\n\r")));
*ppSurf = (DDGPESurf *)NULL;
return E_OUTOFMEMORY;
}
else
{
// GPE_PREFER_VIDEO_MEMORY -> allocate system memory...
}
}
// Allocate Surface in System Memory
*ppSurf = new DDGPESurf(width, height, stride, format, pixelFormat);
if (*ppSurf != NULL)
{
// Check Allocated Surface
if ( (*ppSurf)->Buffer() != NULL)
{
DISPDRV_MSG((_T("[DISPDRV] AllocSurface() : S3C6400Surf() Allocated in System Memory\n\r")));
return S_OK;
}
else
{
delete *ppSurf;
}
}
DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : Allocate in System Memory Failed\n\r")));
return E_OUTOFMEMORY;
}
void S3C6400Disp::SetVisibleSurface(GPESurf *pSurf, BOOL bWaitForVBlank)
{
S3C6400Surf *pDDSurf = (S3C6400Surf *)pSurf;
if (m_VideoPowerState == VideoPowerOff)
{
if(pDDSurf->IsOverlay() == FALSE)
{
m_pVisibleSurface = pDDSurf;
}
else
{
m_OverlayCtxt.pSurface = pDDSurf;
}
// To Avoid System Hang in SystemIdle State
// When Application access to DDraw API in SystemIdle State
// System Hangs... (Maybe Display Driver in VideoPowerOff state)
DISPDRV_INF((_T("[DISPDRV:INF] SetVisibleSurface() : Skipped in 'VideoPowerOff State'\n\r")));
}
else
{
EnterCriticalSection(&m_csDevice);
DevSetVisibleSurface(pDDSurf, bWaitForVBlank);
LeaveCriticalSection(&m_csDevice);
}
}
//-----------------------------------------------------------------------------
S3C6400Surf::S3C6400Surf(int width, int height, DWORD offset, VOID *pBits, int stride,
EGPEFormat format, EDDGPEPixelFormat pixelFormat, SurfaceHeap *pHeap)
: DDGPESurf(width, height, pBits, stride, format, pixelFormat)
{
dwSurfaceCount++;
m_pHeap = pHeap;
m_fInVideoMemory = TRUE;
m_nOffsetInVideoMemory = offset;
if (pixelFormat == ddgpePixelFormat_I420)
{
m_uiOffsetCb = width*height;
m_uiOffsetCr = m_uiOffsetCb+width*height/4;
}
else if (pixelFormat == ddgpePixelFormat_YV12)
{
m_uiOffsetCr = width*height;
m_uiOffsetCb = m_uiOffsetCr+width*height/4;
}
else
{
m_uiOffsetCr = 0;
m_uiOffsetCb = 0;
}
m_hSurface = NULL;
m_pSurface = NULL;
DISPDRV_INF((_T("[DISPDRV:INF] S3C6400Surf::S3C6400Surf() : @ 0x%08x, %d\n\r"), m_nOffsetInVideoMemory, dwSurfaceCount));
}
S3C6400Surf::~S3C6400Surf()
{
dwSurfaceCount--;
if (m_pSurface != NULL)
{
ADDRESS address = (ADDRESS)m_pSurface;
address &= ~(PAGE_SIZE - 1);
UnmapViewOfFile((VOID*)address);
}
if (m_hSurface != NULL)
{
CloseHandle(m_hSurface);
}
if (m_pHeap != NULL)
{
m_pHeap->Free();
}
DISPDRV_INF((_T("[DISPDRV:INF] S3C6400Surf::~S3C6400Surf() : @ 0x%08x, %d\n\r"), m_nOffsetInVideoMemory, dwSurfaceCount));
}
#if 0
//------------------------------------------------------------------------------
//
// Method: WriteBack
//
// Flush surface memory in cache.
//
VOID S3C6400Surf::WriteBack()
{
ASSERT(m_pSurface != NULL);
RETAILMSG(DBGLCD, (TEXT("S3C6400Surf::WriteBack\n")));
if (m_pSurface != NULL)
CacheRangeFlush((VOID*)m_pSurface, m_nStrideBytes * m_nHeight, CACHE_SYNC_WRITEBACK);
}
//------------------------------------------------------------------------------
//
// Method: Discard
//
// Flush and invalidate surface memory in cache.
//
VOID S3C6400Surf::Discard()
{
ASSERT(m_pSurface != NULL);
RETAILMSG(DBGLCD, (TEXT("S3C6400Surf::Discard\n")));
if (m_pSurface != NULL)
CacheRangeFlush((VOID*)m_pSurface, m_nStrideBytes * m_nHeight, CACHE_SYNC_DISCARD);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -