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

📄 surf.cpp

📁 AU1100嵌入式处理器lcd显示驱动程序
💻 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) 1995-2000 Microsoft Corporation.  All rights reserved.
Copyright (c) 2002-2003 BSQUARE Corporation. All rights reserved.

Module Name:	surface allocation/manipulation/free routines

Abstract:

Functions:


Notes:


--*/

#include "headers.h"

#ifdef DDRAW_ENABLE

/********************************************************************/
void Au1100LCD::CheckVisibleSurface(void)
{
   unsigned long tickCount = GetTickCount();
   if( tickCount - m_nTicksAtFlip > m_nTicksPerFrame + 1 )
   {
      m_pOldVisibleSurface = m_pNewVisibleSurface;
      return;
   }

   DEBUGMSG (GPE_ZONE_FLIP, 
      (TEXT("Remaining ticks per frame:%d\n\r"), (tickCount-m_nTicksAtFlip)) );

   WaitForVBlank();
   return;
}

/********************************************************************/
int Au1100LCD::SurfaceBusyFlipping( DDGPESurf *pSurf )
{
   if( pSurf == m_pOldVisibleSurface || pSurf == m_pNewVisibleSurface )
      CheckVisibleSurface();

   return ( pSurf == m_pOldVisibleSurface || pSurf == m_pNewVisibleSurface );
}

/********************************************************************/
int Au1100LCD::FlipInProgress(void)
{
   if( m_pOldVisibleSurface != m_pNewVisibleSurface )
      CheckVisibleSurface();
   else
      return 0;

   if( m_pOldVisibleSurface != m_pNewVisibleSurface )
   {
      DEBUGMSG (GPE_ZONE_FLIP, ( TEXT("Flip from surf 0x%08x to 0x%08x in progress\r\n"),
         m_pOldVisibleSurface, m_pNewVisibleSurface ));
   }

   return ( m_pOldVisibleSurface != m_pNewVisibleSurface );
}

void Au1100LCD::VBlankReceived()
{
	m_nTicksAtFlip = m_nTicksAtResync = GetTickCount();
	m_pOldVisibleSurface = m_pNewVisibleSurface;
}

/********************************************************************/
// wait to get into/out of vertical blank signal
void Au1100LCD::WaitForVBlank()
{
   DEBUGMSG(GPE_ZONE_FLIP, (TEXT("WaitForVBlank: wait to be out of vblank\r\n")));
   while (InVBlank())
   {
   	   DEBUGMSG(GPE_ZONE_FLIP, (TEXT("-")));
   };
   
   DEBUGMSG(GPE_ZONE_FLIP, (TEXT("\r\nWaitForVBlank: wait to get into vblank\r\n")));
   while (!InVBlank())
   {
	   DEBUGMSG(GPE_ZONE_FLIP, (TEXT("+")));
   };
   DEBUGMSG(GPE_ZONE_FLIP, (TEXT("\r\n")));

   VBlankReceived();	// Reset counters etc
}

/********************************************************************/
// display the surface
void Au1100LCD::SetVisibleSurface( GPESurf *pSurf, BOOL bWaitForVBlank )
{  
    if (bWaitForVBlank)
        WaitForVBlank();

	DEBUGMSG (GPE_ZONE_FLIP, (TEXT("SetVisibleSurface after WaitForVBlank\r\n")));

    SetVisibleSurface(pSurf);
}

/********************************************************************/
// surface constructor
Au1100LCDSurf::Au1100LCDSurf(
   int width,
   int height,
   unsigned long offset,
   void *pBits,            // virtual address of allocated bits
   int stride,
   EGPEFormat format,
   EDDGPEPixelFormat pixelFormat,
   SurfaceHeap *pNode
   )
   : DDGPESurf( width, height, pBits, stride, format, pixelFormat )
{
   m_pSurfaceHeap = pNode;
   m_fInVideoMemory = TRUE;
   m_nOffsetInVideoMemory = offset;
}

