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

📄 surf.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 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"

#define ALIGN(x, align)		(((x) + ((align) - 1)) & ~((align) - 1))
#define PIXEL_ALIGN_BPP16	2
#define PIXEL_ALIGN_YV12	16

static DWORD dwSurfaceCount = 0;

//  This method is called for all normal surface allocations from ddgpe and gpe
SCODE
S3C6410Disp::AllocSurface(
						GPESurf **ppSurf,
						int width,
						int height,
						EGPEFormat format,
						int surfaceFlags)
{
	RETAILMSG(0, (TEXT("[AS] %dx%d FMT:%d F:%08x\n\r"), width, height,  format, surfaceFlags));

	// This method is only for surface in system memory
	if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
	{
		DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : Can not allocate GPE_REQUIRE_VIDEO_MEMORY Surface in system memory\n\r")));
		return E_OUTOFMEMORY;
	}

#if G2D_ACCELERATE
#if USE_PACSURF	
	/// Only Support 16bpp, 24bpp, 32bpp
	if(  ( (format == gpe16Bpp || format == gpeDeviceCompatible)
#if G2D_BLT_OPTIMIZE	
	         && (width*height*2 > PAC_ALLOCATION_BOUNDARY) 
#endif	//< G2D_BLT_OPTIMIZE
	         )
	||
	      ( (format == gpe24Bpp || format == gpe32Bpp)
#if G2D_BLT_OPTIMIZE	      
	      	&& (width*height*4 > PAC_ALLOCATION_BOUNDARY )
#endif	//< G2D_BLT_OPTIMIZE
	      	)
	      	) 
	{
		/// try to allocate physically linear address
			*ppSurf = new PACSurf(width, height, format);
		
		if (*ppSurf == NULL)
		{
			DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : PACSurface allocate Failed -> Try to allocate Normal GPE Surface\n\r")));
		}
		else if ((*ppSurf)->Buffer() == NULL)
		{
			delete *ppSurf;
			*ppSurf = NULL;

			DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : PACSurface Buffer is NULL -> Try to allocate Normal GPE Surface\n\r")));
		}
		else		/// PAC Allocation succeeded.
		{
			RETAILMSG(0,(_T("[DISPDRV] AllocSurface() : PACSurf() Allocated in System Memory\n\r")));	
			return S_OK;
		}
	}
#endif	//< USE_PACSURF
#endif	//< G2D_ACCELERATE
	/// if allocation is failed or boundary condition is not met, just create GPESurf in normal system memory that can be non-linear physically.	
	
	// Allocate surface from system memory
	*ppSurf = new GPESurf(width, height, format);

	if (*ppSurf != NULL)
	{
		if (((*ppSurf)->Buffer()) == NULL)
		{
			DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : Surface Buffer is NULL\n\r")));
			delete *ppSurf;
			return E_OUTOFMEMORY;
		}
		else
		{
			RETAILMSG(0,(_T("[DISPDRV] AllocSurface() : GPESurf() Allocated in System Memory\n\r")));			
			return S_OK;
		}
	}

	DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : Surface allocate Failed\n\r")));
	return E_OUTOFMEMORY;
}


