overlay.c
来自「Lido PXA270平台开发板的最新BSP,包括源代码」· C语言 代码 · 共 764 行 · 第 1/2 页
C
764 行
{
psColourKey=&psData->overlayFX.dckDestColorkey;
}
else
{
psColourKey=&psData->lpDDDestSurface->ddckCKDestOverlay;
}
/*Check if this is RGB or chroma colour key*/
if (psColourKey->dwColorSpaceLowValue == psColourKey->dwColorSpaceHighValue)
{
/*So this is RGB colour key*/
if (psData->dwFlags & DDOVER_KEYDEST)
{
DPFLX(DBG_OVERLAY, "Setting dst colour key with RGB 0x%lx from dst surface", psColourKey->dwColorSpaceLowValue);
}
else
{
DPFLX(DBG_OVERLAY, "Overiding dst colour key with RGB 0x%lx", psColourKey->dwColorSpaceLowValue);
}
/*Set up colour key fields in the structure*/
psOverlayAttribs->bCKeyOn = TRUE;
psOverlayAttribs->dwCKeyValue = psColourKey->dwColorSpaceLowValue;
}
else
{
/* So this is a chroma range and hence is not supported */
DPF("UpdateOverlay : Attempt to use chroma keying range ");
psData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_NOTHANDLED;
}
}
else
{
/* no colour keying */
psOverlayAttribs->bCKeyOn = FALSE;
}
/* De-interlacing flags */
if (psData->dwFlags & DDOVER_BOB)
{
psSurfData->sOverlaySurface.DeInterlace = PDP_BOB_ODD;
}
else
{
psSurfData->sOverlaySurface.DeInterlace = PDP_WEAVE;
}
/* we need to wait for any outstanding flips before we carry on */
psSyncInfo = psSurfData->psMemInfo->psSyncInfo;
do
{
if(*psSyncInfo->pui32LastWriteOp == psSyncInfo->ui32NextWriteOp-1 &&
psSyncInfo->ui32ReadOpsComplete == psSyncInfo->ui32ReadOpsPending)
{
bTimeout = IMG_FALSE;
break;
}
if(bStart == IMG_FALSE)
{
bStart = IMG_TRUE;
uiStart = HostClockus();
}
HostWaitus(MAX_HW_TIME_US/(WAIT_TRY_COUNT));
} while ((HostClockus() - uiStart) < MAX_HW_TIME_US);
if(bTimeout == IMG_TRUE)
{
PVR_DPF((PVR_DBG_ERROR, "HALUpdateOverlay: Dependencies failed for surface 0x%8.8X", psSurfData));
return PVRSRV_ERROR_GENERIC;
}
if (g_DISPState.ui32SourceRotation)
{
/* Rotate the overlay before flipping */
PDP_OVERLAY sRotateOverlay;
RotateOverlay(psSurfData, 0, &sRotateOverlay);
psFlipToOverlay = &sRotateOverlay;
}
else
{
/* Overlay is not rotated before flipping */
psFlipToOverlay = &psSurfData->sOverlaySurface;
}
/* flip to specified surface immediately (rather than waiting for vsync) */
if (PDP_FlipOverlaySurface(g_PDPHandle, psFlipToOverlay) != PDP_ERROR_OK)
{
/* call failed */
DPF("UpdateOverlay : failed to flip to new surface");
psData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_NOTHANDLED;
}
/* Are we turning the overlay off, if so then we must wait for all operations on
all the surfaces in the overlay flip chain to complete. If this is not done
then the async-completion of a queued flip can turn the overlay back on */
if((psOverlayAttribs->wValidFlags & PDP_OVERLAYATTRIB_VALID_VISIBILITY) &&
(psOverlayAttribs->bOverlayOn == FALSE))
{
/* DAB */
DWORD dwSurfaceCnt = gpsDriverData->sOvlFlipTable.dwActiveSurfaces;
while(dwSurfaceCnt)
{
PSURFDATA psOverlaySurfData;
bTimeout = IMG_TRUE;
psOverlaySurfData = (PSURFDATA) gpsDriverData->sOvlFlipTable.asSurfaceInfo[dwSurfaceCnt-1].pvSurfaceData;
psSyncInfo = psOverlaySurfData->psMemInfo->psSyncInfo;
uiStart = HostClockus();
do
{
if(*psSyncInfo->pui32LastWriteOp == psSyncInfo->ui32NextWriteOp-1 &&
psSyncInfo->ui32ReadOpsComplete == psSyncInfo->ui32ReadOpsPending)
{
bTimeout = IMG_FALSE;
break;
}
HostWaitus(MAX_HW_TIME_US/(WAIT_TRY_COUNT));
} while ((HostClockus() - uiStart) < MAX_HW_TIME_US);
if(bTimeout == IMG_TRUE)
{
PVR_DPF((PVR_DBG_ERROR, "HALUpdateOverlay: Dependencies failed for surface 0x%8.8X", psOverlaySurfData));
}
dwSurfaceCnt--;
}
}
/* Set the overlay attributes */
if (PDP_SetOverlayAttributes(g_PDPHandle, psOverlayAttribs) != PDP_ERROR_OK)
{
/* call failed */
DPF("UpdateOverlay : failed call to PDP_SetOverlayAttributes");
psData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_NOTHANDLED;
}
psData->ddRVal = DD_OK;
return (DDHAL_DRIVER_HANDLED);
}
/***********************************************************************************
Function Name : RotateOverlay
Inputs : eDeinterlace
psSurfData
Outputs : psOverlay
Returns : IMG_VOID
Description : Rotates the overlay surface in psSurfData and stores the
rotated surface information in psOverlay. This function was
adapted from VDISP_OverlayFlip.
************************************************************************************/
IMG_VOID RotateOverlay(PSURFDATA psSurfData, PDP_DEINTERLACE eDeinterlace, PDP_OVERLAY* psOverlay)
{
PVRSRV_MEM_INFO *pDstBuf;
IMG_UINT32 aui32BltData[32], ui32DisplayWidth, ui32DisplayHeight, ui32DisplayStride;
IMG_UINT32 ui32BltWordCount = 0, ui32BltRotateCmd = 0;
PDP_OVERLAY sFlipTo = psSurfData->sOverlaySurface;
/* test for rotation */
if(g_DISPState.ui32SourceRotation)
{
switch(g_DISPState.ui32SourceRotation)
{
case 90:
{
ui32DisplayWidth = psSurfData->dwHeight;
ui32DisplayStride = ((psSurfData->dwHeight + (4 - 1)) & ~(4 - 1));
ui32DisplayHeight = psSurfData->dwWidth;
ui32BltRotateCmd = MBX2D_TEXTROT_270DEGS;
break;
}
case 270:
{
ui32DisplayWidth = psSurfData->dwHeight;
ui32DisplayStride = ((psSurfData->dwHeight + (4 - 1)) & ~(4 - 1));
ui32DisplayHeight = psSurfData->dwWidth;
ui32BltRotateCmd = MBX2D_TEXTROT_90DEGS;
break;
}
case 180:
default:
{
ui32DisplayWidth = psSurfData->dwWidth;
ui32DisplayStride = psSurfData->lStride;
ui32DisplayHeight = psSurfData->dwHeight;
ui32BltRotateCmd = MBX2D_TEXTROT_180DEGS;
break;
}
}
/* This overlay is rotated so we need to perform a blit. */
pDstBuf = g_DISPState.apsDisplaySurfaces[g_DISPState.ui32NextRotatedBuffer];
g_DISPState.ui32NextRotatedBuffer++;
g_DISPState.ui32NextRotatedBuffer &= (DISP_NUM_ROT_SURFACES - 1);
psOverlay->pvOvlBase = (void *) pDstBuf->uiDevAddr.uiAddr;
psOverlay->pvOvlUBase = (void *) (pDstBuf->uiDevAddr.uiAddr + (ui32DisplayStride * ui32DisplayHeight));
psOverlay->pvOvlVBase = (void *) ((IMG_UINT32) psOverlay->pvOvlUBase + (ui32DisplayStride / 2));
/* set up destination surface */
aui32BltData[ui32BltWordCount++] = MBX2D_DST_CTRL_BH | MBX2D_SRC_332RGB | ui32DisplayStride;
aui32BltData[ui32BltWordCount++] = ((((IMG_UINT32) psOverlay->pvOvlBase) >> MBX2D_DST_ADDR_ALIGNSHIFT) << MBX2D_DST_ADDR_SHIFT)
& MBX2D_DST_ADDR_MASK;
/* set up source surface */
aui32BltData[ui32BltWordCount++] = MBX2D_SRC_CTRL_BH | MBX2D_SRC_FBMEM | MBX2D_SRC_332RGB | sFlipTo.wStride;
aui32BltData[ui32BltWordCount++] = (((IMG_UINT32) sFlipTo.pvOvlBase >> MBX2D_SRC_ADDR_ALIGNSHIFT) << MBX2D_SRC_ADDR_SHIFT)
& MBX2D_SRC_ADDR_MASK;
/* set src start XY to zero */
aui32BltData[ui32BltWordCount++] = MBX2D_SRC_OFF_BH | (0 << MBX2D_SRCOFF_XSTART_SHIFT) | (0 << MBX2D_SRCOFF_YSTART_SHIFT);
/* disable stretch */
aui32BltData[ui32BltWordCount++] = MBX2D_STRETCH_BH | (MBX2D_NO_STRETCH << MBX2D_X_STRETCH_SHIFT) | (MBX2D_NO_STRETCH << MBX2D_Y_STRETCH_SHIFT);
/* kick off blit */
aui32BltData[ui32BltWordCount++] = MBX2D_BLIT_BH | MBX2D_USE_PAT | ui32BltRotateCmd | MBX2D_ROP3_SRCCOPY;
aui32BltData[ui32BltWordCount++] = (0 << MBX2D_DST_XSTART_SHIFT) | (0 << MBX2D_DST_YSTART_SHIFT);
if(g_DISPState.ui32SourceRotation == 180)
{
aui32BltData[ui32BltWordCount++] = (ui32DisplayWidth << MBX2D_DST_XEND_SHIFT) | (ui32DisplayHeight << MBX2D_DST_YEND_SHIFT);
}
else
{
/* 90 or 270 case */
aui32BltData[ui32BltWordCount++] = (ui32DisplayWidth << MBX2D_DST_YEND_SHIFT) | (ui32DisplayHeight << MBX2D_DST_XEND_SHIFT);
}
/* now add chroma planes
*
* need to redefine src and dest surfaces
*/
/* U plane */
aui32BltData[ui32BltWordCount++] = MBX2D_DST_CTRL_BH | MBX2D_SRC_332RGB | ui32DisplayStride;
aui32BltData[ui32BltWordCount++] = ((((IMG_UINT32)psOverlay->pvOvlUBase) >> MBX2D_DST_ADDR_ALIGNSHIFT)
<< MBX2D_DST_ADDR_SHIFT) & MBX2D_DST_ADDR_MASK;
aui32BltData[ui32BltWordCount++] = MBX2D_SRC_CTRL_BH | MBX2D_SRC_FBMEM | MBX2D_SRC_332RGB | sFlipTo.wStride;
aui32BltData[ui32BltWordCount++] = ((((IMG_UINT32) sFlipTo.pvOvlBase + (sFlipTo.wStride * sFlipTo.wHeight)) >> MBX2D_SRC_ADDR_ALIGNSHIFT)
<< MBX2D_SRC_ADDR_SHIFT) & MBX2D_SRC_ADDR_MASK;
/* kick off blit */
aui32BltData[ui32BltWordCount++] = MBX2D_BLIT_BH | MBX2D_USE_PAT | ui32BltRotateCmd | MBX2D_ROP3_SRCCOPY;
aui32BltData[ui32BltWordCount++] = (0 << MBX2D_DST_XSTART_SHIFT) | (0 << MBX2D_DST_YSTART_SHIFT);
if(g_DISPState.ui32SourceRotation == 180)
{
aui32BltData[ui32BltWordCount++] = ((ui32DisplayWidth/2) << MBX2D_DST_XEND_SHIFT) | ((ui32DisplayHeight/2) << MBX2D_DST_YEND_SHIFT);
}
else
{
/* 90 or 270 case */
aui32BltData[ui32BltWordCount++] = ((ui32DisplayWidth/2) << MBX2D_DST_YEND_SHIFT) | ((ui32DisplayHeight/2) << MBX2D_DST_XEND_SHIFT);
}
/* V plane */
aui32BltData[ui32BltWordCount++] = MBX2D_DST_CTRL_BH | MBX2D_SRC_332RGB | ui32DisplayStride;
aui32BltData[ui32BltWordCount++] = ((((IMG_UINT32) psOverlay->pvOvlVBase) >> MBX2D_DST_ADDR_ALIGNSHIFT)
<< MBX2D_DST_ADDR_SHIFT) & MBX2D_DST_ADDR_MASK;
aui32BltData[ui32BltWordCount++] = MBX2D_SRC_CTRL_BH | MBX2D_SRC_FBMEM | MBX2D_SRC_332RGB | psSurfData->lStride;
aui32BltData[ui32BltWordCount++] = ((( (IMG_UINT32) sFlipTo.pvOvlBase + (sFlipTo.wStride * sFlipTo.wHeight) + sFlipTo.wStride/2) >> MBX2D_SRC_ADDR_ALIGNSHIFT)
<< MBX2D_SRC_ADDR_SHIFT) & MBX2D_SRC_ADDR_MASK;
/* kick off blit */
aui32BltData[ui32BltWordCount++] = MBX2D_BLIT_BH | MBX2D_USE_PAT | ui32BltRotateCmd | MBX2D_ROP3_SRCCOPY;
aui32BltData[ui32BltWordCount++] = (0 << MBX2D_DST_XSTART_SHIFT) | (0 << MBX2D_DST_YSTART_SHIFT);
if(g_DISPState.ui32SourceRotation == 180)
{
aui32BltData[ui32BltWordCount++] = ((ui32DisplayWidth/2) << MBX2D_DST_XEND_SHIFT) | ((ui32DisplayHeight/2) << MBX2D_DST_YEND_SHIFT);
}
else
{
/* 90 or 270 case */
aui32BltData[ui32BltWordCount++] = ((ui32DisplayWidth/2) << MBX2D_DST_YEND_SHIFT) | ((ui32DisplayHeight/2) << MBX2D_DST_XEND_SHIFT);
}
PVRSRVQueueBlt(g_DISPState.psBlitQueueInfo, pDstBuf->psSyncInfo, 0, &psSurfData->psMemInfo->psSyncInfo, ui32BltWordCount, aui32BltData);
psOverlay->wWidth = (WORD) ui32DisplayWidth;
psOverlay->wHeight = (WORD) ui32DisplayHeight;
psOverlay->wStride = (WORD) ui32DisplayStride;
/* no deinterlacing when rotated */
psOverlay->DeInterlace = PDP_WEAVE;
/* Now wait for the blit to complete before proceeding to flip */
while(*pDstBuf->psSyncInfo->pui32LastWriteOp < (pDstBuf->psSyncInfo->ui32NextWriteOp -1))
{
Sleep(0);
SysKickCmdProc (g_DISPState.psBlitQueueInfo->pui32KickerAddr);
}
}
else
{
psOverlay->pvOvlBase = (void *) sFlipTo.pvOvlBase;
psOverlay->pvOvlUBase = (void *) ((IMG_UINT32) sFlipTo.pvOvlBase + (sFlipTo.wStride * sFlipTo.wHeight));
psOverlay->pvOvlVBase = (void *) ((IMG_UINT32) psOverlay->pvOvlUBase + (sFlipTo.wStride / 2));
psOverlay->wWidth = (WORD) sFlipTo.wWidth;
psOverlay->wHeight = (WORD) sFlipTo.wHeight;
psOverlay->wStride = (WORD) sFlipTo.wStride;
psOverlay->DeInterlace = eDeinterlace;
}
}
/*****************************************************************************
FUNCTION : HALSetOverlayPosition
PURPOSE : Updates overlay position on screen
PARAMETERS : psData from DirectX
RETURNS : DDHAL return code.
*****************************************************************************/
DWORD __stdcall HALSetOverlayPosition(LPDDHAL_SETOVERLAYPOSITIONDATA psData)
{
/* we only get an X/Y location for the overlay in this case so we assume the rest
of the parameters are already setup */
PSURFDATA psSurfData;
PDXHALDATA psDriverData;
PVRSRV_DEV_INFO *psDevInfo;
PPDP_OVERLAYATTRIBS psOverlayAttribs;
DWORD dwWidth, dwHeight; /* destination dimensions */
/*Extract our driver data from global object*/
psDriverData = GetDriverData(psData->lpDD);
psDevInfo = psDriverData->sDisplayDevData.psDevInfoKM;
psSurfData = (PSURFDATA) psData->lpDDSrcSurface->lpGbl->dwReserved1;
psOverlayAttribs = &psDriverData->sOverlayAttributes;
dwWidth = psOverlayAttribs->nRight - psOverlayAttribs->nLeft;
dwHeight = psOverlayAttribs->nBottom - psOverlayAttribs->nTop;
/* calculate new coordinates */
psOverlayAttribs->nLeft = psData->lXPos;
psOverlayAttribs->nTop = psData->lYPos;
psOverlayAttribs->nRight = psOverlayAttribs->nLeft + dwWidth;
psOverlayAttribs->nBottom = psOverlayAttribs->nTop + dwHeight;
psOverlayAttribs->wValidFlags = PDP_OVERLAYATTRIB_VALID_DSTPOSITION;
/* Set the overlay attributes */
if(PDP_SetOverlayAttributes(g_PDPHandle, psOverlayAttribs) != PDP_ERROR_OK)
{
/* call failed */
DPF("SetOverlayPosition : failed call to PDPAL");
psData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_NOTHANDLED;
}
psData->ddRVal = DD_OK;
return(DDHAL_DRIVER_HANDLED);
}
/*****************************************************************************
End of file (OVERLAY.C)
*****************************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?