/********************************************************************/
// surface destructor
Au1100LCDSurf::~Au1100LCDSurf(void)
{
    m_pSurfaceHeap->Free();
}

/********************************************************************/
SCODE
Au1100LCD::AllocSurface(
    DDGPESurf       **ppSurf,
    int               width,
    int               height,
    EGPEFormat        format,
    EDDGPEPixelFormat pixelFormat,
    int               surfaceFlags
    )
{
   if ( surfaceFlags & (GPE_REQUIRE_VIDEO_MEMORY|GPE_PREFER_VIDEO_MEMORY)  )
   {
	   if( ( format != m_pMode->format ) )
	   {
		   RETAILMSG(1, (TEXT("Alloc: format != m_pMode->format. \n\r")));
		   return E_INVALIDARG;
	   }

       // Attempt to allocate from video memory
       DWORD ulStride = ((width + 7) & (int) ~0x7) * m_nBytesPerPixel;
       DWORD ulHeapSize = ulStride * height;
        
	   ULONG memAvail =  m_pVideoMemory->Available();
	   DEBUGMSG(1, (TEXT("Alloc: Vmem avail: 0x%x(%u)\r\n"), memAvail, memAvail));
	   DEBUGMSG(1, (TEXT("Alloc: width, height, request size (%u,%u,%u)\r\n"), width, height, ulHeapSize));
	   
       SurfaceHeap *pNode = m_pVideoMemory->Alloc(ulHeapSize);

       if (pNode)
       {
           ULONG offset = pNode->Address() - (DWORD)m_pLAW;
           *ppSurf = new Au1100LCDSurf(width, height, offset, (void *)pNode->Address(), ulStride, format, pixelFormat, pNode);
           if (!(*ppSurf))
           {
               pNode->Free();
               return E_OUTOFMEMORY;
           }

		   DEBUGMSG(1, (TEXT("Alloc: ppSurf=%x\r\n"), ppSurf)); 
		   DEBUGMSG(1, (TEXT("Alloc: Vmem addr, offs, size: 0x%x, 0x%x, %u\r\n"), 
			   pNode->Address(), offset, pNode->NodeSize()));
           return S_OK;
       }

       if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
       {
           *ppSurf = (DDGPESurf *)NULL;
           return E_OUTOFMEMORY;
       }
   } // endif ( surfaceFlags & (GPE_REQUIRE_VIDEO_MEMORY|GPE_PREFER_VIDEO_MEMORY)  )


   // Allocate from system memory
   DEBUGMSG(1, (L"Alloc: Creating a DDGPESurf in system memory."));
   DEBUGMSG(1, (L" EGPEFormat %d, width %d, height %d.\r\n",
	   (int)format, width, height));

   *ppSurf = new DDGPESurf(width, height, format);
   if (*ppSurf != NULL)
   {
       // check we allocated bits succesfully
       if (((*ppSurf)->Buffer()) == NULL)
       {
		   RETAILMSG(1, (L"Alloc: failed to allocate from system memory\r\n"));
           delete *ppSurf;
       }
       else
       {
		   DEBUGMSG(1, (L"Alloc: *ppSurf->Buffer() %x\r\n", (*ppSurf)->Buffer()));
           return	S_OK;
       }
   } // allocation from system memory succeeded

   return E_OUTOFMEMORY;
}

#else // not DDRAW_ENABLE

/********************************************************************/
Au1100LCDSurf::Au1100LCDSurf(int width, int height, ULONG offset, PVOID pBits, int stride, EGPEFormat format, Node2D *pNode)
	: GPESurf(width, height, pBits, stride, format)
{
    m_pNode2D = pNode;
	m_fInVideoMemory = TRUE;
	m_nOffsetInVideoMemory = offset;
}

/********************************************************************/
Au1100LCDSurf::~Au1100LCDSurf(void)
{
    m_pNode2D->Free();
}

#endif DDRAW_ENABLE