//  This method is used for DirectDraw enabled surfaces
SCODE
S3C6410Disp::AllocSurface(
						DDGPESurf **ppSurf,
						int width,
						int height,
						EGPEFormat format,
						EDDGPEPixelFormat pixelFormat,
						int surfaceFlags)
{
	DISPDRV_MSG((_T("[DISPDRV] S3C6410Disp::AllocSurface(%d, %d, %d, %d, 0x%08x)\n\r"), width, height, format, pixelFormat, surfaceFlags));

	unsigned int bpp;
	unsigned int stride;
	unsigned int align_width;

	if (pixelFormat == ddgpePixelFormat_I420 || pixelFormat == ddgpePixelFormat_YV12)
	{
		// in this case, stride can't be calculated. because of planar format (non-interleaved...)
		bpp = 12;
		align_width = ALIGN(width, 16);
	}
	else if (pixelFormat == ddgpePixelFormat_YVYU || pixelFormat == ddgpePixelFormat_VYUY)
	{
		bpp = 16;
		align_width = width;
	}
	else
	{
		bpp = EGPEFormatToBpp[format];
		align_width = width;
	}

	//DISPDRV_ERR((_T("[AS] %dx%d %dbpp FMT:%d F:%08x\n\r"), width, height, bpp, format, surfaceFlags));

	//--------------------------------------
	// Try to allocate surface from video memory
	//--------------------------------------

	// stride are all 32bit aligned for Video Memory
	stride = ((bpp * align_width + 31) >> 5) << 2;

	if ((surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
		|| (surfaceFlags & GPE_BACK_BUFFER)
		//|| ((surfaceFlags & GPE_PREFER_VIDEO_MEMORY) && (format == m_pMode->format)))
		|| (surfaceFlags & GPE_PREFER_VIDEO_MEMORY) && (format == m_pMode->format))
	{
		SCODE rv = AllocSurfaceVideo(ppSurf, width, height, stride, format, pixelFormat);
		if (rv == S_OK)
		{
			return S_OK;
		}
		else
		{
			if (surfaceFlags & (GPE_REQUIRE_VIDEO_MEMORY|GPE_BACK_BUFFER))
			{
				DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurface() : AllocSurfaceVideo() failed\n\r")));
				return E_OUTOFMEMORY;
			}
		}
	}

	//--------------------------------------
	// Try to allocate surface from system memory
	//--------------------------------------

	// stride and surface size for system memory surfaces
	stride = ((bpp * width + 31) >> 5) << 2;
	unsigned int surface_size = stride*height;

	// Allocate from system memory
	*ppSurf = new DDGPESurf(width, height, stride, format, pixelFormat);

	if (*ppSurf)	// check we allocated bits succesfully
	{
		if (!((*ppSurf)->Buffer()))
		{
			delete *ppSurf;
			return E_OUTOFMEMORY;
		}
	}

	return S_OK;
}


SCODE
S3C6410Disp::AllocSurfaceVideo(
						DDGPESurf **ppSurf,
						int width,
						int height,
						int stride,
						EGPEFormat format,
						EDDGPEPixelFormat pixelFormat)
{
	// align frame buffer size with 4-word unit
	DWORD dwSize = ALIGN(stride * height, 16);

	// Try to allocate surface from video memory
	SurfaceHeap *pHeap = m_pVideoMemoryHeap->Alloc(dwSize);
	if (pHeap != NULL)
	{
		DWORD dwVideoMemoryOffset = pHeap->Address() - (DWORD)m_VideoMemoryVirtualBase;
		DISPDRV_MSG((_T("[DISPDRV] AllocSurfaceVideo() : Allocated PA = 0x%08x\n\r"), dwVideoMemoryOffset+m_VideoMemoryPhysicalBase));

		*ppSurf = new S3C6410Surf(width, height, dwVideoMemoryOffset, (PVOID)pHeap->Address(), stride, format, pixelFormat, pHeap);
		if (*ppSurf  == NULL)
		{
			DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurfaceVideo() : Create S3C6410Surf() Failed\n\r")));

			pHeap->Free();

			return E_OUTOFMEMORY;
		}

		DISPDRV_MSG((_T("[DISPDRV] AllocSurfaceVideo() : S3C6410Surf() Allocated in Video Memory\n\r")));

		return S_OK;
	}
	else
	{
		DISPDRV_ERR((_T("[DISPDRV:ERR] AllocSurfaceVideo() : SurfaceHeap Alloc() Failed\n\r")));

		*ppSurf = (DDGPESurf *)NULL;

		return E_OUTOFMEMORY;
	}
}


void S3C6410Disp::SetVisibleSurface(GPESurf *pSurf, BOOL bWaitForVBlank)
{
	S3C6410Surf *pDDSurf = (S3C6410Surf *)pSurf;

	if(pDDSurf->IsOverlay() == TRUE)
	{
		m_OverlayCtxt.pPrevSurface = m_OverlayCtxt.pSurface;		// Being Flipped Surface
		m_OverlayCtxt.pSurface = pDDSurf;
	}
	else
	{
		m_pVisibleSurface = pDDSurf;
	}

	EnterCriticalSection(&m_csDevice);

	DevSetVisibleSurface(pDDSurf, bWaitForVBlank);

	LeaveCriticalSection(&m_csDevice);
}

//-----------------------------------------------------------------------------

S3C6410Surf::S3C6410Surf(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_fInVideoMemory = TRUE;
	m_nOffsetInVideoMemory = offset;
	m_pSurfHeap = pHeap;

	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;
	}

	DISPDRV_INF((_T("[DISPDRV:INF] S3C6410Surf::S3C6410Surf() : @ 0x%08x, %d\n\r"), m_nOffsetInVideoMemory, dwSurfaceCount));
}


S3C6410Surf::~S3C6410Surf()
{
	dwSurfaceCount--;

	m_pSurfHeap->Free();

	DISPDRV_INF((_T("[DISPDRV:INF] S3C6410Surf::~S3C6410Surf() : @ 0x%08x, %d\n\r"), m_nOffsetInVideoMemory, dwSurfaceCount));
}

