📄 ddipu_sdc.cpp
字号:
m_CurrentPanel = (PANEL_INFO*)&g_PanelArray[m_dwPanelType];
#if defined(PLAT_WPC) || defined(PLAT_SMARTPHONE)
// Set rotation for the primary surface
m_pPrimarySurface->SetRotation(m_pMode->width, m_pMode->height, m_iRotate);
#endif
SetRotation(modeNo, m_iRotate);
m_nScreenBpp = m_pMode->Bpp;
// The line stride of SDC display panel is 32-bits (4 bytes) aligned
m_nScreenStride = ((m_nScreenWidthSave * (m_nScreenBpp / 8) + 3) >> 2) << 2;
m_pModeEx->lPitch = m_nScreenStride;
m_dwPhysicalModeID = m_pMode->modeId;
int nBPP = m_nScreenBpp/8 - 1;
if (pPalette)
{
switch (m_nScreenBpp)
{
case 8:
// TODO:
break;
case 16:
case 24:
case 32:
*pPalette = EngCreatePalette (PAL_BITFIELDS,
0,
NULL,
BitMasks[nBPP][0],
BitMasks[nBPP][1],
BitMasks[nBPP][2]);
break;
}
}
InitHardware();
if(m_pPrimarySurface->OffsetInVideoMemory())
SetVisibleSurface((GPESurf *) m_pPrimarySurface);
}
m_rcWorkRect.left = 0;
m_rcWorkRect.top = 0;
m_rcWorkRect.right = m_nScreenWidth;
m_rcWorkRect.bottom = m_nScreenHeight;
// The following line informs the OS that the working rectangle has changed.
// TVOUT and the LCD may have different working rectangles depending on the design of the hardware.
// Without this call, the UI not will not be drawn correctly.
SystemParametersInfo(SPI_SETWORKAREA, 0, &m_rcWorkRect, SPIF_SENDCHANGE);
LeaveCriticalSection(&m_csDrawLock);
return S_OK;
}
//------------------------------------------------------------------------------
//
// Function: GetModeInfo
//
// This method populates a GPEMode structure with data
// for the requested mode.
//
// Parameters:
// pMode
// [out] Pointer to a GPEMode structure.
//
// modeNo
// [in] Integer specifying the mode to return information about.
//
// Returns:
// S_OK successful
// others failed
//
//------------------------------------------------------------------------------
SCODE DDIPU_SDC::GetModeInfo(GPEMode * pMode, int modeNo)
{
if(modeNo >= NumModes())
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("IPU_SDC GetModeInfo: wrong mode (%d)!!\r\n"), modeNo));
return E_INVALIDARG;
}
*pMode = *m_pMode;
return S_OK;
}
//------------------------------------------------------------------------------
//
// Function: GetModeInfoEx
//
// This method populates a GPEMode structure with data
// for the requested mode.
//
// Parameters:
// pMode
// [out] Pointer to a GPEModeEx structure.
//
// modeNo
// [in] Integer specifying the mode to return information about.
//
// Returns:
// S_OK successful
// others failed
//
//------------------------------------------------------------------------------
SCODE DDIPU_SDC::GetModeInfoEx(GPEModeEx * pModeEx, int modeNo)
{
if(modeNo >= NumModes())
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("IPU_SDC GetModeInfoEx: wrong mode (%d)!!\r\n"), modeNo));
return E_INVALIDARG;
}
*pModeEx = *m_pModeEx;
return S_OK;
}
//------------------------------------------------------------------------------
//
// Function: NumModes
//
// This method returns the number of
// display modes supported by a driver.
//
// Parameters:
// None.
//
// Returns:
// The number of supported display modes
//
//------------------------------------------------------------------------------
int DDIPU_SDC::NumModes(VOID)
{
return MAX_NUM_MODES;
}
//------------------------------------------------------------------------------
//
// Function: GetPhysicalVideoMemory
//
// This method retrieves the information of video memory.
//
// NOTE: The VIRTUAL address should be passed back as defined by Microsoft.
//
// Parameters:
// pPhysicalMemoryBase
// [out] Pointer to physical memory.
//
// pVideoMemorySize
// [out] Pointer to video memory size.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
VOID DDIPU_SDC::GetPhysicalVideoMemory(PULONG pPhysicalMemoryBase, PULONG pVideoMemorySize)
{
// The return value should be virtual address
*pPhysicalMemoryBase = (ULONG) m_pLAW;
*pVideoMemorySize = m_nVideoMemorySize;
}
//------------------------------------------------------------------------------
//
// Function: GetBpp
//
// Return the Bpp of the current monitor.
//
// Parameters:
// None.
//
// Returns:
// BPP of the current monitor.
//
//------------------------------------------------------------------------------
int DDIPU_SDC::GetBpp(VOID)
{
return m_nScreenBpp;
}
//------------------------------------------------------------------------------
//
// Function: GetModeInfo
//
// Software perspective initialization of IPU_SDC class.
//
// Parameters:
// None.
//
// Returns:
// TRUE successful
// FALSE failed
//
//------------------------------------------------------------------------------
BOOL DDIPU_SDC::Init(VOID)
{
BOOL result = TRUE;
BOOL bModeGot = FALSE;
int nBPP;
MSGQUEUEOPTIONS queueOptions;
// Pre-Initialization
m_bPPBusy = FALSE;
InitializeCriticalSection(&m_csPPLock);
InitializeCriticalSection(&m_csDirtyRect);
InitializeCriticalSection(&m_csDrawLock);
InitializeCriticalSection(&m_csOverlayShutdown);
m_pPrimarySurface = NULL;
m_pVisibleOverlay = NULL;
m_pVideoMemoryHeap = NULL;
m_CurrentPanel = NULL;
// Always start up in LCD panel mode... must
// switch to TV mode via DrvEscape
m_bTVModeActive = FALSE;
m_bTVNTSCOut = TRUE;
// Pre-setup display mode in DDGPE engine
m_pModeEx = &m_ModeInfoEx;
m_pMode = &m_ModeInfoEx.modeInfo;
memset(m_pModeEx, 0, sizeof(GPEModeEx));
m_pModeEx->dwSize = sizeof(GPEModeEx);
m_pModeEx->dwVersion = GPEMODEEX_CURRENTVERSION;
// Setting the current panel
m_dwPanelType = GetPanelTypeFromRegistry();
if (m_dwPanelType != -1)
{
if ((m_dwPanelType >= numModes))
{
// Use default panel type
m_dwPanelType = DISPLAY_PANEL_DEFAULT;
}
m_CurrentPanel = (PANEL_INFO*)VirtualAlloc(NULL,sizeof(PANEL_INFO),MEM_COMMIT,PAGE_EXECUTE_READWRITE ); //allocation is happening here.
// Setting the current panel
m_CurrentPanel = (PANEL_INFO*)&g_PanelArray[m_dwPanelType];
}
else
{
DEBUGMSG(GPE_ZONE_INIT, (TEXT("%s: Could not get panel type!\r\n"), __WFUNCTION__));
}
// Build array of supported modes
m_SupportedModes = (GPEMode *)LocalAlloc(LPTR, MAX_NUM_MODES * sizeof(GPEMode));
m_SupportedModes[DISPLAY_MODE_DEVICE] = ModeArray[m_dwPanelType];
m_SupportedModes[DISPLAY_MODE_NTSC] = NTSCMode;
m_SupportedModes[DISPLAY_MODE_PAL] = PALMode;
// Always start using the LCD mode (never TV)
memcpy(m_pMode, &(m_SupportedModes[DISPLAY_MODE_DEVICE]), sizeof(GPEMode));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("%s: Got display mode, %d!\r\n"), __WFUNCTION__, m_pMode->modeId));
// Read registry to determine whether TV mode is supported
// Sets m_bTVSupported
GetTVModeSupportFromRegistry();
// Set up this variable here, for use in call to initialize SDC
m_nScreenBpp = m_pMode->Bpp;
if(m_SupportedModes[m_pMode->modeId].modeId != m_pMode->modeId)
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("IPU_SDC Init: Unmatched hardware init info!\r\n")));
result = FALSE;
goto _done;
}
// Setup surface alignment as required by the IPU for 4 bytes
m_nSurfacePixelAlign = 4 / (m_pMode->Bpp / 8);
// Sanity Check for screen width
if(m_pMode->width & (m_nSurfacePixelAlign - 1))
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("IPU_SDC Init: Screen width (%d) is not aligned for %d bytes!\r\n"), m_pMode->width, m_nSurfacePixelAlign));
result = FALSE;
goto _done;
}
// Setup other DDGPE mode information
nBPP = m_pMode->Bpp/8 - 1;
switch (m_pMode->Bpp)
{
case 8:
case 16:
case 24:
case 32:
m_pModeEx->ePixelFormat = ePixelFormat[nBPP];
m_pModeEx->lPitch = m_nScreenStride;
m_pModeEx->dwRBitMask = BitMasks[nBPP][0];
m_pModeEx->dwGBitMask = BitMasks[nBPP][1];
m_pModeEx->dwBBitMask = BitMasks[nBPP][2];
break;
default:
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("IPU_SDC Init: Invalid BPP value passed to driver - Bpp = %d\r\n"), m_pMode->Bpp));
m_pMode->format = gpeUndefined;
result = FALSE;
goto _done;
}
// Setup Rotation
m_nScreenHeightSave = m_pMode->height;
m_nScreenWidthSave = m_pMode->width;
m_iRotate = GetRotateModeFromReg();
SetRotateParams();
m_nScreenWidth = m_pMode->width;
m_nScreenHeight = m_pMode->height;
// Pre-initialize the graphic window operator for overlay
m_pOverlaySurfaceOp = (pOverlaySurf_t)malloc(sizeof(overlaySurf_t));
if(m_pOverlaySurfaceOp)
{
memset(m_pOverlaySurfaceOp, 0x00, sizeof(overlaySurf_t));
}
else
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("IPU_SDC Init: failed to allocate memory for graphic windower operator, error(%d)\r\n"), GetLastError()));
result = FALSE;
goto _done;
}
// Open handle to Post-processing driver
m_hPP = PPOpenHandle();
if (m_hPP == NULL)
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("%s: CreateFile(PP): Unable to open file! Default to non-accelerated blt\r\n"), __WFUNCTION__));
result = FALSE;
goto _done;
}
m_PPConfiguration = PPConfiguration_None;
m_bOverlayConfiggedForTV = FALSE; // We always start in LCD mode.
// Event to receive the signal that end-of-frame
// has occurred for the post-processing task.
m_hPPEOFEvent = CreateEvent(NULL, FALSE, FALSE, PP_EOF_EVENT_NAME);
if (m_hPPEOFEvent == NULL)
{
DEBUGMSG(GPE_ZONE_ERROR,
(TEXT("%s: CreateEvent failed for PP EOF\r\n"), __WFUNCTION__));
result = FALSE;
goto _done;
}
// Start PP Overlay thread
// Initialize thread for PP Overlay handling
// pThreadAttributes = NULL (must be NULL)
// dwStackSize = 0 => default stack size determined by linker
// lpStartAddress = CspiProcessQueue => thread entry point
// lpParameter = NULL => point to thread parameter
// dwCreationFlags = 0 => no flags
// lpThreadId = NULL => thread ID is not returned
m_hPPOverlayThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PPOverlayThread, this, 0, NULL);
if (m_hPPOverlayThread == NULL)
{
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("%s: CreateThread failed!\r\n"), __WFUNCTION__));
result = FALSE;
goto _done;
}
else
{
DEBUGMSG(GPE_ZONE_INIT, (TEXT("%s: create PP Overlay update thread success\r\n"), __WFUNCTION__));
}
DEBUGMSG(GPE_ZONE_INIT, (TEXT("%s: Create msgqueues\r\n"), __WFUNCTION__));
// Create queues for reading and writing messages
queueOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
queueOptions.dwFlags = MSGQUEUE_ALLOW_BROKEN;
queueOptions.dwMaxMessages = 10;
queueOptions.cbMaxMessage = sizeof(ppOverlayOpData);
queueOptions.bReadAccess = TRUE; // we need read-access to msgqueue
// Create read handles for queues
m_hReadPPOverlayQueue = CreateMsgQueue(NULL, &queueOptions);
if (!m_hReadPPOverlayQueue)
{
DEBUGMSG(GPE_ZONE_ERROR,
(TEXT("%s: Error creating PP overlay queue. Initialization failed! \r\n"), __WFUNCTION__));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -