Bug 923290 - Don't use the window CGContext as a source with Moz2D. r=Bas
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 10 Oct 2013 17:44:09 +1300
changeset 164106 64b24d431280e09bbb4db1e030db6f34a26b003d
parent 164105 b73a8fa118dd016f2409d299b51f23f2f9b07bc2
child 164107 4dad2edca27ef26d90a156a16800852fecdea0d6
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs923290
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 923290 - Don't use the window CGContext as a source with Moz2D. r=Bas
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxContext.h
widget/cocoa/nsChildView.mm
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -26,16 +26,18 @@
 
 #if CAIRO_HAS_DWRITE_FONT
 #include "gfxWindowsPlatform.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
+UserDataKey gfxContext::sDontUseAsSourceKey;
+
 /* This class lives on the stack and allows gfxContext users to easily, and
  * performantly get a gfx::Pattern to use for drawing in their current context.
  */
 class GeneralPattern
 {
 public:    
   GeneralPattern(gfxContext *aContext) : mContext(aContext), mPattern(nullptr) {}
   ~GeneralPattern() { if (mPattern) { mPattern->~Pattern(); } }
@@ -1609,18 +1611,19 @@ gfxContext::PushGroupAndCopyBackground(g
       }
     }
   } else {
     IntRect clipExtents;
     if (mDT->GetFormat() != FORMAT_B8G8R8X8) {
       gfxRect clipRect = GetRoundOutDeviceClipExtents(this);
       clipExtents = IntRect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
     }
-    if (mDT->GetFormat() == FORMAT_B8G8R8X8 ||
-        mDT->GetOpaqueRect().Contains(clipExtents)) {
+    if ((mDT->GetFormat() == FORMAT_B8G8R8X8 ||
+         mDT->GetOpaqueRect().Contains(clipExtents)) &&
+        !mDT->GetUserData(&sDontUseAsSourceKey)) {
       DrawTarget *oldDT = mDT;
       RefPtr<SourceSurface> source = mDT->Snapshot();
       Point oldDeviceOffset = CurrentState().deviceOffset;
 
       PushNewDT(GFX_CONTENT_COLOR);
 
       Point offset = CurrentState().deviceOffset - oldDeviceOffset;
       Rect surfRect(0, 0, Float(mDT->GetSize().width), Float(mDT->GetSize().height));
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -703,16 +703,18 @@ public:
     void DumpAsDataURL();
 
     /**
      * Copy a PNG encoded Data URL to the clipboard.
      */
     void CopyAsDataURL();
 #endif
 
+    static mozilla::gfx::UserDataKey sDontUseAsSourceKey;
+
 private:
   friend class GeneralPattern;
   friend struct GlyphBufferAzure;
 
   typedef mozilla::gfx::Matrix Matrix;
   typedef mozilla::gfx::DrawTarget DrawTarget;
   typedef mozilla::gfx::Color Color;
   typedef mozilla::gfx::StrokeOptions StrokeOptions;
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -3372,22 +3372,24 @@ NSEvent* gLastDragMouseDownEvent = nil;
   targetSurface->SetAllowUseAsSource(false);
 
   nsRefPtr<gfxContext> targetContext;
   if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(gfx::BACKEND_CAIRO)) {
     RefPtr<gfx::DrawTarget> dt =
       gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(targetSurface,
                                                              gfx::IntSize(backingSize.width,
                                                                           backingSize.height));
+    dt->AddUserData(&gfxContext::sDontUseAsSourceKey, dt, nullptr);
     targetContext = new gfxContext(dt);
   } else if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(gfx::BACKEND_COREGRAPHICS)) {
     RefPtr<gfx::DrawTarget> dt =
       gfx::Factory::CreateDrawTargetForCairoCGContext(aContext,
                                                       gfx::IntSize(backingSize.width,
                                                                    backingSize.height));
+    dt->AddUserData(&gfxContext::sDontUseAsSourceKey, dt, nullptr);
     targetContext = new gfxContext(dt);
   } else {
     targetContext = new gfxContext(targetSurface);
   }
 
   // Set up the clip region.
   nsIntRegionRectIterator iter(region);
   targetContext->NewPath();