#if G2D_ACCELERATE
#if	USE_PACSURF

/**
*	@class	PACSurf
*	@desc	This Surface will try to allocate physically linear address
*		
**/
/**
*	@fn		PACSurf::PACSurf
*	@brief	try to allocate memory region that is physically linear
*	@param	GPESurf **ppSurf, INT width, INT height, EGPEFormat format, int surfaceFlags
*	@sa		GPESurf
*	@note	This Surface format is compatible to GPESurf
**/
PACSurf::PACSurf(int width, int height, EGPEFormat format)
{
	RETAILMSG(0, (_T("[DISPDRV] PACSurf Constructor(%d, %d, %d, 0x%08x)\n\r"), width, height, format));	

    // Even though "width" and "height" are int's, they must be positive.
    ASSERT(width > 0);
    ASSERT(height > 0);

    memset( &m_Format, 0, sizeof ( m_Format ) );

    m_pVirtAddr            = NULL;
    m_nStrideBytes         = 0;
    m_eFormat              = gpeUndefined;
    m_fInVideoMemory       = 0;
    m_fInUserMemory        = FALSE;
    m_fOwnsBuffer          = 0;
    m_nWidth               = 0;
    m_nHeight              = 0;
    m_nOffsetInVideoMemory = 0;
    m_iRotate              = DMDO_0;
    m_ScreenWidth          = 0;
    m_ScreenHeight         = 0;
    m_BytesPixel           = 0;
    m_nHandle              = NULL;
    m_fPLAllocated		= 0;

    if (width > 0 && height > 0)
    {
		m_nWidth               = width;
		m_nHeight              = height;
		m_eFormat              = format;
		m_nStrideBytes         = ( (EGPEFormatToBpp[ format ] * width + 7 )/ 8 + 3 ) & ~3L;
		m_pVirtAddr  = (ADDRESS) AllocPhysMem(  m_nStrideBytes * height, PAGE_READWRITE, 0, 0,&m_pPhysAddr);
		if(m_pVirtAddr != NULL)
		{
	       	 m_fPLAllocated = 1;		
					 CeSetMemoryAttributes((void *)m_pVirtAddr, (void *)(m_pPhysAddr >>8), m_nStrideBytes * height, PAGE_WRITECOMBINE);
	       	 RETAILMSG(0,(TEXT("\nPAC Surf PA Base : 0x%x VA Base : 0x%x STRIDE : %d"), m_pPhysAddr, m_pVirtAddr, m_nStrideBytes));
       	 }
		else
		{
			m_fPLAllocated = 0;
	       	 RETAILMSG(0,(TEXT("\nPAC Surf PA Base : 0x%x VA Base : 0x%x STRIDE : %d  new unsigned char"), m_pPhysAddr, m_pVirtAddr, m_nStrideBytes));		
	       	 m_pVirtAddr = (ADDRESS) new unsigned char[ m_nStrideBytes * height ];
	        }
		m_fOwnsBuffer          = 1;
		m_BytesPixel           = EGPEFormatToBpp[m_eFormat] >> 3;
    }
}

PACSurf::~PACSurf()
{
    if( m_fOwnsBuffer )
    {
    	if(m_fPLAllocated)
    	{
    		if(m_pVirtAddr)
    		{
			if( !FreePhysMem((LPVOID)m_pVirtAddr) )
			{
				RETAILMSG(TRUE,(TEXT("PACSurface deallocation is failed\r\n")));
			}
			else
			{
				m_pVirtAddr = NULL;
				m_fPLAllocated = 0;
				m_fOwnsBuffer = 0;
				RETAILMSG(0,(TEXT("PACSurface deallocation is succeeded\r\n")));
			}
    		}

    	}
    	else if( m_pVirtAddr )
        {
		RETAILMSG(TRUE,(TEXT("PACSurface dealloc is trying for non-contigious\r\n")));        
            delete [] (void *)m_pVirtAddr;
            m_pVirtAddr = NULL;
            m_fOwnsBuffer = 0;
        }
    }
}

#endif	//< USE_PACSURF
#endif	//< G2D_ACCELERATE
	
//-----------------------------------------------------------------------------

#if	0
//------------------------------------------------------------------------------
//
//  Method:  WriteBack
//
//  Flush surface memory in cache.
//
VOID S3C6410Surf::WriteBack()
{
    	ASSERT(m_pSurface != NULL);

	RETAILMSG(DBGLCD, (TEXT("S3C6410Surf::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 S3C6410Surf::Discard()
{
    	ASSERT(m_pSurface != NULL);
		RETAILMSG(DBGLCD, (TEXT("S3C6410Surf::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 + -