/********************************************************************/
SCODE
Au1100LCD::AllocSurface(GPESurf **ppSurf, int width, int height, EGPEFormat format, int surfaceFlags)
{
#ifdef DDRAW_ENABLE

    EDDGPEPixelFormat pixelFormat;
    GPEModeEx modeInfoEx;

    GetModeInfoEx(&modeInfoEx, GetModeId());

    // GDI Issue Work-Around
    // There is an issue with GDI where if you have a printer device context
    // that has the same number of bits per pixel as the display, but
    // different bit masks, you will get the display's masks.

    // This is because in this function, when we are passed
    // the gpeDeviceCompatible constant, it refers to the current device,
    // which we have no knowledge of, not the display.

    if ( (format == modeInfoEx.modeInfo.format) || (format == gpeDeviceCompatible) )
    {
        pixelFormat = modeInfoEx.ePixelFormat;

        DEBUGMSG(1, 
            (TEXT("Display Compatible requested: format, ")
             TEXT("pixelFormat = 0x%x, 0x%x\r\n"), format, pixelFormat));
    }
    else
    {
        pixelFormat = EGPEFormatToEDDGPEPixelFormat[format];
        DEBUGMSG(1, 
            (TEXT("Explicitly requested: format, ")
             TEXT("pixelFormat = 0x%x, 0x%x\r\n"), format, pixelFormat));
    }

    return AllocSurface((DDGPESurf**)ppSurf, width, height, format, pixelFormat, surfaceFlags);

#else // not DDRAW_ENABLE

	if ((surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY) || (format == m_pMode->format) && (surfaceFlags & GPE_PREFER_VIDEO_MEMORY))
	{
		if (!(format == m_pMode->format))
			return E_INVALIDARG;

		// Attempt to allocate from video memory
		Node2D *pNode = m_p2DVideoMemory->Alloc(width, height);
		if (pNode)
		{
			ULONG offset = m_LineSizeInBytes * pNode->Top() + (pNode->Left() * EGPEFormatToBpp[format]) / 8 ;
			*ppSurf = new Au1100LCDSurf(width, height, offset, m_pLAW + offset, m_LineSizeInBytes, format, pNode);
			if (!(*ppSurf))
			{
				pNode->Free();
				return E_OUTOFMEMORY;
			}
			return S_OK;
		}

		if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
		{
			*ppSurf = (GPESurf *)NULL;
			return E_OUTOFMEMORY;
		}
	}

	if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
	{
		*ppSurf = (GPESurf*)NULL;
		return	E_OUTOFMEMORY;
	}

	// Allocate from system memory
	RETAILMSG(1, (TEXT("Creating a GPESurf in system memory. EGPEFormat = %d\r\n"), (int) format));
	*ppSurf = new GPESurf(width, height, format);


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

	return E_OUTOFMEMORY;

#endif DDRAW_ENABLE
}

#if DEBUG
int tickCountValid = 0;
unsigned int lastTickCount;
int frameCount = 0;
#endif

void Au1100LCD::SetVisibleSurface( GPESurf *pSurf )
{
    ULONG offset = pSurf->OffsetInVideoMemory();

    // display debug message before switching surface
	DEBUGMSG (GPE_ZONE_FLIP, (TEXT("SetVisibleSurface: vid mem start=%x, offset=%x\r\n"),
		m_pFb, offset ));

	m_pNewVisibleSurface = (Au1100LCDSurf *)pSurf;
	if (isDSTN(m_mode->mode_control))
	{
		m_Reg->dmaaddr0 = m_pFb + offset + ((m_words * 4) / 2);
		m_Reg->dmaaddr1 = m_pFb + offset;
	}
	else
	{
		m_Reg->dmaaddr0 = m_pFb + offset;
	}

	m_nTicksAtFlip = GetTickCount();

#if DEBUG
	if( tickCountValid )
	{
		frameCount++;
		if( m_nTicksAtFlip - lastTickCount > 10000 )
		{
			int framesPerTenSecs = frameCount * 10000 / ( m_nTicksAtFlip - lastTickCount );
			if( framesPerTenSecs < 2000 )
			{
				DEBUGMSG( 1, (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 DEBUG
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -