basesurf.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:144k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: basesurf.cpp,v 1.11.4.3 2004/07/26 10:27:38 pankajgupta Exp $
- *
- * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file,
- * are subject to the current version of the RealNetworks Public
- * Source License (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (the "RCSL") available at
- * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
- * will apply. You may also obtain the license terms directly from
- * RealNetworks. You may not use this file except in compliance with
- * the RPSL or, if you have a valid RCSL with RealNetworks applicable
- * to this file, the RCSL. Please see the applicable RPSL or RCSL for
- * the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the
- * portions it created.
- *
- * This file, and the files included with this file, is distributed
- * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
- * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
- * ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- #include "hxcom.h"
- #include "hxtypes.h"
- #include "hxwintyp.h"
- #include "hxvsurf.h"
- #include "hxslist.h"
- #include "hxthread.h"
- #include "hxver.h"
- #if defined(_WINDOWS)
- #include "winsurf.h"
- #if defined (HELIX_FEATURE_VS2)
- #include "winsurf2.h"
- #endif
- #include "winroot.h" // must be included before colormap.h
- #endif
- #include "region.h"
- #include "basesurf.h"
- #include "basesite.h"
- #include "baseroot.h"
- #include "hxprefs.h"
- #include "hxtick.h"
- #include "hxheap.h"
- #include "colormap.h"
- #include "microsleep.h"
- #include "hxevent.h"
- #include "infmt.h"
- //MMX alphablending only available on linux and windows right now.
- //Should work just fine on any IA plaform though (intel solaris for example)
- #ifdef _USE_MMX
- #include "mmx_util.h" //for checkMmxAvailablity()
- extern "C"
- {
- void AlphaBlendMMX( UINT32*, UINT32*, INT32 );
- }
- #endif
- #include <math.h> // fabs()
- #include "drawline.h"
- #if defined(_UNIX) && !defined(_MAC_UNIX)
- # include "unixsurf.h"
- #endif
- #if defined(_MACINTOSH) || defined(_MAC_UNIX)
- //#include "../dcondev/dcon.h"
- #include "platform/mac/macsurf.h"
- #endif
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- #ifdef _DEBUG
- #include "region.h" //just for _DumpString
- #endif
- #include "sitefact.h"
- #include "hwmemobj.h"
- #define NOT_IMPL 0
- /*
- * Defines used for testing various parts of the code.
- */
- //#define _CHECK_PERFORMANCE
- //#define _CHECK_SCROLLBARS
- //#define _CHECK_MODES
- #define NOT_IMPL 0
- #define OVERLAY_BYPASS_THRESHOLD 8
- #define OVERLAY_FAILURE_THRESHOLD 3 // What the heck should this number be? Does it really matter?
- CBaseSurface::CBaseSurface(IUnknown* pContext, CHXBaseSite* pSite)
- : m_lRefCount(0)
- , m_pContext(pContext)
- , m_Brightness(0)
- , m_Contrast(0)
- , m_Saturation(0)
- , m_Hue(0)
- , m_Sharpness(0)
- , m_ModeSharpness(0)
- , m_PrevBrightness(0)
- , m_PrevContrast(0)
- , m_PrevSaturation(0)
- , m_PrevHue(0)
- , m_PrevSharpness(0)
- , m_pSite(pSite)
- , m_pRootSurface(NULL)
- , m_pOptimizedFormat(NULL)
- , m_nSrcCID(0)
- , m_nBltMode(HX_BASIC_BLT)
- , m_nSurfaceCID(0)
- , m_bBackGroundDirty(TRUE)
- , m_fScrollBarZoom(1.0)
- , zm_pColorAcc(NULL)
- , m_pyuvInputMngr(NULL)
- , m_pHwMemObj(NULL)
- , m_pucLastImage(NULL)
- , m_ulLastBlendTime(0)
- , m_bSpamUpdateOverlay(TRUE)
- , m_bFlipOverlay(FALSE)
- , m_nBackBufferCount(0)
- , m_nMaxBackBuffers(3)
- , m_bDisableFillColorKey(TRUE)
- , m_bMultipleOverlay(FALSE)
- , m_nOldBltMode(0)
- , m_nOldBltMode2(0)
- , m_oldOverlayColorDepth(0)
- , m_convertedOverlayColor(0x00010203)
- , m_bUseOverlays(TRUE)
- , m_nOverlayFailureCount(0)
- , m_nDDSurfaceSize(0)
- , m_nUpdateOverlayByPassCount(0)
- , m_scaleFactorX(1.0)
- , m_scaleFactorY(1.0)
- , m_paSrcRects(NULL)
- , m_paDestRects(NULL)
- , m_pAdditionalColorKey(NULL)
- , m_bNeedColorKeyFilled(FALSE)
- , m_bYUVBlending(FALSE)
- , m_bVideoSurface2(FALSE)
- , m_bOptimalVideoScheduler(FALSE)
- , m_pLinkedOverlay(NULL)
- , m_bAllowOverlayLinking(TRUE)
- , m_bLostHWAcceleration(FALSE)
- , m_bOffBecauseofShinking(FALSE)
- , m_bImageBlocksGood(FALSE)
- , m_pOverlayManager(NULL)
- {
- HX_ASSERT( m_pContext );
- m_pContext->AddRef();
- memset( &m_bmiLastImage, 0, sizeof( HXBitmapInfoHeader ) );
- memset( &m_bmiLastBlt, 0, sizeof( HXBitmapInfoHeader ) );
- memset( &m_surfaceSize, 0, sizeof(HXxSize) );
- memset( &m_lastUpdateDestRect, 0, sizeof(m_lastUpdateDestRect) );
- memset( &m_lastUpdateSrcRect, 0, sizeof(m_lastUpdateSrcRect) );
- memset( &m_lastSrcRect, 0, sizeof(m_lastSrcRect) );
- memset( &m_bmi, 0, sizeof(m_bmi) );
- #if !defined(_GOLD) && 0
- m_TimeStamps.Init(m_pContext, this);
- #endif
- IHXPreferences* pPreferences = NULL;
- IHXBuffer* pBuffer = NULL;
- if (HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences,(void**)&pPreferences))
- {
- if (pPreferences->ReadPref("SiteZoomFactor", pBuffer) == HXR_OK)
- {
- m_fScrollBarZoom = !(::atoi((char*) pBuffer->GetBuffer()) == 1);
- }
- HX_RELEASE(pBuffer);
- if (pPreferences->ReadPref("UseOverlay", pBuffer) == HXR_OK)
- {
- m_bUseOverlays = ::atoi((char*) pBuffer->GetBuffer()) == 1;
- }
- HX_RELEASE(pBuffer);
- if (pPreferences->ReadPref("SpamUpdateOverlay", pBuffer) == HXR_OK)
- {
- m_bSpamUpdateOverlay = ::atoi((char*) pBuffer->GetBuffer()) == 1;
- }
- HX_RELEASE(pBuffer);
- if (pPreferences->ReadPref("FlipOverlay", pBuffer) == HXR_OK)
- {
- m_bFlipOverlay = ::atoi((char*) pBuffer->GetBuffer()) == 1;
- }
- HX_RELEASE(pBuffer);
- if (pPreferences->ReadPref("YUY2First", pBuffer) == HXR_OK)
- {
- if (::atoi((char*) pBuffer->GetBuffer()) == 1)
- {
- int list[] = {0,3,1,4};
- m_pyuvInputMngr->SetOutputPriority(CID_I420, list, 4);
- }
- }
- HX_RELEASE(pBuffer);
- if (pPreferences->ReadPref("LinkOverlays", pBuffer) == HXR_OK)
- {
- m_bAllowOverlayLinking = ::atoi((char*) pBuffer->GetBuffer()) == 1;
- }
- HX_RELEASE(pBuffer);
- m_pContext->QueryInterface(IID_IHXOverlayManager, (void**)&m_pOverlayManager);
- }
- HX_RELEASE(pPreferences);
- #ifdef _DEBUG
- const char* szKeyName = "Software\"HXVER_COMMUNITY"\Debug\SetHook";
- m_bAllocHook = HXDebugOptionEnabled(szKeyName);
- #endif
- }
- CBaseSurface::~CBaseSurface()
- {
- HX_DELETE(zm_pColorAcc);
- HX_DELETE(m_pyuvInputMngr);
- HX_DELETE(m_pHwMemObj);
- HX_RELEASE(m_pRootSurface);
- // CBaseSite::Destroy calls EndOptimizedBlt. We can't call
- // EndOptimizedBlt from the destructor since it calls DestroySurfaces
- // which calls _ReleaseSurface which is a pure virtual...the derived
- // class was already destoryed.
- HX_ASSERT(!m_pOptimizedFormat);
- HX_RELEASE(m_pContext);
- HX_FREE(m_pucLastImage);
- memset( &m_bmiLastImage, 0, sizeof( m_bmiLastImage ) );
- memset( &m_bmiLastBlt, 0, sizeof( m_bmiLastBlt ) );
- HX_FREE( m_paSrcRects );
- HX_FREE( m_paDestRects );
- //Clean up alphablending YUVA image list
- CHXMapPtrToPtr::Iterator i = m_YUVAImageList.Begin();
- while(i != m_YUVAImageList.End())
- {
- Image* pImage = (Image*)*i;
- HX_VECTOR_DELETE(pImage->pucImage);
- HX_DELETE(pImage);
- ++i;
- }
- m_YUVAImageList.RemoveAll();
- CHXSimpleList::Iterator j = m_imageBlocks.Begin();
- m_bImageBlocksGood = FALSE;
- while(j != m_imageBlocks.End())
- {
- ImageBlock* pBlock = (ImageBlock*)*j;
- Image* pImage = pBlock->pImage;
- HX_FREE(pImage->pucImage);
- HX_DELETE(pImage);
- HX_DELETE(pBlock);
- ++j;
- }
- m_imageBlocks.RemoveAll();
- if (m_pOverlayManager)
- {
- m_pOverlayManager->RemoveOverlayRequest((IHXOverlayResponse*)this);
- }
- HX_RELEASE(m_pOverlayManager);
- HXDestroyRegion(m_pAdditionalColorKey);
- m_pAdditionalColorKey = NULL;
- m_LinkedSites.RemoveAll();
- }
- void CBaseSurface::SetRootSurface( CBaseRootSurface* pSurface)
- {
- m_pRootSurface = pSurface;
- pSurface->AddRef();
- }
- void CBaseSurface::DestroySurfaces()
- {
- if (m_surfaceSize.cx || m_surfaceSize.cy)
- {
- CBaseRootSurface* pSurface = m_pSite->GetRootSurface();
- // XXXAH huh? Should this not be releasing it's own internal
- // surface? Again, minimal Changes.
- //XXXgfw not to mention that you can't call this from the dtor
- //of this class like is happening. Lets make sure that whatever
- //is needed happens when the root surface is deleted.
- if (pSurface)
- {
- _ReleaseSurface(pSurface);
- }
- ::memset(&m_surfaceSize, 0, sizeof(m_surfaceSize));
- }
- HX_DELETE(m_pHwMemObj);
- }
- void CBaseSurface::ReInitSurfaces()
- {
- if (m_pOptimizedFormat)
- {
- HXBitmapInfoHeader optFormat;
- memcpy(&optFormat, m_pOptimizedFormat, sizeof(HXBitmapInfoHeader)); /* Flawfinder: ignore */
- memset(&m_surfaceSize, 0, sizeof(HXxSize));
- BeginOptimizedBlt(&optFormat);
- }
- }
- BOOL CBaseSurface::ForceGDIMode(BOOL bForceGDI)
- {
- if(bForceGDI)
- {
- if (m_nBltMode == HX_OVERLAY_BLT)
- {
- m_nBltMode = HX_BASIC_BLT;
- #if defined(_UNIX) && !defined(_MAC_UNIX)
- _ReleaseSurface();
- #endif
- m_pSite->InternalForceRedraw();
- m_pSite->m_pTopLevelSite->ScheduleCallback(CLIP, 0 );
- m_nOldBltMode = HX_OVERLAY_BLT;
- }
- }
- else
- {
- if (m_nOldBltMode == HX_OVERLAY_BLT)
- {
- m_nBltMode = HX_OVERLAY_BLT;
- #if defined(_UNIX) && !defined(_MAC_UNIX)
- TryCreateOverlay(TRUE);
- #endif
- m_pSite->InternalForceRedraw();
- m_pSite->m_pTopLevelSite->ScheduleCallback(CLIP, 0 );
- FillColorKey();
- m_nOldBltMode = HX_BASIC_BLT;
- m_bOffBecauseofShinking = FALSE;
- }
- }
- return TRUE;
- }
- /************************************************************************
- * Method:
- * IUnknown::QueryInterface
- */
- STDMETHODIMP CBaseSurface::QueryInterface(REFIID riid, void** ppvObj)
- {
- if (IsEqualIID(riid, IID_IHXVideoSurface))
- {
- AddRef();
- *ppvObj = (IUnknown*)(IHXVideoSurface*)this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IUnknown))
- {
- AddRef();
- *ppvObj = (IUnknown*)(IHXSite*)this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXVideoControl))
- {
- AddRef();
- *ppvObj = (IUnknown*)(IHXVideoControl*)this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXOverlayResponse))
- {
- AddRef();
- *ppvObj = (IUnknown*)(IHXOverlayResponse*)this;
- return HXR_OK;
- }
- *ppvObj = NULL;
- return HXR_NOINTERFACE;
- }
- /************************************************************************
- * Method:
- * IUnknown::AddRef
- */
- STDMETHODIMP_(ULONG32) CBaseSurface::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- /************************************************************************
- * Method:
- * IUnknown::Release
- */
- STDMETHODIMP_(ULONG32) CBaseSurface::Release()
- {
- if (InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- delete this;
- return 0;
- }
- BOOL CBaseSurface::IsPixelTransparent(HXxPoint& point, INT32 nAlphaLevel )
- {
- BOOL retVal = FALSE;
- INT32 nCID = -1;
- INT32 nPitch = 0;
- HXxPoint origin = *(m_pSite->GetOrigin());
- //It can only be transparent if we are blt'ing ARGB32.
- nCID = GETBITMAPCOLOR(&m_bmiLastBlt);
- nPitch = GETBITMAPPITCH(&m_bmiLastImage);
- if( nCID == CID_ARGB32 )
- {
- if( m_pucLastImage )
- {
- UINT32* pPixel=NULL;
- if( nPitch<0 )
- {
- pPixel = (UINT32*)(m_pucLastImage+m_bmiLastImage.biSizeImage+nPitch);
- pPixel -= (point.y-origin.y)*m_bmiLastImage.biWidth - (point.x-origin.x);
- }
- else
- {
- pPixel = (UINT32*)m_pucLastImage;
- pPixel += (point.y-origin.y)*m_bmiLastImage.biWidth + (point.x-origin.x);
- }
- if( pPixel>=(UINT32*)m_pucLastImage &&
- pPixel<(UINT32*)(m_pucLastImage+m_bmiLastImage.biSizeImage))
- {
- int alpha = (*pPixel&0xff000000)>>24;
- if( alpha > nAlphaLevel )
- {
- retVal = TRUE;
- }
- }
- }
- }
- return retVal;
- }
- void CBaseSurface::_AlphaBlend( HXREGION* pRegionToBlend,
- UCHAR* pBottomImage,
- HXBitmapInfoHeader* pbmiBottomImageInfo,
- HXxPoint* pBottomPosition,
- UCHAR* pTopImage,
- HXBitmapInfoHeader* pbmiTopImageInfo,
- HXxPoint* pTopPosition
- )
- {
- #ifdef _USE_MMX
- static const BOOL bMMXAvailable = (checkMmxAvailablity()&CPU_HAS_MMX)?1:0;
- #else
- static const BOOL bMMXAvailable = FALSE;
- #endif
- #if defined(_DEBUG) && 0
- _DumpRegion(pRegionToBlend);
- #endif
- if( pBottomImage == NULL || pTopImage == NULL )
- {
- return;
- }
- //Make sure we only try to alpha blend ARGB32 content.
- int nCIDBottom = GETBITMAPCOLOR( pbmiBottomImageInfo );
- int nCIDTop = GETBITMAPCOLOR( pbmiTopImageInfo );
- int nBottomPitch = GETBITMAPPITCH( pbmiBottomImageInfo );
- int nTopPitch = GETBITMAPPITCH( pbmiTopImageInfo );
- if( nCIDTop != CID_ARGB32 || (nCIDBottom!=CID_ARGB32 && nCIDBottom!=CID_RGB32) )
- {
- HX_ASSERT( "Trying to alphablend unsupported type." );
- return;
- }
- BOOL bFade=FALSE;
- int completeness = 0;
- if( (m_pSite->m_fpTransitionEffect == Crossfade ||
- m_pSite->m_fpTransitionEffect == FadeToColor ||
- m_pSite->m_fpTransitionEffect == FadeFromColor )
- && m_pSite->m_nTransitionState!= 1000 )
- {
- completeness = m_pSite->m_nTransitionState;
- if((m_pSite->m_fpTransitionEffect != Crossfade &&
- m_pSite->m_bTransitionReversed) ||
- (m_pSite->m_fpTransitionEffect == Crossfade &&
- (!m_pSite->m_bTransitionTranIn ^
- m_pSite->m_bTransitionReversed)))
- {
- completeness = 1000 - completeness;
- }
- if( m_pSite->m_fpTransitionEffect== FadeFromColor)
- {
- completeness = 1000 - completeness;
- }
- //Map [0,1000] --> [0,1024] for fixed point fade math.
- completeness = (int)((float)completeness*1024.0/1000.0);
- bFade=TRUE;
- }
- if( !HXEmptyRegion(pRegionToBlend) )
- {
- int nBottomOffset = 0;
- int nTopOffset = 0;
- int nBotPosX = 0;
- int nBotPosY = 0;
- int nTopPosX = 0;
- int nTopPosY = 0;
- for(int i =0; i< pRegionToBlend->numRects; i++)
- {
- //We need to alpha blend each rect in the region.
- int topX=0, topY = 0;
- int botX=0, botY = 0;
- topX = pRegionToBlend->rects[i].x1;
- topY = pRegionToBlend->rects[i].y1;
- botX = pRegionToBlend->rects[i].x2;
- botY = pRegionToBlend->rects[i].y2;
- if( nBottomPitch<0 )
- nBottomOffset = -(pbmiBottomImageInfo->biWidth+(botX-topX));
- else
- nBottomOffset = pbmiBottomImageInfo->biWidth-(botX-topX);
- if( nTopPitch<0 )
- nTopOffset = -(pbmiTopImageInfo->biWidth+(botX-topX));
- else
- nTopOffset = pbmiTopImageInfo->biWidth-(botX-topX);
- nTopPosX = pTopPosition->x;
- nTopPosY = pTopPosition->y;
- nBotPosX = pBottomPosition->x;
- nBotPosY = pBottomPosition->y;
- //blend this rect.
- UINT32* pulBotPixel=NULL;
- UINT32* pulTopPixel=NULL;
- if( nBottomPitch<0 )
- {
- pulBotPixel = (UINT32*)(pBottomImage+pbmiBottomImageInfo->biSizeImage+nBottomPitch);
- pulBotPixel -= ((topY-nBotPosY)*pbmiBottomImageInfo->biWidth - (topX-nBotPosX));
- }
- else
- {
- pulBotPixel = (UINT32*)pBottomImage;
- pulBotPixel += ((topY-nBotPosY)*pbmiBottomImageInfo->biWidth + (topX-nBotPosX));
- }
- if( nTopPitch<0 )
- {
- pulTopPixel = (UINT32*)(pTopImage+pbmiTopImageInfo->biSizeImage+nTopPitch);
- pulTopPixel -= ((topY-nTopPosY)*pbmiTopImageInfo->biWidth - (topX-nTopPosX));
- }
- else
- {
- pulTopPixel = (UINT32*)pTopImage;
- pulTopPixel += ((topY-nTopPosY)*pbmiTopImageInfo->biWidth + (topX-nTopPosX));
- }
- int alpha = 0;
- int alphasave = 0;
- for( int y=topY ; y<=botY-1 ; y++ )
- {
- //XXXgfw this blows! We need a version of our MMX version
- //for doing fades as well.
- if( !bMMXAvailable || bFade )
- {
- for( int x=topX ; x<=botX-1 ; x++ )
- {
- //Blend it.
- //We *MUST* preserve the alpha channel in the top image.
- //This is needed for hit testing on transparent pixels.
- if( !bFade )
- {
- alpha = 255-((*pulTopPixel & 0xff000000)>>24);
- alphasave = *pulTopPixel & 0xff000000;
- alpha = alpha>128 ? alpha + 1 : alpha;
- }
- else
- {
- if( m_pSite->m_fpTransitionEffect == Crossfade )
- {
- //fixed point version of (comp/1000 * alpha )
- alpha = (*pulTopPixel & 0xff000000)>>24;
- if( GETBITMAPCOLOR(&m_bmiLastBlt) != CID_ARGB32 )
- alpha = 0x00;
- alpha = ((completeness*(255-alpha)+512))>>10;
- alphasave = (255-alpha)<<24;
- }
- else if( m_pSite->m_fpTransitionEffect == FadeToColor ||
- m_pSite->m_fpTransitionEffect == FadeFromColor)
- {
- //Not only affect alpha but also fading to color.
- alpha = (completeness*255+512)>>10;
- UINT32 fadeColor = (m_pSite->m_ulTransitionFadeColor&0x00ffffff)|(alpha<<24);
- int a1 = 255-((*pulTopPixel&0xff000000)>>24);
- *pulTopPixel =
- (((alpha*( (fadeColor&0x00ff0000)-(*pulTopPixel&0x00ff0000))+((*pulTopPixel&0x00ff0000)<<8))>>8)&0x00ff0000)|
- (((alpha*( (fadeColor&0x0000ff00)-(*pulTopPixel&0x0000ff00))+((*pulTopPixel&0x0000ff00)<<8))>>8)&0x0000ff00)|
- (((alpha*( (fadeColor&0x000000ff)-(*pulTopPixel&0x000000ff))+((*pulTopPixel&0x000000ff)<<8))>>8)&0x000000ff);
- if( alpha<a1 )
- alpha = a1;
- //Now make sure the rest of the blending uses the
- //new alpha channel from the FadeToColor state.
- alphasave = *pulTopPixel & ((255-alpha)<<24);
- //OK, we never alpha blend if a renderer outputs in plain old
- //RGB, only if they output in ARGB. Now, some renderer blt'ing in
- //RGB32 output random numbers, all zeros or all 0xFF in the alpha
- //channel. That can screw us up, so we will just set it here to not
- //have an alpha channel.
- if( GETBITMAPCOLOR(&m_bmiLastBlt) != CID_ARGB32 )
- alpha = 0xFF;
- }
- }
- *pulTopPixel =
- (((alpha*( (*pulTopPixel&0x00ff0000)-(*pulBotPixel&0x00ff0000))+((*pulBotPixel&0x00ff0000)<<8))>>8)&0x00ff0000)|
- (((alpha*( (*pulTopPixel&0x0000ff00)-(*pulBotPixel&0x0000ff00))+((*pulBotPixel&0x0000ff00)<<8))>>8)&0x0000ff00)|
- (((alpha*( (*pulTopPixel&0x000000ff)-(*pulBotPixel&0x000000ff))+((*pulBotPixel&0x000000ff)<<8))>>8)&0x000000ff);
- *pulTopPixel = *pulTopPixel|alphasave;
- //Next pixel
- pulBotPixel++;
- pulTopPixel++;
- }
- //Next row.
- pulBotPixel += nBottomOffset;
- pulTopPixel += nTopOffset;
- }
- else
- {
- #ifdef _USE_MMX
- //Use MMX version of blender
- AlphaBlendMMX( pulTopPixel,
- pulBotPixel,
- (botX-topX)
- );
- //Next row.
- pulBotPixel += nBottomOffset+(botX-topX);
- pulTopPixel += nTopOffset+(botX-topX);
- #endif
- }
- }
- #ifdef _USE_MMX
- //Do our emms instruction here so we don't have do it each
- //line. It is a expensive operation.
- #ifdef _WIN32
- __asm emms
- #elif defined(_LINUX)
- __asm__ __volatile__ ( "emms" );
- #endif
- #endif
- }
- }
- }
- #if 0
- void CBaseSurface::DrawCheckerBoard(UCHAR *pY, UCHAR *pU, UCHAR *pV,
- INT32 nYPitch, INT32 nUPitch, INT32 nVPitch,
- INT32 nImageWidth, INT32 nImageHeight)
- {
- const int COLS = 5;
- const int ROWS = 5;
- int Y[2] = {255, 0};
- int Cb = 128;
- int Cr = 128;
- int nColWidth = nImageWidth/COLS;
- int nRowWidth = nImageHeight/ROWS;
- IHXPreferences* pPreferences = NULL;
- IHXBuffer* pBuffer = NULL;
- if (HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences,(void**)&pPreferences))
- {
- if (pPreferences->ReadPref("VideoBoost\Y0", pBuffer) == HXR_OK)
- {
- Y[0] = ::atoi((char*) pBuffer->GetBuffer());
- HX_RELEASE(pBuffer);
- }
- if (pPreferences->ReadPref("VideoBoost\Y1", pBuffer) == HXR_OK)
- {
- Y[1] = ::atoi((char*) pBuffer->GetBuffer());
- HX_RELEASE(pBuffer);
- }
- if (pPreferences->ReadPref("VideoBoost\Cb", pBuffer) == HXR_OK)
- {
- Cb = ::atoi((char*) pBuffer->GetBuffer());
- HX_RELEASE(pBuffer);
- }
- if (pPreferences->ReadPref("VideoBoost\Cr", pBuffer) == HXR_OK)
- {
- Cr = ::atoi((char*) pBuffer->GetBuffer());
- HX_RELEASE(pBuffer);
- }
- HX_RELEASE(pPreferences);
- }
- UCHAR* pTemp = pY;
- for (int i=0; i<nImageHeight; i++)
- {
- // Draw a line of y for each column
- for (int j=0; j<COLS; j++)
- {
- memset(pTemp, Y[j%2], nColWidth);
- pTemp += nColWidth;
- }
- // Move y pointer to next row
- pTemp = pY + nYPitch*(i+1);
- // Swap y colors at each new row
- if (i%nRowWidth == 0)
- {
- int nTemp = Y[0];
- Y[0] = Y[1];
- Y[1] = nTemp;
- }
- }
- // Draw the Cr and Cb planes
- memset(pU, Cb, nImageWidth*nImageHeight/4);
- memset(pV, Cr, nImageWidth*nImageHeight/4);
- }
- #endif //0
- HXREGION* CBaseSurface::_DetermineBestRegion()
- {
- HXRECTANGLE rect;
- ImageBlock* pBlock = NULL;
- //Create a region from out image block list.
- HXREGION* pRetReg = HXCreateRegion();
- CHXSimpleList::Iterator j = m_imageBlocks.Begin();
- while(j != m_imageBlocks.End())
- {
- pBlock = (ImageBlock*)*j;
- rect.x = (short)pBlock->rect.left;
- rect.y = (short)pBlock->rect.top;
- rect.width = (short)(pBlock->rect.right-pBlock->rect.left);
- rect.height = (short)(pBlock->rect.bottom-pBlock->rect.top);
- HXUnionRectWithRegion( &rect, pRetReg, pRetReg );
- ++j;
- }
- return pRetReg;
- }
- void CBaseSurface::_RemoveYUVImageLists()
- {
- m_pSite->_TLSLock();
- CHXSimpleList::Iterator jj = m_imageBlocks.Begin();
- while(jj != m_imageBlocks.End())
- {
- ImageBlock* pXBlock = (ImageBlock*)*jj;
- Image* pXTmp = pXBlock->pImage;
- HX_FREE(pXTmp->pucImage);
- HX_DELETE(pXTmp);
- HX_DELETE(pXBlock);
- ++jj;
- }
- m_imageBlocks.RemoveAll();
- m_bImageBlocksGood = FALSE;
- CHXMapPtrToPtr::Iterator i = m_YUVAImageList.Begin();
- while(i != m_YUVAImageList.End())
- {
- Image* pImage = (Image*)*i;
- HX_DELETE(pImage->pucImage);
- HX_DELETE(pImage);
- ++i;
- }
- m_YUVAImageList.RemoveAll();
- m_pSite->_TLSUnlock();
- }
- CHXBaseSite* CBaseSurface::_SearchForYUV(CHXBaseSite* pTopSite)
- {
- HX_ASSERT( pTopSite );
- CHXBaseSite* pRetSite = NULL;
- CHXMapPtrToPtr::Iterator i;
- CBaseSurface* pSurf = pTopSite->m_pVideoSurface;
- if( pSurf )
- {
- int nCID2 = GETBITMAPCOLOR(&(pSurf->m_bmiLastBlt));
- if( IsYUV(nCID2) && pSurf->_IsDisplaySurfaceYuv())
- {
- pRetSite = pTopSite;
- }
- }
- if( !pRetSite )
- {
- //If the one passed in isn't any good, we need to go through its
- //lists of alphablend sites and so on.
- for( i=pTopSite->m_AlphaBlendSites.Begin() ;
- i!=pTopSite->m_AlphaBlendSites.End() && !pRetSite ;
- ++i)
- {
- CHXBaseSite* pSite = (CHXBaseSite*) i.get_key();
- pRetSite = _SearchForYUV( pSite );
- }
- }
- return pRetSite;
- }
- BOOL CBaseSurface::_BlendYUVRects( AlphaStruct* pList, int nCount, UINT32 ulDestFourCC)
- {
- BOOL bBlend = TRUE;
- //These rects in pList *must* match the ones in m_imageBlocks.
- //If they don't, time for recompute clip again.
- CHXSimpleList::Iterator g = m_imageBlocks.Begin();
- int i=0;
- while(g != m_imageBlocks.End() )
- {
- ImageBlock* pBlockOut = (ImageBlock*)*g;
- Image* pImageOut = pBlockOut->pImage;
- CHXBaseSite* pSite = pBlockOut->pSrcSite;
- Image* pImage = NULL;
- //Find ourselves in that site's YUV list.
- CHXBaseSite* pTmp = NULL;
- CHXMapPtrToPtr::Iterator j = pSite->m_pVideoSurface->m_YUVAImageList.Begin();
- while( j!=pSite->m_pVideoSurface->m_YUVAImageList.End() )
- {
- pTmp = (CHXBaseSite*)j.get_key();
- if( pTmp == m_pSite )
- {
- pImage = (Image*)*j;
- break;
- }
- ++j;
- }
- //HX_ASSERT( pImage );
- if( pImage)
- {
- //Blend pList[i] under AYUV and put in pTmp
- int nSizeX = pBlockOut->rect.right-pBlockOut->rect.left;
- int nSizeY = pBlockOut->rect.bottom-pBlockOut->rect.top;
- //int nPImageDataPitch = GETBITMAPPITCH(pList[i].lPitch);
- int nPImageOutPitch = GETBITMAPPITCH(&pImageOut->bmiImage);
- int nPImagePitch = GETBITMAPPITCH(&pImage->bmiImage);
- // These rects should match...might crash if they don't
- if( nSizeX > pImage->bmiImage.biWidth ||
- nSizeX > pImageOut->bmiImage.biWidth ||
- nSizeX > HXxRECT_WIDTH(pList[i].rcImageRect) )
- {
- bBlend = FALSE;
- }
- if( nSizeY > pImage->bmiImage.biHeight ||
- nSizeY > pImageOut->bmiImage.biHeight ||
- nSizeY > HXxRECT_HEIGHT(pList[i].rcImageRect) )
- {
- bBlend = FALSE;
- }
- if( pBlockOut->startX<0 || pBlockOut->startY<0 )
- {
- bBlend = FALSE;
- }
- if (bBlend)
- {
- HX_RESULT hr = zm_pColorAcc->I420andYUVA(
- pList[i].pBuffer,
- pList[i].ulImageWidth, pList[i].ulImageHeight,
- pList[i].lPitch,
- pList[i].rcImageRect.left,
- pList[i].rcImageRect.top,
- //pBlockOut->rect.left, pBlockOut->rect.top,
- pImage->pucImage,
- pImage->bmiImage.biWidth, pImage->bmiImage.biHeight,
- nPImagePitch,
- pBlockOut->startX, pBlockOut->startY,
- pImageOut->pucImage,
- pImageOut->bmiImage.biWidth, pImageOut->bmiImage.biHeight,
- nPImageOutPitch,
- 0, 0,
- nSizeX, nSizeY,
- MapFourCCtoCID(ulDestFourCC)
- );
- bBlend = hr==HXR_OK;
- //Now keep drawing up the line through all
- //overlapping ARGB images.
- pSite->m_pVideoSurface->_RecursiveYUVBlend( pImageOut,
- pBlockOut->rect,
- this, 0, 0);
- }
- i++;
- }
- ++g;
- }
- return bBlend;
- }
- BOOL CBaseSurface::_DoYUVRectsIntersect()
- {
- BOOL bBlend = FALSE;
- CHXMapPtrToPtr::Iterator i;
- while( i != m_pSite->m_AlphaBlendNotifiers.End() && !bBlend )
- {
- CHXBaseSite* pSite = (CHXBaseSite*)*i;
- if( pSite->m_AlphaBlendNotifiers.GetCount() )
- {
- bBlend = TRUE;
- }
- }
- return bBlend;
- }
- BOOL CBaseSurface::_RecursiveYUVBlend( Image* pImageOut,
- HXxRect boundingRect,
- CBaseSurface* pSurface,
- INT32 lXOffset,
- INT32 lYOffset)
- {
- BOOL bRetVal = FALSE;
- CHXMapPtrToPtr::Iterator i;
- if( m_pSite->m_AlphaBlendNotifiers.GetCount()==0 )
- {
- return bRetVal;
- }
- for( i=m_pSite->m_AlphaBlendNotifiers.Begin() ;
- i!=m_pSite->m_AlphaBlendNotifiers.End() ;
- ++i)
- {
- CHXBaseSite* pSite = (CHXBaseSite*)*i;
- HXREGION* pReg = NULL;
- //Find the region we need to blend with.
- CHXMapPtrToPtr::Iterator j = pSite->m_AlphaBlendSites.Begin();
- CHXBaseSite* pTmp = NULL;
- while( j != pSite->m_AlphaBlendSites.End() && pTmp != m_pSite )
- {
- pTmp = (CHXBaseSite*)j.get_key();
- if( pTmp == m_pSite )
- {
- pReg = (HXREGION*)*j;
- break;
- }
- ++j;
- }
- //Hmmmm, something is probably wrong here...
- if( HXEmptyRegion(pReg) )
- {
- HX_ASSERT("oops"==NULL);
- break;
- }
- //Find the YUVA buffer we need to blend against....
- Image* pImage = NULL;
- j = pSite->m_pVideoSurface->m_YUVAImageList.Begin();
- pTmp = NULL;
- while( j!=pSite->m_pVideoSurface->m_YUVAImageList.End() )
- {
- pTmp = (CHXBaseSite*)j.get_key();
- if( pTmp == m_pSite )
- {
- pImage = (Image*)*j;
- break;
- }
- ++j;
- }
- //Now blend with this image....
- if( pReg && pImage )
- {
- bRetVal = TRUE;
- //blend by extents, blt by rects, and save for Blt().
- for(int nIdx=0 ; nIdx<pReg->numRects ; nIdx++ )
- {
- HXxRect BlockOut;
- BlockOut.left = pReg->rects[nIdx].x1;
- BlockOut.top = pReg->rects[nIdx].y1;
- BlockOut.right = pReg->rects[nIdx].x2;
- BlockOut.bottom = pReg->rects[nIdx].y2;
- //Downscale all rects....
- double scaleX = 1;
- double scaleY = 1;
- scaleX = pSurface->m_scaleFactorX/pSite->m_pVideoSurface->m_scaleFactorX;
- scaleY = pSurface->m_scaleFactorY/pSite->m_pVideoSurface->m_scaleFactorY;
- //We must restrict this region to just the part that
- //overlaps the actuall YUV surface...
- int tlx = (int)((double)(m_pSite->m_topleft.x)/scaleX+.5);
- int tly = (int)((double)(m_pSite->m_topleft.y)/scaleY+.5);
- int xx = tlx - boundingRect.left;
- int yy = tly - boundingRect.top;
- if( (int)(BlockOut.left/scaleX+.5) < boundingRect.left )
- BlockOut.left = (INT32)(boundingRect.left*scaleX+.5);
- if( (int)(BlockOut.top/scaleY+.5) < boundingRect.top )
- BlockOut.top = (INT32)(boundingRect.top*scaleY+.5);
- if( (int)(BlockOut.right/scaleX+.5) > boundingRect.right )
- BlockOut.right = (INT32)(boundingRect.right*scaleX+.5);
- if( (int)(BlockOut.bottom/scaleY+.5) > boundingRect.bottom )
- BlockOut.bottom = (INT32)(boundingRect.bottom*scaleY+.5);
- BlockOut.left =
- (int)((double)(BlockOut.left-m_pSite->m_topleft.x)/scaleX+.5);
- BlockOut.top =
- (int)((double)(BlockOut.top-m_pSite->m_topleft.y)/scaleY+.5);
- BlockOut.right =
- (int)((double)(BlockOut.right-m_pSite->m_topleft.x)/scaleX+.5);
- BlockOut.bottom =
- (int)((double)(BlockOut.bottom-m_pSite->m_topleft.y)/scaleY+.5);
- // Ensure we start on even pixels (for yuv blending/conversion)
- BlockOut.left &= ~1;
- BlockOut.top &= ~1;
- if( (BlockOut.right-BlockOut.left) & 1 )
- {
- BlockOut.right &= ~1;
- }
- if( (BlockOut.bottom-BlockOut.top) & 1 )
- {
- BlockOut.bottom &= ~1;
- }
- int nSizeX = BlockOut.right-BlockOut.left;
- int nSizeY = BlockOut.bottom-BlockOut.top;
- //Take care of odd number lines and pels that are
- //not a multimple of four.
- int nSizeOutX = (nSizeX+3)&~3;
- int nSizeOutY = (nSizeY+1)&~1;
- int nPSiteRectLeft =
- (int)((double)(pReg->rects[nIdx].x1-pSite->m_topleft.x)/scaleX+.5);
- int nPSiteRectTop =
- (int)((double)(pReg->rects[nIdx].y1-pSite->m_topleft.y)/scaleY+.5);
- //Now blend into the new buffer.
- //Have to pass pointers to the actual pixel.
- int nPImagePitch = GETBITMAPPITCH(&pImage->bmiImage);
- int nPImageOutPitch = GETBITMAPPITCH(&pImageOut->bmiImage);
- int nPImageDataPitch = nPImageOutPitch;
- if( BlockOut.left+xx < 0)
- xx = -BlockOut.left;
- if( BlockOut.top+yy < 0)
- yy = -BlockOut.top;
- if( BlockOut.left+xx+nSizeX > pImageOut->bmiImage.biWidth )
- xx -= 1;
- if( BlockOut.top+yy+nSizeY > pImageOut->bmiImage.biHeight )
- yy -= 1;
- zm_pColorAcc->I420andYUVA(
- //Botton YUV image
- pImageOut->pucImage,
- pImageOut->bmiImage.biWidth, pImageOut->bmiImage.biHeight,
- nPImageDataPitch,
- BlockOut.left+xx, BlockOut.top+yy,
- //Top source YUVA Image
- pImage->pucImage,
- pImage->bmiImage.biWidth, pImage->bmiImage.biHeight,
- nPImagePitch,
- nPSiteRectLeft, nPSiteRectTop,
- //Output Image
- pImageOut->pucImage,
- pImageOut->bmiImage.biWidth, pImageOut->bmiImage.biHeight,
- nPImageOutPitch,
- BlockOut.left+xx, BlockOut.top+yy,
- nSizeX, nSizeY,
- // Output color format.
- CID_I420
- );
- //Now keep drawing up the line through all
- //overlapping ARGB images.
- pSite->m_pVideoSurface->_RecursiveYUVBlend( pImageOut,
- boundingRect,
- pSurface,
- lXOffset+xx,
- lYOffset+yy
- );
- }
- }
- }
- return bRetVal;
- }
- BOOL CBaseSurface::_SetUpBlendRects( HXBitmapInfoHeader* pBitmapInfo,
- UCHAR* pImageData)
- {
- BOOL bRetVal = FALSE;
- CHXMapPtrToPtr::Iterator i;
- //YUV optimized blending. We must blend 'up' the chain in this
- //case. For each alpha notifier we have we must grab that sites
- //YUVA buffer and blend it against ourselves.
- CHXSimpleList::Iterator jj = m_imageBlocks.Begin();
- HXDestroyRegion(m_pAdditionalColorKey);
- m_pAdditionalColorKey = HXCreateRegion();
- if( m_pSite->m_AlphaBlendNotifiers.GetCount()==0 )
- {
- m_bYUVBlending = FALSE;
- return bRetVal;
- }
- for( i=m_pSite->m_AlphaBlendNotifiers.Begin() ;
- i!=m_pSite->m_AlphaBlendNotifiers.End() ;
- ++i)
- {
- CHXBaseSite* pSite = (CHXBaseSite*)*i;
- HXREGION* pReg = NULL;
- //Find the region we need to blend with.
- CHXMapPtrToPtr::Iterator j = pSite->m_AlphaBlendSites.Begin();
- CHXBaseSite* pTmp = NULL;
- while( j != pSite->m_AlphaBlendSites.End() && pTmp != m_pSite )
- {
- pTmp = (CHXBaseSite*)j.get_key();
- if( pTmp == m_pSite )
- {
- pReg = (HXREGION*)*j;
- break;
- }
- ++j;
- }
- if( !pReg )
- {
- break;
- }
- //Find the YUVA buffer we need to blend against....
- Image* pImage = NULL;
- j = pSite->m_pVideoSurface->m_YUVAImageList.Begin();
- pTmp = NULL;
- while( j!=pSite->m_pVideoSurface->m_YUVAImageList.End() )
- {
- pTmp = (CHXBaseSite*)j.get_key();
- if( pTmp == m_pSite )
- {
- pImage = (Image*)*j;
- break;
- }
- ++j;
- }
- //Now blend with this image....
- if( pReg && pImage )
- {
- bRetVal = TRUE;
- //blend by extents, blt by rects, and save for Blt().
- for(int nIdx=0 ; nIdx<pReg->numRects ; nIdx++ )
- {
- //reuse the last imageblock....
- ImageBlock* pBlockOut = NULL;
- Image* pImageOut = NULL;
- if( jj == m_imageBlocks.End() )
- {
- //We ran out of image blocks.
- pBlockOut = new ImageBlock;
- pImageOut = new Image;
- memset( pImageOut, 0, sizeof(Image) );
- memset( pBlockOut, 0, sizeof(ImageBlock) );
- pBlockOut->pImage = pImageOut;
- m_imageBlocks.AddTail((void*)pBlockOut);
- jj = m_imageBlocks.End();
- }
- else
- {
- pBlockOut = (ImageBlock*)*jj;
- ++jj;
- pImageOut = pBlockOut->pImage;
- }
- pBlockOut->pSrcSite = pSite;
- //Downscale all rects....
- double scaleX = 1;
- double scaleY = 1;
- scaleX = m_scaleFactorX/pSite->m_pVideoSurface->m_scaleFactorX;
- scaleY = m_scaleFactorY/pSite->m_pVideoSurface->m_scaleFactorY;
- pBlockOut->rect.left =
- (int)((double)(pReg->rects[nIdx].x1-m_pSite->m_topleft.x)/scaleX+.5);
- pBlockOut->rect.top =
- (int)((double)(pReg->rects[nIdx].y1-m_pSite->m_topleft.y)/scaleY+.5);
- pBlockOut->rect.right =
- (int)((double)(pReg->rects[nIdx].x2-m_pSite->m_topleft.x)/scaleX+.5);
- pBlockOut->rect.bottom =
- (int)((double)(pReg->rects[nIdx].y2-m_pSite->m_topleft.y)/scaleY+.5);
- // Ensure we start on even pixels (for yuv blending/conversion)
- pBlockOut->rect.left &= ~1;
- pBlockOut->rect.top &= ~1;
- if( (pBlockOut->rect.right-pBlockOut->rect.left) & 1 )
- {
- pBlockOut->rect.right &= ~1;
- }
- if( (pBlockOut->rect.bottom-pBlockOut->rect.top) & 1 )
- {
- pBlockOut->rect.bottom &= ~1;
- }
- int nSizeX = pBlockOut->rect.right-pBlockOut->rect.left;
- int nSizeY = pBlockOut->rect.bottom-pBlockOut->rect.top;
- //Take care of odd number lines and pels that are
- //not a multimple of four.
- int nSizeOutX = (nSizeX+3)&~3;
- int nSizeOutY = (nSizeY+1)&~1;
- int nPSiteRectLeft =
- (int)((double)(pReg->rects[nIdx].x1-pSite->m_topleft.x)/scaleX+.5);
- int nPSiteRectTop =
- (int)((double)(pReg->rects[nIdx].y1-pSite->m_topleft.y)/scaleY+.5);
- pBlockOut->startX = nPSiteRectLeft;
- pBlockOut->startY = nPSiteRectTop;
- #ifdef _WIN32
- int nResult = MakeBitmap( (LPBITMAPINFO)&(pImageOut->bmiImage),
- sizeof(pImageOut->bmiImage),
- CID_I420,
- nSizeOutX,
- nSizeOutY,
- NULL,
- 0);
- #else
- int nResult = MakeBitmap( (HXBitmapInfo*)&(pImageOut->bmiImage),
- sizeof(pImageOut->bmiImage),
- CID_I420,
- nSizeOutX,
- nSizeOutY,
- NULL,
- 0);
- #endif
- //Alloc it.
- if( pImageOut->pucImage )
- {
- pImageOut->pucImage = (UCHAR*)
- realloc( pImageOut->pucImage,
- sizeof(UCHAR)*pImageOut->bmiImage.biSizeImage
- );
- }
- else
- {
- pImageOut->pucImage = (UCHAR*)
- malloc( sizeof(UCHAR)*pImageOut->bmiImage.biSizeImage);
- }
- if( pBitmapInfo && pImageData )
- {
- //Now blend into the new buffer.
- //Have to pass pointers to the actual pixel.
- int nPImageDataPitch = GETBITMAPPITCH(pBitmapInfo);
- int nPImagePitch = GETBITMAPPITCH(&pImage->bmiImage);
- int nPImageOutPitch = GETBITMAPPITCH(&pImageOut->bmiImage);
- //Sanity check for rapid SetSize calls.
- BOOL bDoIt =
- nSizeX <= pImage->bmiImage.biWidth &&
- nSizeY <= pImage->bmiImage.biHeight &&
- nSizeX <= pBitmapInfo->biWidth &&
- nSizeY <= pBitmapInfo->biHeight &&
- pBlockOut->rect.right <= pBitmapInfo->biWidth &&
- pBlockOut->rect.left <= pBitmapInfo->biWidth &&
- pBlockOut->rect.bottom <= pBitmapInfo->biHeight &&
- pBlockOut->rect.top <= pBitmapInfo->biHeight &&
- pBlockOut->rect.right >=0 &&
- pBlockOut->rect.left >=0 &&
- pBlockOut->rect.bottom >=0 &&
- pBlockOut->rect.top >=0 &&
- nPSiteRectLeft >= 0 &&
- nPSiteRectTop >= 0;
- if( bDoIt )
- {
- zm_pColorAcc->I420andYUVA(
- //Botton YUV image
- pImageData,
- pBitmapInfo->biWidth, pBitmapInfo->biHeight,
- nPImageDataPitch,
- pBlockOut->rect.left, pBlockOut->rect.top,
- //Top source YUVA Image
- pImage->pucImage,
- pImage->bmiImage.biWidth, pImage->bmiImage.biHeight,
- nPImagePitch,
- nPSiteRectLeft, nPSiteRectTop,
- //Output Image
- pImageOut->pucImage,
- pImageOut->bmiImage.biWidth, pImageOut->bmiImage.biHeight,
- nPImageOutPitch,
- 0, 0,
- nSizeX, nSizeY,
- // Output color format.
- CID_I420
- );
- //Now keep drawing up the line through all
- //overlapping ARGB images.
- pSite->m_pVideoSurface->_RecursiveYUVBlend( pImageOut,
- pBlockOut->rect,
- this, 0, 0);
- }
- }
- }
- if( m_imageBlocks.GetCount() )
- {
- //Save the last time we did a blend on this site. This is used to
- //help keep animated images blended over paused or stopped YUV
- //content because on YUV we blend from the bottom up.
- m_ulLastBlendTime = HX_GET_BETTERTICKCOUNT();
- }
- //Merge the region to m_Region for the YUV image.
- HXUnionRegion( m_pAdditionalColorKey, pReg, m_pAdditionalColorKey);
- //Remove the region from the overlapping ARGB surface
- //so it doesn't blt any more unless it changes.
- if( pSite && pSite->m_Region )
- HXSubtractRegion( pSite->m_Region, pReg, pSite->m_Region );
- }
- }
- return bRetVal;
- }
- BOOL CBaseSurface::_AlphaSetupAndBlending(HXBitmapInfoHeader* pBitmapInfo,
- UCHAR* pImageData,
- HXxRect& rSrcRect,
- HXxRect& rDestRect
- )
- {
- BOOL bDoAlpha = FALSE;
- CHXMapPtrToPtr::Iterator i;
- if (!pImageData)
- return bDoAlpha;
- //Are borders being drawn?
- INT32 nCID = GETBITMAPCOLOR(pBitmapInfo);
- HX_ASSERT( m_pSite );
- if( ( m_pucLastImage==NULL ||
- m_bmiLastImage.biWidth!=m_pSite->m_size.cx ||
- m_bmiLastImage.biHeight!=m_pSite->m_size.cy
- ) &&
- (( m_pSite->_BordersActive() ||
- m_pSite->_FadeTransitionActive() ||
- m_pSite->_TakesPartInAlphaChain()) ||
- (( m_pSite->m_AlphaBlendNotifiers.GetCount() != 0 ||
- m_pSite->m_AlphaBlendSites.GetCount() != 0)
- &&
- !(IsYUV(nCID) && _IsDisplaySurfaceYuv())
- )
- ))
- {
- memset( &m_bmiLastImage, 0, sizeof( m_bmiLastImage ) );
- //Alloc new frame data...
- #ifdef _WIN32
- int nResult = MakeBitmap( (LPBITMAPINFO)&m_bmiLastImage,
- sizeof(m_bmiLastImage),
- CID_ARGB32,
- m_pSite->m_size.cx,
- m_pSite->m_size.cy,
- NULL,
- 0);
- #else
- int nResult = MakeBitmap( (HXBitmapInfo*)&m_bmiLastImage,
- sizeof(m_bmiLastImage),
- CID_ARGB32,
- m_pSite->m_size.cx,
- m_pSite->m_size.cy,
- NULL,
- 0);
- #endif
- int size = sizeof(UCHAR)*m_bmiLastImage.biSizeImage;
- if( !m_pucLastImage )
- m_pucLastImage = (UCHAR*)malloc(size);
- else
- m_pucLastImage = (UCHAR*)realloc((void*)m_pucLastImage, size);
- HX_ASSERT( m_pucLastImage);
- }
- if( ( m_pucLastImage &&
- !m_pSite->_BordersActive() &&
- !m_pSite->_FadeTransitionActive() &&
- !m_pSite->_TakesPartInAlphaChain() &&
- (
- m_pSite->m_AlphaBlendNotifiers.GetCount() == 0 &&
- m_pSite->m_AlphaBlendSites.GetCount() == 0 ||
- (IsYUV(nCID) && _IsDisplaySurfaceYuv())
- )
- )
- )
- {
- //We don't need the allocated buffer. Delete it.
- HX_FREE(m_pucLastImage);
- }
- //Save the image data. This is where all the alpha blending
- //will take place.
- if( m_pucLastImage &&
- ( m_pSite->m_AlphaBlendNotifiers.GetCount()!=0 ||
- CID_ARGB32==nCID ||
- m_pSite->_BordersActive() || m_pSite->_FadeTransitionActive()
- )
- )
- {
- //Stretch or shrink, if nessecary, to make the the image
- //the same size as our site. If we dont' we will get
- //alpha blending artifacts...
- #ifdef _WINDOWS
- zm_pColorAcc->SetPlayer(m_pSite->m_pRootSurface->GetPlayer());
- #endif
- BOOL bConverter = zm_pColorAcc->CheckColorConverter(nCID, CID_ARGB32);
- m_pSite->ColorConverterRequest(nCID, CID_ARGB32, bConverter);
- if (bConverter )
- {
- int cx = m_bmiLastImage.biWidth;
- int cy = m_bmiLastImage.biHeight;
- int pitchIn = GETBITMAPPITCH( pBitmapInfo );
- int pitchOut = GETBITMAPPITCH( &m_bmiLastImage );
- zm_pColorAcc->ColorConvert(CID_ARGB32,
- m_pucLastImage,
- cx, cy,
- pitchOut,
- rDestRect.left, rDestRect.top,
- rDestRect.right-rDestRect.left,
- rDestRect.bottom-rDestRect.top,
- nCID,
- pImageData,
- pBitmapInfo->biWidth,
- pBitmapInfo->biHeight,
- pitchIn,
- rSrcRect.left, rSrcRect.top,
- rSrcRect.right-rSrcRect.left,
- rSrcRect.bottom-rSrcRect.top
- );
- }
- else
- {
- #ifdef _DEBUG
- fprintf( stderr, "Can't get color converter!n" );
- #endif
- }
- bDoAlpha=TRUE;
- //MOVE
- if( !IsYUV(nCID) )
- rSrcRect = rDestRect;
- }
- if(m_pSite->_BordersActive())
- {
- DrawTransitionBorders(&m_bmiLastImage,
- m_pSite->m_nTransitionBorderWidth,
- m_pSite->m_ulTransitionBorderColor,
- m_pSite->m_bTransitionBlendBorder
- );
- bDoAlpha = TRUE;
- }
- //Do we even care about alpha blening ourselves?
- if( ( nCID==CID_ARGB32 ||
- m_pSite->_BlendedBordersActive() ||
- m_pSite->_FadeTransitionActive() ) &&
- m_pSite->GetParentSite() )
- {
- //Alphablend against all of our regions.
- for( i=m_pSite->m_AlphaBlendSites.Begin() ;
- i!=m_pSite->m_AlphaBlendSites.End() ;
- ++i)
- {
- CHXBaseSite* pSite = (CHXBaseSite*) i.get_key();
- HXREGION* pRegion = (HXREGION*)*i;
- //We need to intersect this region with the rect that we
- //are actually blt'ing. SubRect support.
- HXxRect TmpRect = rDestRect;
- TmpRect.left += m_pSite->m_topleft.x;
- TmpRect.right += m_pSite->m_topleft.x;
- TmpRect.top += m_pSite->m_topleft.y;
- TmpRect.bottom += m_pSite->m_topleft.y;
- HXREGION* pInter = HXCreateRectRegion( TmpRect.left,
- TmpRect.top,
- TmpRect.right-TmpRect.left,
- TmpRect.bottom-TmpRect.top
- );
- HXIntersectRegion( pInter, pRegion, pInter );
- CBaseSurface* pTmp = pSite->m_pVideoSurface;
- if( pTmp->m_pucLastImage &&
- !(IsYUV(GETBITMAPCOLOR(&pTmp->m_bmiLastImage)) && pTmp->_IsDisplaySurfaceYuv())
- )
- {
- _AlphaBlend( pInter,
- pSite->m_pVideoSurface->m_pucLastImage,
- &(pSite->m_pVideoSurface->m_bmiLastImage),
- &(pSite->m_topleft),
- m_pucLastImage,
- &m_bmiLastImage,
- &(m_pSite->m_topleft)
- );
- }
- HXDestroyRegion( pInter );
- }
- bDoAlpha = TRUE;
- }
- //For optimized YUV alphablending. Create a YUVA image here, if
- //we have a YUV site that we blend against, and then down-scale
- //and color convert to YUVA. The YUV render's call to Blt() will
- //grab this and alphablend against us.
- //Clean up the old ones..
- i = m_YUVAImageList.Begin();
- while(i != m_YUVAImageList.End())
- {
- Image* pImage = (Image*)*i;
- HX_DELETE(pImage->pucImage);
- HX_DELETE(pImage);
- ++i;
- }
- m_YUVAImageList.RemoveAll();
- BOOL bHaveYUVBlender = FALSE;
- for( i=m_pSite->m_AlphaBlendSites.Begin() ;
- i!=m_pSite->m_AlphaBlendSites.End() ;
- ++i)
- {
- //CHXBaseSite* pSite = (CHXBaseSite*) i.get_key();
- CHXBaseSite* pSite = NULL;
- //Do a recursive search for YUV surfaces below us.
- CHXBaseSite* pSiteOrig = (CHXBaseSite*)i.get_key();
- pSite = _SearchForYUV( pSiteOrig );
- if( pSite && pSite->m_pVideoSurface )
- {
- int nCID2 = GETBITMAPCOLOR(&(pSite->m_pVideoSurface->m_bmiLastBlt));
- if( IsYUV(nCID2) && pSite->m_pVideoSurface->_IsDisplaySurfaceYuv())
- {
- //Create a YUVA buffer to hold the last frame.
- Image* pImage = new Image;
- memset( pImage, 0, sizeof( Image) );
- //Color convert to scaled YUVA into image struct.
- double scaleX = pSite->m_pVideoSurface->m_scaleFactorX/m_scaleFactorX;
- double scaleY = pSite->m_pVideoSurface->m_scaleFactorY/m_scaleFactorY;
- int nSizeX = (int)(((double)(m_bmiLastImage.biWidth))/scaleX+.5);
- int nSizeY = (int)(((double)(m_bmiLastImage.biHeight))/scaleY+.5);
- //Fix non mod quad sizes
- nSizeX = (nSizeX+3)&~3;
- nSizeY = (nSizeY+1)&~1;
- UCHAR* pucDownscaledRGB = NULL;
- HXBitmapInfoHeader bmiDownscaledRGB;
- memset( &bmiDownscaledRGB, 0, sizeof( bmiDownscaledRGB ) );
- #ifdef _WIN32
- MakeBitmap( (LPBITMAPINFO)&(pImage->bmiImage),
- sizeof(pImage->bmiImage),
- CID_YUVA,
- nSizeX,
- nSizeY,
- NULL,
- 0);
- MakeBitmap( (LPBITMAPINFO)&bmiDownscaledRGB,
- sizeof(bmiDownscaledRGB),
- CID_ARGB32,
- nSizeX,
- nSizeY,
- NULL,
- 0);
- #else
- MakeBitmap( (HXBitmapInfo*)&(pImage->bmiImage),
- sizeof(pImage->bmiImage),
- CID_YUVA,
- nSizeX,
- nSizeY,
- NULL,
- 0);
- MakeBitmap( (HXBitmapInfo*)&bmiDownscaledRGB,
- sizeof(bmiDownscaledRGB),
- CID_ARGB32,
- nSizeX,
- nSizeY,
- NULL,
- 0);
- #endif
- //Alloc it.
- pImage->pucImage = new UCHAR[pImage->bmiImage.biSizeImage];
- pucDownscaledRGB = new UCHAR[bmiDownscaledRGB.biSizeImage];
- //downscale the ARGB first....
- int ik = 0;
- UCHAR* pBits = pImageData;
- HXBitmapInfoHeader* pBIS = pBitmapInfo;
- if( IsYUV(nCID) && bDoAlpha )
- {
- pBits = m_pucLastImage;
- pBIS = &m_bmiLastImage;
- }
- BOOL bConverter = zm_pColorAcc->CheckColorConverter(CID_ARGB32, CID_ARGB32);
- pSite->ColorConverterRequest(CID_ARGB32, CID_ARGB32, bConverter);
- if (bConverter)
- {
- ik = zm_pColorAcc->ColorConvert(
- CID_ARGB32,
- pucDownscaledRGB,
- bmiDownscaledRGB.biWidth,
- bmiDownscaledRGB.biHeight,
- GETBITMAPPITCH(&bmiDownscaledRGB),
- 0,
- 0,
- nSizeX,
- nSizeY,
- CID_ARGB32,
- pBits,
- pBIS->biWidth,
- pBIS->biHeight,
- GETBITMAPPITCH(pBIS),
- 0,
- 0,
- pBitmapInfo->biWidth,
- pBitmapInfo->biHeight
- );
- }
- HX_ASSERT(ik==0);
- //We must apply any fade transitions here......
- BOOL bFade=FALSE;
- int completeness = 0;
- if( (m_pSite->m_fpTransitionEffect == Crossfade ||
- m_pSite->m_fpTransitionEffect == FadeToColor ||
- m_pSite->m_fpTransitionEffect == FadeFromColor )
- && m_pSite->m_nTransitionState!=1000 )
- {
- completeness = m_pSite->m_nTransitionState;
- if(m_pSite->m_bTransitionReversed)
- {
- completeness = 1000 - completeness;
- }
- if( m_pSite->m_fpTransitionEffect== FadeFromColor)
- {
- completeness = 1000 - completeness;
- }
- //Map [0,1000] --> [0,1024] for fixed point fade math.
- completeness = (int)((float)completeness*1024.0/1000.0);
- bFade=TRUE;
- if( bFade )
- {
- int alpha = 0;
- int alphasave = 0;
- ULONG32* pTmp = (ULONG32*)pucDownscaledRGB;
- for( UINT32 i=0 ; i< bmiDownscaledRGB.biSizeImage/4; i++, pTmp++ )
- {
- if( m_pSite->m_fpTransitionEffect == Crossfade )
- {
- //fixed point version of (comp/1000 * alpha )
- alpha = (*pTmp & 0xff000000)>>24;
- alpha = ((completeness*(255-alpha)+512))>>10;
- alphasave = (255-alpha)<<24;
- *pTmp = (*pTmp&0x00ffffff) | alphasave;
- }
- else if( m_pSite->m_fpTransitionEffect == FadeToColor ||
- m_pSite->m_fpTransitionEffect == FadeFromColor)
- {
- //Not only affect alpha but also fading to color.
- alpha = (completeness*255+512)>>10;
- UINT32 fadeColor = (m_pSite->m_ulTransitionFadeColor&0x00ffffff)|(alpha<<24);
- int pTmpAlpha = (*pTmp&0xff000000)>>24;
- int newalpha = (((0xff-alpha)*pTmpAlpha)>>8)<<24;
- *pTmp = newalpha |
- (((alpha*( (fadeColor&0x00ff0000)-(*pTmp&0x00ff0000))+((*pTmp&0x00ff0000)<<8))>>8)&0x00ff0000)|
- (((alpha*( (fadeColor&0x0000ff00)-(*pTmp&0x0000ff00))+((*pTmp&0x0000ff00)<<8))>>8)&0x0000ff00)|
- (((alpha*( (fadeColor&0x000000ff)-(*pTmp&0x000000ff))+((*pTmp&0x000000ff)<<8))>>8)&0x000000ff);
- }
- }
- }
- }
- //Color convert downscaled ARGB to YUVA
- bConverter = zm_pColorAcc->CheckColorConverter(CID_ARGB32, CID_YUVA);
- pSite->ColorConverterRequest(CID_ARGB32, CID_YUVA, bConverter);
- if( bConverter )
- ik = zm_pColorAcc->ColorConvert(
- CID_YUVA,
- pImage->pucImage,
- pImage->bmiImage.biWidth,
- pImage->bmiImage.biHeight,
- GETBITMAPPITCH(&pImage->bmiImage),
- 0,
- 0,
- nSizeX,
- nSizeY,
- CID_ARGB32,
- pucDownscaledRGB,
- bmiDownscaledRGB.biWidth,
- bmiDownscaledRGB.biHeight,
- GETBITMAPPITCH(&bmiDownscaledRGB),
- 0,
- 0,
- bmiDownscaledRGB.biWidth,
- bmiDownscaledRGB.biHeight
- );
- HX_ASSERT( ik==0 );
- HX_VECTOR_DELETE( pucDownscaledRGB );
- //Add into YUVA image map for this site.
- m_pSite->_TLSLock();
- m_YUVAImageList.SetAt( pSiteOrig, pImage );
- pSiteOrig->m_pVideoSurface->m_bYUVBlending = TRUE;
- m_pSite->_TLSUnlock();
- //Remove the region from the overlapping ARGB surface
- //so it doesn't blt any more unless it changes.
- HXREGION* pRegion = (HXREGION*)*i;
- //Wow, recursive YUV blending is not fun. If we are on
- //top of an ARGB image and it is on top of a YUV image
- //then we need subtract only that part of our region
- //that overlaps the ARGB image *AND* the YUV image
- //down below.
- HXREGION* hTemp = NULL;
- HXxSize size;
- HXxPoint* pPosition = NULL;
- pSite->GetSize( size );
- pPosition = pSite->GetOrigin();
- hTemp = pSite->Transition(pPosition->x, pPosition->y,
- pPosition->x + size.cx,
- pPosition->y + size.cy);
- HXIntersectRegion( hTemp, pRegion, hTemp );
- HXSubtractRegion( m_pSite->m_Region, hTemp, m_pSite->m_Region );
- HXDestroyRegion( hTemp );
- }
- }
- }
- //-----------------------------------------
- // YUV Blending Part 2
- //-----------------------------------------
- if( IsYUV(nCID)&& _IsDisplaySurfaceYuv() &&
- m_pSite->m_AlphaBlendNotifiers.GetCount() )
- {
- _SetUpBlendRects(pBitmapInfo, pImageData);
- }
- #if defined(_DEBUG) && 0
- if( IsYUV(nCID) && ((m_nBltMode==HX_OVERLAY_BLT&&!m_bOffBecauseofShinking) || m_pLinkedOverlay) )
- {
- char szBuff[256]; /* Flawfinder: ignore */
- sprintf( szBuff, "Left with m_imageBlocks: %dn", m_imageBlocks.GetCount() ); /* Flawfinder: ignore */
- _DumpString(szBuff);
- CHXSimpleList::Iterator jjj = m_imageBlocks.Begin();
- while(jjj != m_imageBlocks.End())
- {
- ImageBlock* pBlock = (ImageBlock*)*jjj;
- sprintf( szBuff, " Block: (%d, %d) -- (%d, %d)n", /* Flawfinder: ignore */
- pBlock->rect.left,
- pBlock->rect.top,
- pBlock->rect.right,
- pBlock->rect.bottom
- );
- _DumpString(szBuff);
- ++jjj;
- }
- }
- #endif
- return bDoAlpha;
- }
- void CBaseSurface::_ConstructRects(HXxRect& rSrcRectCopy,
- HXxRect& rDestRectCopy,
- BOOL bDoAlpha,
- int& nNumRects,
- HXxRect** paSrcRects,
- HXxRect** paDestRects,
- HXREGION* pAdditionalRegion
- )
- {
- HXxRect newDestRect;
- HXxRect origDestRect = rDestRectCopy;
- HXxPoint originOffset;
- memcpy(&originOffset,m_pSite->GetOrigin(),sizeof(HXxPoint)); /* Flawfinder: ignore */
- rDestRectCopy.left = (INT32) ((double) rDestRectCopy.left *
- m_fScrollBarZoom + 0.5);
- rDestRectCopy.right = (INT32) ((double) rDestRectCopy.right *
- m_fScrollBarZoom + 0.5);
- rDestRectCopy.top = (INT32) ((double) rDestRectCopy.top *
- m_fScrollBarZoom + 0.5);
- rDestRectCopy.bottom = (INT32) ((double) rDestRectCopy.bottom *
- m_fScrollBarZoom + 0.5);
- newDestRect.left = rDestRectCopy.left + originOffset.x;
- newDestRect.right = rDestRectCopy.right + originOffset.x;
- newDestRect.top = rDestRectCopy.top + originOffset.y;
- newDestRect.bottom = rDestRectCopy.bottom + originOffset.y;
- //If we are in full screen we have to offset our origin
- HXxPoint screenOffset = m_pSite->GetScreenOffset();
- //compute our scaling factor if we don't have access to the real
- //site scaling info via BltSubRects or IHXOriginalSize.
- if( !m_pSite->SiteScaleingInfoAvailable() || m_pSite->_TakesPartInAlphaChain() )
- {
- int nDestDX = rDestRectCopy.right - rDestRectCopy.left;
- int nSrcDX = rSrcRectCopy.right - rSrcRectCopy.left;
- int nDestDY = rDestRectCopy.bottom - rDestRectCopy.top;
- int nSrcDY = rSrcRectCopy.bottom - rSrcRectCopy.top;
- m_scaleFactorX = (double)nDestDX/(double)nSrcDX;
- m_scaleFactorY = (double)nDestDY/(double)nSrcDY;
- }
- //Scrolling support. XXXAH phew. We might want to go over this!
- IHXValues* pValues = NULL;
- ULONG32 bScroll = FALSE;
- HXxRect rect;
- int xSrcOffSet = 0;
- int ySrcOffSet = 0;
- if( m_pSite->QueryInterface( IID_IHXValues, (void**) &pValues )==HXR_OK )
- {
- pValues->GetPropertyULONG32("ScrollingSite", bScroll);
- if (bScroll)
- {
- m_pSite->GetWindowRect(&rect);
- HXxSize size;
- size.cx = rect.right - rect.left;
- size.cy = rect.bottom - rect.top;
- if (rDestRectCopy.right - rDestRectCopy.left > size.cx)
- {
- int xDelta = rDestRectCopy.right - rDestRectCopy.left - 1;
- m_pSite->SafeSetXSliderRange(xDelta);
- int xsliderPos = m_pSite->GetXSliderPos();
- int currentXDelta = m_pSite->GetXSliderRange();
- // find the thumb size
- HXxSize parentSize;
- m_pSite->m_pParentSite->GetSize(parentSize);
- xDelta = xDelta - parentSize.cx + m_pSite->GetSliderWidth();
- currentXDelta -=parentSize.cx;
- if(xsliderPos && currentXDelta)
- {
- double sliderPercentage = (double)xsliderPos / currentXDelta;
- if (sliderPercentage > 1.0) sliderPercentage = 1.0; // how does this happen?
- xSrcOffSet = (int) ((sliderPercentage * xDelta ) / m_scaleFactorX + 0.5) ;
- }
- //Modify the dest rect. This is a bit crazy.
- newDestRect.left = originOffset.x;
- newDestRect.right = originOffset.x + size.cx - m_pSite->GetSliderWidth();
- }
- if (rDestRectCopy.bottom - rDestRectCopy.top > size.cy)
- {
- int yDelta = rDestRectCopy.bottom - rDestRectCopy.top - 1;
- m_pSite->SafeSetYSliderRange(yDelta);
- int ysliderPos = m_pSite->GetYSliderPos();
- int currentYDelta = m_pSite->GetYSliderRange();
- // find the thumb size
- HXxSize parentSize;
- m_pSite->m_pParentSite->GetSize(parentSize);
- yDelta = yDelta - parentSize.cy + m_pSite->GetSliderHeight();
- currentYDelta -=parentSize.cy;
- if(ysliderPos && currentYDelta)
- {
- double sliderPercentage = (double)ysliderPos / currentYDelta;
- if (sliderPercentage > 1.0) sliderPercentage = 1.0; // how does this happen?
- ySrcOffSet = (int) ((sliderPercentage * yDelta ) / m_scaleFactorY + 0.5) ;
- }
- //Modify the dest rect. This is a bit crazy.
- newDestRect.top = originOffset.y;
- newDestRect.bottom = originOffset.y + size.cy - m_pSite->GetSliderHeight();
- }
- }
- HX_RELEASE(pValues);
- }
- rDestRectCopy = newDestRect;
- CBaseRootSurface* pRootSurface = m_pSite->GetRootSurface();
- HX_ASSERT( pRootSurface );
- if( !pRootSurface )
- return;
- nNumRects = 0;
- if( !m_pSite->m_Region )
- return;
- HXREGION* pWhole = HXCreateRegion();
- if( pAdditionalRegion)
- {
- HXUnionRegion( m_pSite->m_Region, pAdditionalRegion, pWhole );
- }
- else
- {
- HXUnionRegion( m_pSite->m_Region, pWhole, pWhole );
- }
- //Intersect incoming rectangle with our region.
- HXREGION* pDirty = HXCreateRectRegion( newDestRect.left,
- newDestRect.top,
- newDestRect.right-newDestRect.left,
- newDestRect.bottom-newDestRect.top
- );
- if( pDirty )
- {
- HXIntersectRegion( pDirty, pWhole, pWhole );
- HXDestroyRegion( pDirty );
- }
- HX_ASSERT( pWhole );
- //Set up the array of src and dest rect returns
- if ((_IsDisplaySurfaceYuv() && HX_OVERLAY_BLT == m_nBltMode) &&
- (m_bVideoSurface2 || !m_bYUVBlending) &&
- !m_pLinkedOverlay && !m_LinkedSites.GetCount()
- )
- nNumRects = 1;
- else
- nNumRects = pWhole->numRects;
- if( NULL == paSrcRects )
- *paSrcRects = (HXxRect*)malloc(sizeof(HXxRect)*nNumRects);
- else
- {
- #ifdef _DEBUG
- // We can not trace reallocs in pndebug...so use allocs when tracing
- if (m_bAllocHook)
- {
- free(*paSrcRects);
- *paSrcRects = (HXxRect*)malloc(sizeof(HXxRect)*nNumRects);
- }
- else
- *paSrcRects = (HXxRect*)realloc(*paSrcRects, sizeof(HXxRect)*nNumRects);
- #else
- *paSrcRects = (HXxRect*)realloc(*paSrcRects, sizeof(HXxRect)*nNumRects);
- #endif
- }
- if( NULL == paDestRects )
- *paDestRects = (HXxRect*)malloc(sizeof(HXxRect)*nNumRects);
- else
- {
- #ifdef _DEBUG
- // We can not trace reallocs in pndebug...so use allocs when tracing
- if (m_bAllocHook)
- {
- free(*paDestRects);
- *paDestRects = (HXxRect*)malloc(sizeof(HXxRect)*nNumRects);
- }
- else
- *paDestRects = (HXxRect*)realloc(*paDestRects, sizeof(HXxRect)*nNumRects);
- #else
- *paDestRects = (HXxRect*)realloc(*paDestRects, sizeof(HXxRect)*nNumRects);
- #endif
- }
- HX_ASSERT( paSrcRects );
- HX_ASSERT( paDestRects );
- for( int i=0 ; i<nNumRects ; i++)
- {
- HXxRect rgnRect;
- rgnRect.left = pWhole->rects[i].x1;
- rgnRect.top = pWhole->rects[i].y1;
- rgnRect.right = pWhole->rects[i].x2;
- rgnRect.bottom = pWhole->rects[i].y2;
- if( (_IsDisplaySurfaceYuv() && HX_OVERLAY_BLT == m_nBltMode) &&
- (m_bVideoSurface2 || !m_bYUVBlending ) &&
- !m_pLinkedOverlay && !m_LinkedSites.GetCount()
- )
- {
- //Merge our region with the list of regions in the image block
- //list....
- HXREGION* pRegTmp = HXCreateRegion();
- HXUnionRegion( pRegTmp, pWhole, pRegTmp );
- CHXMapPtrToPtr::Iterator i;
- for( i=m_pSite->m_AlphaBlendNotifiers.Begin() ;
- i!=m_pSite->m_AlphaBlendNotifiers.End() ;
- ++i)
- {
- CHXBaseSite* pSite = (CHXBaseSite*)*i;
- HXREGION* pReg = NULL;
- //Find the region we need to blend with.
- CHXMapPtrToPtr::Iterator j = pSite->m_AlphaBlendSites.Begin();
- CHXBaseSite* pTmp = NULL;
- while( j != pSite->m_AlphaBlendSites.End() && pTmp != m_pSite )
- {
- pTmp = (CHXBaseSite*)j.get_key();
- if( pTmp == m_pSite )
- {
- pReg = (HXREGION*)*j;
- HXUnionRegion( pRegTmp, pReg, pRegTmp );
- break;
- }
- ++j;
- }
- }
- //now just take the extents.....
- rgnRect.left = pRegTmp->extents.x1;
- rgnRect.top = pRegTmp->extents.y1;
- rgnRect.right = pRegTmp->extents.x2;
- rgnRect.bottom = pRegTmp->extents.y2;
- HXDestroyRegion( pRegTmp );
- }
- UINT32 whichMonitor;
- for (whichMonitor = 0; whichMonitor < pRootSurface->_GetNumberOfMonitors(); whichMonitor++)
- {