Bug 1280324, part 1 - Add functionality to the PrintTarget sub-classes to return reference DrawTargets. r=edwin
authorJonathan Watt <jwatt@jwatt.org>
Thu, 27 Oct 2016 19:24:12 +0100
changeset 363047 bcb5f7b49427929996c0b8425cb9220f0c07e7bc
parent 363046 4a6cd6dff941517c15ce49226f74e438f83983e8
child 363048 620893e272d615af3192524b9ca959890f9a2c24
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersedwin
bugs1280324
milestone52.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 1280324, part 1 - Add functionality to the PrintTarget sub-classes to return reference DrawTargets. r=edwin
gfx/thebes/PrintTarget.cpp
gfx/thebes/PrintTarget.h
gfx/thebes/PrintTargetThebes.cpp
gfx/thebes/PrintTargetThebes.h
--- a/gfx/thebes/PrintTarget.cpp
+++ b/gfx/thebes/PrintTarget.cpp
@@ -71,16 +71,46 @@ PrintTarget::MakeDrawTarget(const IntSiz
       return nullptr;
     }
   }
 
   return dt.forget();
 }
 
 already_AddRefed<DrawTarget>
+PrintTarget::GetReferenceDrawTarget()
+{
+  if (!mRefDT) {
+    IntSize size(1, 1);
+
+    cairo_surface_t* surface =
+      cairo_surface_create_similar(mCairoSurface,
+                                   cairo_surface_get_content(mCairoSurface),
+                                   size.width, size.height);
+
+    if (cairo_surface_status(surface)) {
+      return nullptr;
+    }
+
+    RefPtr<DrawTarget> dt =
+      Factory::CreateDrawTargetForCairoSurface(surface, size);
+
+    // The DT addrefs the surface, so we need drop our own reference to it:
+    cairo_surface_destroy(surface);
+
+    if (!dt || !dt->IsValid()) {
+      return nullptr;
+    }
+
+    mRefDT = dt.forget();
+  }
+  return do_AddRef(mRefDT);
+}
+
+already_AddRefed<DrawTarget>
 PrintTarget::CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
                                        DrawTarget* aDrawTarget)
 {
   MOZ_ASSERT(aRecorder);
   MOZ_ASSERT(aDrawTarget);
 
   RefPtr<DrawTarget> dt;
 
--- a/gfx/thebes/PrintTarget.h
+++ b/gfx/thebes/PrintTarget.h
@@ -106,29 +106,38 @@ public:
    *
    * TODO: Consider adding a SetDPI method that calls
    * cairo_surface_set_fallback_resolution.
    */
   virtual already_AddRefed<DrawTarget>
   MakeDrawTarget(const IntSize& aSize,
                  DrawEventRecorder* aRecorder = nullptr);
 
+  /**
+   * Returns a reference DrawTarget. Unlike MakeDrawTarget, this method is not
+   * restricted to being called between BeginPage()/EndPage() calls, and the
+   * returned DrawTarget it is still valid to use after EndPage() has been
+   * called.
+   */
+  virtual already_AddRefed<DrawTarget> GetReferenceDrawTarget();
+
 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;
+  RefPtr<DrawTarget> mRefDT; // reference DT
   IntSize mSize;
   bool mIsFinished;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_PRINTTARGET_H */
--- a/gfx/thebes/PrintTargetThebes.cpp
+++ b/gfx/thebes/PrintTargetThebes.cpp
@@ -47,16 +47,30 @@ PrintTargetThebes::MakeDrawTarget(const 
     if (!dt || !dt->IsValid()) {
       return nullptr;
     }
   }
 
   return dt.forget();
 }
 
+already_AddRefed<DrawTarget>
+PrintTargetThebes::GetReferenceDrawTarget()
+{
+  if (!mRefDT) {
+    RefPtr<gfx::DrawTarget> dt =
+      gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mGfxSurface, mSize);
+    if (!dt || !dt->IsValid()) {
+      return nullptr;
+    }
+    mRefDT = dt->CreateSimilarDrawTarget(IntSize(1,1), dt->GetFormat());
+  }
+  return do_AddRef(mRefDT);
+}
+
 nsresult
 PrintTargetThebes::BeginPrinting(const nsAString& aTitle,
                                  const nsAString& aPrintToFileName)
 {
   return mGfxSurface->BeginPrinting(aTitle, aPrintToFileName);
 }
 
 nsresult
--- a/gfx/thebes/PrintTargetThebes.h
+++ b/gfx/thebes/PrintTargetThebes.h
@@ -36,16 +36,18 @@ public:
   virtual nsresult BeginPage() override;
   virtual nsresult EndPage() override;
   virtual void Finish() override;
 
   virtual already_AddRefed<DrawTarget>
   MakeDrawTarget(const IntSize& aSize,
                  DrawEventRecorder* aRecorder = nullptr) override;
 
+  virtual already_AddRefed<DrawTarget> GetReferenceDrawTarget() final;
+
 private:
 
   // Only created via CreateOrNull
   explicit PrintTargetThebes(gfxASurface* aSurface);
 
   RefPtr<gfxASurface> mGfxSurface;
 };