⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 surf.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 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 + -