macsurf.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,064 行 · 第 1/3 页
CPP
1,064 行
// desktop area.
//
// But if we ensure that after the first successful blit we
// then rebuild the overlay, we never encounter the problem
// in the sequence of events. I need to revisit this!
// I created a stand-alone app that tried to repro the problem
// and I couldn't. I added window sizing code to CarbMini and
// couldn't repro the problem. I don't know if we're getting
// called when we're in a bad state in the middle of resizing
// or what.
//
// The whole notion of the image sequence technique is that when
// you know that your grafport is going to be consistent for awhile
// you can take advantage of that by using a sequence ID so each
// blit can rely on the parameters that remain consistent. What this
// workaround is doing is probably that something in the
// grafport has changed and we haven't detected it. What I don't
// know, but I should look into the sequence of events of first
// overlay rebuild, actual SizeWindow() command, second overlay blit
// that would slam to the desktop if we didn't kludge.
//
// Initially I thought that there were two possible kludges that
// would avoid the problem. One was to delay the Carbon Timer by
// a millisecond. The other was to use this "catch up" technique.
// It turns out that when I delayed the Carbon Timer, I was able
// to reproduce the problem by actively resizing the simple case,
// and most of the time using a more complex SMIL repro case.
// The "catch up" technique used to have a simple boolean for
// whether the kludge should kick in. Now it has a counter that's
// higher for more complicated SMIL presentations. I don't know
// what the magic number is, but using a boolean (i.e. "one")
// was too low in complex SMIL presentations, and the number of
// sites seems to work.
//
// xxxbobclark 20 Sep 02
static ULONG32 sbCatchUp = 0;
RgnHandle newMaskRgn = nil;
if (bOverlayRebuildingRequired)
{
CHXMacSite* pSite = (CHXMacSite*)zm_pOverlaySurface->m_pSite;
HXREGION* pEntireReg = HXCreateRegion();
HXUnionRegion(pEntireReg, pSite->m_Region, pEntireReg);
// xxxbobclark do this "manual clipping" thing to ensure that opaque
// parents are clipped out.
CHXMacSite* parentSite = (CHXMacSite*)pSite->GetParentSite();
while (parentSite)
{
HXIntersectRegion(pEntireReg, parentSite->m_RegionWithoutChildren, pEntireReg);
parentSite = (CHXMacSite*)parentSite->GetParentSite();
}
// xxxbobclark chunk of code snagged from CBaseSurface::FillColorKey.
// Necessary because our overlay clip region needs to be able to
// differentiate between clipped-out areas and alpha-blended areas.
CHXMapPtrToPtr::Iterator ii;
for( ii=pSite->m_AlphaBlendNotifiers.Begin() ;
ii!=pSite->m_AlphaBlendNotifiers.End() ;
++ii)
{
CHXBaseSite* pPotentialAlphaBlendedSite = (CHXBaseSite*)*ii;
HXREGION* pReg = NULL;
CHXMapPtrToPtr::Iterator j = pPotentialAlphaBlendedSite->m_AlphaBlendSites.Begin();
CHXBaseSite* pTmpSite = NULL;
while( j != pPotentialAlphaBlendedSite->m_AlphaBlendSites.End() && pTmpSite != pSite )
{
pTmpSite = (CHXBaseSite*)j.get_key();
if( pTmpSite == pSite )
{
pReg = (HXREGION*)*j;
HXUnionRegion( pEntireReg, pReg, pEntireReg );
break;
}
++j;
}
}
// xxxbobclark is this involved in a linked overlay?
// If so, we need to include the linked site's regions.
CHXSimpleList::Iterator linkedSitesIter;
for ( linkedSitesIter = m_LinkedSites.Begin();
linkedSitesIter != m_LinkedSites.End();
++linkedSitesIter)
{
CHXBaseSite* pSite = (CHXBaseSite*)(*linkedSitesIter);
HXUnionRegion(pEntireReg, pSite->m_Region, pEntireReg);
CHXMapPtrToPtr::Iterator ii;
for( ii=pSite->m_AlphaBlendNotifiers.Begin() ;
ii!=pSite->m_AlphaBlendNotifiers.End() ;
++ii)
{
CHXBaseSite* pPotentialAlphaBlendedSite = (CHXBaseSite*)*ii;
HXREGION* pReg = NULL;
CHXMapPtrToPtr::Iterator j = pPotentialAlphaBlendedSite->m_AlphaBlendSites.Begin();
CHXBaseSite* pTmpSite = NULL;
while( j != pPotentialAlphaBlendedSite->m_AlphaBlendSites.End() && pTmpSite != pSite )
{
pTmpSite = (CHXBaseSite*)j.get_key();
if( pTmpSite == pSite )
{
pReg = (HXREGION*)*j;
HXUnionRegion( pEntireReg, pReg, pEntireReg );
break;
}
++j;
}
}
}
newMaskRgn = CHXMacSite::_ConvertRegionToMacRegion(pEntireReg);
CHXMacSite* pMacSite = (CHXMacSite*)zm_pOverlaySurface->m_pSite;
// xxxbobclark should we shrink the region if we have scrollbars? I certainly think so!
if (pMacSite->m_hHScrollBar || pMacSite->m_hVScrollBar)
{
Rect rgnBounds;
::GetRegionBounds(newMaskRgn, &rgnBounds);
if (pMacSite->m_hHScrollBar)
{
rgnBounds.bottom -= 16;
}
if (pMacSite->m_hVScrollBar)
{
rgnBounds.right -= 16;
}
RgnHandle rectRgn = ::NewRgn();
if (rectRgn)
{
RectRgn(rectRgn, &rgnBounds);
::SectRgn(rectRgn, newMaskRgn, newMaskRgn);
::DisposeRgn(rectRgn);
}
}
OffsetRgn(newMaskRgn, -pEntireReg->extents.x1, -pEntireReg->extents.y1);
HXDestroyRegion(pEntireReg);
// xxxbobclark now intersect with current port's clip region and vis region.
RgnHandle trimRgn = ::NewRgn();
::GetPortVisibleRegion(::GetQDGlobalsThePort(), trimRgn);
::SectRgn(newMaskRgn, trimRgn, newMaskRgn);
if (1 /*pSite->m_bIsRealPlayerTLC*/)
{
::GetClip(trimRgn);
::SectRgn(newMaskRgn, trimRgn, newMaskRgn);
}
else
{
// xxxbobclark now intersect with PNxWindow's clip rect. Only if we're
// in an embedded player; this whole mechanism relies on browsers setting
// up clip regions before sending null events.
HXxWindow* pWindow = pSite->GetWindow();
if ((pWindow->x < pWindow->clipRect.left) || ((pWindow->x + pWindow->width) > pWindow->clipRect.right) ||
(pWindow->y < pWindow->clipRect.top) || ((pWindow->y + pWindow->height) > pWindow->clipRect.bottom))
{
bOverlayRebuildingRequired = TRUE;
}
::SetRectRgn(trimRgn, pWindow->clipRect.left, pWindow->clipRect.top, pWindow->clipRect.right, pWindow->clipRect.bottom);
// offset region
::OffsetRgn(trimRgn, -pWindow->x, -pWindow->y);
::SectRgn(newMaskRgn, trimRgn, newMaskRgn);
}
::DisposeRgn(trimRgn);
if ( (!bOverlayRebuildingRequired) && (!zm_OverlayMaskRgn || !::EqualRgn(newMaskRgn, zm_OverlayMaskRgn)))
{
bOverlayRebuildingRequired = TRUE;
}
}
if (bOverlayRebuildingRequired)
{
// reset the workaround counter
sbCatchUp = CHXMacSite::zm_ListOfMacSites.GetCount();
}
else if (sbCatchUp > 0)
{
bOverlayRebuildingRequired = TRUE;
sbCatchUp--;
}
if (bOverlayRebuildingRequired)
{
if (!IsMacInCooperativeThread())
{
// // xxxbobclark these shouldn't be here 'cause they can
// // force it out of overlay mode even as it's switching
// // to full-screen mode, for example.
// retVal = HXR_FAIL;
// goto exit;
}
else
{
sLastPoint = sP;
sLastSize = s;
sLastSrcSize = srcSize;
if (!newMaskRgn && zm_OverlayMaskRgn)
{
// CleanUpOverlay is going to clear out
// zm_OverlayMaskRgn. Since newMaskRgn is
// null and zm_OverlayMaskRgn exists we know
// that we're in the sbCatchUp workaround,
// and we need to remember the mask region
// around the CleanUpOverlay function call.
newMaskRgn = ::NewRgn();
::CopyRgn(zm_OverlayMaskRgn, newMaskRgn);
}
CleanUpOverlay();
if (newMaskRgn)
{
HX_ASSERT(!zm_OverlayMaskRgn);
zm_OverlayMaskRgn = newMaskRgn;
newMaskRgn = NULL;
}
HX_ASSERT(zm_OverlayMaskRgn);
ConstructOverlay(sP.h, sP.v, s.cx, s.cy, srcSize.cx, srcSize.cy, zm_OverlayMaskRgn);
}
}
if (newMaskRgn)
{
::DisposeRgn(newMaskRgn);
}
}
else
{
retVal = HXR_FAIL;
goto exit;
}
if (zm_pOverlayBuf == nil || zm_nOverlayRowBytes == 0)
{
retVal = HXR_FAIL;
goto exit;
}
*ppSurPtr = (UCHAR*)zm_pOverlayBuf;
*pnSurfPitch = zm_nOverlayRowBytes;
exit:
HX_ASSERT(savePort != nil);
::SetPort(savePort);
return retVal;
}
/************************************************************************
* Method:
* CMacSurface::_UnlockInternalSurface
*/
HX_RESULT
CMacSurface::_UnlockInternalSurface(UCHAR* pSurfPtr)
{
// On RagePro, the ImageCodecDrawBand call does not NEED to
// be made. Since it uses a key color, whatever's drawn
// to the overlay magically shows up through the key color.
// The Rage128 ignores key color, though, and requires a
// call to ImageCodecDrawBand to update the overlay. This
// blasts through everything, obeying the mask region.
// So if the mask region may be outdated we will not make
// the call to ImageCodecDrawBand.
if (gDumbCursorRedrawNeeded)
{
gDumbCursorRedrawNeeded = FALSE;
}
BOOL bDoOverlayBlit = TRUE;
CHXMacSite* pSite = (CHXMacSite*)zm_pOverlaySurface->m_pSite;
HXxPoint offset;
offset.x = 0;
offset.y = 0;
pSite->GetMacContentAreaOffset(offset);
SetOriginAndMaintainClipRgn(-offset.x, -offset.y);
if (bDoOverlayBlit)
{
if (zm_SequenceID)
{
short err = DecompressSequenceFrameWhen(
zm_SequenceID,
(Ptr)zm_pOverlayBuf, zm_nOverlayBufferSize,
0, // flags
nil,
nil,
nil);
}
}
SetOriginAndMaintainClipRgn(0,0);
return HXR_OK;
}
/************************************************************************
* Method:
* CMacSurface::_SetupDCObjects
*/
void
CMacSurface::_SetupDCObjects(HXxDC hxxDC, void** phOldBrush, void** phOldPen)
{
}
/************************************************************************
* Method:
* CMacSurface::_FillRectangle
*/
void
CMacSurface::_FillRectangle(HXxDC hxxDC, UINT32 left, UINT32 top, UINT32 right, UINT32 bottom)
{
if (zm_bOverlayRequiresKeyColor)
{
GrafPtr savePort;
::GetPort(&savePort);
HX_ASSERT(m_pSite);
HXxWindow* pWindow = m_pSite->GetWindow();
HX_ASSERT(pWindow && pWindow->window);
::SetPort((GrafPtr)pWindow->window);
Rect r;
r.left = left + pWindow->x;
r.top = top + pWindow->y;
r.right = right + pWindow->x;
r.bottom = bottom + pWindow->y;
// xxxbobclark for ATI RagePro cards, they use a key
// color, and the key color is hardcoded. I don't
// know, but this may change if we stumble across a
// card that supports key colors that aren't hard-
// coded -- or that use a DIFFERENT hard-coded one.
static RGBColor keyColor = {0x0000, 0x1000, 0x0000};
RGBColor hold;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?