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 + -
显示快捷键?