📄 surf.cpp
字号:
//-----------------------------------------------------------------------
//
// 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.
// Copyright (c) 1999 Microsoft Corporation
//
// written by: ESG Solution Center Munich
//
// Module Name: surf.cpp
//
// abstract: Windows CE display driver for C&T 69000
// video memory management
//
//-----------------------------------------------------------------------
#include "precomp.h"
//-----------------------------------------------------------------------------
//
// CT69000::AllocSurface
//
// allocate a surface in video memory. function allocates only surfaces with
// same format as the primary surface in video memory. Otherwise the surface
// will be allocated in system memory.
//
//-----------------------------------------------------------------------------
SCODE
CT69000::AllocSurface(GPESurf **ppSurf,
INT width,
INT height,
EGPEFormat format,
INT surfaceFlags)
{
DEBUGMSG(CT69K_ZONE_FUNCTION, (TEXT("CT69000::AllocSurface()\r\n")));
if ((surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
|| ((format == m_pMode->format) &&
(surfaceFlags & GPE_PREFER_VIDEO_MEMORY))
)
{
if (!(format == m_pMode->format) &&
!(surfaceFlags & GPE_SPECIAL_SURFACE))
return E_INVALIDARG;
// Attempt to allocate from video memory
INT nStride;
INT offset = m_pVMHeap->Alloc ( width, height, format, nStride);
if (!FAILED(offset))
{
*ppSurf = new CT69000Surf( width,
height,
offset,
m_pFrameBuffer + offset,
nStride,
format,
m_pVMHeap,
surfaceFlags);
if (!(*ppSurf))
{
m_pVMHeap->Free(offset);
return E_OUTOFMEMORY;
}
DEBUGMSG(CT69K_ZONE_SURF,
(TEXT("Creating a CT69000 Surf in video memory. ")));
DEBUGMSG(CT69K_ZONE_SURF,
(TEXT("EGPEFormat = %d, offset 0x%05lx\r\n"),
(int) format, offset));
DEBUGMSG(CT69K_ZONE_SURF,
(TEXT("--%ldx%ldx%ld \r\n"),
width,height,EGPEFormatToBpp[format]));
return S_OK;
}
if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
{
*ppSurf = (GPESurf *)NULL;
return E_OUTOFMEMORY;
}
}
// Allocate from system memory
DEBUGMSG( CT69K_ZONE_SURF,
(TEXT("Creating a GPESurf in system memory. EGPEFormat = %d\r\n"),
(int) format));
if (surfaceFlags & GPE_DDRAW_SURFACE)
{
*ppSurf = new SGPESurf(width, height, format);
}
else
{
*ppSurf = new GPESurf(width, height, format);
}
if (*ppSurf)
{
// check we allocated bits succesfully
if (!((*ppSurf)->Buffer()))
{
delete *ppSurf;
return E_OUTOFMEMORY;
}
}
return S_OK;
}
//-----------------------------------------------------------------------------
//
// CT69000Surf::CT69000Surf
//
// create a surface in video memory and mark it as 'inVideoMemory' and
// remember the offset in video memory.
//
//-----------------------------------------------------------------------------
CT69000Surf *CT69000Surf::m_pRoot=NULL;
CT69000Surf::CT69000Surf(INT width,
INT height,
ULONG offset,
PVOID pBits,
INT stride,
EGPEFormat format,
LinHeap *pVMHeap,
INT flags
)
: GPESurf(width, height, pBits, stride, format)
{
m_pVMHeap = pVMHeap;
m_fInVideoMemory = TRUE;
m_nOffsetInVideoMemory = offset;
m_Flags = flags;
//
// add this object as first in list
//
m_pPrev=NULL;
if (m_pRoot)
{
m_pRoot->m_pPrev = this;
}
m_pNext=m_pRoot;
m_pRoot=this;
}
//-----------------------------------------------------------------------------
//
// CT69000Surf::~CT69000Surf
//
// delete surface and remove it from heap
//
//-----------------------------------------------------------------------------
CT69000Surf::~CT69000Surf(void)
{
if (m_pPrev==NULL)
{
m_pRoot=m_pNext;
}
else
{
m_pPrev->m_pNext=m_pNext;
}
if (m_pNext)
{
m_pNext->m_pPrev = m_pPrev;
}
if (m_pVMHeap)
{
m_pVMHeap->Free(m_nOffsetInVideoMemory);
}
}
//-----------------------------------------------------------------------------
//
// CT69000Surf::DemoteAll
//
// BOOL bAll - FALSE: stop after one surf was successfully removed
// TRUE: try to demote all surfaces
//
// move all removable surfaces from video to systemmeory. Needed to switch
// to directdraw exclusive mode.
//
//-----------------------------------------------------------------------------
BOOL
CT69000Surf::DemoteSurf(BOOL bAll)
{
CT69000Surf * pSurf=m_pRoot;
BOOL bRes =FALSE;
while ( pSurf )
{
bRes = pSurf->Demote() || bRes;
pSurf = pSurf->m_pNext;
if (!bAll && bRes)
break;
}
return bRes;
}
//-----------------------------------------------------------------------------
//
// CT69000Surf::Demote
//
// move surface from video to systemmemory. This is an unrecoverable process!
//
//-----------------------------------------------------------------------------
BOOL
CT69000Surf::Demote(void)
{
if ((m_Flags & GPE_REQUIRE_VIDEO_MEMORY) ||
(m_Flags & GPE_SPECIAL_SURFACE) ||
(m_Flags & GPE_DDRAW_SURFACE) ||
!m_fInVideoMemory)
{
//
// This surface cannot be demoted to sysmem,
// because it is required to stay in memory,
// special or already demoted
//
return FALSE;
}
// allocate new surf
INT nSize = Stride()*Height();
PBYTE pVirtAddr = new BYTE [nSize];
if (pVirtAddr == NULL)
{
return FALSE;
}
// copy old surf to new surf
memcpy( pVirtAddr, Buffer(), nSize);
m_pVirtAddr = (ULONG) pVirtAddr;
m_pVMHeap->Free(m_nOffsetInVideoMemory);
//
// pretend to be a normal GPESurf
//
m_pVMHeap = NULL;
m_fInVideoMemory = FALSE;
m_nOffsetInVideoMemory = 0;
m_fOwnsBuffer=TRUE;
return TRUE;
}
//-----------------------------------------------------------------------------
//
// SGPESurf::SGPESurf
//
// Create DirectDraw Systemmemory surface
//
//-----------------------------------------------------------------------------
SGPESurf::SGPESurf(
int width,
int height,
EGPEFormat format)
{
DWORD bpp = EGPEFormatToBpp[format];
LONG align = 8;
DWORD alignedWidth = (( width + align - 1 ) & ( - align ));
DWORD nSurfaceBytes = ((bpp) * ( alignedWidth * height )) / 8;
DWORD realStride = ((alignedWidth * bpp) / 8);
BYTE* pLocalBytes = (BYTE*)RemoteLocalAlloc( LMEM_FIXED, nSurfaceBytes );
Init(width, height, pLocalBytes, realStride, format);
m_fOwnsBuffer = TRUE;
}
//-----------------------------------------------------------------------------
//
// SGPESurf::~SGPESurf
//
// Delete DirectDraw Systemmemory surface
//
//-----------------------------------------------------------------------------
SGPESurf::~SGPESurf()
{
if (m_fOwnsBuffer)
{
if (m_pVirtAddr != NULL)
{
RemoteLocalFree((void*)m_pVirtAddr);
m_pVirtAddr = NULL;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -