Backed out changeset 1bd6da31483d (bug 1279654)
authorJonathan Watt <jwatt@jwatt.org>
Thu, 16 Jun 2016 17:28:50 +0100
changeset 379743 633b29c1f22c1ee1a9a10554581563dbc2575905
parent 379742 32292614185f62df5f6d19d5e05d74401f9d3b5f
child 379744 62a7c0592bb76023acb880348eca2cf5b0240cd8
push id21042
push userbechen@mozilla.com
push dateFri, 17 Jun 2016 09:22:30 +0000
bugs1279654
milestone50.0a1
backs out1bd6da31483db28d8fd65a0ef69d8dfe42cb0f0f
Backed out changeset 1bd6da31483d (bug 1279654)
gfx/thebes/PrintTarget.cpp
gfx/thebes/PrintTarget.h
gfx/thebes/PrintTargetThebes.cpp
gfx/thebes/PrintTargetThebes.h
gfx/thebes/moz.build
widget/nsDeviceContextSpecProxy.cpp
--- a/gfx/thebes/PrintTarget.cpp
+++ b/gfx/thebes/PrintTarget.cpp
@@ -47,33 +47,59 @@ PrintTarget::~PrintTarget()
 
 already_AddRefed<DrawTarget>
 PrintTarget::MakeDrawTarget(const IntSize& aSize,
                             DrawEventRecorder* aRecorder)
 {
   MOZ_ASSERT(mCairoSurface,
              "We shouldn't have been constructed without a cairo surface");
 
-  MOZ_ASSERT(!aRecorder,
-             "aRecorder should only be passed to an instance of "
-             "PrintTargetRecording");
-
   if (cairo_surface_status(mCairoSurface)) {
     return nullptr;
   }
 
   // Note than aSize may not be the same as mSize (the size of mCairoSurface).
   // See the comments in our header.  If the sizes are different a clip will
   // be applied to mCairoSurface.
   RefPtr<DrawTarget> dt =
     Factory::CreateDrawTargetForCairoSurface(mCairoSurface, aSize);
   if (!dt || !dt->IsValid()) {
     return nullptr;
   }
 
+  if (aRecorder) {
+    dt = CreateRecordingDrawTarget(aRecorder, dt);
+    if (!dt || !dt->IsValid()) {
+      return nullptr;
+    }
+  }
+
+  return dt.forget();
+}
+
+already_AddRefed<DrawTarget>
+PrintTarget::CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
+                                       DrawTarget* aDrawTarget)
+{
+  MOZ_ASSERT(aRecorder);
+  MOZ_ASSERT(aDrawTarget);
+
+  RefPtr<DrawTarget> dt;
+
+  if (aRecorder) {
+    // It doesn't really matter what we pass as the DrawTarget here.
+    dt = gfx::Factory::CreateRecordingDrawTarget(aRecorder, aDrawTarget);
+  }
+
+  if (!dt || !dt->IsValid()) {
+    gfxCriticalNote
+      << "Failed to create a recording DrawTarget for PrintTarget";
+    return nullptr;
+  }
+
   return dt.forget();
 }
 
 void
 PrintTarget::Finish()
 {
   if (mIsFinished) {
     return;
--- a/gfx/thebes/PrintTarget.h
+++ b/gfx/thebes/PrintTarget.h
@@ -94,16 +94,18 @@ public:
    * is the only platform where we get passed an aRecorder.  Probably the
    * issue is that we get called more than once with a different aRecorder, so
    * storing one recording DrawTarget for our lifetime doesn't currently work.
    *
    * XXX Could we pass aRecorder to our subclass's CreateOrNull factory methods?
    * We'd need to check that our consumers always pass the same aRecorder for
    * our entire lifetime.
    *
+   * XXX Once PrintTargetThebes is removed this can become non-virtual.
+   *
    * XXX In the long run, this class and its sub-classes should be converted to
    * use STL classes and mozilla::RefCounted<> so the can be moved to Moz2D.
    *
    * TODO: Consider adding a SetDPI method that calls
    * cairo_surface_set_fallback_resolution.
    */
   virtual already_AddRefed<DrawTarget>
   MakeDrawTarget(const IntSize& aSize,
@@ -112,16 +114,20 @@ public:
 protected:
 
   // Only created via subclass's constructors
   explicit PrintTarget(cairo_surface_t* aCairoSurface, const IntSize& aSize);
 
   // Protected because we're refcounted
   virtual ~PrintTarget();
 
+  already_AddRefed<DrawTarget>
+  CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
+                            DrawTarget* aDrawTarget);
+
   cairo_surface_t* mCairoSurface;
   IntSize mSize;
   bool mIsFinished;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
--- a/gfx/thebes/PrintTargetThebes.cpp
+++ b/gfx/thebes/PrintTargetThebes.cpp
@@ -31,26 +31,29 @@ PrintTargetThebes::PrintTargetThebes(gfx
   , mGfxSurface(aSurface)
 {
 }
 
 already_AddRefed<DrawTarget>
 PrintTargetThebes::MakeDrawTarget(const IntSize& aSize,
                                   DrawEventRecorder* aRecorder)
 {
-  MOZ_ASSERT(!aRecorder,
-             "aRecorder should only be passed to an instance of "
-             "PrintTargetRecording");
-
   RefPtr<gfx::DrawTarget> dt =
     gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mGfxSurface, aSize);
   if (!dt || !dt->IsValid()) {
     return nullptr;
   }
 
+  if (aRecorder) {
+    dt = CreateRecordingDrawTarget(aRecorder, dt);
+    if (!dt || !dt->IsValid()) {
+      return nullptr;
+    }
+  }
+
   return dt.forget();
 }
 
 nsresult
 PrintTargetThebes::BeginPrinting(const nsAString& aTitle,
                                  const nsAString& aPrintToFileName)
 {
   return mGfxSurface->BeginPrinting(aTitle, aPrintToFileName);
--- a/gfx/thebes/PrintTargetThebes.h
+++ b/gfx/thebes/PrintTargetThebes.h
@@ -14,16 +14,19 @@ namespace mozilla {
 namespace gfx {
 
 /**
  * XXX Remove this class.
  *
  * This class should go away once all the logic from the gfxASurface subclasses
  * has been moved to new PrintTarget subclasses and we no longer need to
  * wrap a gfxASurface.
+ *
+ * When removing this class, be sure to make PrintTarget::MakeDrawTarget
+ * non-virtual!
  */
 class PrintTargetThebes final : public PrintTarget {
 public:
 
   static already_AddRefed<PrintTargetThebes>
   CreateOrNull(gfxASurface* aSurface);
 
   virtual nsresult BeginPrinting(const nsAString& aTitle,
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -47,17 +47,16 @@ EXPORTS += [
     'gfxUtils.h',
     'RoundedRect.h',
     'SoftwareVsyncSource.h',
     'VsyncSource.h',
 ]
 
 EXPORTS.mozilla.gfx += [
     'PrintTarget.h',
-    'PrintTargetRecording.h',
     'PrintTargetThebes.h',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     EXPORTS += [
         'gfxAndroidPlatform.h',
         'gfxFT2FontBase.h',
         'gfxFT2Fonts.h',
@@ -215,17 +214,16 @@ SOURCES += [
     # on X11, gfxDrawable.cpp includes X headers for an old workaround which
     # we could consider removing soon (affects Ubuntus older than 10.04 LTS)
     # which currently prevent it from joining UNIFIED_SOURCES.
     'gfxDrawable.cpp',
     # gfxPlatform.cpp includes mac system header conflicting with point/size
     'gfxPlatform.cpp',
     'gfxPrefs.cpp',
     'PrintTarget.cpp',
-    'PrintTargetRecording.cpp',
     'PrintTargetThebes.cpp',
 ]
 
 UNIFIED_SOURCES += [
     'CJKCompatSVS.cpp',
     'gfxAlphaRecovery.cpp',
     'gfxBaseSharedMemorySurface.cpp',
     'gfxBlur.cpp',
--- a/widget/nsDeviceContextSpecProxy.cpp
+++ b/widget/nsDeviceContextSpecProxy.cpp
@@ -1,19 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDeviceContextSpecProxy.h"
 
+#include "gfxASurface.h"
 #include "gfxPlatform.h"
 #include "mozilla/gfx/DrawEventRecorder.h"
-#include "mozilla/gfx/PrintTargetRecording.h"
+#include "mozilla/gfx/PrintTargetThebes.h"
 #include "mozilla/layout/RemotePrintJobChild.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/unused.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIPrintSession.h"
 #include "nsIPrintSettings.h"
 
 using mozilla::Unused;
@@ -74,17 +75,38 @@ nsDeviceContextSpecProxy::MakePrintTarge
   if (NS_WARN_IF(NS_FAILED(rv)) || width <= 0 || height <= 0) {
     return nullptr;
   }
 
   // convert twips to points
   width /= TWIPS_PER_POINT_FLOAT;
   height /= TWIPS_PER_POINT_FLOAT;
 
-  return PrintTargetRecording::CreateOrNull(IntSize(width, height));
+  RefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->
+    CreateOffscreenSurface(mozilla::gfx::IntSize(width, height),
+                           mozilla::gfx::SurfaceFormat::A8R8G8B8_UINT32);
+  if (!surface) {
+    return nullptr;
+  }
+
+  // The type of PrintTarget that we return here shouldn't really matter since
+  // our implementation of GetDrawEventRecorder returns an object, which means
+  // the DrawTarget returned by the PrintTarget will be a DrawTargetRecording.
+  // The recording will be serialized and sent over to the parent process where
+  // PrintTranslator::TranslateRecording will call MakePrintTarget (indirectly
+  // via PrintTranslator::CreateDrawTarget) on whatever type of
+  // nsIDeviceContextSpecProxy is created for the platform that we are running
+  // on.  It is that DrawTarget that the recording will be replayed on to
+  // print.
+  // XXX(jwatt): The above isn't quite true.  We do want to use a
+  // PrintTargetRecording here, but we can't until bug 1280324 is figured out
+  // and fixed otherwise we will cause bug 1280181 to happen again.
+  RefPtr<PrintTarget> target = PrintTargetThebes::CreateOrNull(surface);
+
+  return target.forget();
 }
 
 NS_IMETHODIMP
 nsDeviceContextSpecProxy::GetDrawEventRecorder(mozilla::gfx::DrawEventRecorder** aDrawEventRecorder)
 {
   MOZ_ASSERT(aDrawEventRecorder);
   RefPtr<mozilla::gfx::DrawEventRecorder> result = mRecorder;
   result.forget(aDrawEventRecorder);