Bug 965967, part 1 - Get rid of some Thebes backed gfxContexts in the plugin code (Moz2D migration). r=mattwoodrow
authorReed Koser <srkoser@gmail.com>
Fri, 06 Jun 2014 10:24:24 +0100
changeset 206299 ca725c15bdeb62c97ca0876a40aaacb8cac542e3
parent 206298 7e7061043b859b4493a3bb9cf5a62fd9da6b672f
child 206300 e9d959645b8f63abbd97761db50b99da8087aee1
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs965967
milestone32.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 965967, part 1 - Get rid of some Thebes backed gfxContexts in the plugin code (Moz2D migration). r=mattwoodrow
dom/plugins/ipc/PluginInstanceChild.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatform.h
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -8,17 +8,20 @@
 #include "PluginInstanceChild.h"
 #include "PluginModuleChild.h"
 #include "BrowserStreamChild.h"
 #include "PluginStreamChild.h"
 #include "StreamNotifyChild.h"
 #include "PluginProcessChild.h"
 #include "gfxASurface.h"
 #include "gfxContext.h"
+#include "gfxPlatform.h"
+#include "gfx2DGlue.h"
 #include "nsNPAPIPluginInstance.h"
+#include "mozilla/gfx/2D.h"
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
 #endif
 #ifdef XP_WIN
 #include "mozilla/gfx/SharedDIBSurface.h"
 #include "nsCrashOnException.h"
 extern const wchar_t* kFlashFullscreenClass;
 using mozilla::gfx::SharedDIBSurface;
@@ -87,16 +90,41 @@ static const TCHAR kPluginIgnoreSubclass
 
 template<>
 struct RunnableMethodTraits<PluginInstanceChild>
 {
     static void RetainCallee(PluginInstanceChild* obj) { }
     static void ReleaseCallee(PluginInstanceChild* obj) { }
 };
 
+/**
+ * We can't use gfxPlatform::CreateDrawTargetForSurface() because calling
+ * gfxPlatform::GetPlatform() instantiates the prefs service, and that's not
+ * allowed from processes other than the main process. So we have our own
+ * version here.
+ */
+static RefPtr<DrawTarget>
+CreateDrawTargetForSurface(gfxASurface *aSurface)
+{
+  SurfaceFormat format;
+  if (aSurface->GetContentType() == gfxContentType::ALPHA) {
+    format = SurfaceFormat::A8;
+  } else if (aSurface->GetContentType() == gfxContentType::COLOR) {
+    format = SurfaceFormat::B8G8R8X8;
+  } else {
+    format = SurfaceFormat::B8G8R8A8;
+  }
+  RefPtr<DrawTarget> drawTarget =
+    Factory::CreateDrawTargetForCairoSurface(aSurface->CairoSurface(),
+                                             ToIntSize(gfxIntSize(aSurface->GetSize())),
+                                             &format);
+  aSurface->SetData(&kDrawTarget, drawTarget, nullptr);
+  return drawTarget;
+}
+
 PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface)
     : mPluginIface(aPluginIface)
 #if defined(XP_MACOSX)
     , mContentsScaleFactor(1.0)
 #endif
     , mDrawingModel(kDefaultDrawingModel)
     , mCurrentAsyncSurface(0)
     , mAsyncInvalidateMutex("PluginInstanceChild::mAsyncInvalidateMutex")
