overlay.c
来自「Lido PXA270平台开发板的最新BSP,包括源代码」· C语言 代码 · 共 764 行 · 第 1/2 页
C
764 行
/*****************************************************************************
Name : OVERLAY.C
Title : Direct Draw surface Overlay callbacks
C Author : Kevan Ahmadi
Created : 13/01/03
Copyright : 2003 by Imaginationc Technologies Limited. All rights reserved.
: No part of this software, either material or conceptual
: may be copied or distributed, transmitted, transcribed,
: stored in a retrieval system or translated into any
: human or computer language in any form by any means,
: electronic, mechanical, manual or other-wise, or
: disclosed to third parties without the express written
: permission of Imagination Technologies Limited, Unit 8, HomePark
: Industrial Estate, King's Langley, Hertfordshire,
: WD4 8LZ, U.K.
Description : DDRAW Overlay callbacks
This source file is a modified version of overlay.c, originally located in:
embedded\wince\directx\dxcommon
Program Type : 32-bit DLL
Version : $Revision: 1.9.1.2 $
Modifications :
$Log: overlay.c $
*****************************************************************************/
#include "ddraw_headers.h"
#include "vlddrawi.h"
#include "overlay.h"
#include "services.h"
#include "drvescape.h"
enum {eOVERLAY_SUCCESS = 0, eOVERLAY_ERROR = 1};
DISP_STATE g_DISPState = { FALSE, 0, NULL, 0, 0, 0, FALSE};
static IMG_INT32 DisplayStateInit();
/***********************************************************************************
Function Name : GetRotationAngle
Inputs :
Outputs :
Returns : ui32Angle
Description : Returns display rotation angle.
************************************************************************************/
static IMG_UINT32 GetRotationAngle()
{
IMG_UINT32 ui32Angle=0;
/*
* This driver escape gives us a consistant interpretation of rotation angle
* Otherwise we get different angles for PocketPC and WinCE
*/
ExtEscape(g_DISPState.hdcDriver, DRVESC_GET_PHYS_ROTATION, 0,
NULL, sizeof(PDWORD), (LPSTR)&ui32Angle);
switch(ui32Angle)
{
case DMDO_0:
/* do nothing */
default:
break;
case DMDO_90:
ui32Angle=90;
break;
case DMDO_180:
ui32Angle=180;
break;
case DMDO_270:
ui32Angle=270;
break;
}
return(ui32Angle);
}
/***********************************************************************************
Function Name : DisplayStateInit
Inputs :
Outputs :
Returns : IMG_UINT32
Description : Initialize global DISP_STATE struct.
************************************************************************************/
static IMG_INT32 DisplayStateInit()
{
if (g_DISPState.bHardwareInUse)
{
return eOVERLAY_SUCCESS;
}
g_DISPState.psLastSyncObject = NULL;
g_DISPState.bFirstSyncIncremented = IMG_FALSE;
memset(&g_DISPState, 0, sizeof(g_DISPState));
g_DISPState.bHardwareInUse = TRUE;
g_DISPState.hdcDriver = GetWindowDC(NULL);
if (PVRSRVAcquireDeviceData(NULL, 0, &g_DISPState.sDevData, PVRSRV_DEVICE_TYPE_MBX1_LITE) != PVRSRV_OK)
{
DPF("UpdateOverlay : failed call to PVRSRVAcquireDeviceData");
g_DISPState.hServices = NULL;
return eOVERLAY_ERROR;
}
return eOVERLAY_SUCCESS;
}
/***********************************************************************************
Function Name : DisplayStateDeinit
Inputs :
Outputs :
Returns : IMG_UINT32
Description : Deinitialize global DISP_STATE struct - free resources.
************************************************************************************/
IMG_UINT32 DisplayStateDeinit()
{
IMG_UINT32 ui32i;
if (!g_DISPState.bHardwareInUse)
{
return eOVERLAY_SUCCESS;
}
if (g_DISPState.psLastSyncObject != NULL)
{
/* The method by which ui32ReadOpsComplete is incremented does not handle
the last surface to be flipped to. Hence this must be corrected during
deinitialization. */
g_DISPState.psLastSyncObject->ui32ReadOpsComplete = g_DISPState.psLastSyncObject->ui32ReadOpsPending;
}
g_DISPState.psLastSyncObject = NULL;
g_DISPState.bFirstSyncIncremented = IMG_FALSE;
if (g_DISPState.bRotatedBuffersAllocated == TRUE)
{
/* free the device memory we allocated for rotation */
for (ui32i=0; ui32i < DISP_NUM_ROT_SURFACES; ui32i++)
{
if (PVRSRVFreeDeviceMem(&g_DISPState.sDevData, g_DISPState.apsDisplaySurfaces[ui32i]) != PVRSRV_OK)
{
DPF("UpdateOverlay : failed call to PVRSRVFreeDeviceMem");
return eOVERLAY_ERROR;
}
g_DISPState.apsDisplaySurfaces[ui32i] = NULL;
}
/* Destroy the command queue */
PVRSRVDestroyCommandQueue(&g_DISPState.sDevData,g_DISPState.psBlitQueueInfo);
g_DISPState.bRotatedBuffersAllocated = FALSE;
}
ReleaseDC(NULL, g_DISPState.hdcDriver);
PVRSRVReleaseDeviceData(&g_DISPState.sDevData);
g_DISPState.hServices = NULL;
g_DISPState.hdcDriver = NULL;
g_DISPState.bHardwareInUse = FALSE;
return eOVERLAY_SUCCESS;
}
/*****************************************************************************
FUNCTION : UpdateOverlay
PURPOSE : Updates overlay properties
PARAMETERS : psData from DirectX
RETURNS : DDHAL return code.
*****************************************************************************/
DWORD __stdcall HALUpdateOverlay(LPDDHAL_UPDATEOVERLAYDATA psData)
{
PSURFDATA psSurfData;
PDXHALDATA psDriverData;
PVRSRV_DEV_INFO *psDevInfo;
PPDP_OVERLAYATTRIBS psOverlayAttribs;
DDCOLORKEY *psColourKey;
WORD wFlags =0;
IMG_UINT32 ui32Size;
IMG_UINT32 ui32ScreenWidth, ui32ScreenHeight;
PDP_OVERLAY* psFlipToOverlay;
IMG_UINT32 ui32i;
IMG_BOOL bTimeout = IMG_TRUE;
IMG_BOOL bStart = IMG_FALSE;
IMG_UINT32 uiStart = 0;
// FIXME - Part of temp flush fix below
PVRSRV_SYNC_INFO *psSyncInfo;
/*Extract our driver data from global object*/
psDriverData = GetDriverData(psData->lpDD);
psDevInfo = psDriverData->sDisplayDevData.psDevInfoKM;
psSurfData = (PSURFDATA) psData->lpDDSrcSurface->lpGbl->dwReserved1;
psOverlayAttribs = &psDriverData->sOverlayAttributes;
/*
* source and dest rectangles are always updated.
* The Pixel format is always valid
* Colour key is always either enabled or disabled
*/
/* If we need to hide the overlay, assume all other overlay attributes
in psData are invalid. */
if (psData->dwFlags & DDOVER_HIDE)
{
psOverlayAttribs->wValidFlags = PDP_OVERLAYATTRIB_VALID_VISIBILITY;
psOverlayAttribs->bOverlayOn = FALSE;
}
else
{
psOverlayAttribs->wValidFlags = PDP_OVERLAYATTRIB_VALID_DSTPOSITION |
PDP_OVERLAYATTRIB_VALID_SRCPOSITION |
PDP_OVERLAYATTRIB_VALID_PIXFMT |
PDP_OVERLAYATTRIB_VALID_CKEY;
}
/************************************ Rotation ********************************/
/* Note: the code below (handling rotation) was adapted from VDISP_SetOverlayAttributes. */
if (DisplayStateInit() != 0)
{
/* Failed to initialize DISP_STATE struct */
DPF("HALUpdateOverlay: ERROR: Call to DisplayStateInit failed");
psData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_NOTHANDLED;
}
g_DISPState.ui32DisplayRotation = GetRotationAngle();
if (g_DISPState.ui32DisplayRotation)
{
/* If rotation is performed pixel format must be IMC2 */
if (psOverlayAttribs->PixFormat != PDP_OVL_IMC2)
{
/* If pixel format is not IMC2, then disable rotation. */
g_DISPState.ui32DisplayRotation = 0;
g_DISPState.ui32SourceRotation = 0;
}
}
ui32ScreenWidth = GetDeviceCaps(g_DISPState.hdcDriver, HORZRES);
ui32ScreenHeight = GetDeviceCaps(g_DISPState.hdcDriver, VERTRES);
/* If the screen is rotated (and assuming a Disable Rotation flag is not set) then we need to
make sure we have rotated display surfaces allocated and that we tell PDPAPI the
rotated coordinates. */
if (g_DISPState.ui32DisplayRotation)
{
/* we need to rotate the video */
g_DISPState.ui32SourceRotation = g_DISPState.ui32DisplayRotation;
/* Create command queue and allocate buffers if not already done. */
if (!g_DISPState.bRotatedBuffersAllocated)
{
IMG_UINT32 ui32RotatedDisplaySurfStride;
/* Create the blit queue that we need */
if (PVRSRVCreateCommandQueue(&g_DISPState.sDevData, DISP_QUEUE_SIZE, &g_DISPState.psBlitQueueInfo) != PVRSRV_OK)
{
/* Failed to get the blit queue so we can't rotate the video. */
DPF("HALUpdateOverlay: ERROR: Call to PVRSRVCreateCommandQueue failed - cannot perform rotation-blit");
psData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_NOTHANDLED;
}
/* allocate the buffers */
/* assume that the width and height will have suitable alignments */
ui32RotatedDisplaySurfStride = (g_DISPState.ui32DisplayRotation == 180) ?
((psData->rSrc.right + (4 - 1)) & ~(4 - 1)):
((psData->rSrc.bottom + (4 - 1)) & ~(4 - 1));
ui32Size = (g_DISPState.ui32DisplayRotation == 180) ?
psData->rSrc.bottom * ((ui32RotatedDisplaySurfStride * 3) / 2):
psData->rSrc.right * ((ui32RotatedDisplaySurfStride * 3) / 2);
for (ui32i=0; ui32i < DISP_NUM_ROT_SURFACES; ui32i++)
{
if (PVRSRVAllocDeviceMem(&g_DISPState.sDevData, 0, ui32Size, ALLOCATION_ALIGNMENT, &g_DISPState.apsDisplaySurfaces[ui32i]) != PVRSRV_OK)
{
/* Allocation failed so clean up any we successfully allocated then exit */
DPF("HALUpdateOverlay: ERROR: Call to PVRSRVAllocDeviceMem failed - cannot perform rotation-blit");
psData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_NOTHANDLED;
}
}
g_DISPState.bRotatedBuffersAllocated = TRUE;
}
}
else
{
g_DISPState.ui32SourceRotation = 0;
}
switch (g_DISPState.ui32DisplayRotation)
{
case 0:
psOverlayAttribs->nTop = psData->rDest.top;
psOverlayAttribs->nBottom = psData->rDest.bottom;
psOverlayAttribs->nLeft = psData->rDest.left;
psOverlayAttribs->nRight = psData->rDest.right;
break;
case 90:
psOverlayAttribs->nTop = ui32ScreenWidth - psData->rDest.right;
psOverlayAttribs->nBottom = ui32ScreenWidth - psData->rDest.left;
psOverlayAttribs->nLeft = psData->rDest.top;
psOverlayAttribs->nRight = psData->rDest.bottom;
break;
case 180:
psOverlayAttribs->nTop = ui32ScreenHeight - psData->rDest.bottom;
psOverlayAttribs->nBottom = ui32ScreenHeight - psData->rDest.top;
psOverlayAttribs->nLeft = ui32ScreenWidth - psData->rDest.right;
psOverlayAttribs->nRight = ui32ScreenWidth - psData->rDest.left;
break;
case 270:
psOverlayAttribs->nTop = psData->rDest.left;
psOverlayAttribs->nBottom = psData->rDest.right;
psOverlayAttribs->nLeft = ui32ScreenHeight - psData->rDest.bottom;
psOverlayAttribs->nRight = ui32ScreenHeight - psData->rDest.top;
break;
}
switch (g_DISPState.ui32SourceRotation)
{
case 0:
psOverlayAttribs->wSrcX1 = (WORD)psData->rSrc.left;
psOverlayAttribs->wSrcY1 = (WORD)psData->rSrc.top;
psOverlayAttribs->wSrcX2 = (WORD)psData->rSrc.right;
psOverlayAttribs->wSrcY2 = (WORD)psData->rSrc.bottom;
break;
case 90:
psOverlayAttribs->wSrcX1 = (WORD) psData->rSrc.top;
psOverlayAttribs->wSrcY1 = (WORD) (psSurfData->dwWidth - psData->rSrc.right);
psOverlayAttribs->wSrcX2 = (WORD) psData->rSrc.bottom;
psOverlayAttribs->wSrcY2 = (WORD) (psSurfData->dwWidth - psData->rSrc.left);
break;
case 180:
psOverlayAttribs->wSrcX1 = (WORD) (psSurfData->dwWidth - psData->rSrc.right);
psOverlayAttribs->wSrcY1 = (WORD) (psSurfData->dwHeight - psData->rSrc.bottom);
psOverlayAttribs->wSrcX2 = (WORD) (psSurfData->dwWidth - psData->rSrc.left);
psOverlayAttribs->wSrcY2 = (WORD) (psSurfData->dwHeight - psData->rSrc.top);
break;
case 270:
psOverlayAttribs->wSrcX1 = (WORD) (psSurfData->dwHeight - psData->rSrc.bottom);
psOverlayAttribs->wSrcY1 = (WORD) psData->rSrc.left;
psOverlayAttribs->wSrcX2 = (WORD) (psSurfData->dwHeight - psData->rSrc.top);
psOverlayAttribs->wSrcY2 = (WORD) psData->rSrc.right;
break;
}
/*Check if we need to show the overlay*/
if (psData->dwFlags & DDOVER_SHOW)
{
psOverlayAttribs->wValidFlags |= PDP_OVERLAYATTRIB_VALID_VISIBILITY;
psOverlayAttribs->bOverlayOn = TRUE;
}
if (psData->dwFlags & (DDOVER_KEYDEST | DDOVER_KEYDESTOVERRIDE))
{
/*Find colour key structure to use*/
if (psData->dwFlags & DDOVER_KEYDESTOVERRIDE)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?