macsurf.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:33k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 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
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (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.
- *
- * 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 ***** */
- /****************************************************************************
- *
- * $Id: macsurf.cpp,v 1.5 2003/05/27 20:05:54 bobclark Exp $
- *
- */
- #include "hxcom.h"
- #include "hxtypes.h"
- #include "hxwintyp.h"
- #include "hxmap.h"
- #include "hxslist.h"
- #include "ihxpckts.h"
- #include "hxwin.h"
- #include "hxengin.h"
- #include "hxsite2.h"
- #include "chxxtype.h"
- #include "hxvctrl.h"
- #include "hxvsurf.h"
- #include "hxcodec.h"
- #include "surface.h"
- #include "vidosurf.h"
- #include "sitetext.h"
- #include "chxpckts.h"
- #include "hxevent.h"
- #include "bltpatch.h"
- #ifndef _MAC_UNIX
- #include "hxmm.h"
- #endif
- #include "hxprefs.h"
- #include "hxevent.h"
- #include "hxthread.h"
- #include "platform/mac/macsurf.h"
- #include "platform/mac/macroot.h"
- #include "baseroot.h"
- #include "basesite.h"
- #include "platform/mac/macsite.h"
- #include "platform/mac/hx_moreprocesses.h"
- #ifndef _MACINTOSH
- #ifndef _MAC_UNIX
- #error This is the Macintosh platform specific implementation.
- #endif
- #endif
- #include "fauxcodec.h"
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- // xxxbobclark the notion is that if it's going to be
- // a 1X blit, we'll use the faux codec method if there
- // are 76800 pixels or more. If it's stretched in any
- // way, it's a smaller threshhold: since using the faux
- // codec method gives us stretching for free, that's a
- // much larger gain than normal 1x color conversions.
- // 76800 is used because that's 320x240.
- #define USE_FAUX_CODEC_1X_THRESHHOLD 76800
- #define USE_FAUX_CODEC_STRETCHED_THRESHHOLD 38400
- CHXSimpleList CMacSurface::zm_SurfaceList;
- void* CMacSurface::zm_pOverlayBuf = nil;
- long CMacSurface::zm_nOverlayRowBytes = 0;
- RgnHandle CMacSurface::zm_OverlayMaskRgn = NULL;
- BOOL CMacSurface::zm_bSafeToOverlayBlit = FALSE;
- CMacSurface* CMacSurface::zm_pOverlaySurface = nil;
- BOOL CMacSurface::zm_bOverlayRequiresKeyColor = FALSE;
- BOOL CMacSurface::zm_bOverlayRequiresDrawBand = FALSE;
- BOOL CMacSurface::zm_bUsingFauxCodec = TRUE;
- ImageSequence CMacSurface::zm_SequenceID = NULL;
- ImageDescriptionHandle CMacSurface::zm_ImageDescriptionHandle = NULL;
- long CMacSurface::zm_nOverlayBufferSize = 0;
- void* CMacSurface::zm_pHoldOverlayBuf = NULL;
- long CMacSurface::zm_nHoldOverlayBufSize = 0;
- #pragma options align=mac68k
- struct BogusCodecDecompressParams
- {
- CodecDecompressParams decompParams;
- long dummy[100];
- // XXXbobclark
- // sheesh. OK, when ImageCodecNewImageBufferMemory() is
- // called, memory can be corrupted. The address of a
- // CodecDecompressParams is passed to the call, and it
- // pokes memory past the end of the 210-byte structure.
- // I've reproduced this in ATI's YUVSDK as well. ATI
- // insists that it can't be their fault and they don't
- // think it's Apple's fault either. Whatever. Memory
- // is still getting corrupted. By including a bunch of
- // dummy space, that corruption happens in a harmless
- // place. Instead of, like it was doing for weeks, in
- // some random variable that would cause strange behavior
- // and/or crashes at ill-defined times.
- };
- typedef BogusCodecDecompressParams BogusCodecDecompressParams;
- ComponentInstanceRecord *gYUV = nil;
- BogusCodecDecompressParams bogusDecompParams;
- ImageSubCodecDecompressRecord drp;
- #pragma options align=reset
- /************************************************************************
- * Method:
- * CMacSurface constructor
- */
- CMacSurface::CMacSurface(IUnknown* pContext, CHXBaseSite* pSite)
- : CBaseSurface(pContext, pSite)
- {
- zm_SurfaceList.AddTail(this);
- }
- /************************************************************************
- * Method:
- * CHXMacSite destructor
- */
- CMacSurface::~CMacSurface()
- {
-
- if (CMacSurface::zm_pOverlaySurface == this)
- {
- CleanUpOverlay();
- CMacSurface::zm_pOverlaySurface = nil;
-
- ::DisposePtr((Ptr)zm_pHoldOverlayBuf);
- zm_pHoldOverlayBuf = NULL;
- zm_nHoldOverlayBufSize = 0;
- }
-
- LISTPOSITION pos = zm_SurfaceList.Find(this);
- zm_SurfaceList.RemoveAt(pos);
- }
- /************************************************************************
- * Method:
- * CMacSurface::_ReleaseSurface
- */
- void
- CMacSurface::_ReleaseSurface(CBaseRootSurface* pSurface)
- {
- }
- /************************************************************************
- * Method:
- * CMacSurface::_DrawBlack
- */
- void
- CMacSurface::_DrawBlack(void* pWindow)
- {
- }
- /************************************************************************
- * Method:
- * CMacSurface::__Sleep
- */
- void
- CMacSurface::__Sleep(int milliseconds)
- {
- }
- /************************************************************************
- * Method:
- * CMacSurface::_BltToPrimary
- */
- HX_RESULT
- CMacSurface::_BltToPrimary(REF(HXxRect) rDestRect, REF(HXxRect) rSrcRect)
- {
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * CMacSurface::_CreateBuffer
- */
- void
- CMacSurface::_CreateBuffer()
- {
- }
- /************************************************************************
- * Method:
- * CMacSurface::_GetCaps
- */
- HX_RESULT
- CMacSurface::_GetCaps(UINT32* pfSurfaceCaps)
- {
- // see if it supports stuff like overlay.
-
- if (pfSurfaceCaps)
- {
- *pfSurfaceCaps = 0;
- if (_OverlayAvailable())
- {
- *pfSurfaceCaps |= HX_OVERLAY;
- }
- }
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * CMacSurface::_CreateOverlay
- */
- HX_RESULT
- CMacSurface::_CreateOverlay(BOOL bOverlay, int cid, int x, int y)
- {
- HX_ASSERT(_OverlayAvailable());
- if (CMacSurface::zm_pOverlaySurface == nil)
- {
- CMacSurface::zm_pOverlaySurface = this;
- // we don't want to construct the overlay here, uhhh, because
- // we don't yet know WHERE it's gonna be. We'll construct it
- // the first time we need it.
- }
- else if (CMacSurface::zm_pOverlaySurface == this)
- {
- CleanUpOverlay();
- }
- if (CMacSurface::zm_pOverlaySurface == this)
- {
- m_nBltMode = HX_OVERLAY_BLT;
- m_surfaceSize.cx = x;
- m_surfaceSize.cy = y;
- }
- return HXR_OK;
- }
- // xxxbobclark weird, it looks like the first time the color convertor is used,
- // it slams something weird into the mouse pointer. I'm just doing a quick
- // (unnoticeable really) cursor switch to obscure the garbagey stuff.
- BOOL gDumbCursorRedrawNeeded = FALSE;
- /************************************************************************
- * Method:
- * CMacSurface::_LockInternalSurface
- */
- HX_RESULT
- CMacSurface::_LockInternalSurface(UCHAR** ppSurPtr, LONG32* pnSurfPitch, REF(HXxSize) srcSize)
- {
- HX_RESULT retVal = HXR_OK;
-
- GrafPtr savePort = nil;
-
- if (IsMacInCooperativeThread())
- {
- ::GetPort(&savePort);
- HXxWindow* pWindow = m_pSite->m_pTopLevelSite->GetWindow();
- HX_ASSERT(pWindow);
-
- if (!pWindow)
- {
- return HXR_FAIL;
- }
-
- HX_ASSERT(pWindow->window);
- ::SetPort( GetWindowPort( (WindowPtr)pWindow->window ) );
- }
-
- if (zm_pOverlayBuf == nil)
- {
- CMacSurface::zm_pOverlaySurface = this;
- m_nSurfaceCID = CID_YUY2;
- }
- if (CMacSurface::zm_pOverlaySurface == this)
- {
- static Point sLastPoint = {-1,-1};
- static HXxSize sLastSize = {0,0};
- static HXxSize sLastSrcSize = {0,0};
- static Point sP = {-1,-1};
- HX_ASSERT(m_pSite);
-
- HXxSize s;
-
- m_pSite->GetSize(s);
-
- sP.h = 0;
- sP.v = 0;
- BOOL bOverlayRebuildingRequired = FALSE;
-
- if (sLastPoint.h != sP.h || sLastPoint.v != sP.v) bOverlayRebuildingRequired = TRUE;
- if (sLastSize.cx != s.cx || sLastSize.cy != s.cy) bOverlayRebuildingRequired = TRUE;
- if (sLastSrcSize.cx != srcSize.cx || sLastSrcSize.cy != srcSize.cy) bOverlayRebuildingRequired = TRUE;
- if (zm_pOverlayBuf == nil) bOverlayRebuildingRequired = TRUE;
-
- // xxxbobclark this catch up workaround is necessary because with some
- // parameters of the overlay while the TLC is resizing, a glitch can
- // happen and blits start happening outside of our window onto the
- // desktop.
- // If (a) the overlay extends beyond the window or (b) a mask region
- // is used when creating the overlay, then when the TLC resizes the
- // following sequence of events takes place:
- // 1. overlay (sequenceID) created.
- // 2. blit happens (DecompressSequenceFrameWhen) successfully
- // 3. All future blits fail with slamming the frame onto the
- // 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;
-
- if (!zm_bUsingFauxCodec)
- {
- if (!zm_bSafeToOverlayBlit) bOverlayRebuildingRequired = TRUE;
- }
-
- RgnHandle newMaskRgn = nil;
-
- if (!bOverlayRebuildingRequired)
- {
- // see if the vis region has changed. If it has, then tear down and rebuild the
- // overlay. This code is very similar to code in CMacRootSurface; that remembers
- // a member variable called m_LastVisRgn. Here we use bogusDecompParams.
- // decompParams.maskRegion, since that needs to be constructed at the time of
- // creating the overlay anyway.
-
- if (!zm_bUsingFauxCodec)
- {
- RgnHandle rgn = BuildOverlayVisRgn();
- if (!::EqualRgn(rgn, bogusDecompParams.decompParams.maskRegion))
- {
- bOverlayRebuildingRequired = TRUE;
- }
- ::DisposeRgn(rgn);
- }
- }
- else
- {
- 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);
- 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 && zm_bUsingFauxCodec)
- {
- // 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;
-
- if (!zm_bUsingFauxCodec)
- {
- if (!zm_bSafeToOverlayBlit)
- {
- bDoOverlayBlit = FALSE;
- }
- }
-
- if (zm_bUsingFauxCodec)
- {
- if (bDoOverlayBlit)
- {
- if (zm_SequenceID)
- {
- short err = DecompressSequenceFrameWhen(
- zm_SequenceID,
- (Ptr)zm_pOverlayBuf, zm_nOverlayBufferSize,
- 0, // flags
- nil,
- nil,
- nil);
- }
- }
- }
- else
- {
- if (bDoOverlayBlit && zm_bOverlayRequiresDrawBand)
- {
- ImageCodecDrawBand(gYUV, &drp);
- }
- }
-
- 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;
- ::GetForeColor(&hold);
- ::RGBForeColor(&keyColor);
-
- PaintRect(&r);
-
- ::RGBForeColor(&hold);
- ::SetPort(savePort);
- }
- }
- /************************************************************************
- * Method:
- * CMacSurface::_RestoreDCObjects
- */
- void
- CMacSurface::_RestoreDCObjects(HXxDC hxxDC, void* hOldBrush, void* hOldPen)
- {
- }
- /************************************************************************
- * Method:
- * CMacSurface::_GetCompositeionSurfacePNxDC
- */
- void
- CMacSurface::_GetCompositionSurfaceHXxDC(HXxDC* hdc)
- {
- }
- /************************************************************************
- * Method:
- * CMacSurface::_ReleaseCompositionSurfaceHXxDC
- */
- void
- CMacSurface::_ReleaseCompositionSurfaceHXxDC(HXxDC hdc)
- {
- }
- /************************************************************************
- * Method:
- * CMacSurface::_InsureColorMatch
- */
- INT32
- CMacSurface::_InsureColorMatch(INT32 InColor)
- {
- return InColor; // XXXbobclark
- }
- /************************************************************************
- * Method:
- * CMacSurface::_SetColorKey
- */
- void
- CMacSurface::_SetColorKey(INT32 nColorSpaceLowValue, INT32 nColorSpaceHighValue)
- {
- }
- /************************************************************************
- * Method:
- * CMacSurface::_UpdateOverlay
- */
- void
- CMacSurface::_UpdateOverlay(HXxRect* src, HXxRect* dest, INT32 inFlags)
- {
- }
- /************************************************************************
- * Method:
- * CMacSurface::_IsSurfaceVisible
- */
- BOOL
- CMacSurface::_IsSurfaceVisible()
- {
- return TRUE;
- }
- /************************************************************************
- * Method:
- * CMacSurface::_ReleaseSurface
- */
- void
- CMacSurface::_ReleaseSurface()
- {
- if (CMacSurface::zm_pOverlaySurface == this)
- {
- CleanUpOverlay();
- CMacSurface::zm_pOverlaySurface = nil;
- }
- }
- /************************************************************************
- * Method:
- * CMacSurface::_GetDC
- */
- HXxDC
- CMacSurface::_GetDC(HXxWindow* pWindow)
- {
- return NULL; // XXXbobclark gotta figure out what to return, duh
- }
- /************************************************************************
- * Method:
- * CMacSurface::_ReleaseDC
- */
- void
- CMacSurface::_ReleaseDC(HXxWindow* pWindow, HXxDC pdc)
- {
- }
- /************************************************************************
- * Method:
- * CMacSurface::_GetWindowDeviceCords
- */
- void
- CMacSurface::_GetWindowDeviceCords(HXxRect* rect)
- {
- static Point sLastCords = {0,0};
-
- sLastCords.h = 0;
- sLastCords.v = 0;
- ::LocalToGlobal(&sLastCords);
- rect->left = sLastCords.h;
- rect->top = sLastCords.v;
- }
- /************************************************************************
- * Method:
- * CMacSurface::_OverlayAvailable
- */
- BOOL
- CMacSurface::_OverlayAvailable()
- {
- if (!m_bUseOverlays) return FALSE;
-
- static BOOL zbWeveExploredOverlayCapabilities = FALSE;
- static BOOL zbOverlayAvailable = FALSE;
-
- if (!zbWeveExploredOverlayCapabilities)
- {
- zbWeveExploredOverlayCapabilities = TRUE;
-
- // start out by assuming that we can use ATI's
- // deferred-task-safe overlay code. We'll fall
- // back on Apple's mechanism if necessary.
- zm_bUsingFauxCodec = FALSE;
-
- if (!zbOverlayAvailable)
- {
- zm_bUsingFauxCodec = TRUE;
- zbOverlayAvailable = TRUE;
- FauxCodecRegister();
- }
- }
- return zbOverlayAvailable;
- }
- /************************************************************************
- * Method:
- * CMacSurface::_AllowsOverlayShrinking
- */
- BOOL
- CMacSurface::_AllowsOverlayShrinking()
- {
- return TRUE;
- }
- // some of the following is from ATI's YUVSDK.
- // Some ATI specific definitions
- #define kATIYUVComponentType 'imdc'
- #define kATIYUVComponentSubType 'yuvs'
- #define kATIYUVComponentManufacturer 'ATI '
- #pragma options align=mac68k
- //QT 3.x stuff : begin -- Anita
- struct YUVSdecompressRecord {
- short width; // width (in pixels) of a row
- long numStrips; // number of strips to draw
- long srcDataIncrement; // increment for srcData between strips
- long baseAddrIncrement; // increment for baseAddr between strips
- struct Globals *glob; // pointer to our globals
- };
- typedef struct YUVSdecompressRecord YUVSdecompressRecord;
- // Added for VAU
- struct BDCTextureDRP
- {
- ByteCount dataSize; // Number of bytes in compressed data
- SInt16 width; // Width in pixels
- SInt16 height; // Height in lines
- };
- typedef struct BDCTextureDRP BDCTextureDRP;
- pascal void MymemoryGoneProc(Ptr memoryBlock, void *refcon);
- ICMMemoryDisposedUPP theMemoryProc = nil;
- pascal void MymemoryGoneProc(Ptr memoryBlock, void *refcon)
- {
- // do nothing.
- }
- /* static */
- void CMacSurface::ConstructOverlay(long screenCoorX, long screenCoorY, long screenWidth, long screenHeight, long sourceWidth, long sourceHeight,
- RgnHandle maskRgn)
- {
- // xxxbobclark if we're running native on OS X, then the screen coordinates are in
- // local coordinates. If we're NOT running native on OS X then the screen coordinates
- // are in global coordinates. The reason for this is that we have a chance to talk
- // directly to the hardware on OS 9 and below, which requires global coordinates. On
- // OS X by using local coordinates we ensure that we can accurately hit a moving window.
- // (If we try to use global coords on OS X, it's possible that the window is moved
- // between when the global coords are figured out and we construct the overlay.
- if (zm_bUsingFauxCodec)
- {
- // xxxbobclark if we're using the faux codec, then as of this
- // writing, on OS 9, we can not blit at interrupt time. This
- // presents us with a dilemma. For one thing, a lot of work
- // went into interrupt-time blitting. And in many cases it is
- // a vast improvement. Worse, it is hard to tell at compile
- // time or even runtime whether ITB sans overlay is better than
- // overlay sans ITB. We can make some runtime assumptions,
- // like at what destination size the dropped frames due to
- // yuv-rgb conversions equal the dropped frames due to not
- // having ITB active... but even that can shift due to conditions
- // like, say, an email program checking mail in the background.
- // I think I'm going to make some assumptions that the user
- // won't be doing all kinds of things in the background.
- // Note that this will suddenly become a non-issue once we
- // move to OS X (because we can ITB without any concerns)
- // or Apple helps us use the Image Compression Manager ("faux
- // codec") mechanism at deferred time.
- // xxxbobclark ... although the settings preferences could
- // dictate that we use overlay; if for example ITB is turned
- // off but overlay is turned on in the preferences, we should
- // always do overlay...
-
- // OK we need to set up zm_pOverlayBuf, zm_nOverlayRowBytes, and zm_bSafeToOverlayBlit
- // Oh, and zm_nOverlayBufferSize.
- // first let's find our component.
- ComponentDescription cd;
- Component c = NULL;
- Component foundComponent = NULL;
- cd.componentType = 'imdc';
- cd.componentSubType = 'yuvs';
- cd.componentManufacturer = 'RNWK';
-
- // xxxbobclark if we pass in zero for the componentManufacturer
- // instead of 'RNWK', it will still grab an actual codec. And if
- // we haven't done FauxCodecRegister() it still grabs one, at least
- // on Jaguar. This is very interesting. It may be possible that on
- // Jaguar and later, the faux codec trick is redundant. I'm reluctant
- // to remove it now, but it could bear looking into.
-
- cd.componentFlags = 0;
- cd.componentFlagsMask = 0;
-
- while ((c = FindNextComponent(c, &cd)) != 0)
- {
- HX_ASSERT(foundComponent == NULL);
- foundComponent = c;
- break;
- // xxxbobclark this is a short-term kludge. The real problem is that every time pnvideo
- // is loaded and a surface used for overlay, it calls FauxCodecRegister. pnvideo's terminate
- // routine should call some corresponding FauxCodecUnregister, but since it doesn't yet,
- // a pile of faux codecs gets added to every time pnvideo is unloaded/reloaded. This doesn't
- // typically happen in the player but in the embedded player it can happen frequently.
- // By breaking out of this loop now we only use (apparently) the most recently installed
- // version, which fortunately is the one still in loaded pnvideo code.
-
- // The fix should be straightforward: unregister the faux codec from the dtor which tears down
- // the overlay or worst case from the shlb's terminate routine. xxxbobclark 6/12/02 this should
- // be one of the first things fixed when I have a chance.
- }
- // this chunk o' code assumes local coordinates.
- Point local;
- local.h = screenCoorX;
- local.v = screenCoorY;
- if (!IsRunningNativeOnMacOSX())
- {
- GlobalToLocal(&local);
- }
- Rect srcR, dstR;
- srcR.left = 0;
- srcR.top = 0;
- srcR.right = sourceWidth;
- srcR.bottom = sourceHeight;
- dstR.left = local.h;
- dstR.top = local.v;
- dstR.right = local.h + screenWidth;
- dstR.bottom = local.v + screenHeight;
- zm_ImageDescriptionHandle = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription));
- (**zm_ImageDescriptionHandle).idSize = sizeof(ImageDescription);
- (**zm_ImageDescriptionHandle).cType = 'yuvs';
- (**zm_ImageDescriptionHandle).width = srcR.right-srcR.left;
- (**zm_ImageDescriptionHandle).height = srcR.bottom-srcR.top;
- (**zm_ImageDescriptionHandle).hRes = 72L << 16;
- (**zm_ImageDescriptionHandle).vRes = 72L << 16;
- (**zm_ImageDescriptionHandle).frameCount = 1;
- (**zm_ImageDescriptionHandle).clutID = -1;
- MatrixRecord matrix;
- RectMatrix(&matrix, &srcR, &dstR);
- OSErr err = DecompressSequenceBeginS(
- &zm_SequenceID,
- zm_ImageDescriptionHandle,
- nil, 0, // data pointer and data length
- nil, // use the current port
- nil, // go to screen
- &srcR,
- &matrix,
- ditherCopy,
- maskRgn,
- codecFlagUseImageBuffer,
- codecNormalQuality,
- foundComponent);
- zm_nOverlayRowBytes = (srcR.right-srcR.left) * 2;
- zm_nOverlayBufferSize = (srcR.bottom - srcR.top) * zm_nOverlayRowBytes;
-
- if ((zm_nOverlayBufferSize == zm_nHoldOverlayBufSize) && zm_pHoldOverlayBuf)
- {
- zm_pOverlayBuf = zm_pHoldOverlayBuf;
- }
- else
- {
- zm_pOverlayBuf = ::NewPtr(zm_nOverlayBufferSize);
- if (zm_pHoldOverlayBuf)
- {
- ::DisposePtr((Ptr)zm_pHoldOverlayBuf);
- }
- zm_pHoldOverlayBuf = zm_pOverlayBuf;
- zm_nHoldOverlayBufSize = zm_nOverlayBufferSize;
- }
- }
- else
- {
- // ATI-specific overlay implementation
- HX_ASSERT( NULL == "no non-faux-codec mechanism!");
- }
- }
- void CMacSurface::CleanUpOverlay()
- {
- if (zm_bUsingFauxCodec)
- {
- if (zm_SequenceID)
- {
- CDSequenceEnd(zm_SequenceID);
- }
- zm_SequenceID = NULL;
-
- if (zm_pOverlayBuf)
- {
- // xxxbobclark don't dispose this; hold on to it in
- // zm_pHoldOverlayBuf in case we create another overlay
- // of the same size. Saves allocation and initialization
- // time, plus sidesteps some alpha-blending bugs.
- // DisposePtr((Ptr)zm_pOverlayBuf);
- }
- zm_pOverlayBuf = nil;
-
- zm_nOverlayRowBytes = 0;
- zm_nOverlayBufferSize = 0;
-
- if (zm_OverlayMaskRgn)
- {
- ::DisposeRgn(zm_OverlayMaskRgn);
- }
- zm_OverlayMaskRgn = NULL;
- if (zm_ImageDescriptionHandle)
- {
- ::DisposeHandle((Handle)zm_ImageDescriptionHandle);
- }
- zm_ImageDescriptionHandle = NULL;
- }
- else
- {
- // ATI-specific overlay implementation
- }
- }
- RgnHandle
- CMacSurface::BuildOverlayVisRgn()
- {
- // This assumes that the decomp params
- // rectangle has already been set up!
- //
- // It also assumes that the port has
- // been set to the correct window!
- //
- // The caller must dispose of the
- // region!
-
- HX_ASSERT(IsMacInCooperativeThread());
-
- RgnHandle rgn = ::NewRgn();
-
- ::RectRgn(rgn, &bogusDecompParams.decompParams.dstRect);
- return rgn;
- }
- #pragma options align=reset