@@ -3166,33 +3194,33 @@ PluginInstanceChild::PaintRectToSurface(
     }
     if (mHelperSurface) {
         // On X11 we can paint to non Xlib surface only with HelperSurface
         renderSurface = mHelperSurface;
     }
 #endif
 
     if (mIsTransparent && !CanPaintOnBackground()) {
-       // Clear surface content for transparent rendering
-       nsRefPtr<gfxContext> ctx = new gfxContext(renderSurface);
-       ctx->SetDeviceColor(aColor);
-       ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
-       ctx->Rectangle(GfxFromNsRect(plPaintRect));
-       ctx->Fill();
+        // Clear surface content for transparent rendering
+        ColorPattern color(ToColor(aColor));
+        RefPtr<DrawTarget> dt = CreateDrawTargetForSurface(renderSurface);
+        dt->FillRect(gfx::Rect(plPaintRect.x, plPaintRect.y,
+                               plPaintRect.width, plPaintRect.height),
+                     color,
+                     DrawOptions(1.f, CompositionOp::OP_SOURCE));
     }
 
     PaintRectToPlatformSurface(plPaintRect, renderSurface);
 
     if (renderSurface != aSurface) {
         // Copy helper surface content to target
-        nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
-        ctx->SetSource(renderSurface);
-        ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
-        ctx->Rectangle(GfxFromNsRect(aRect));
-        ctx->Fill();
+        RefPtr<DrawTarget> dt = CreateDrawTargetForSurface(aSurface);
+        RefPtr<SourceSurface> surface =
+            gfxPlatform::GetSourceSurfaceForSurface(dt, renderSurface);
+        dt->CopySurface(surface, ToIntRect(aRect), ToIntPoint(aRect.TopLeft()));
     }
 }
 
 void
 PluginInstanceChild::PaintRectWithAlphaExtraction(const nsIntRect& aRect,
                                                   gfxASurface* aSurface)
 {
     NS_ABORT_IF_FALSE(aSurface->GetContentType() == gfxContentType::COLOR_ALPHA,
@@ -3237,22 +3265,20 @@ PluginInstanceChild::PaintRectWithAlphaE
     // we don't accidentally attempt that.
     if (!SharedDIBSurface::IsSharedDIBSurface(aSurface))
         NS_RUNTIMEABORT("Expected SharedDIBSurface!");
 
     // Paint the plugin directly onto the target, with a white
     // background and copy the result
     PaintRectToSurface(rect, aSurface, gfxRGBA(1.0, 1.0, 1.0));
     {
-        gfxRect copyRect(gfxPoint(0, 0), targetRect.Size());
-        nsRefPtr<gfxContext> ctx = new gfxContext(whiteImage);
-        ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
-        ctx->SetSource(aSurface, deviceOffset);
-        ctx->Rectangle(copyRect);
-        ctx->Fill();
+        RefPtr<DrawTarget> dt = CreateDrawTargetForSurface(whiteImage);
+        RefPtr<SourceSurface> surface =
+            gfxPlatform::GetSourceSurfaceForSurface(dt, aSurface);
+        dt->CopySurface(surface, ToIntRect(rect), IntPoint());
     }
 
     // Paint the plugin directly onto the target, with a black
     // background
     PaintRectToSurface(rect, aSurface, gfxRGBA(0.0, 0.0, 0.0));
 
     // Don't copy the result, just extract a subimage so that we can
     // recover alpha directly into the target
@@ -3283,21 +3309,22 @@ PluginInstanceChild::PaintRectWithAlphaE
     // image
     if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage)) {
         return;
     }
 
     // If we had to use a temporary black surface, copy the pixels
     // with alpha back to the target
     if (!useSurfaceSubimageForBlack) {
-        nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
-        ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
-        ctx->SetSource(blackImage);
-        ctx->Rectangle(targetRect);
-        ctx->Fill();
+        RefPtr<DrawTarget> dt = CreateDrawTargetForSurface(aSurface);
+        RefPtr<SourceSurface> surface =
+            gfxPlatform::GetSourceSurfaceForSurface(dt, blackImage);
+        dt->CopySurface(surface,
+                        IntRect(0, 0, rect.width, rect.height),
+                        ToIntPoint(rect.TopLeft()));
     }
 }
 
 bool
 PluginInstanceChild::CanPaintOnBackground()
 {
     return (mBackground &&
             mCurrentSurface &&
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -666,26 +666,26 @@ CopySurface(gfxASurface* aSurface)
   ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
   ctx->Paint();
 
   data->Unmap();
 
   return data;
 }
 
-RefPtr<SourceSurface>
+/* static */ RefPtr<SourceSurface>
 gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurface)
 {
   if (!aSurface->CairoSurface() || aSurface->CairoStatus()) {
     return nullptr;
   }
 
   if (!aTarget) {
-    if (ScreenReferenceDrawTarget()) {
-      aTarget = ScreenReferenceDrawTarget();
+    if (gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget()) {
+      aTarget = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
     } else {
       return nullptr;
     }
   }
 
   void *userData = aSurface->GetData(&kSourceSurface);
 
   if (userData) {
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -197,18 +197,22 @@ public:
 
     /*
      * Creates a SourceSurface for a gfxASurface. This function does no caching,
      * so the caller should cache the gfxASurface if it will be used frequently.
      * The returned surface keeps a reference to aTarget, so it is OK to keep the
      * surface, even if aTarget changes.
      * aTarget should not keep a reference to the returned surface because that
      * will cause a cycle.
+     *
+     * This function is static so that it can be accessed from
+     * PluginInstanceChild (where we can't call gfxPlatform::GetPlatform()
+     * because the prefs service can only be accessed from the main process).
      */
-    virtual mozilla::RefPtr<mozilla::gfx::SourceSurface>
+    static mozilla::RefPtr<mozilla::gfx::SourceSurface>
       GetSourceSurfaceForSurface(mozilla::gfx::DrawTarget *aTarget, gfxASurface *aSurface);
 
     static void ClearSourceSurfaceForSurface(gfxASurface *aSurface);
 
     static mozilla::RefPtr<mozilla::gfx::DataSourceSurface>
         GetWrappedDataSourceSurface(gfxASurface *aSurface);
 
     virtual mozilla::TemporaryRef<mozilla::gfx::ScaledFont>