?? surf.cpp
字號:
/*
* $Workfile: SURF.CPP $
* $Revision: 6 $
* $Date: 4/07/00 8:52a $
* $Modtime: 4/07/00 8:35a $
* $Author: Sarma $
*
* Copyright (c) 1998 National Semiconductor Corporation.
* All Rights Reserved.
*
* This software is the confidential and proprietary information of National
* Semiconductor Corporation. ("Confidential Information").
* You shall not disclose such Confidential Information and shall use it only
* in accordance with the terms of the license agreement you entered into
* with National Semiconductor Corporation.
* This code is supplied as is.
*
*/
/*
*$Log: /CE/Platform/Nsc/Drivers/Video/gxvideo/base/SURF.CPP $
*
* 6 4/07/00 8:52a Sarma
* Removed Cyrix Corporation from the legal/confidentail information.
*
* 5 4/06/00 10:36a Hari
* Removed Debug messages.
*
* 4 3/29/00 9:29a Sarma
* Added special READ/WRITE macros to be used by Directdraw functions. Two
* new Alloc functions added for directdraw , AllocSurface and
* AllocOverlaySurface. The new Gxvideo constructor is also for the
* directdraw interface.
*
* 3 12/01/98 1:08p Sarma
* Added few debug statements and also set the pNode to 0 once the memory
* is freed.
*
* 2 11/12/98 3:14p Sarma
* Added Confidential copyright to files with VSS keywords for
* log/history.
*$History: SURF.CPP $
*
* ***************** Version 6 *****************
* User: Sarma Date: 4/07/00 Time: 8:52a
* Updated in $/CE/Platform/Nsc/Drivers/Video/gxvideo/base
* Removed Cyrix Corporation from the legal/confidentail information.
*
* ***************** Version 5 *****************
* User: Hari Date: 4/06/00 Time: 10:36a
* Updated in $/CE/Platform/Nsc/Drivers/Video/gxvideo/base
* Removed Debug messages.
*
* ***************** Version 4 *****************
* User: Sarma Date: 3/29/00 Time: 9:29a
* Updated in $/CE/Platform/Nsc/Drivers/Video/gxvideo/base
* Added special READ/WRITE macros to be used by Directdraw functions. Two
* new Alloc functions added for directdraw , AllocSurface and
* AllocOverlaySurface. The new Gxvideo constructor is also for the
* directdraw interface.
*
* ***************** Version 3 *****************
* User: Sarma Date: 12/01/98 Time: 1:08p
* Updated in $/wince/v2.1/gxvideo
* Added few debug statements and also set the pNode to 0 once the memory
* is freed.
*
* ***************** Version 2 *****************
* User: Sarma Date: 11/12/98 Time: 3:14p
* Updated in $/wince/v2.1/gxvideo
* Added Confidential copyright to files with VSS keywords for
* log/history.
*/
#include "precomp.h"
/////////////////////////////////////////////////////////////////////////////////////
SCODE GxVideo::AllocSurface(
GPESurf **ppSurf,
int width,
int height,
EGPEFormat format,
int surfaceFlags )
{
if( ( surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY ) ||
( format == m_pMode->format ) &&
( surfaceFlags & GPE_PREFER_VIDEO_MEMORY ) )
{
if( !( format == m_pMode->format ) )
return E_INVALIDARG;
DEBUGMSG(0,(TEXT("AllocSurface %d %d %d, avail = %d\n"),
width, height,EGPEFormatToBpp[format], m_p2DVideoMemory->AvailSpace()));
// Attempt to allocate from video memory
Node2D *pNode = m_p2DVideoMemory->Alloc( width, height );
if( pNode )
{
unsigned long offset = m_nScreenStride * pNode->Top() +
( pNode->Left() * EGPEFormatToBpp[format] ) / 8 ;
DEBUGMSG(0,(TEXT("AllocSurface %d %d, %d\n"),
pNode->Left(), pNode->Top(), offset));
*ppSurf = new GxVideoSurf(
width,
height,
offset,
m_pLAW + offset,
m_nScreenStride,
format,
pNode );
DEBUGMSG(0,(TEXT("%d %d\n"), (*ppSurf)->Buffer(), (*ppSurf)->Stride()));
if( !(*ppSurf) )
{
pNode->Free();
pNode = 0;
return E_OUTOFMEMORY;
}
return S_OK;
}
if( surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY )
{
*ppSurf = (GPESurf *)NULL;
return E_OUTOFMEMORY;
}
}
// Allocate from system memory
DEBUGMSG(0,(TEXT("Creating a GPESurf in system memory. EGPEFormat = %d\r\n"), (int)format ));
*ppSurf = new GPESurf( width, height, format );
if( *ppSurf )
{
// check we allocated bits succesfully
if( !((*ppSurf)->Buffer()) )
delete *ppSurf; // and then return E_OUTOFMEMORY
else
return S_OK;
}
return E_OUTOFMEMORY;
}
#ifdef DD_SUPPORT
SCODE GxVideo::AllocSurface(
DDGPESurf **ppSurf,
int width,
int height,
EGPEFormat format,
EDDGPEPixelFormat pixelFormat,
int surfaceFlags )
{
if( ( surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY ) ||
( format == m_pMode->format ) &&
( surfaceFlags & GPE_PREFER_VIDEO_MEMORY ) )
{
if( !( format == m_pMode->format ) )
return E_INVALIDARG;
DEBUGMSG(0,(TEXT("AllocSurface %d %d %d, avail = %d\n"),
width, height,EGPEFormatToBpp[format], m_p2DVideoMemory->AvailSpace()));
// Attempt to allocate from video memory
Node2D *pNode = m_p2DVideoMemory->Alloc( width, height );
if( pNode )
{
unsigned long offset = m_nScreenStride * pNode->Top() +
( pNode->Left() * EGPEFormatToBpp[format] ) / 8 ;
DEBUGMSG(0,(TEXT("AllocSurface %d %d, %d\n"),
pNode->Left(), pNode->Top(), offset));
*ppSurf = new GxVideoSurf(
width,
height,
offset,
m_pLAW + offset,
m_nScreenStride,
format,
pixelFormat,
pNode );
DEBUGMSG(0,(TEXT("%d %d\n"), (*ppSurf)->Buffer(), (*ppSurf)->Stride()));
if( !(*ppSurf) )
{
pNode->Free();
pNode = 0;
return E_OUTOFMEMORY;
}
return S_OK;
}
if( surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY )
{
*ppSurf = (DDGPESurf *)NULL;
return E_OUTOFMEMORY;
}
}
// Allocate from system memory
DEBUGMSG(0,(TEXT("Creating a GPESurf in system memory. EGPEFormat = %d\r\n"), (int)format ));
*ppSurf = new DDGPESurf( width, height, format );
if( *ppSurf )
{
// check we allocated bits succesfully
if( !((*ppSurf)->Buffer()) )
delete *ppSurf; // and then return E_OUTOFMEMORY
else
return S_OK;
}
return E_OUTOFMEMORY;
}
SCODE GxVideo::AllocOverlaySurface(
DDGPESurf **ppSurf,
int width,
int height,
EGPEFormat format,
EDDGPEPixelFormat pixelFormat,
int surfaceFlags )
{
Node2D *pNode;
int AllocHeight;
int StridePixels;
int PixelShift;
if (!(surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)) {
return E_INVALIDARG;
}
switch (pixelFormat) {
case ddgpePixelFormat_565:
case ddgpePixelFormat_YUYV422:
case ddgpePixelFormat_UYVY422:
if (format == gpe16Bpp)
PixelShift = 1;
else
PixelShift = 0;
StridePixels = (m_nScreenStride >> PixelShift);
AllocHeight = ((width * height) + StridePixels - 1) / StridePixels;
pNode = m_p2DVideoMemory->Alloc( StridePixels, AllocHeight );
if( pNode )
{
unsigned long offset = m_nScreenStride * pNode->Top() +
( pNode->Left() * EGPEFormatToBpp[format] ) / 8 ;
DEBUGMSG(0,(TEXT("AllocSurface %d %d, %d\n"),
pNode->Left(), pNode->Top(), offset));
*ppSurf = new GxVideoSurf(
width,
height,
offset,
m_pLAW + offset,
width * (EGPEFormatToBpp[format] / 8),
format,
pixelFormat,
pNode );
DEBUGMSG(0,(TEXT("%d %d\n"), (*ppSurf)->Buffer(), (*ppSurf)->Stride()));
if( !(*ppSurf) )
{
pNode->Free();
pNode = 0;
return E_OUTOFMEMORY;
}
return S_OK;
}
DEBUGMSG(0, (TEXT("Node2d returned NULL!\r\n")));
return E_OUTOFMEMORY;
default:
break;
}
return E_INVALIDARG;
/* if( ( surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY ) ||
( format == m_pMode->format ) &&
( surfaceFlags & GPE_PREFER_VIDEO_MEMORY ) )
{
if( !( format == m_pMode->format ) )
return E_INVALIDARG;
DEBUGMSG(0,(TEXT("AllocOverlaySurface %d %d %d, avail = %d\n"),
width, height,EGPEFormatToBpp[format], m_p2DVideoMemory->AvailSpace()));
// Attempt to allocate from video memory
Node2D *pNode = m_p2DVideoMemory->Alloc( width, height );
if( pNode )
{
unsigned long offset = m_nScreenStride * pNode->Top() +
( pNode->Left() * EGPEFormatToBpp[format] ) / 8 ;
DEBUGMSG(0,(TEXT("AllocSurface %d %d, %d\n"),
pNode->Left(), pNode->Top(), offset));
*ppSurf = new GxVideoSurf(
width,
height,
offset,
m_pLAW + offset,
m_nScreenStride,
format,
pixelFormat,
pNode );
DEBUGMSG(0,(TEXT("%d %d\n"), (*ppSurf)->Buffer(), (*ppSurf)->Stride()));
if( !(*ppSurf) )
{
pNode->Free();
pNode = 0;
return E_OUTOFMEMORY;
}
return S_OK;
}
if( surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY )
{
*ppSurf = (DDGPESurf *)NULL;
return E_OUTOFMEMORY;
}
}
// Allocate from system memory
DEBUGMSG(1,(TEXT("Creating a GPESurf in system memory. EGPEFormat = %d\r\n"), (int)format ));
*ppSurf = new DDGPESurf( width, height, format );
if( *ppSurf )
{
// check we allocated bits succesfully
if( !((*ppSurf)->Buffer()) )
delete *ppSurf; // and then return E_OUTOFMEMORY
else
return S_OK;
}
return E_OUTOFMEMORY;
*/
}
#endif //DD_SUPPORT
GxVideoSurf::GxVideoSurf(
int width,
int height,
unsigned long offset,
void *pBits, // virtual address of allocated bits
int stride,
EGPEFormat format,
Node2D *pNode )
#ifdef DD_SUPPORT
: DDGPESurf( width, height, pBits, stride, format )
#else
: GPESurf( width, height, pBits, stride, format )
#endif //DD_SUPPORT
{
m_pNode2D = pNode;
m_fInVideoMemory = TRUE;
m_nOffsetInVideoMemory = offset;
}
#ifdef DD_SUPPORT
GxVideoSurf::GxVideoSurf(
int width,
int height,
unsigned long offset,
void *pBits, // virtual address of allocated bits
int stride,
EGPEFormat format,
EDDGPEPixelFormat pixelFormat,
Node2D *pNode )
: DDGPESurf( width, height, pBits, stride, format, pixelFormat )
{
m_pNode2D = pNode;
m_fInVideoMemory = TRUE;
m_nOffsetInVideoMemory = offset;
}
#endif //DD_SUPPORT
GxVideoSurf::~GxVideoSurf()
{
DEBUGMSG(0,(TEXT("~GxVideoSurf %d %d\n"), m_pNode2D->Left(), m_pNode2D->Top()));
m_pNode2D->Free();
m_pNode2D = 0; //NULL it
}
void GxVideo::CheckVisibleSurface()
{
unsigned long tickCount = GetTickCount();
if( tickCount - m_nTicksAtFlip > m_nTicksPerFrame + 1 )
{
m_pOldVisibleSurface = m_pNewVisibleSurface;
return;
}
unsigned int phase = ( tickCount - m_nTicksAtResync ) % m_nTicksPerFrame;
unsigned int flipPhase = ( m_nTicksAtFlip - m_nTicksAtResync ) % m_nTicksPerFrame;
if( (phase >= m_nTicksPerFrame * 7 / 8) || // near end of frame, may as well wait
( tickCount - m_nTicksAtResync > m_nTicksPerFrame * 20 ) || // overdue for resync
( tickCount < m_nTicksAtFlip ) || // Time went backwards
( m_nTicksAtFlip < m_nTicksAtResync ) ) // Time went backwards
{
//WaitForVBlank();
return;
}
if( phase < flipPhase )
{
m_pOldVisibleSurface = m_pNewVisibleSurface;
return;
}
DEBUGMSG( 0,
( TEXT("Not flipped. Ticks at flip:%d, now %d, "),
m_nTicksAtFlip,
tickCount ) );
DEBUGMSG( 0,
( TEXT("per frame %d resync %d\r\n"),
m_nTicksPerFrame,
m_nTicksAtResync ) );
}
int GxVideo::SurfaceBusyFlipping( GxVideoSurf *pSurf )
{
if( pSurf == m_pOldVisibleSurface || pSurf == m_pNewVisibleSurface )
CheckVisibleSurface();
return ( pSurf == m_pOldVisibleSurface || pSurf == m_pNewVisibleSurface );
}
int GxVideo::FlipInProgress()
{
if( m_pOldVisibleSurface != m_pNewVisibleSurface )
CheckVisibleSurface();
else
return 0;
if( m_pOldVisibleSurface != m_pNewVisibleSurface )
{
DEBUGMSG( 0, ( TEXT("Flip from surf 0x%08x to 0x%08x in progress\r\n"),
m_pOldVisibleSurface, m_pNewVisibleSurface ));
}
return ( m_pOldVisibleSurface != m_pNewVisibleSurface );
}
#if DEBUG
int tickCountValid = 0;
unsigned int lastTickCount;
int frameCount = 0;
#endif
void GxVideo::SetVisibleSurface( GPESurf *pTempSurf )
{
GxVideoSurf *pSurf = (GxVideoSurf *) pTempSurf;
int displayStart = pSurf->Stride() * pSurf->Top();
m_pNewVisibleSurface = pSurf;
Unlock();
DEBUGMSG(0,(TEXT("displayStart = 0x%08x\r\n"),displayStart));
WRITE_REG32(GXregisters, DC_FB_ST_OFFSET, displayStart);
Lock();
m_nTicksAtFlip = GetTickCount();
#if DEBUG
if( tickCountValid )
{
frameCount++;
if( m_nTicksAtFlip - lastTickCount > 10000 )
{
int framesPerTenSecs = frameCount * 10000 / ( m_nTicksAtFlip - lastTickCount );
if( framesPerTenSecs < 2000 )
{
DEBUGMSG( 0, (TEXT("Frames per second: %d.%1d\r\n"),
framesPerTenSecs/10, framesPerTenSecs%10 ));
}
lastTickCount = m_nTicksAtFlip;
frameCount = 0;
}
}
else
{
tickCountValid = 1;
lastTickCount = m_nTicksAtFlip;
frameCount = 0;
}
#endif
}
void
GxVideo::SetVisibleSurface(GPESurf *pSurf, BOOL bWaitForVBlank) {
DEBUGMSG(0,(TEXT("SET VISIBLE SURFACE 2\r\n")));
if (bWaitForVBlank) {
while (InVBlank()) {}
while (!InVBlank()) {}
}
SetVisibleSurface(pSurf);
}
void GxVideo::VBlankReceived()
{
m_nTicksAtFlip = m_nTicksAtResync = GetTickCount();
m_pOldVisibleSurface = m_pNewVisibleSurface;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -