macsurf.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:33k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /****************************************************************************
  36.  * 
  37.  *  $Id: macsurf.cpp,v 1.5 2003/05/27 20:05:54 bobclark Exp $
  38.  *  
  39.  */
  40. #include "hxcom.h"
  41. #include "hxtypes.h"
  42. #include "hxwintyp.h"
  43. #include "hxmap.h"
  44. #include "hxslist.h"
  45. #include "ihxpckts.h"
  46. #include "hxwin.h"
  47. #include "hxengin.h"
  48. #include "hxsite2.h"
  49. #include "chxxtype.h"
  50. #include "hxvctrl.h"
  51. #include "hxvsurf.h"
  52. #include "hxcodec.h"
  53. #include "surface.h"
  54. #include "vidosurf.h"
  55. #include "sitetext.h"
  56. #include "chxpckts.h"
  57. #include "hxevent.h"
  58. #include "bltpatch.h"
  59. #ifndef _MAC_UNIX
  60. #include "hxmm.h"
  61. #endif
  62. #include "hxprefs.h"
  63. #include "hxevent.h"
  64. #include "hxthread.h"
  65. #include "platform/mac/macsurf.h"
  66. #include "platform/mac/macroot.h"
  67. #include "baseroot.h"
  68. #include "basesite.h"
  69. #include "platform/mac/macsite.h"
  70. #include "platform/mac/hx_moreprocesses.h"
  71. #ifndef _MACINTOSH
  72. #ifndef _MAC_UNIX
  73. #error This is the Macintosh platform specific implementation.
  74. #endif
  75. #endif
  76. #include "fauxcodec.h"
  77. #include "hxheap.h"
  78. #ifdef _DEBUG
  79. #undef HX_THIS_FILE
  80. static const char HX_THIS_FILE[] = __FILE__;
  81. #endif
  82. // xxxbobclark the notion is that if it's going to be
  83. // a 1X blit, we'll use the faux codec method if there
  84. // are 76800 pixels or more. If it's stretched in any
  85. // way, it's a smaller threshhold: since using the faux
  86. // codec method gives us stretching for free, that's a
  87. // much larger gain than normal 1x color conversions.
  88. // 76800 is used because that's 320x240.
  89. #define USE_FAUX_CODEC_1X_THRESHHOLD 76800
  90. #define USE_FAUX_CODEC_STRETCHED_THRESHHOLD 38400
  91. CHXSimpleList CMacSurface::zm_SurfaceList;
  92. void* CMacSurface::zm_pOverlayBuf = nil;
  93. long CMacSurface::zm_nOverlayRowBytes = 0;
  94. RgnHandle CMacSurface::zm_OverlayMaskRgn = NULL;
  95. BOOL CMacSurface::zm_bSafeToOverlayBlit = FALSE;
  96. CMacSurface* CMacSurface::zm_pOverlaySurface = nil;
  97. BOOL CMacSurface::zm_bOverlayRequiresKeyColor = FALSE;
  98. BOOL CMacSurface::zm_bOverlayRequiresDrawBand = FALSE;
  99. BOOL CMacSurface::zm_bUsingFauxCodec = TRUE;
  100. ImageSequence CMacSurface::zm_SequenceID = NULL;
  101. ImageDescriptionHandle CMacSurface::zm_ImageDescriptionHandle = NULL;
  102. long CMacSurface::zm_nOverlayBufferSize = 0;
  103. void* CMacSurface::zm_pHoldOverlayBuf = NULL;
  104. long CMacSurface::zm_nHoldOverlayBufSize = 0;
  105. #pragma options align=mac68k
  106. struct BogusCodecDecompressParams
  107. {
  108.     CodecDecompressParams decompParams;
  109.     long dummy[100];
  110.     // XXXbobclark
  111.     // sheesh. OK, when ImageCodecNewImageBufferMemory() is
  112.     // called, memory can be corrupted. The address of a
  113.     // CodecDecompressParams is passed to the call, and it
  114.     // pokes memory past the end of the 210-byte structure.
  115.     // I've reproduced this in ATI's YUVSDK as well. ATI
  116.     // insists that it can't be their fault and they don't
  117.     // think it's Apple's fault either. Whatever. Memory
  118.     // is still getting corrupted. By including a bunch of
  119.     // dummy space, that corruption happens in a harmless
  120.     // place. Instead of, like it was doing for weeks, in
  121.     // some random variable that would cause strange behavior
  122.     // and/or crashes at ill-defined times.
  123. };
  124. typedef BogusCodecDecompressParams BogusCodecDecompressParams;
  125. ComponentInstanceRecord *gYUV = nil;
  126. BogusCodecDecompressParams bogusDecompParams;
  127. ImageSubCodecDecompressRecord drp;
  128. #pragma options align=reset
  129. /************************************************************************
  130.  *  Method:
  131.  *    CMacSurface constructor
  132.  */
  133. CMacSurface::CMacSurface(IUnknown* pContext, CHXBaseSite* pSite)
  134.  : CBaseSurface(pContext, pSite)
  135. {
  136.     zm_SurfaceList.AddTail(this);
  137. }
  138. /************************************************************************
  139.  *  Method:
  140.  *    CHXMacSite destructor
  141.  */
  142. CMacSurface::~CMacSurface()
  143. {
  144.     
  145.     if (CMacSurface::zm_pOverlaySurface == this)
  146.     {
  147. CleanUpOverlay();
  148. CMacSurface::zm_pOverlaySurface = nil;
  149. ::DisposePtr((Ptr)zm_pHoldOverlayBuf);
  150. zm_pHoldOverlayBuf = NULL;
  151. zm_nHoldOverlayBufSize = 0;
  152.     }
  153.     
  154.     LISTPOSITION pos = zm_SurfaceList.Find(this);
  155.     zm_SurfaceList.RemoveAt(pos);
  156. }
  157. /************************************************************************
  158.  *  Method:
  159.  *    CMacSurface::_ReleaseSurface
  160.  */
  161. void
  162. CMacSurface::_ReleaseSurface(CBaseRootSurface* pSurface)
  163. {
  164. }
  165. /************************************************************************
  166.  *  Method:
  167.  *    CMacSurface::_DrawBlack
  168.  */
  169. void
  170. CMacSurface::_DrawBlack(void* pWindow)
  171. {
  172. }
  173. /************************************************************************
  174.  *  Method:
  175.  *    CMacSurface::__Sleep
  176.  */
  177. void
  178. CMacSurface::__Sleep(int milliseconds)
  179. {
  180. }
  181. /************************************************************************
  182.  *  Method:
  183.  *    CMacSurface::_BltToPrimary
  184.  */
  185. HX_RESULT
  186. CMacSurface::_BltToPrimary(REF(HXxRect) rDestRect, REF(HXxRect) rSrcRect)
  187. {
  188.     return HXR_OK;
  189. }
  190. /************************************************************************
  191.  *  Method:
  192.  *    CMacSurface::_CreateBuffer
  193.  */
  194. void
  195. CMacSurface::_CreateBuffer()
  196. {
  197. }
  198. /************************************************************************
  199.  *  Method:
  200.  *    CMacSurface::_GetCaps
  201.  */
  202. HX_RESULT
  203. CMacSurface::_GetCaps(UINT32* pfSurfaceCaps)
  204. {
  205.     // see if it supports stuff like overlay.
  206.     
  207.     if (pfSurfaceCaps)
  208.     {
  209. *pfSurfaceCaps = 0;
  210. if (_OverlayAvailable())
  211. {
  212.     *pfSurfaceCaps |= HX_OVERLAY;
  213. }
  214.     }
  215.     return HXR_OK;
  216. }
  217. /************************************************************************
  218.  *  Method:
  219.  *    CMacSurface::_CreateOverlay
  220.  */
  221. HX_RESULT
  222. CMacSurface::_CreateOverlay(BOOL bOverlay, int cid, int x, int y)
  223. {
  224.     HX_ASSERT(_OverlayAvailable());
  225.     if (CMacSurface::zm_pOverlaySurface == nil)
  226.     {
  227. CMacSurface::zm_pOverlaySurface = this;
  228. // we don't want to construct the overlay here, uhhh, because
  229. // we don't yet know WHERE it's gonna be. We'll construct it
  230. // the first time we need it.
  231.     }
  232.     else if (CMacSurface::zm_pOverlaySurface == this)
  233.     {
  234. CleanUpOverlay();
  235.     }
  236.     if (CMacSurface::zm_pOverlaySurface == this)
  237.     {
  238. m_nBltMode = HX_OVERLAY_BLT;
  239. m_surfaceSize.cx = x;
  240. m_surfaceSize.cy = y;
  241.     }
  242.     return HXR_OK;
  243. }
  244. // xxxbobclark weird, it looks like the first time the color convertor is used,
  245. // it slams something weird into the mouse pointer. I'm just doing a quick
  246. // (unnoticeable really) cursor switch to obscure the garbagey stuff.
  247. BOOL gDumbCursorRedrawNeeded = FALSE;
  248. /************************************************************************
  249.  *  Method:
  250.  *    CMacSurface::_LockInternalSurface
  251.  */
  252. HX_RESULT
  253. CMacSurface::_LockInternalSurface(UCHAR** ppSurPtr, LONG32* pnSurfPitch, REF(HXxSize) srcSize)
  254. {
  255.     HX_RESULT retVal = HXR_OK;
  256.     
  257.     GrafPtr savePort = nil;
  258.     
  259.     if (IsMacInCooperativeThread())
  260.     {
  261. ::GetPort(&savePort);
  262. HXxWindow* pWindow = m_pSite->m_pTopLevelSite->GetWindow();
  263. HX_ASSERT(pWindow);
  264. if (!pWindow)
  265. {
  266.     return HXR_FAIL;
  267. }
  268. HX_ASSERT(pWindow->window);
  269. ::SetPort( GetWindowPort( (WindowPtr)pWindow->window ) );
  270.     }
  271.     
  272.     if (zm_pOverlayBuf == nil)
  273.     {
  274. CMacSurface::zm_pOverlaySurface = this;
  275. m_nSurfaceCID = CID_YUY2;
  276.     }
  277.     if (CMacSurface::zm_pOverlaySurface == this)
  278.     {
  279. static Point sLastPoint = {-1,-1};
  280. static HXxSize sLastSize = {0,0};
  281. static HXxSize sLastSrcSize = {0,0};
  282. static Point sP = {-1,-1};
  283. HX_ASSERT(m_pSite);
  284. HXxSize s;
  285. m_pSite->GetSize(s);
  286. sP.h = 0;
  287. sP.v = 0;
  288. BOOL bOverlayRebuildingRequired = FALSE;
  289. if (sLastPoint.h != sP.h || sLastPoint.v != sP.v) bOverlayRebuildingRequired = TRUE;
  290. if (sLastSize.cx != s.cx || sLastSize.cy != s.cy) bOverlayRebuildingRequired = TRUE;
  291. if (sLastSrcSize.cx != srcSize.cx || sLastSrcSize.cy != srcSize.cy) bOverlayRebuildingRequired = TRUE;
  292. if (zm_pOverlayBuf == nil) bOverlayRebuildingRequired = TRUE;
  293. // xxxbobclark this catch up workaround is necessary because with some
  294. // parameters of the overlay while the TLC is resizing, a glitch can
  295. // happen and blits start happening outside of our window onto the
  296. // desktop.
  297. // If (a) the overlay extends beyond the window or (b) a mask region
  298. // is used when creating the overlay, then when the TLC resizes the
  299. // following sequence of events takes place:
  300. // 1. overlay (sequenceID) created.
  301. // 2. blit happens (DecompressSequenceFrameWhen) successfully
  302. // 3. All future blits fail with slamming the frame onto the
  303. //    desktop area.
  304. //
  305. // But if we ensure that after the first successful blit we
  306. // then rebuild the overlay, we never encounter the problem
  307. // in the sequence of events. I need to revisit this!
  308. // I created a stand-alone app that tried to repro the problem
  309. // and I couldn't. I added window sizing code to CarbMini and
  310. // couldn't repro the problem. I don't know if we're getting
  311. // called when we're in a bad state in the middle of resizing
  312. // or what.
  313. //
  314. // The whole notion of the image sequence technique is that when
  315. // you know that your grafport is going to be consistent for awhile
  316. // you can take advantage of that by using a sequence ID so each
  317. // blit can rely on the parameters that remain consistent. What this
  318. // workaround is doing is probably that something in the
  319. // grafport has changed and we haven't detected it. What I don't
  320. // know, but I should look into the sequence of events of first
  321. // overlay rebuild, actual SizeWindow() command, second overlay blit
  322. // that would slam to the desktop if we didn't kludge.
  323. //
  324. // Initially I thought that there were two possible kludges that
  325. // would avoid the problem. One was to delay the Carbon Timer by
  326. // a millisecond. The other was to use this "catch up" technique.
  327. // It turns out that when I delayed the Carbon Timer, I was able
  328. // to reproduce the problem by actively resizing the simple case,
  329. // and most of the time using a more complex SMIL repro case.
  330. // The "catch up" technique used to have a simple boolean for
  331. // whether the kludge should kick in. Now it has a counter that's
  332. // higher for more complicated SMIL presentations. I don't know
  333. // what the magic number is, but using a boolean (i.e. "one")
  334. // was too low in complex SMIL presentations, and the number of
  335. // sites seems to work.
  336. //
  337. // xxxbobclark 20 Sep 02
  338. static ULONG32 sbCatchUp = 0;
  339. if (!zm_bUsingFauxCodec)
  340. {
  341.     if (!zm_bSafeToOverlayBlit) bOverlayRebuildingRequired = TRUE;
  342. }
  343. RgnHandle newMaskRgn = nil;
  344. if (!bOverlayRebuildingRequired)
  345. {
  346.     // see if the vis region has changed. If it has, then tear down and rebuild the
  347.     // overlay. This code is very similar to code in CMacRootSurface; that remembers
  348.     // a member variable called m_LastVisRgn. Here we use bogusDecompParams.
  349.     // decompParams.maskRegion, since that needs to be constructed at the time of
  350.     // creating the overlay anyway.
  351.     
  352.     if (!zm_bUsingFauxCodec)
  353.     {
  354. RgnHandle rgn = BuildOverlayVisRgn();
  355. if (!::EqualRgn(rgn, bogusDecompParams.decompParams.maskRegion))
  356. {
  357.     bOverlayRebuildingRequired = TRUE;
  358. }
  359. ::DisposeRgn(rgn);
  360.     }
  361. }
  362. else
  363. {
  364.     CHXMacSite* pSite = (CHXMacSite*)zm_pOverlaySurface->m_pSite;
  365.     HXREGION* pEntireReg = HXCreateRegion();
  366.     HXUnionRegion(pEntireReg, pSite->m_Region, pEntireReg);
  367.     // xxxbobclark do this "manual clipping" thing to ensure that opaque
  368.     // parents are clipped out.
  369.     CHXMacSite* parentSite = (CHXMacSite*)pSite->GetParentSite();
  370.     while (parentSite)
  371.     {
  372. HXIntersectRegion(pEntireReg, parentSite->m_RegionWithoutChildren, pEntireReg);
  373. parentSite = (CHXMacSite*)parentSite->GetParentSite();
  374.     }
  375.     // xxxbobclark chunk of code snagged from CBaseSurface::FillColorKey.
  376.     // Necessary because our overlay clip region needs to be able to
  377.     // differentiate between clipped-out areas and alpha-blended areas.
  378.     CHXMapPtrToPtr::Iterator ii;
  379.     for( ii=pSite->m_AlphaBlendNotifiers.Begin() ;
  380.  ii!=pSite->m_AlphaBlendNotifiers.End()  ;
  381.  ++ii)
  382.     {
  383. CHXBaseSite* pPotentialAlphaBlendedSite = (CHXBaseSite*)*ii;
  384. HXREGION* pReg = NULL;
  385. CHXMapPtrToPtr::Iterator j = pPotentialAlphaBlendedSite->m_AlphaBlendSites.Begin();
  386. CHXBaseSite* pTmpSite = NULL;
  387. while( j != pPotentialAlphaBlendedSite->m_AlphaBlendSites.End() && pTmpSite != pSite )
  388. {
  389.     pTmpSite = (CHXBaseSite*)j.get_key();
  390.     if( pTmpSite == pSite )
  391.     {
  392. pReg = (HXREGION*)*j;
  393. HXUnionRegion( pEntireReg, pReg, pEntireReg );
  394. break;
  395.     }
  396.     ++j;
  397. }
  398.     }
  399.     // xxxbobclark is this involved in a linked overlay?
  400.     // If so, we need to include the linked site's regions.
  401.     CHXSimpleList::Iterator linkedSitesIter;
  402.     for ( linkedSitesIter = m_LinkedSites.Begin();
  403. linkedSitesIter != m_LinkedSites.End();
  404. ++linkedSitesIter)
  405.     {
  406. CHXBaseSite* pSite = (CHXBaseSite*)(*linkedSitesIter);
  407. HXUnionRegion(pEntireReg, pSite->m_Region, pEntireReg);
  408. CHXMapPtrToPtr::Iterator ii;
  409. for( ii=pSite->m_AlphaBlendNotifiers.Begin() ;
  410. ii!=pSite->m_AlphaBlendNotifiers.End()  ;
  411. ++ii)
  412. {
  413.     CHXBaseSite* pPotentialAlphaBlendedSite = (CHXBaseSite*)*ii;
  414.     HXREGION* pReg = NULL;
  415.     CHXMapPtrToPtr::Iterator j = pPotentialAlphaBlendedSite->m_AlphaBlendSites.Begin();
  416.     CHXBaseSite* pTmpSite = NULL;
  417.     while( j != pPotentialAlphaBlendedSite->m_AlphaBlendSites.End() && pTmpSite != pSite )
  418.     {
  419. pTmpSite = (CHXBaseSite*)j.get_key();
  420. if( pTmpSite == pSite )
  421. {
  422.     pReg = (HXREGION*)*j;
  423.     HXUnionRegion( pEntireReg, pReg, pEntireReg );
  424.     break;
  425. }
  426. ++j;
  427.     }
  428. }
  429.     }
  430.     newMaskRgn = CHXMacSite::_ConvertRegionToMacRegion(pEntireReg);
  431.     OffsetRgn(newMaskRgn, -pEntireReg->extents.x1, -pEntireReg->extents.y1);
  432.     HXDestroyRegion(pEntireReg);
  433.     // xxxbobclark now intersect with current port's clip region and vis region.
  434.     RgnHandle trimRgn = ::NewRgn();
  435.     ::GetPortVisibleRegion(::GetQDGlobalsThePort(), trimRgn);
  436.     ::SectRgn(newMaskRgn, trimRgn, newMaskRgn);
  437.     if (1 /*pSite->m_bIsRealPlayerTLC*/)
  438.     {
  439. ::GetClip(trimRgn);
  440. ::SectRgn(newMaskRgn, trimRgn, newMaskRgn);
  441.     }
  442.     else
  443.     {
  444. // xxxbobclark now intersect with PNxWindow's clip rect. Only if we're
  445. // in an embedded player; this whole mechanism relies on browsers setting
  446. // up clip regions before sending null events.
  447. HXxWindow* pWindow = pSite->GetWindow();
  448. if ((pWindow->x < pWindow->clipRect.left) || ((pWindow->x + pWindow->width)  > pWindow->clipRect.right) ||
  449.         (pWindow->y < pWindow->clipRect.top)  || ((pWindow->y + pWindow->height) > pWindow->clipRect.bottom))
  450. {
  451.     bOverlayRebuildingRequired = TRUE;
  452. }
  453. ::SetRectRgn(trimRgn, pWindow->clipRect.left, pWindow->clipRect.top, pWindow->clipRect.right, pWindow->clipRect.bottom);
  454. // offset region
  455. ::OffsetRgn(trimRgn, -pWindow->x, -pWindow->y);
  456. ::SectRgn(newMaskRgn, trimRgn, newMaskRgn);
  457.     }
  458.     ::DisposeRgn(trimRgn);
  459.     if ( (!bOverlayRebuildingRequired) && (!zm_OverlayMaskRgn || !::EqualRgn(newMaskRgn, zm_OverlayMaskRgn)))
  460.     {
  461. bOverlayRebuildingRequired = TRUE;
  462.     }
  463. }
  464. if (bOverlayRebuildingRequired && zm_bUsingFauxCodec)
  465. {
  466.     // reset the workaround counter
  467.     sbCatchUp = CHXMacSite::zm_ListOfMacSites.GetCount();
  468. }
  469. else if (sbCatchUp > 0)
  470. {
  471.     bOverlayRebuildingRequired = TRUE;
  472.     sbCatchUp--;
  473. }
  474. if (bOverlayRebuildingRequired)
  475. {
  476.     if (!IsMacInCooperativeThread)
  477.     {
  478. // // xxxbobclark these shouldn't be here 'cause they can
  479. // // force it out of overlay mode even as it's switching
  480. // // to full-screen mode, for example.
  481. // retVal = HXR_FAIL;
  482. // goto exit;
  483.     }
  484.     else
  485.     {
  486. sLastPoint = sP;
  487. sLastSize = s;
  488. sLastSrcSize = srcSize;
  489.                 
  490.                 if (!newMaskRgn && zm_OverlayMaskRgn)
  491.                 {
  492.                     // CleanUpOverlay is going to clear out
  493.                     // zm_OverlayMaskRgn. Since newMaskRgn is
  494.                     // null and zm_OverlayMaskRgn exists we know
  495.                     // that we're in the sbCatchUp workaround,
  496.                     // and we need to remember the mask region
  497.                     // around the CleanUpOverlay function call.
  498.                     newMaskRgn = ::NewRgn();
  499.                     ::CopyRgn(zm_OverlayMaskRgn, newMaskRgn);
  500.                 }
  501. CleanUpOverlay();
  502. if (newMaskRgn)
  503. {
  504.     HX_ASSERT(!zm_OverlayMaskRgn);
  505.     zm_OverlayMaskRgn = newMaskRgn;
  506.     newMaskRgn = NULL;
  507. }
  508. HX_ASSERT(zm_OverlayMaskRgn);
  509. ConstructOverlay(sP.h, sP.v, s.cx, s.cy, srcSize.cx, srcSize.cy, zm_OverlayMaskRgn);
  510.     }
  511. }
  512. if (newMaskRgn)
  513. {
  514.     ::DisposeRgn(newMaskRgn);
  515. }
  516.     }
  517.     else
  518.     {
  519. retVal = HXR_FAIL;
  520. goto exit;
  521.     }
  522.     if (zm_pOverlayBuf == nil || zm_nOverlayRowBytes == 0)
  523.     {
  524. retVal = HXR_FAIL;
  525. goto exit;
  526.     }
  527.     *ppSurPtr = (UCHAR*)zm_pOverlayBuf;
  528.     *pnSurfPitch = zm_nOverlayRowBytes;
  529.     
  530. exit:
  531.     HX_ASSERT(savePort != nil);
  532.     ::SetPort(savePort);
  533.     return retVal;
  534. }
  535. /************************************************************************
  536.  *  Method:
  537.  *    CMacSurface::_UnlockInternalSurface
  538.  */
  539. HX_RESULT
  540. CMacSurface::_UnlockInternalSurface(UCHAR* pSurfPtr)
  541. {
  542.     // On RagePro, the ImageCodecDrawBand call does not NEED to
  543.     // be made. Since it uses a key color, whatever's drawn
  544.     // to the overlay magically shows up through the key color.
  545.     // The Rage128 ignores key color, though, and requires a
  546.     // call to ImageCodecDrawBand to update the overlay. This
  547.     // blasts through everything, obeying the mask region.
  548.     // So if the mask region may be outdated we will not make
  549.     // the call to ImageCodecDrawBand.
  550.     
  551.     if (gDumbCursorRedrawNeeded)
  552.     {
  553. gDumbCursorRedrawNeeded = FALSE;
  554.     }
  555.     
  556.     BOOL bDoOverlayBlit = TRUE;
  557.     
  558.     if (!zm_bUsingFauxCodec)
  559.     {
  560. if (!zm_bSafeToOverlayBlit)
  561. {
  562.     bDoOverlayBlit = FALSE;
  563. }
  564.     }
  565.     
  566.     if (zm_bUsingFauxCodec)
  567.     {
  568. if (bDoOverlayBlit)
  569. {
  570.     if (zm_SequenceID)
  571.     {
  572. short err = DecompressSequenceFrameWhen(
  573. zm_SequenceID,
  574. (Ptr)zm_pOverlayBuf, zm_nOverlayBufferSize,
  575. 0, // flags
  576. nil,
  577. nil,
  578. nil);
  579.     }
  580. }
  581.     }
  582.     else
  583.     {
  584. if (bDoOverlayBlit && zm_bOverlayRequiresDrawBand)
  585. {
  586.     ImageCodecDrawBand(gYUV, &drp);
  587. }
  588.     }
  589.     
  590.     return HXR_OK;
  591. }
  592. /************************************************************************
  593.  *  Method:
  594.  *    CMacSurface::_SetupDCObjects
  595.  */
  596. void
  597. CMacSurface::_SetupDCObjects(HXxDC hxxDC, void** phOldBrush, void** phOldPen)
  598. {
  599. }
  600. /************************************************************************
  601.  *  Method:
  602.  *    CMacSurface::_FillRectangle
  603.  */
  604. void
  605. CMacSurface::_FillRectangle(HXxDC hxxDC, UINT32 left, UINT32 top, UINT32 right, UINT32 bottom)
  606. {
  607.     if (zm_bOverlayRequiresKeyColor)
  608.     {
  609. GrafPtr savePort;
  610. ::GetPort(&savePort);
  611. HX_ASSERT(m_pSite);
  612. HXxWindow* pWindow = m_pSite->GetWindow();
  613. HX_ASSERT(pWindow && pWindow->window);
  614. ::SetPort((GrafPtr)pWindow->window);
  615. Rect r;
  616. r.left = left + pWindow->x;
  617. r.top = top + pWindow->y;
  618. r.right = right + pWindow->x;
  619. r.bottom = bottom + pWindow->y;
  620. // xxxbobclark for ATI RagePro cards, they use a key
  621. // color, and the key color is hardcoded. I don't
  622. // know, but this may change if we stumble across a
  623. // card that supports key colors that aren't hard-
  624. // coded -- or that use a DIFFERENT hard-coded one.
  625. static RGBColor keyColor = {0x0000, 0x1000, 0x0000};
  626. RGBColor hold;
  627. ::GetForeColor(&hold);
  628. ::RGBForeColor(&keyColor);
  629. PaintRect(&r);
  630. ::RGBForeColor(&hold);
  631. ::SetPort(savePort);
  632.     }
  633. }
  634. /************************************************************************
  635.  *  Method:
  636.  *    CMacSurface::_RestoreDCObjects
  637.  */
  638. void
  639. CMacSurface::_RestoreDCObjects(HXxDC hxxDC, void* hOldBrush, void* hOldPen)
  640. {
  641. }
  642. /************************************************************************
  643.  *  Method:
  644.  *    CMacSurface::_GetCompositeionSurfacePNxDC
  645.  */
  646. void
  647. CMacSurface::_GetCompositionSurfaceHXxDC(HXxDC* hdc)
  648. {
  649. }
  650. /************************************************************************
  651.  *  Method:
  652.  *    CMacSurface::_ReleaseCompositionSurfaceHXxDC
  653.  */
  654. void
  655. CMacSurface::_ReleaseCompositionSurfaceHXxDC(HXxDC hdc)
  656. {
  657. }
  658. /************************************************************************
  659.  *  Method:
  660.  *    CMacSurface::_InsureColorMatch
  661.  */
  662. INT32
  663. CMacSurface::_InsureColorMatch(INT32 InColor)
  664. {
  665.     return InColor; // XXXbobclark
  666. }
  667. /************************************************************************
  668.  *  Method:
  669.  *    CMacSurface::_SetColorKey
  670.  */
  671. void
  672. CMacSurface::_SetColorKey(INT32 nColorSpaceLowValue, INT32 nColorSpaceHighValue)
  673. {
  674. }
  675. /************************************************************************
  676.  *  Method:
  677.  *    CMacSurface::_UpdateOverlay
  678.  */
  679. void
  680. CMacSurface::_UpdateOverlay(HXxRect* src, HXxRect* dest, INT32 inFlags)
  681. {
  682. }
  683. /************************************************************************
  684.  *  Method:
  685.  *    CMacSurface::_IsSurfaceVisible
  686.  */
  687. BOOL
  688. CMacSurface::_IsSurfaceVisible()
  689. {
  690.     return TRUE;
  691. }
  692. /************************************************************************
  693.  *  Method:
  694.  *    CMacSurface::_ReleaseSurface
  695.  */
  696. void
  697. CMacSurface::_ReleaseSurface()
  698. {
  699.     if (CMacSurface::zm_pOverlaySurface == this)
  700.     {
  701. CleanUpOverlay();
  702. CMacSurface::zm_pOverlaySurface = nil;
  703.     }
  704. }
  705. /************************************************************************
  706.  *  Method:
  707.  *    CMacSurface::_GetDC
  708.  */
  709. HXxDC
  710. CMacSurface::_GetDC(HXxWindow* pWindow)
  711. {
  712.     return NULL; // XXXbobclark gotta figure out what to return, duh
  713. }
  714. /************************************************************************
  715.  *  Method:
  716.  *    CMacSurface::_ReleaseDC
  717.  */
  718. void
  719. CMacSurface::_ReleaseDC(HXxWindow* pWindow, HXxDC pdc)
  720. {
  721. }
  722. /************************************************************************
  723.  *  Method:
  724.  *    CMacSurface::_GetWindowDeviceCords
  725.  */
  726. void
  727. CMacSurface::_GetWindowDeviceCords(HXxRect* rect)
  728. {
  729.     static Point sLastCords = {0,0};
  730.     
  731.     sLastCords.h = 0;
  732.     sLastCords.v = 0;
  733.     ::LocalToGlobal(&sLastCords);
  734.     rect->left = sLastCords.h;
  735.     rect->top = sLastCords.v;
  736. }
  737. /************************************************************************
  738.  *  Method:
  739.  *    CMacSurface::_OverlayAvailable
  740.  */
  741. BOOL
  742. CMacSurface::_OverlayAvailable()
  743. {
  744.     if (!m_bUseOverlays) return FALSE;
  745.     
  746.     static BOOL zbWeveExploredOverlayCapabilities = FALSE;
  747.     static BOOL zbOverlayAvailable = FALSE;
  748.     
  749.     if (!zbWeveExploredOverlayCapabilities)
  750.     {
  751. zbWeveExploredOverlayCapabilities = TRUE;
  752. // start out by assuming that we can use ATI's
  753. // deferred-task-safe overlay code. We'll fall
  754. // back on Apple's mechanism if necessary.
  755. zm_bUsingFauxCodec = FALSE;
  756. if (!zbOverlayAvailable)
  757. {
  758.     zm_bUsingFauxCodec = TRUE;
  759.     zbOverlayAvailable = TRUE;
  760.     FauxCodecRegister();
  761. }
  762.     }
  763.     return zbOverlayAvailable;
  764. }
  765. /************************************************************************
  766.  *  Method:
  767.  *    CMacSurface::_AllowsOverlayShrinking
  768.  */
  769. BOOL
  770. CMacSurface::_AllowsOverlayShrinking()
  771. {
  772.     return TRUE;
  773. }
  774. // some of the following is from ATI's YUVSDK.
  775. // Some ATI specific definitions
  776. #define  kATIYUVComponentType 'imdc'
  777. #define kATIYUVComponentSubType 'yuvs'
  778. #define kATIYUVComponentManufacturer 'ATI '
  779. #pragma options align=mac68k
  780. //QT 3.x stuff : begin -- Anita
  781. struct YUVSdecompressRecord {
  782. short width; // width (in pixels) of a row
  783. long numStrips; // number of strips to draw
  784. long srcDataIncrement; // increment for srcData between strips
  785. long baseAddrIncrement; // increment for baseAddr between strips
  786. struct Globals *glob; // pointer to our globals
  787. };
  788. typedef struct YUVSdecompressRecord YUVSdecompressRecord;
  789. // Added for VAU
  790. struct BDCTextureDRP
  791. {
  792. ByteCount dataSize; // Number of bytes in compressed data
  793. SInt16  width; // Width in pixels
  794. SInt16  height; // Height in lines
  795. };
  796. typedef struct BDCTextureDRP BDCTextureDRP;
  797. pascal void MymemoryGoneProc(Ptr memoryBlock, void *refcon);
  798. ICMMemoryDisposedUPP theMemoryProc = nil;
  799. pascal void MymemoryGoneProc(Ptr memoryBlock, void *refcon)
  800. {
  801. // do nothing.
  802. }
  803. /* static */
  804. void CMacSurface::ConstructOverlay(long screenCoorX, long screenCoorY, long screenWidth, long screenHeight, long sourceWidth, long sourceHeight,
  805. RgnHandle maskRgn)
  806. {
  807.     // xxxbobclark if we're running native on OS X, then the screen coordinates are in
  808.     // local coordinates. If we're NOT running native on OS X then the screen coordinates
  809.     // are in global coordinates. The reason for this is that we have a chance to talk
  810.     // directly to the hardware on OS 9 and below, which requires global coordinates. On
  811.     // OS X by using local coordinates we ensure that we can accurately hit a moving window.
  812.     // (If we try to use global coords on OS X, it's possible that the window is moved
  813.     // between when the global coords are figured out and we construct the overlay.
  814.     if (zm_bUsingFauxCodec)
  815.     {
  816. // xxxbobclark if we're using the faux codec, then as of this
  817. // writing, on OS 9, we can not blit at interrupt time. This
  818. // presents us with a dilemma. For one thing, a lot of work
  819. // went into interrupt-time blitting. And in many cases it is
  820. // a vast improvement. Worse, it is hard to tell at compile
  821. // time or even runtime whether ITB sans overlay is better than
  822. // overlay sans ITB. We can make some runtime assumptions,
  823. // like at what destination size the dropped frames due to
  824. // yuv-rgb conversions equal the dropped frames due to not
  825. // having ITB active... but even that can shift due to conditions
  826. // like, say, an email program checking mail in the background.
  827. // I think I'm going to make some assumptions that the user
  828. // won't be doing all kinds of things in the background.
  829. // Note that this will suddenly become a non-issue once we
  830. // move to OS X (because we can ITB without any concerns)
  831. // or Apple helps us use the Image Compression Manager ("faux
  832. // codec") mechanism at deferred time.
  833. // xxxbobclark ... although the settings preferences could
  834. // dictate that we use overlay; if for example ITB is turned
  835. // off but overlay is turned on in the preferences, we should
  836. // always do overlay...
  837.     
  838. // OK we need to set up zm_pOverlayBuf, zm_nOverlayRowBytes, and zm_bSafeToOverlayBlit
  839. // Oh, and zm_nOverlayBufferSize.
  840. // first let's find our component.
  841. ComponentDescription cd;
  842. Component c = NULL;
  843. Component foundComponent = NULL;
  844. cd.componentType = 'imdc';
  845. cd.componentSubType = 'yuvs';
  846. cd.componentManufacturer = 'RNWK';
  847. // xxxbobclark if we pass in zero for the componentManufacturer
  848. // instead of 'RNWK', it will still grab an actual codec. And if
  849. // we haven't done FauxCodecRegister() it still grabs one, at least
  850. // on Jaguar. This is very interesting. It may be possible that on
  851. // Jaguar and later, the faux codec trick is redundant. I'm reluctant
  852. // to remove it now, but it could bear looking into.
  853. cd.componentFlags = 0;
  854. cd.componentFlagsMask = 0;
  855.     
  856. while ((c = FindNextComponent(c, &cd)) != 0)
  857. {
  858.     HX_ASSERT(foundComponent == NULL);
  859.     foundComponent = c;
  860.     break;
  861.     // xxxbobclark this is a short-term kludge. The real problem is that every time pnvideo
  862.     // is loaded and a surface used for overlay, it calls FauxCodecRegister. pnvideo's terminate
  863.     // routine should call some corresponding FauxCodecUnregister, but since it doesn't yet,
  864.     // a pile of faux codecs gets added to every time pnvideo is unloaded/reloaded. This doesn't
  865.     // typically happen in the player but in the embedded player it can happen frequently.
  866.     // By breaking out of this loop now we only use (apparently) the most recently installed
  867.     // version, which fortunately is the one still in loaded pnvideo code.
  868.     
  869.     // The fix should be straightforward: unregister the faux codec from the dtor which tears down
  870.     // the overlay or worst case from the shlb's terminate routine. xxxbobclark 6/12/02 this should
  871.     // be one of the first things fixed when I have a chance.
  872. }
  873. // this chunk o' code assumes local coordinates.
  874. Point local;
  875. local.h = screenCoorX;
  876. local.v = screenCoorY;
  877. if (!IsRunningNativeOnMacOSX())
  878. {
  879.     GlobalToLocal(&local);
  880. }
  881. Rect srcR, dstR;
  882. srcR.left = 0;
  883. srcR.top = 0;
  884. srcR.right = sourceWidth;
  885. srcR.bottom = sourceHeight;
  886. dstR.left = local.h;
  887. dstR.top = local.v;
  888. dstR.right = local.h + screenWidth;
  889. dstR.bottom = local.v + screenHeight;
  890. zm_ImageDescriptionHandle = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription));
  891. (**zm_ImageDescriptionHandle).idSize = sizeof(ImageDescription);
  892. (**zm_ImageDescriptionHandle).cType = 'yuvs';
  893. (**zm_ImageDescriptionHandle).width = srcR.right-srcR.left;
  894. (**zm_ImageDescriptionHandle).height = srcR.bottom-srcR.top;
  895. (**zm_ImageDescriptionHandle).hRes = 72L << 16;
  896. (**zm_ImageDescriptionHandle).vRes = 72L << 16;
  897. (**zm_ImageDescriptionHandle).frameCount = 1;
  898. (**zm_ImageDescriptionHandle).clutID = -1;
  899. MatrixRecord matrix;
  900. RectMatrix(&matrix, &srcR, &dstR);
  901. OSErr err = DecompressSequenceBeginS(
  902. &zm_SequenceID,
  903. zm_ImageDescriptionHandle,
  904. nil, 0, // data pointer and data length
  905. nil, // use the current port
  906. nil, // go to screen
  907. &srcR,
  908. &matrix,
  909. ditherCopy,
  910. maskRgn,
  911. codecFlagUseImageBuffer,
  912. codecNormalQuality,
  913. foundComponent);
  914. zm_nOverlayRowBytes = (srcR.right-srcR.left) * 2;
  915. zm_nOverlayBufferSize = (srcR.bottom - srcR.top) * zm_nOverlayRowBytes;
  916. if ((zm_nOverlayBufferSize == zm_nHoldOverlayBufSize) && zm_pHoldOverlayBuf)
  917. {
  918.     zm_pOverlayBuf = zm_pHoldOverlayBuf;
  919. }
  920. else
  921. {
  922.     zm_pOverlayBuf = ::NewPtr(zm_nOverlayBufferSize);
  923.     if (zm_pHoldOverlayBuf)
  924.     {
  925. ::DisposePtr((Ptr)zm_pHoldOverlayBuf);
  926.     }
  927.     zm_pHoldOverlayBuf = zm_pOverlayBuf;
  928.     zm_nHoldOverlayBufSize = zm_nOverlayBufferSize;
  929. }
  930.     }
  931.     else
  932.     {
  933. // ATI-specific overlay implementation
  934.         HX_ASSERT( NULL == "no non-faux-codec mechanism!");
  935.     }
  936. }
  937. void CMacSurface::CleanUpOverlay()
  938. {
  939.     if (zm_bUsingFauxCodec)
  940.     {
  941. if (zm_SequenceID)
  942. {
  943.     CDSequenceEnd(zm_SequenceID);
  944. }
  945. zm_SequenceID = NULL;
  946. if (zm_pOverlayBuf)
  947. {
  948.     // xxxbobclark don't dispose this; hold on to it in
  949.     // zm_pHoldOverlayBuf in case we create another overlay
  950.     // of the same size. Saves allocation and initialization
  951.     // time, plus sidesteps some alpha-blending bugs.
  952.     // DisposePtr((Ptr)zm_pOverlayBuf);
  953. }
  954. zm_pOverlayBuf = nil;
  955. zm_nOverlayRowBytes = 0;
  956. zm_nOverlayBufferSize = 0;
  957. if (zm_OverlayMaskRgn)
  958. {
  959.     ::DisposeRgn(zm_OverlayMaskRgn);
  960. }
  961. zm_OverlayMaskRgn = NULL;
  962. if (zm_ImageDescriptionHandle)
  963. {
  964.     ::DisposeHandle((Handle)zm_ImageDescriptionHandle);
  965. }
  966. zm_ImageDescriptionHandle = NULL;
  967.     }
  968.     else
  969.     {
  970. // ATI-specific overlay implementation
  971.     }
  972. }
  973. RgnHandle
  974. CMacSurface::BuildOverlayVisRgn()
  975. {
  976.     // This assumes that the decomp params
  977.     // rectangle has already been set up!
  978.     //
  979.     // It also assumes that the port has
  980.     // been set to the correct window!
  981.     //
  982.     // The caller must dispose of the
  983.     // region!
  984.     
  985.     HX_ASSERT(IsMacInCooperativeThread());
  986.     
  987.     RgnHandle rgn = ::NewRgn();
  988.     
  989.     ::RectRgn(rgn, &bogusDecompParams.decompParams.dstRect);
  990.     return rgn;
  991. }
  992. #pragma options align=reset