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 194432 ca725c15bdeb62c97ca0876a40aaacb8cac542e3
parent 194431 7e7061043b859b4493a3bb9cf5a62fd9da6b672f
child 194433 e9d959645b8f63abbd97761db50b99da8087aee1
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-esr52@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs965967
milestone32.0a1
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>