📄 blt.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 2007-2008. Samsung Electronics, co. ltd All rights reserved.
Module Name: blt.cpp
Abstract: Related to Blit function
Functions: BltPrepare, BltComplete, ...
Notes:
--*/
#include "precomp.h"
#include <dispperf.h>
#if G2D_ACCELERATE
DDGPESurf *gpScratchSurf;
GPESurf *oldSrcSurf;
#endif
#define TEMP_DEBUG (FALSE)
#define FULL_TEST_OK (0)
SCODE S3C2450DISP::BltPrepare(GPEBltParms *blitParameters)
{
RECTL rectl;
int iSwapTmp;
BOOL bRotate = FALSE;
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2450DISP::BltPrepare\r\n")));
#ifdef DO_DISPPERF
DispPerfStart(blitParameters->rop4);
DispPerfParam(pBltParms);
#endif
// default to base EmulatedBlt routine
blitParameters->pBlt = EmulatedBlt;
// see if we need to deal with cursor
// check for destination overlap with cursor and turn off cursor if overlaps
if (blitParameters->pDst == m_pPrimarySurface) // only care if dest is main display surface
{
if (m_CursorVisible && !m_CursorDisabled)
{
if (blitParameters->prclDst != NULL) // make sure there is a valid prclDst
{
rectl = *blitParameters->prclDst; // if so, use it
// There is no guarantee of a well ordered rect in blitParamters
// due to flipping and mirroring.
if(rectl.top > rectl.bottom)
{
iSwapTmp = rectl.top;
rectl.top = rectl.bottom;
rectl.bottom = iSwapTmp;
}
if(rectl.left > rectl.right)
{
iSwapTmp = rectl.left;
rectl.left = rectl.right;
rectl.right = iSwapTmp;
}
}
else
{
rectl = m_CursorRect; // if not, use the Cursor rect - this forces the cursor to be turned off in this case
}
if (m_CursorRect.top <= rectl.bottom && m_CursorRect.bottom >= rectl.top &&
m_CursorRect.left <= rectl.right && m_CursorRect.right >= rectl.left)
{
CursorOff();
m_CursorForcedOff = TRUE;
}
}
if (m_iRotate ) // if screen (destination primary surface) is rotated.
{
bRotate = TRUE;
}
}
// check for source overlap with cursor and turn off cursor if overlaps
if (blitParameters->pSrc == m_pPrimarySurface) // only care if source is main display surface
{
if (m_CursorVisible && !m_CursorDisabled)
{
if (blitParameters->prclSrc != NULL) // make sure there is a valid prclSrc
{
rectl = *blitParameters->prclSrc; // if so, use it
}
else
{
rectl = m_CursorRect; // if not, use the CUrsor rect - this forces the cursor to be turned off in this case
}
if (m_CursorRect.top < rectl.bottom && m_CursorRect.bottom > rectl.top &&
m_CursorRect.left < rectl.right && m_CursorRect.right > rectl.left)
{
CursorOff();
m_CursorForcedOff = TRUE;
}
}
if (m_iRotate) //if screen(source primary surface) is rotated
{
bRotate = TRUE;
}
}
if (bRotate) // if source or desitnation surface is rotated.
{
blitParameters->pBlt = (SCODE (GPE::*)(GPEBltParms *))EmulatedBltRotate;
}
// EmulatedBltSelect02(blitParameters);
// EmulatedBltSelect08(blitParameters);
#if (BSP_TYPE == BSP_SMDK2450)
#if G2D_ACCELERATE
if( //(m_VideoPowerState != VideoPowerOff) && // to avoid hanging while bring up display H/W
((S3C2450Surf *)(blitParameters->pDst))->InVideoMemory() &&
(((S3C2450Surf *)(blitParameters->pDst))->Format() == gpe16Bpp)
// && blitParameters->pBlt == &GPE::EmulatedBlt // Disable Rotation Case
)
{
AcceleratedBltSelect16(blitParameters);
}
else
{
#endif
#endif
// EmulatedBltSelect16(blitParameters);
#if (BSP_TYPE == BSP_SMDK2450)
#if G2D_ACCELERATE
}
m_oG2D->WaitForIdle(); //< Wait for Fully Empty Command Fifo for all HW BitBlt request
#endif
#endif
return S_OK;
}
// This function would be used to undo the setting of clip registers etc
SCODE S3C2450DISP::BltComplete(GPEBltParms *blitParameters)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2450DISP::BltComplete\r\n")));
// see if cursor was forced off because of overlap with source or destination and turn back on
if (m_CursorForcedOff)
{
m_CursorForcedOff = FALSE;
CursorOn();
}
#if G2D_ACCELERATE
if(gpScratchSurf)
{
blitParameters->pSrc = oldSrcSurf;
delete gpScratchSurf;
gpScratchSurf=NULL;
}
#endif
#ifdef DO_DISPPERF
DispPerfEnd(0);
#endif
return S_OK;
}
/**
* @fn SCODE S3C2450DISP::AcceleratedBltFIll(GPEBltParms *pBltParms)
* @brief Rectangle Solid Filling Function. Solid Fill has no Source Rectangle
* @param pBltParms Blit Parameter Information Structure
* @sa GPEBltParms
* @note ROP : 0xF0F0
* @note Using Information : DstSurface, ROP, Solidcolor
*/
#if (BSP_TYPE == BSP_SMDK2450)
SCODE S3C2450DISP::AcceleratedBltFill(GPEBltParms *pBltParms)
{
PRECTL prclDst = pBltParms->prclDst;
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("++S3C6410DISP::AcceleratedBltFill\r\n")));
/**
* Prepare Source & DestinationSurface Information
*
*/
// m_oG2D->Init();
SURFACE_DESCRIPTOR descDstSurface;
// When Screen is rotated, ScreenHeight and ScreenWidth always has initial surface property.
descDstSurface.dwBaseaddr = (IMAGE_FRAMEBUFFER_DMA_BASE + (( S3C2450Surf *)(pBltParms->pDst))->OffsetInVideoMemory());
descDstSurface.dwColorMode = pBltParms->pDst->Format();
descDstSurface.dwHoriRes = pBltParms->pDst->Stride()/(EGPEFormatToBpp[pBltParms->pDst->Format()]/8);
descDstSurface.dwVertRes = pBltParms->pDst->ScreenHeight();
m_oG2D->SetSrcSurface(&descDstSurface); // Fill dummy value
m_oG2D->SetDstSurface(&descDstSurface);
if(pBltParms->prclClip)
{
m_oG2D->SetClipWindow(pBltParms->prclClip);
}
else
{
if(pBltParms->pDst->IsRotate())
{
RotateRectl(prclDst);
RETAILMSG(FULL_TEST_OK, (TEXT("AfterRotate DstRect:(L%d,T%d,R%d,B%d)\r\n"),
prclDst->left, prclDst->top, prclDst->right, prclDst->bottom
));
}
m_oG2D->SetClipWindow(prclDst);
}
m_oG2D->SetRopEtype(ROP_SRC_ONLY);
RETAILMSG(FULL_TEST_OK, (TEXT("FillRectA %x\r\n"), this));
RETAILMSG(FULL_TEST_OK, (TEXT("BlitFill : Dst Stride:%d, W:%d, H:%d, Screen(W:%d,H:%d), DstRect:(L%d,T%d,R%d,B%d)\r\n"),
pBltParms->pDst->Stride(), pBltParms->pDst->Width(), pBltParms->pDst->Height(),
pBltParms->pDst->ScreenWidth(), pBltParms->pDst->ScreenHeight(),
prclDst->left, prclDst->top, prclDst->right, prclDst->bottom
));
EnterCriticalSection(&m_cs2D);
m_oG2D->FillRect(prclDst, pBltParms->solidColor);
LeaveCriticalSection(&m_cs2D);
RETAILMSG(FULL_TEST_OK, (TEXT("FillRectB\r\n")));
if(pBltParms->pDst->IsRotate())
{
RotateRectlBack(prclDst);
RETAILMSG(FULL_TEST_OK, (TEXT("End Fill DstRect:(L%d,T%d,R%d,B%d)\r\n"),
prclDst->left, prclDst->top, prclDst->right, prclDst->bottom
));
}
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("--S3C2450DISP::AcceleratedBltFill\r\n")));
return S_OK;
}
#else
SCODE S3C2450DISP::AcceleratedBltFill(GPEBltParms *pBltParms)
{
return S_OK;
}
#endif
SCODE S3C2450DISP::AcceleratedDestInvert(GPEBltParms *pBltParms)
{
int dstX = pBltParms->prclDst->left;
int dstY = pBltParms->prclDst->top;
int width = pBltParms->prclDst->right - pBltParms->prclDst->left;
int height = pBltParms->prclDst->bottom - pBltParms->prclDst->top;
// printf("DestInvert need to implement");
return S_OK;
}
/// From Frame Buffer to Frame Buffer Directly
/// Constraints
/// Source Surface's width is same with Destination Surface's width.
/// Source and Dest must be in Video FrameBuffer Region
/// In Surface Format
/// ScreenHeight and ScreenWidth means logical looking aspect for application
/// Height and Width means real data format.
/**
* @fn SCODE S3C2450DISP::AcceleratedSrcCopyBlt(GPEBltParms *pBltParms)
* @brief Do Blit with SRCCOPY, SRCAND, SRCPAINT, SRCINVERT
* @param pBltParms Blit Parameter Information Structure
* @sa GPEBltParms
* @note ROP : 0xCCCC(SRCCOPY), 0x8888(SRCAND), 0x6666(SRCINVERT), 0XEEEE(SRCPAINT)
* @note Using Information : DstSurface, ROP, Solidcolor
*/
#if (BSP_TYPE == BSP_SMDK2450)
SCODE S3C2450DISP::AcceleratedSrcCopyBlt (GPEBltParms *pBltParms)
{
PRECTL prclSrc, prclDst;
RECT rectlSrcBackup;
BOOL bHWSuccess = FALSE;
prclSrc = pBltParms->prclSrc;
prclDst = pBltParms->prclDst;
// Set Destination Offset In Video Memory, this point is Dest lefttop point
//
// m_oG2D->Init();
/**
* Prepare Source & Destination Surface Information
*/
SURFACE_DESCRIPTOR descSrcSurface, descDstSurface;
DWORD dwSrcBaseAddrOffset = 0;
DWORD dwTopStrideStartAddr = 0;
descSrcSurface.dwColorMode = pBltParms->pSrc->Format();
/// !!!!Surface Width can not match to Real Data format!!!!
/// !!!!Set Width by Scan Stride Size!!!!
descSrcSurface.dwHoriRes = pBltParms->pSrc->Stride()/ (EGPEFormatToBpp[pBltParms->pSrc->Format()]/8);
/// If source surface is created by user temporary, that has no screen width and height.
descSrcSurface.dwVertRes = (pBltParms->pSrc->ScreenHeight() != 0 ) ? pBltParms->pSrc->ScreenHeight() : pBltParms->pSrc->Height();
if(pBltParms->pDst->IsRotate())
{
RotateRectl(prclDst); //< RotateRectl rotate rectangle with screen rotation information
if(pBltParms->prclClip)
{
RotateRectl(pBltParms->prclClip);
}
}
if(pBltParms->pSrc->IsRotate())
{
RotateRectl(prclSrc);
}
if (pBltParms->bltFlags & BLT_TRANSPARENT)
{
RETAILMSG(0,(TEXT("TransparentMode Color : %d\n"), pBltParms->solidColor));
m_oG2D->SetTransparentMode(1, pBltParms->solidColor); // turn on transparency & set comparison color
}
switch (pBltParms->rop4)
{
case 0x6666: // SRCINVERT
RETAILMSG(G2D_MSG, (TEXT("SRCINVERT\r\n")));
m_oG2D->SetRopEtype(ROP_SRC_XOR_DST);
break;
case 0x8888: // SRCAND
RETAILMSG(G2D_MSG, (TEXT("SRCAND\r\n")));
m_oG2D->SetRopEtype(ROP_SRC_AND_DST);
break;
case 0xCCCC: // SRCCOPY
RETAILMSG(G2D_MSG, (TEXT("SRCCOPY\r\n")));
m_oG2D->SetRopEtype(ROP_SRC_ONLY);
break;
case 0xEEEE: // SRCPAINT
RETAILMSG(G2D_MSG, (TEXT("SRCPAINT\r\n")));
m_oG2D->SetRopEtype(ROP_SRC_OR_DST);
break;
}
/// Check Source Rectangle Address
/// HW Coordinate limitation is 2048
/// 1. Get the Top line Start Address
/// 2. Set the base offset to Top line Start Address
/// 3. Recalulate top,bottom rectangle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -