Bug 1417549: Execute IntoLuminanceSource during replay rather than synchronously. r=dvander
MozReview-Commit-ID: DWGQoTpUnyT
--- 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