Bug 1417549: Execute IntoLuminanceSource during replay rather than synchronously. r=dvander draft
authorBas Schouten <bschouten@mozilla.com>
Thu, 16 Nov 2017 21:44:03 +0100
changeset 699214 55d70d26a7238fcef50ae4efbc1c778adeaa5016
parent 699136 062e2a74416a462a7497f287f4fc57f1c8b34db1
child 740566 1c9b34bc3af55991347334501efd0536859a8dad
push id89497
push userbschouten@mozilla.com
push dateThu, 16 Nov 2017 20:45:32 +0000
reviewersdvander
bugs1417549
milestone59.0a1
Bug 1417549: Execute IntoLuminanceSource during replay rather than synchronously. r=dvander MozReview-Commit-ID: DWGQoTpUnyT
gfx/2d/DrawTargetCapture.cpp
gfx/2d/DrawTargetCapture.h
gfx/2d/SourceSurfaceCapture.cpp
gfx/2d/SourceSurfaceCapture.h
--- a/gfx/2d/DrawTargetCapture.cpp
+++ b/gfx/2d/DrawTargetCapture.cpp
@@ -82,16 +82,24 @@ DrawTargetCaptureImpl::Snapshot()
     mSnapshot = new SourceSurfaceCapture(this);
   }
 
   RefPtr<SourceSurface> surface = mSnapshot;
   return surface.forget();
 }
 
 already_AddRefed<SourceSurface>
+DrawTargetCaptureImpl::IntoLuminanceSource(LuminanceType aLuminanceType,
+                                           float aOpacity)
+{
+  RefPtr<SourceSurface> surface = new SourceSurfaceCapture(this, true, aLuminanceType, aOpacity);
+  return surface.forget();
+}
+
+already_AddRefed<SourceSurface>
 DrawTargetCaptureImpl::OptimizeSourceSurface(SourceSurface *aSurface) const
 {
   // If the surface is a recording, make sure it gets resolved on the paint thread.
   if (aSurface->GetType() == SurfaceType::CAPTURE) {
     RefPtr<SourceSurface> surface = aSurface;
     return surface.forget();
   }
   return mRefDT->OptimizeSourceSurface(aSurface);
--- a/gfx/2d/DrawTargetCapture.h
+++ b/gfx/2d/DrawTargetCapture.h
@@ -28,16 +28,18 @@ public:
 
   bool Init(const IntSize& aSize, DrawTarget* aRefDT);
   void InitForData(int32_t aStride, size_t aSurfaceAllocationSize);
 
   virtual BackendType GetBackendType() const override { return mRefDT->GetBackendType(); }
   virtual DrawTargetType GetType() const override { return mRefDT->GetType(); }
   virtual bool IsCaptureDT() const override { return true; }
   virtual already_AddRefed<SourceSurface> Snapshot() override;
+  virtual already_AddRefed<SourceSurface> IntoLuminanceSource(LuminanceType aLuminanceType,
+                                                              float aOpacity) override;
   virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA) override;
   virtual void DetachAllSnapshots() override;
   virtual IntSize GetSize() override { return mSize; }
   virtual void Flush() override {}
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions,
--- a/gfx/2d/SourceSurfaceCapture.cpp
+++ b/gfx/2d/SourceSurfaceCapture.cpp
@@ -7,26 +7,37 @@
 #include "DrawCommand.h"
 #include "DrawTargetCapture.h"
 #include "MainThreadUtils.h"
 #include "mozilla/gfx/Logging.h"
 
 namespace mozilla {
 namespace gfx {
 
-SourceSurfaceCapture::SourceSurfaceCapture(DrawTargetCaptureImpl* aOwner)
+SourceSurfaceCapture::SourceSurfaceCapture(DrawTargetCaptureImpl* aOwner,
+                                           bool aShouldResolveToLuminance /* = false */,
+                                           LuminanceType aLuminanceType /* = LuminanceType::LINEARRGB */,
+                                           Float aOpacity /* = 1.0f */)
  : mOwner(aOwner),
    mHasCommandList(false),
+   mShouldResolveToLuminance{aShouldResolveToLuminance},
+   mLuminanceType{aLuminanceType},
+   mOpacity{aOpacity},
    mLock("SourceSurfaceCapture.mLock")
 {
   mSize = mOwner->GetSize();
   mFormat = mOwner->GetFormat();
   mRefDT = mOwner->mRefDT;
   mStride = mOwner->mStride;
   mSurfaceAllocationSize = mOwner->mSurfaceAllocationSize;
+
+  if (mShouldResolveToLuminance) {
+    // In this case our DrawTarget will not track us, so copy its drawing commands.
+    DrawTargetWillChange();
+  }
 }
 
 SourceSurfaceCapture::~SourceSurfaceCapture()
 {
 }
 
 bool
 SourceSurfaceCapture::IsValid() const
@@ -100,17 +111,21 @@ SourceSurfaceCapture::ResolveImpl(Backen
   // our own (which will be empty).
   CaptureCommandList& commands = mHasCommandList
                                  ? mCommands
                                  : mOwner->mCommands;
   for (CaptureCommandList::iterator iter(commands); !iter.Done(); iter.Next()) {
     DrawingCommand* cmd = iter.Get();
     cmd->ExecuteOnDT(dt, nullptr);
   }
-  return dt->Snapshot();
+  if (!mShouldResolveToLuminance) {
+    return dt->Snapshot();
+  } else {
+    return dt->IntoLuminanceSource(mLuminanceType, mOpacity);
+  }
 }
 
 already_AddRefed<DataSourceSurface>
 SourceSurfaceCapture::GetDataSurface()
 {
   RefPtr<SourceSurface> surface = Resolve();
   if (!surface) {
     return nullptr;
--- a/gfx/2d/SourceSurfaceCapture.h
+++ b/gfx/2d/SourceSurfaceCapture.h
@@ -16,17 +16,20 @@ namespace gfx {
 class DrawTargetCaptureImpl;
 
 class SourceSurfaceCapture : public SourceSurface
 {
   friend class DrawTargetCaptureImpl;
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceCapture, override)
 
-  explicit SourceSurfaceCapture(DrawTargetCaptureImpl* aOwner);
+  explicit SourceSurfaceCapture(DrawTargetCaptureImpl* aOwner,
+                                bool aShouldResolveToLuminance = false,
+                                LuminanceType aLuminanceType = LuminanceType::LINEARRGB,
+                                float aOpacity = 1.0f);
   ~SourceSurfaceCapture();
 
   SurfaceType GetType() const override { return SurfaceType::CAPTURE; }
   IntSize GetSize() const override { return mSize; }
   SurfaceFormat GetFormat() const override { return mFormat; }
 
   bool IsValid() const override;
   already_AddRefed<DataSourceSurface> GetDataSurface() override;
@@ -45,16 +48,20 @@ private:
   SurfaceFormat mFormat;
   int32_t mStride;
   int32_t mSurfaceAllocationSize;
   RefPtr<DrawTarget> mRefDT;
   DrawTargetCaptureImpl* mOwner;
   CaptureCommandList mCommands;
   bool mHasCommandList;
 
+  bool mShouldResolveToLuminance;
+  LuminanceType mLuminanceType;
+  float mOpacity;
+
   // Note that we have to keep a reference around. Internal methods like
   // GetSkImageForSurface expect their callers to hold a reference, which
   // isn't easily possible for nested surfaces.
   mutable Mutex mLock;
   RefPtr<SourceSurface> mResolved;
 };
 
 } // namespace gfx