📄 ddipu_sdc_surf.cpp
字号:
//-----------------------------------------------------------------------------
// Copyright (C) 2004-2005, MOTOROLA, INC. All Rights Reserved
// THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
// BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
// MOTOROLA, INC.
//------------------------------------------------------------------------------
//
// Copyright (C) 2005-2007, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
// File: ddipu_sdc_rotate.cpp
//
// Implementation of DDIPU_SDC surface allocation/manipulation/free routines.
//
//------------------------------------------------------------------------------
#include "precomp.h"
//------------------------------------------------------------------------------
// External Functions
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------
//
// Function: SetVisibleSurface
//
// This function is used to update the display to
// a surface other than current one.
//
// Parameters:
// pSurf
// [in] A pointer to the surface that will be displayed.
//
// bWaitForVBlank
// [in] Indicates whether the flip should wait to
// synchronize with a vertical blank.
//
// Returns:
// TRUE: successful
// FALSE: failed
//
//------------------------------------------------------------------------------
VOID DDIPU_SDC::SetVisibleSurface(GPESurf * pSurf, BOOL bWaitForVBlank)
{
PHYSICAL_ADDRESS physAddr;
if (bWaitForVBlank)
WaitForNotBusy(DisplayPlane_0);
// In TV mode, the visible surface should not be the primary surface
if (m_bTVModeActive && (pSurf == m_pPrimarySurface))
{
return;
}
physAddr.QuadPart = m_nLAWPhysical + pSurf->OffsetInVideoMemory();
BackgroundSetSrcBuffer(&physAddr);
return;
}
//------------------------------------------------------------------------------
//
// Function: AllocSurface
//
// This method executes when the driver
// must allocate storage for surface pixels.
//
// Parameters:
// ppSurf
// [in] A pointer to a new DDGPESurf object.
//
// width
// [in] The desired width of the surface.
//
// height
// [in] The desired height of the surface.
//
// format
// [in] The desired format of the surface.
//
// pixelFormat
// [in] The desired pixel format of the surface.
//
// surfaceFlags
// [in] GPE surface flags for the surface.
//
// Returns:
// S_OK successful
// others failed
//
//------------------------------------------------------------------------------
SCODE DDIPU_SDC::AllocSurface(GPESurf **ppSurf, int width, int height, EGPEFormat format, int surfaceFlags)
{
return AllocSurface((DDGPESurf**)ppSurf,
width,
height,
format,
EGPEFormatToEDDGPEPixelFormat[format],
surfaceFlags);
}
SCODE DDIPU_SDC::AllocSurface(DDGPESurf **ppSurf, int width, int height,
EGPEFormat format, EDDGPEPixelFormat pixelFormat, int surfaceFlags)
{
DWORD bpp = EGPEFormatToBpp[format];
// YV12 planar is a weird case. Set up surface here.
if (pixelFormat == ddgpePixelFormat_YV12)
{
// YV12 has 12 bits per pixel
bpp = 12;
}
DWORD alignedWidth = ((width + m_nSurfacePixelAlign - 1) & (~(m_nSurfacePixelAlign - 1)));
DWORD nSurfaceSize = (bpp * (alignedWidth * height)) / 8;
DWORD stride = ((alignedWidth * bpp) / 8);
if (pixelFormat == ddgpePixelFormat_YV12)
{
// Y plane has 8 bits per pixel, and this
// is how we measure stride for YV12 surfaces
stride = ((alignedWidth * 8) / 8);
}
if ((surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY) ||
#ifndef PLAT_PMC
((surfaceFlags & GPE_PREFER_VIDEO_MEMORY) && (format == m_pMode->format)) ||
#endif
(surfaceFlags & GPE_BACK_BUFFER))
{
if (!(format == m_pMode->format))
return E_INVALIDARG;
RETAILMSG(0, (TEXT("Video memory before after surface allocation: %x"),
m_pVideoMemoryHeap->Available()));
// Attempt to allocate from video memory
SurfaceHeap *pStack = m_pVideoMemoryHeap->Alloc(nSurfaceSize);
if (pStack)
{
ULONG offset = pStack->Address();
*ppSurf = new DDIPU_SDCSurf(width, height, offset, m_pLAW + offset, stride,
format, pixelFormat, pStack);
RETAILMSG(0, (TEXT("Video memory remaining after surface allocation: %x"),
m_pVideoMemoryHeap->Available()));
if (!(*ppSurf))
{
pStack->Free();
return E_OUTOFMEMORY;
}
return S_OK;
}
if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
{
*ppSurf = NULL;
return E_OUTOFMEMORY;
}
}
// Allocate from system memory
DEBUGMSG(GPE_ZONE_CREATE, (TEXT("Creating a DDGPESurf in system memory - ")
TEXT("EGPEFormat = %d, DDGPEFormat = %d\r\n"),
(int) format, (int) pixelFormat));
*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;
}
//------------------------------------------------------------------------------
//
// Function: Flip
//
// This callback function associates the surface memory for the back
// buffer with the surface memory for the front buffer.
//
// Parameters:
// pd
// [in, out] Pointer to a DDHAL_FLIPDATA structure that
// contains information necessary to perform a flip.
//
// Returns:
// Returns one of the following values:
// DDHAL_DRIVER_HANDLED
// DDHAL_DRIVER_NOTHANDLED
// DDERR_CURRENTLYNOTAVAIL
//
//------------------------------------------------------------------------------
DWORD DDIPU_SDC::Flip(LPDDHAL_FLIPDATA pd)
{
DDGPESurf* surfTarg = DDGPESurf::GetDDGPESurf(pd->lpSurfTarg);
if (pd->lpSurfCurr->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
{
// Synchronicity is handled by double buffering in the SDC
// ...flipping is thus automatically synchronized with
// end-of-frame for the SDC channel.
//if (pd->dwFlags & DDFLIP_WAIT)
//{
// WaitForNotBusy(DisplayPlane_1);
//}
DDGPESurf* surfCurr = DDGPESurf::GetDDGPESurf(pd->lpSurfCurr);
if (surfCurr == m_pVisibleOverlay)
{
#if defined(PLAT_WPC) || defined(PLAT_SMARTPHONE)
RECTL *pOverlaySrcRect = (RECTL *) &pd->lpSurfTarg->rcOverlaySource;
#else
RECTL *pOverlaySrcRect = (RECTL *) &pd->lpSurfTarg->rcOverlaySrc;
#endif
SetVisibleSurfaceOverlay(surfTarg, pOverlaySrcRect);
m_pVisibleOverlay = surfTarg;
}
else
{
pd->ddRVal = DDERR_OUTOFCAPS;
return DDHAL_DRIVER_HANDLED;
}
}
else
{
#if defined(PLAT_WPC) || defined(PLAT_SMARTPHONE)
if (pd->dwFlags & DDFLIP_WAITNOTBUSY)
#else
if (pd->dwFlags & DDFLIP_WAIT)
#endif
{
WaitForNotBusy(DisplayPlane_0);
}
else if (IsBusy())
{
DEBUGMSG(GPE_ZONE_FLIP,(TEXT("Graphics engine busy\r\n")));
pd->ddRVal = DDERR_WASSTILLDRAWING;
return DDHAL_DRIVER_HANDLED;
}
SetVisibleSurface((GPESurf *)surfTarg);
}
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
//------------------------------------------------------------------------------
//
// Function: DDIPU_SDCSurf
//
// Constructor of DDIPU_SDCSurf.
//
// Parameters:
// width
// [in] The requested width for the surface, in pixels.
//
// height
// [in] The requested height for the surface, in pixels.
//
// offset
// [in] Offset in video memory for surface.
//
// pBits
// [in] A pointer allocated for the surface's graphic data.
// If the pBits parameter is not passed into the constructor,
// the DDGPESurf object allocates system memory for that
// surface's data.
//
// stride
// [in] The requested stride for the surface.
//
// format
// [in] The requested format for the surface.
//
// pixelFormat
// [in] The requested pixel format for the surface.
//
// pHeap
// [in] Pointer to surface heap allocated for the surface.
//
// Returns:
// New DDIPU_SDCSurf object.
//
//------------------------------------------------------------------------------
DDIPU_SDCSurf::DDIPU_SDCSurf(int width, int height, ULONG offset, PVOID pBits,
int stride, EGPEFormat format, EDDGPEPixelFormat pixelFormat,
SurfaceHeap *pHeap)
: DDGPESurf(width, height, pBits, stride, format, pixelFormat)
{
m_pHeap = pHeap;
m_fInVideoMemory = TRUE;
m_nOffsetInVideoMemory = offset;
}
//------------------------------------------------------------------------------
//
// Function: ~DDIPU_SDCSurf
//
// Destructor of ~DDIPU_SDCSurf.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
DDIPU_SDCSurf::~DDIPU_SDCSurf(VOID)
{
m_pHeap->Free();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -