?? blt_alpha.cpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// Copyright (c) Samsung Electronics. Co. LTD. All rights reserved.
//
/*++
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.
Module Name: blt_alpha.cpp
Abstract: alphablended accelerated bitblt/rectangle for S3C6410 FIMGSE-2D
Functions:
Notes:
--*/
#include "precomp.h"
/// 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.
/// This function will copy the source and destination surface into scratch buffer
/**
* @fn SCODE S3C6410Disp::AcceleratedAlphaSrcCopyBlt(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
*/
SCODE S3C6410Disp::AcceleratedAlphaSrcCopyBlt(GPEBltParms *pBltParms)
{
PRECTL prclSrc, prclDst;
RECT rectlSrcBackup;
RECT rectlDstBackup;
BOOL bHWSuccess = FALSE;
BOOL bSrcInScratch = FALSE;
BOOL bDstInScratch = FALSE;
/// Allocation Scratch Framebuffer to process Bottom-Up Image
DDGPESurf *SrcScratchSurf = NULL;
DDGPESurf *DstScratchSurf = NULL;
DDGPESurf *pDstClone = NULL;
GPESurf *OldSrcSurf = NULL;
GPESurf *OldDstSurf = NULL;
prclSrc = pBltParms->prclSrc;
prclDst = pBltParms->prclDst;
/**
* Prepare Source & Destination Surface Information
*/
SURFACE_DESCRIPTOR descSrcSurface, descDstSurface;
DWORD dwTopStrideStartAddr = 0;
descSrcSurface.dwColorMode = GetHWColorFormat(pBltParms->pSrc);
descDstSurface.dwColorMode = GetHWColorFormat(pBltParms->pDst);
/// !!!!Surface Width may not match to Real Data format!!!!
/// !!!!Set Width by Scan Stride Size!!!!
descSrcSurface.dwHoriRes = ABS(SURFACE_WIDTH(pBltParms->pSrc));
descDstSurface.dwHoriRes = ABS(SURFACE_WIDTH(pBltParms->pDst));
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));
// turn on transparency & set comparison color
m_oG2D->SetTransparentMode(1, pBltParms->solidColor);
}
switch (pBltParms->rop4)
{
case 0x6666: // SRCINVERT
m_oG2D->SetRopEtype(ROP_SRC_XOR_DST);
break;
case 0x8888: // SRCAND
m_oG2D->SetRopEtype(ROP_SRC_AND_DST);
break;
case 0xCCCC: // SRCCOPY
m_oG2D->SetRopEtype(ROP_SRC_ONLY);
break;
case 0xEEEE: // SRCPAINT
m_oG2D->SetRopEtype(ROP_SRC_OR_DST);
break;
}
/// Check Source Rectangle Address
/// HW Coordinate limitation is 2040
/// 1. Get the Top line Start Address
/// 2. Set the base offset to Top line Start Address
/// 3. Recalulate top,bottom rectangle
/// 4. Do HW Bitblt
CopyRect(&rectlSrcBackup, (LPRECT)pBltParms->prclSrc);
CopyRect(&rectlDstBackup, (LPRECT)pBltParms->prclDst);
/// Destination's Region can have negative coordinate, especially for left, top point
/// In this case, For both destination, source's rectangle must be clipped again to use HW.
ClipDestDrawRect(pBltParms);
/// Set Source Surface Information
if((pBltParms->pSrc->Stride() > 0) && (pBltParms->pSrc->Stride() > 0) && (pBltParms->pSrc == pBltParms->pDst)
&& !(pBltParms->pSrc)->InVideoMemory() ) // OnScreen BitBlt
{
dwTopStrideStartAddr = m_dwPhyAddrOfSurface[0];
descSrcSurface.dwBaseaddr = dwTopStrideStartAddr;
descSrcSurface.dwVertRes = (pBltParms->pSrc->ScreenHeight() != 0 ) ? pBltParms->pSrc->ScreenHeight() : pBltParms->pSrc->Height();
descDstSurface.dwBaseaddr = descSrcSurface.dwBaseaddr;
descDstSurface.dwVertRes = descSrcSurface.dwVertRes;
RETAILMSG(DISP_ZONE_2D,(TEXT("Onscreen CachedBitBlt:Addr:0x%x, Height:%d\r\n"), descSrcSurface.dwBaseaddr, descSrcSurface.dwVertRes));
}
else // OffScreen BitBlt
{
if((( DDGPESurf *)(pBltParms->pSrc))->InVideoMemory() )
{
descSrcSurface.dwBaseaddr = (m_VideoMemoryPhysicalBase + (( DDGPESurf *)(pBltParms->pSrc))->OffsetInVideoMemory());
/// If 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();
RETAILMSG(DISP_ZONE_2D,(TEXT("Offscreen BitBlt Src in VideoMem:Addr:0x%x, Height:%d\r\n"), descSrcSurface.dwBaseaddr, descSrcSurface.dwVertRes));
}
else
{
// In this case, WE must copy source area
if(pBltParms->pSrc->Stride() < 0)
{
bHWSuccess = CreateScratchSurface(pBltParms->pSrc, &SrcScratchSurf, pBltParms->prclSrc, &descSrcSurface, pBltParms->pSrc->Format(), TRUE);
if(!bHWSuccess)
{
goto PostHWBitBlt;
}
OldSrcSurf = pBltParms->pSrc;
pBltParms->pSrc = SrcScratchSurf;
bSrcInScratch = TRUE;
RETAILMSG(DISP_ZONE_2D,(TEXT("SBBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descSrcSurface.dwBaseaddr, descSrcSurface.dwVertRes,
descSrcSurface.dwHoriRes, descSrcSurface.dwColorMode));
}
else
{
if(m_dwPhyAddrOfSurface[0] == NULL) // Copy
{
bHWSuccess = CreateScratchSurface(pBltParms->pSrc, &SrcScratchSurf, pBltParms->prclSrc, &descSrcSurface, pBltParms->pSrc->Format(),TRUE);
if(!bHWSuccess)
{
goto PostHWBitBlt;
}
OldSrcSurf = pBltParms->pSrc;
pBltParms->pSrc = SrcScratchSurf;
bSrcInScratch = TRUE;
RETAILMSG(DISP_ZONE_2D,(TEXT("STBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descSrcSurface.dwBaseaddr, descSrcSurface.dwVertRes,
descSrcSurface.dwHoriRes, descSrcSurface.dwColorMode));
}
else
{
dwTopStrideStartAddr = m_dwPhyAddrOfSurface[0] + pBltParms->prclSrc->top * pBltParms->pSrc->Stride();
descSrcSurface.dwBaseaddr = dwTopStrideStartAddr;
descSrcSurface.dwVertRes = RECT_HEIGHT(pBltParms->prclSrc);
pBltParms->prclSrc->top = 0;
pBltParms->prclSrc->bottom = descSrcSurface.dwVertRes;
RETAILMSG(DISP_ZONE_2D,(TEXT("STVBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descSrcSurface.dwBaseaddr, descSrcSurface.dwVertRes,
descSrcSurface.dwHoriRes, descSrcSurface.dwColorMode));
}
}
}
/// Set Destination Surface Information
if(((DDGPESurf *)(pBltParms->pDst))->InVideoMemory() )
{
descDstSurface.dwBaseaddr = (m_VideoMemoryPhysicalBase + (( DDGPESurf *)(pBltParms->pDst))->OffsetInVideoMemory());
/// If surface is created by user temporary, that has no screen width and height.
descDstSurface.dwVertRes = (pBltParms->pDst->ScreenHeight() != 0 ) ? pBltParms->pDst->ScreenHeight() : pBltParms->pDst->Height();
RETAILMSG(DISP_ZONE_2D,(TEXT("Offscreen BitBlt Dst in VideoMem:Addr:0x%x, Height:%d\r\n"), descDstSurface.dwBaseaddr, descDstSurface.dwVertRes));
}
else
{
if(pBltParms->pDst->Stride() < 0)
{
bHWSuccess = CreateScratchSurface(pBltParms->pDst, &DstScratchSurf, pBltParms->prclDst, &descDstSurface, pBltParms->pDst->Format(), TRUE);
if(!bHWSuccess)
{
goto PostHWBitBlt;
}
OldDstSurf = pBltParms->pDst;
pBltParms->pDst = DstScratchSurf;
bDstInScratch = TRUE;
RETAILMSG(DISP_ZONE_2D,(TEXT("DBBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descDstSurface.dwBaseaddr, descDstSurface.dwVertRes,
descDstSurface.dwHoriRes, descDstSurface.dwColorMode));
/*
RETAILMSG(DISP_ZONE_WARNING,(TEXT("I don't know about this case\n")));
return EmulatedBlt(pBltParms);
*/
}
else
{
if(m_dwPhyAddrOfSurface[1] == NULL) // Prepare
{
bHWSuccess = CreateScratchSurface(pBltParms->pDst, &DstScratchSurf, pBltParms->prclDst, &descDstSurface, pBltParms->pDst->Format(), TRUE);
if(!bHWSuccess)
{
goto PostHWBitBlt;
}
OldDstSurf = pBltParms->pDst;
pBltParms->pDst = DstScratchSurf;
bDstInScratch = TRUE;
RETAILMSG(DISP_ZONE_2D,(TEXT("DTBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descDstSurface.dwBaseaddr, descDstSurface.dwVertRes,
descDstSurface.dwHoriRes, descDstSurface.dwColorMode));
}
else
{
dwTopStrideStartAddr = m_dwPhyAddrOfSurface[1] + pBltParms->prclDst->top * pBltParms->pDst->Stride();
descDstSurface.dwBaseaddr = dwTopStrideStartAddr;
descDstSurface.dwVertRes = RECT_HEIGHT(pBltParms->prclDst);
pBltParms->prclDst->top = 0;
pBltParms->prclDst->bottom = descDstSurface.dwVertRes;
RETAILMSG(DISP_ZONE_2D,(TEXT("DTVBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descDstSurface.dwBaseaddr, descDstSurface.dwVertRes,
descDstSurface.dwHoriRes, descDstSurface.dwColorMode));
}
}
}
}
m_oG2D->Set3rdOperand(G2D_OPERAND3_PAT);
// AlphaBlending Equation, Perpixel and Perplane same.
// Data = (Source * (ALPHA+1) + destination *(256-ALPHA)) >> 8
// Fading
// Data = ((Source * (ALPHA+1) ) >>8) + fading offset
//
// Check if Constant Alpha or Per-Pixel Alpha
if(pBltParms->blendFunction.AlphaFormat != 0 && pBltParms->blendFunction.SourceConstantAlpha != 0xFF)
{
SURFACE_DESCRIPTOR descRealSrcSurface;
SURFACE_DESCRIPTOR descRealDstSurface;
GPESurf *pDstBackup=0;
RECT rectDstBackup;
RECT rectSrcBackup;
RECT rectBackupCloneDst;
// Backup original source region, This can be Scratch Surface's region
CopyRect(&rectSrcBackup, (LPRECT)pBltParms->prclSrc);
// Backup original destination region
CopyRect(&rectDstBackup, (LPRECT)pBltParms->prclDst);
// Bakcup original destination surface
pDstBackup = pBltParms->pDst;
// backup real source Surface.
memcpy(&descRealSrcSurface, &descSrcSurface, sizeof(SURFACE_DESCRIPTOR));
// if Per-Pixel Alpha with SCA then we just run 2 alphablend call
// set destination descriptor as source descriptor.
// prepare scratch for fading.
if(!bSrcInScratch)
{
bHWSuccess = CreateScratchSurface(pBltParms->pSrc, &SrcScratchSurf, pBltParms->prclSrc, &descSrcSurface, pBltParms->pSrc->Format(), FALSE);
OldSrcSurf = pBltParms->pSrc;
pBltParms->pSrc = SrcScratchSurf;
bSrcInScratch = TRUE;
}
// Replace Target region as source itself
pBltParms->prclDst = pBltParms->prclSrc;
// Replace Target Surface as Source Surface
pBltParms->pDst = pBltParms->pSrc;
m_oG2D->SetAlphaMode(G2D_FADING_MODE); //< Self Fading AlphaBlend
m_oG2D->SetAlphaValue(pBltParms->blendFunction.SourceConstantAlpha);
// Do SCA to self(fading mode).
bHWSuccess = HWBitBlt(pBltParms, &descRealSrcSurface, &descSrcSurface);
///////
// restore destination region
pBltParms->prclDst = (LPRECTL)&rectDstBackup;
// restore destination surface
pBltParms->pDst = pDstBackup;
if(!bHWSuccess)
{
goto PostHWBitBlt;
}
#define ALPHABIT_WORKAROUND2 (TRUE)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -