Bug 1728113 - Remove DrawTargetCapture and related code. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D123953
This commit is contained in:
Andrew Osmond 2021-08-30 16:35:50 +00:00
parent fe21b00004
commit ac49f09199
37 changed files with 10 additions and 2917 deletions

View File

@ -96,9 +96,8 @@ already_AddRefed<Path> SVGGeometryElement::GetOrBuildPath(
// and it's not a capturing drawtarget. A capturing DT might start using the
// the Path object on a different thread (OMTP), and we might have a data race
// if we keep a handle to it.
bool cacheable = (aDrawTarget->GetBackendType() ==
gfxPlatform::GetPlatform()->GetDefaultContentBackend()) &&
!aDrawTarget->IsCaptureDT();
bool cacheable = aDrawTarget->GetBackendType() ==
gfxPlatform::GetPlatform()->GetDefaultContentBackend();
if (cacheable && mCachedPath && mCachedPath->GetFillRule() == aFillRule &&
aDrawTarget->GetBackendType() == mCachedPath->GetBackendType()) {

View File

@ -355,7 +355,6 @@ class SurfacePattern : public Pattern {
};
class StoredPattern;
class DrawTargetCaptureImpl;
static const int32_t kReasonableSurfaceSize = 8192;
@ -485,15 +484,8 @@ class SourceSurface : public external::AtomicRefCounted<SourceSurface> {
void RemoveUserData(UserDataKey* key) { mUserData.RemoveAndDestroy(key); }
protected:
friend class DrawTargetCaptureImpl;
friend class StoredPattern;
// This is for internal use, it ensures the SourceSurface's data remains
// valid during the lifetime of the SourceSurface.
// @todo XXX - We need something better here :(. But we may be able to get rid
// of CreateWrappingDataSourceSurface in the future.
virtual void GuaranteePersistance() {}
UserData mUserData;
};
@ -1053,8 +1045,6 @@ class NativeFontResource
size_t mDataLength;
};
class DrawTargetCapture;
/** This is the main class used for all the drawing. It is created through the
* factory and accepts drawing commands. The results of drawing to a target
* may be used either through a Snapshot or by flushing the target and directly
@ -1075,7 +1065,6 @@ class DrawTarget : public external::AtomicRefCounted<DrawTarget> {
virtual BackendType GetBackendType() const = 0;
virtual bool IsRecording() const { return false; }
virtual bool IsCaptureDT() const { return false; }
/**
* Method to generate hyperlink in PDF output (with appropriate backend).
@ -1124,15 +1113,6 @@ class DrawTarget : public external::AtomicRefCounted<DrawTarget> {
*/
virtual void Flush() = 0;
/**
* Realize a DrawTargetCapture onto the draw target.
*
* @param aSource Capture DrawTarget to draw
* @param aTransform Transform to apply when replaying commands
*/
virtual void DrawCapturedDT(DrawTargetCapture* aCaptureDT,
const Matrix& aTransform);
/**
* Draw a surface to the draw target. Possibly doing partial drawing or
* applying scaling. No sampling happens outside the source.
@ -1683,14 +1663,6 @@ class DrawTarget : public external::AtomicRefCounted<DrawTarget> {
SurfaceFormat mFormat;
};
class DrawTargetCapture : public DrawTarget {
public:
bool IsCaptureDT() const override { return true; }
virtual bool IsEmpty() const = 0;
virtual void Dump() = 0;
};
class DrawEventRecorder : public RefCounted<DrawEventRecorder> {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorder)
@ -1777,31 +1749,6 @@ class GFX2D_API Factory {
*/
static already_AddRefed<PathBuilder> CreateSimplePathBuilder();
/**
* Create a DrawTarget that captures the drawing commands to eventually be
* replayed onto the DrawTarget provided. An optional byte size can be
* provided as a limit for the CaptureCommandList. When the limit is reached,
* the CaptureCommandList will be replayed to the target and then cleared.
*
* @param aSize Size of the area this DT will capture.
* @param aFlushBytes The byte limit at which to flush the CaptureCommandList
*/
static already_AddRefed<DrawTargetCapture> CreateCaptureDrawTargetForTarget(
gfx::DrawTarget* aTarget, size_t aFlushBytes = 0);
/**
* Create a DrawTarget that captures the drawing commands and can be replayed
* onto a compatible DrawTarget afterwards.
*
* @param aSize Size of the area this DT will capture.
*/
static already_AddRefed<DrawTargetCapture> CreateCaptureDrawTarget(
BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat);
static already_AddRefed<DrawTargetCapture> CreateCaptureDrawTargetForData(
BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat,
int32_t aStride, size_t aSurfaceAllocationSize);
static already_AddRefed<DrawTarget> CreateRecordingDrawTarget(
DrawEventRecorder* aRecorder, DrawTarget* aDT, IntRect aRect);

View File

@ -1,25 +0,0 @@
/* -*- 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 "CaptureCommandList.h"
#include "DrawCommand.h"
namespace mozilla {
namespace gfx {
CaptureCommandList::~CaptureCommandList() { Clear(); }
void CaptureCommandList::Clear() {
for (iterator iter(*this); !iter.Done(); iter.Next()) {
DrawingCommand* cmd = iter.Get();
cmd->~DrawingCommand();
}
mLastCommand = nullptr;
mStorage.clear();
}
} // namespace gfx
} // namespace mozilla

View File

@ -1,142 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_gfx_2d_CaptureCommandList_h
#define mozilla_gfx_2d_CaptureCommandList_h
#include <limits>
#include <utility>
#include <vector>
#include "DrawCommand.h"
#include "Logging.h"
#include "mozilla/PodOperations.h"
// Command object is stored into record with header containing size and
// redundant size of whole record. Some platforms may require Command
// object to be stored on 8 bytes aligned address. Therefore we need to
// adjust size of header for these platforms.
#ifdef __sparc__
typedef uint32_t kAdvance_t;
#else
typedef uint16_t kAdvance_t;
#endif
namespace mozilla {
namespace gfx {
class CaptureCommandList {
public:
CaptureCommandList() : mLastCommand(nullptr) {}
CaptureCommandList(CaptureCommandList&& aOther)
: mStorage(std::move(aOther.mStorage)),
mLastCommand(aOther.mLastCommand) {
aOther.mLastCommand = nullptr;
}
~CaptureCommandList();
CaptureCommandList& operator=(CaptureCommandList&& aOther) {
mStorage = std::move(aOther.mStorage);
mLastCommand = aOther.mLastCommand;
aOther.mLastCommand = nullptr;
return *this;
}
template <typename T>
T* Append() {
static_assert(sizeof(T) + 2 * sizeof(kAdvance_t) <=
std::numeric_limits<kAdvance_t>::max(),
"encoding is too small to contain advance");
const kAdvance_t kAdvance = sizeof(T) + 2 * sizeof(kAdvance_t);
size_t size = mStorage.size();
mStorage.resize(size + kAdvance);
uint8_t* current = &mStorage.front() + size;
*(kAdvance_t*)(current) = kAdvance;
current += sizeof(kAdvance_t);
*(kAdvance_t*)(current) = ~kAdvance;
current += sizeof(kAdvance_t);
T* command = reinterpret_cast<T*>(current);
mLastCommand = command;
return command;
}
template <typename T>
T* ReuseOrAppend() {
{ // Scope lock
if (mLastCommand != nullptr && mLastCommand->GetType() == T::Type) {
return reinterpret_cast<T*>(mLastCommand);
}
}
return Append<T>();
}
bool IsEmpty() const { return mStorage.empty(); }
template <typename T>
bool BufferWillAlloc() const {
const kAdvance_t kAdvance = sizeof(T) + 2 * sizeof(kAdvance_t);
return mStorage.size() + kAdvance > mStorage.capacity();
}
size_t BufferCapacity() const { return mStorage.capacity(); }
void Clear();
class iterator {
public:
explicit iterator(CaptureCommandList& aParent)
: mParent(aParent), mCurrent(nullptr), mEnd(nullptr) {
if (!mParent.mStorage.empty()) {
mCurrent = &mParent.mStorage.front();
mEnd = mCurrent + mParent.mStorage.size();
}
}
bool Done() const { return mCurrent >= mEnd; }
void Next() {
MOZ_ASSERT(!Done());
kAdvance_t advance = *reinterpret_cast<kAdvance_t*>(mCurrent);
kAdvance_t redundant =
~*reinterpret_cast<kAdvance_t*>(mCurrent + sizeof(kAdvance_t));
MOZ_RELEASE_ASSERT(advance == redundant);
mCurrent += advance;
}
DrawingCommand* Get() {
MOZ_ASSERT(!Done());
return reinterpret_cast<DrawingCommand*>(mCurrent +
2 * sizeof(kAdvance_t));
}
private:
CaptureCommandList& mParent;
uint8_t* mCurrent;
uint8_t* mEnd;
};
void Log(TreeLog<>& aStream) {
for (iterator iter(*this); !iter.Done(); iter.Next()) {
DrawingCommand* cmd = iter.Get();
cmd->Log(aStream);
aStream << "\n";
}
}
private:
CaptureCommandList(const CaptureCommandList& aOther) = delete;
void operator=(const CaptureCommandList& aOther) = delete;
private:
std::vector<uint8_t> mStorage;
DrawingCommand* mLastCommand;
};
} // namespace gfx
} // namespace mozilla
#endif // mozilla_gfx_2d_CaptureCommandList_h

View File

@ -1,67 +0,0 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_DRAWCOMMAND_H_
#define MOZILLA_GFX_DRAWCOMMAND_H_
#include <math.h>
#include "2D.h"
#include "Blur.h"
#include "Filters.h"
#include <vector>
#include "FilterNodeCapture.h"
#include "Logging.h"
namespace mozilla {
namespace gfx {
class CaptureCommandList;
enum class CommandType : int8_t {
DRAWSURFACE = 0,
DRAWFILTER,
DRAWSURFACEWITHSHADOW,
CLEARRECT,
COPYSURFACE,
COPYRECT,
FILLRECT,
FILLROUNDEDRECT,
STROKERECT,
STROKELINE,
STROKE,
FILL,
FILLGLYPHS,
STROKEGLYPHS,
MASK,
MASKSURFACE,
PUSHCLIP,
PUSHCLIPRECT,
PUSHLAYER,
POPCLIP,
POPLAYER,
SETTRANSFORM,
SETPERMITSUBPIXELAA,
FLUSH,
BLUR,
PADEDGES,
};
class DrawingCommand {
public:
virtual ~DrawingCommand() = default;
virtual CommandType GetType() const = 0;
virtual void ExecuteOnDT(DrawTarget* aDT,
const Matrix* aTransform = nullptr) const = 0;
virtual void CloneInto(CaptureCommandList* aList) = 0;
virtual void Log(TreeLog<>& aLog) const = 0;
};
} // namespace gfx
} // namespace mozilla
#endif /* MOZILLA_GFX_DRAWCOMMAND_H_ */

View File

@ -1,997 +0,0 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_DRAWCOMMANDS_H_
#define MOZILLA_GFX_DRAWCOMMANDS_H_
#include <math.h>
#include "2D.h"
#include "Blur.h"
#include "Filters.h"
#include <vector>
#include "CaptureCommandList.h"
#include "DrawCommand.h"
#include "FilterNodeCapture.h"
#include "Logging.h"
#include "nsRegion.h"
namespace mozilla {
namespace gfx {
#define CLONE_INTO(Type) new (aList->Append<Type>()) Type
class StrokeOptionsCommand : public DrawingCommand {
public:
StrokeOptionsCommand(const StrokeOptions& aStrokeOptions)
: mStrokeOptions(aStrokeOptions) {
// Stroke Options dashes are owned by the caller.
// Have to copy them here so they don't get freed
// between now and replay.
if (aStrokeOptions.mDashLength) {
mDashes.resize(aStrokeOptions.mDashLength);
mStrokeOptions.mDashPattern = &mDashes.front();
PodCopy(&mDashes.front(), aStrokeOptions.mDashPattern,
mStrokeOptions.mDashLength);
}
}
virtual ~StrokeOptionsCommand() = default;
protected:
StrokeOptions mStrokeOptions;
std::vector<Float> mDashes;
};
class StoredPattern {
public:
explicit StoredPattern(const Pattern& aPattern) { Assign(aPattern); }
void Assign(const Pattern& aPattern) {
switch (aPattern.GetType()) {
case PatternType::COLOR:
new (mColor) ColorPattern(*static_cast<const ColorPattern*>(&aPattern));
return;
case PatternType::SURFACE: {
SurfacePattern* surfPat = new (mSurface)
SurfacePattern(*static_cast<const SurfacePattern*>(&aPattern));
surfPat->mSurface->GuaranteePersistance();
return;
}
case PatternType::LINEAR_GRADIENT:
new (mLinear) LinearGradientPattern(
*static_cast<const LinearGradientPattern*>(&aPattern));
return;
case PatternType::RADIAL_GRADIENT:
new (mRadial) RadialGradientPattern(
*static_cast<const RadialGradientPattern*>(&aPattern));
return;
case PatternType::CONIC_GRADIENT:
new (mConic) ConicGradientPattern(
*static_cast<const ConicGradientPattern*>(&aPattern));
return;
}
}
~StoredPattern() { reinterpret_cast<Pattern*>(mPattern)->~Pattern(); }
Pattern* Get() { return reinterpret_cast<Pattern*>(mPattern); }
const Pattern* Get() const {
return reinterpret_cast<const Pattern*>(mPattern);
}
operator Pattern&() { return *reinterpret_cast<Pattern*>(mPattern); }
operator const Pattern&() const {
return *reinterpret_cast<const Pattern*>(mPattern);
}
StoredPattern(const StoredPattern& aPattern) { Assign(aPattern); }
private:
StoredPattern operator=(const StoredPattern& aOther) {
// Block this so that we notice if someone's doing excessive assigning.
return *this;
}
union {
char mPattern[sizeof(Pattern)];
char mColor[sizeof(ColorPattern)];
char mLinear[sizeof(LinearGradientPattern)];
char mRadial[sizeof(RadialGradientPattern)];
char mConic[sizeof(ConicGradientPattern)];
char mSurface[sizeof(SurfacePattern)];
};
};
class DrawSurfaceCommand : public DrawingCommand {
public:
DrawSurfaceCommand(SourceSurface* aSurface, const Rect& aDest,
const Rect& aSource,
const DrawSurfaceOptions& aSurfOptions,
const DrawOptions& aOptions)
: mSurface(aSurface),
mDest(aDest),
mSource(aSource),
mSurfOptions(aSurfOptions),
mOptions(aOptions) {}
CommandType GetType() const override { return DrawSurfaceCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(DrawSurfaceCommand)
(mSurface, mDest, mSource, mSurfOptions, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->DrawSurface(mSurface, mDest, mSource, mSurfOptions, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[DrawSurface surf=" << mSurface;
aStream << " dest=" << mDest;
aStream << " src=" << mSource;
aStream << " surfOpt=" << mSurfOptions;
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::DRAWSURFACE;
private:
RefPtr<SourceSurface> mSurface;
Rect mDest;
Rect mSource;
DrawSurfaceOptions mSurfOptions;
DrawOptions mOptions;
};
class DrawSurfaceWithShadowCommand : public DrawingCommand {
public:
DrawSurfaceWithShadowCommand(SourceSurface* aSurface, const Point& aDest,
const DeviceColor& aColor, const Point& aOffset,
Float aSigma, CompositionOp aOperator)
: mSurface(aSurface),
mDest(aDest),
mColor(aColor),
mOffset(aOffset),
mSigma(aSigma),
mOperator(aOperator) {}
CommandType GetType() const override {
return DrawSurfaceWithShadowCommand::Type;
}
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(DrawSurfaceWithShadowCommand)
(mSurface, mDest, mColor, mOffset, mSigma, mOperator);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->DrawSurfaceWithShadow(mSurface, mDest, mColor, mOffset, mSigma,
mOperator);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[DrawSurfaceWithShadow surf=" << mSurface;
aStream << " dest=" << mDest;
aStream << " color=" << mColor;
aStream << " offset=" << mOffset;
aStream << " sigma=" << mSigma;
aStream << " op=" << mOperator;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::DRAWSURFACEWITHSHADOW;
private:
RefPtr<SourceSurface> mSurface;
Point mDest;
DeviceColor mColor;
Point mOffset;
Float mSigma;
CompositionOp mOperator;
};
class DrawFilterCommand : public DrawingCommand {
public:
DrawFilterCommand(FilterNode* aFilter, const Rect& aSourceRect,
const Point& aDestPoint, const DrawOptions& aOptions)
: mFilter(aFilter),
mSourceRect(aSourceRect),
mDestPoint(aDestPoint),
mOptions(aOptions) {}
CommandType GetType() const override { return DrawFilterCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(DrawFilterCommand)(mFilter, mSourceRect, mDestPoint, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
RefPtr<FilterNode> filter = mFilter;
if (mFilter->GetBackendType() == FilterBackend::FILTER_BACKEND_CAPTURE) {
filter = static_cast<FilterNodeCapture*>(filter.get())->Validate(aDT);
// This can happen if the FilterNodeCapture is unable to create a
// backing FilterNode on the target backend. Normally this would be
// handled by the painting code, but here there's not much we can do.
if (!filter) {
return;
}
}
aDT->DrawFilter(filter, mSourceRect, mDestPoint, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[DrawFilter surf=" << mFilter;
aStream << " src=" << mSourceRect;
aStream << " dest=" << mDestPoint;
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::DRAWFILTER;
private:
RefPtr<FilterNode> mFilter;
Rect mSourceRect;
Point mDestPoint;
DrawOptions mOptions;
};
class ClearRectCommand : public DrawingCommand {
public:
explicit ClearRectCommand(const Rect& aRect) : mRect(aRect) {}
CommandType GetType() const override { return ClearRectCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(ClearRectCommand)(mRect);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->ClearRect(mRect);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[ClearRect rect=" << mRect << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::CLEARRECT;
private:
Rect mRect;
};
class CopySurfaceCommand : public DrawingCommand {
public:
CopySurfaceCommand(SourceSurface* aSurface, const IntRect& aSourceRect,
const IntPoint& aDestination)
: mSurface(aSurface),
mSourceRect(aSourceRect),
mDestination(aDestination) {}
CommandType GetType() const override { return CopySurfaceCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(CopySurfaceCommand)(mSurface, mSourceRect, mDestination);
}
virtual void ExecuteOnDT(DrawTarget* aDT,
const Matrix* aTransform) const override {
MOZ_ASSERT(!aTransform || !aTransform->HasNonIntegerTranslation());
Point dest(Float(mDestination.x), Float(mDestination.y));
if (aTransform) {
dest = aTransform->TransformPoint(dest);
}
aDT->CopySurface(mSurface, mSourceRect,
IntPoint(uint32_t(dest.x), uint32_t(dest.y)));
}
void Log(TreeLog<>& aStream) const override {
aStream << "[CopySurface surf=" << mSurface;
aStream << " src=" << mSourceRect;
aStream << " dest=" << mDestination;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::COPYSURFACE;
private:
RefPtr<SourceSurface> mSurface;
IntRect mSourceRect;
IntPoint mDestination;
};
class CopyRectCommand : public DrawingCommand {
public:
CopyRectCommand(const IntRect& aSourceRect, const IntPoint& aDestination)
: mSourceRect(aSourceRect), mDestination(aDestination) {}
CommandType GetType() const override { return CopyRectCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(CopyRectCommand)(mSourceRect, mDestination);
}
virtual void ExecuteOnDT(DrawTarget* aDT,
const Matrix* aTransform) const override {
aDT->CopyRect(mSourceRect, mDestination);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[CopyRect src=" << mSourceRect;
aStream << " dest=" << mDestination;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::COPYRECT;
private:
IntRect mSourceRect;
IntPoint mDestination;
};
class FillRectCommand : public DrawingCommand {
public:
FillRectCommand(const Rect& aRect, const Pattern& aPattern,
const DrawOptions& aOptions)
: mRect(aRect), mPattern(aPattern), mOptions(aOptions) {}
CommandType GetType() const override { return FillRectCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(FillRectCommand)(mRect, mPattern, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->FillRect(mRect, mPattern, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[FillRect rect=" << mRect;
aStream << " pattern=" << mPattern.Get();
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::FILLRECT;
private:
Rect mRect;
StoredPattern mPattern;
DrawOptions mOptions;
};
class FillRoundedRectCommand : public DrawingCommand {
public:
FillRoundedRectCommand(const RoundedRect& aRect, const Pattern& aPattern,
const DrawOptions& aOptions)
: mRect(aRect), mPattern(aPattern), mOptions(aOptions) {}
CommandType GetType() const override { return FillRoundedRectCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(FillRoundedRectCommand)(mRect, mPattern, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->FillRoundedRect(mRect, mPattern, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[FillRoundedRect rect=" << mRect.rect;
aStream << " pattern=" << mPattern.Get();
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::FILLROUNDEDRECT;
private:
RoundedRect mRect;
StoredPattern mPattern;
DrawOptions mOptions;
};
class StrokeRectCommand : public StrokeOptionsCommand {
public:
StrokeRectCommand(const Rect& aRect, const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions)
: StrokeOptionsCommand(aStrokeOptions),
mRect(aRect),
mPattern(aPattern),
mOptions(aOptions) {}
CommandType GetType() const override { return StrokeRectCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(StrokeRectCommand)(mRect, mPattern, mStrokeOptions, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->StrokeRect(mRect, mPattern, mStrokeOptions, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[StrokeRect rect=" << mRect;
aStream << " pattern=" << mPattern.Get();
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::STROKERECT;
private:
Rect mRect;
StoredPattern mPattern;
DrawOptions mOptions;
};
class StrokeLineCommand : public StrokeOptionsCommand {
public:
StrokeLineCommand(const Point& aStart, const Point& aEnd,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions)
: StrokeOptionsCommand(aStrokeOptions),
mStart(aStart),
mEnd(aEnd),
mPattern(aPattern),
mOptions(aOptions) {}
CommandType GetType() const override { return StrokeLineCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(StrokeLineCommand)
(mStart, mEnd, mPattern, mStrokeOptions, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->StrokeLine(mStart, mEnd, mPattern, mStrokeOptions, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[StrokeLine start=" << mStart;
aStream << " end=" << mEnd;
aStream << " pattern=" << mPattern.Get();
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::STROKELINE;
private:
Point mStart;
Point mEnd;
StoredPattern mPattern;
DrawOptions mOptions;
};
class FillCommand : public DrawingCommand {
public:
FillCommand(const Path* aPath, const Pattern& aPattern,
const DrawOptions& aOptions)
: mPath(const_cast<Path*>(aPath)),
mPattern(aPattern),
mOptions(aOptions) {}
CommandType GetType() const override { return FillCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(FillCommand)(mPath, mPattern, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->Fill(mPath, mPattern, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[FillCommand path=" << mPath;
aStream << " pattern=" << mPattern.Get();
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::FILL;
private:
RefPtr<Path> mPath;
StoredPattern mPattern;
DrawOptions mOptions;
};
class StrokeCommand : public StrokeOptionsCommand {
public:
StrokeCommand(const Path* aPath, const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions)
: StrokeOptionsCommand(aStrokeOptions),
mPath(const_cast<Path*>(aPath)),
mPattern(aPattern),
mOptions(aOptions) {}
CommandType GetType() const override { return StrokeCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(StrokeCommand)(mPath, mPattern, mStrokeOptions, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->Stroke(mPath, mPattern, mStrokeOptions, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[Stroke path=" << mPath;
aStream << " pattern=" << mPattern.Get();
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::STROKE;
private:
RefPtr<Path> mPath;
StoredPattern mPattern;
DrawOptions mOptions;
};
class FillGlyphsCommand : public DrawingCommand {
friend class DrawTargetCaptureImpl;
public:
FillGlyphsCommand(ScaledFont* aFont, const GlyphBuffer& aBuffer,
const Pattern& aPattern, const DrawOptions& aOptions)
: mFont(aFont), mPattern(aPattern), mOptions(aOptions) {
mGlyphs.resize(aBuffer.mNumGlyphs);
memcpy(&mGlyphs.front(), aBuffer.mGlyphs,
sizeof(Glyph) * aBuffer.mNumGlyphs);
}
CommandType GetType() const override { return FillGlyphsCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
GlyphBuffer glyphs = {
mGlyphs.data(),
(uint32_t)mGlyphs.size(),
};
CLONE_INTO(FillGlyphsCommand)(mFont, glyphs, mPattern, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
GlyphBuffer buf;
buf.mNumGlyphs = mGlyphs.size();
buf.mGlyphs = &mGlyphs.front();
aDT->FillGlyphs(mFont, buf, mPattern, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[FillGlyphs font=" << mFont;
aStream << " glyphCount=" << mGlyphs.size();
aStream << " pattern=" << mPattern.Get();
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::FILLGLYPHS;
private:
RefPtr<ScaledFont> mFont;
std::vector<Glyph> mGlyphs;
StoredPattern mPattern;
DrawOptions mOptions;
};
class StrokeGlyphsCommand : public StrokeOptionsCommand {
friend class DrawTargetCaptureImpl;
public:
StrokeGlyphsCommand(ScaledFont* aFont, const GlyphBuffer& aBuffer,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions)
: StrokeOptionsCommand(aStrokeOptions),
mFont(aFont),
mPattern(aPattern),
mOptions(aOptions) {
mGlyphs.resize(aBuffer.mNumGlyphs);
memcpy(&mGlyphs.front(), aBuffer.mGlyphs,
sizeof(Glyph) * aBuffer.mNumGlyphs);
}
CommandType GetType() const override { return StrokeGlyphsCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
GlyphBuffer glyphs = {
mGlyphs.data(),
(uint32_t)mGlyphs.size(),
};
CLONE_INTO(StrokeGlyphsCommand)
(mFont, glyphs, mPattern, mStrokeOptions, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
GlyphBuffer buf;
buf.mNumGlyphs = mGlyphs.size();
buf.mGlyphs = &mGlyphs.front();
aDT->StrokeGlyphs(mFont, buf, mPattern, mStrokeOptions, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[StrokeGlyphs font=" << mFont;
aStream << " glyphCount=" << mGlyphs.size();
aStream << " pattern=" << mPattern.Get();
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::STROKEGLYPHS;
private:
RefPtr<ScaledFont> mFont;
std::vector<Glyph> mGlyphs;
StoredPattern mPattern;
DrawOptions mOptions;
};
class MaskCommand : public DrawingCommand {
public:
MaskCommand(const Pattern& aSource, const Pattern& aMask,
const DrawOptions& aOptions)
: mSource(aSource), mMask(aMask), mOptions(aOptions) {}
CommandType GetType() const override { return MaskCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(MaskCommand)(mSource, mMask, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->Mask(mSource, mMask, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[Mask source=" << mSource.Get();
aStream << " mask=" << mMask.Get();
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::MASK;
private:
StoredPattern mSource;
StoredPattern mMask;
DrawOptions mOptions;
};
class MaskSurfaceCommand : public DrawingCommand {
public:
MaskSurfaceCommand(const Pattern& aSource, const SourceSurface* aMask,
const Point& aOffset, const DrawOptions& aOptions)
: mSource(aSource),
mMask(const_cast<SourceSurface*>(aMask)),
mOffset(aOffset),
mOptions(aOptions) {}
CommandType GetType() const override { return MaskSurfaceCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(MaskSurfaceCommand)(mSource, mMask, mOffset, mOptions);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->MaskSurface(mSource, mMask, mOffset, mOptions);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[Mask source=" << mSource.Get();
aStream << " mask=" << mMask;
aStream << " offset=" << &mOffset;
aStream << " opt=" << mOptions;
aStream << "]";
}
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::MASKSURFACE;
private:
StoredPattern mSource;
RefPtr<SourceSurface> mMask;
Point mOffset;
DrawOptions mOptions;
};
class PushClipCommand : public DrawingCommand {
public:
explicit PushClipCommand(const Path* aPath)
: mPath(const_cast<Path*>(aPath)) {}
CommandType GetType() const override { return PushClipCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(PushClipCommand)(mPath);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->PushClip(mPath);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[PushClip path=" << mPath << "]";
}
static const bool AffectsSnapshot = false;
static const CommandType Type = CommandType::PUSHCLIP;
private:
RefPtr<Path> mPath;
};
class PushClipRectCommand : public DrawingCommand {
public:
explicit PushClipRectCommand(const Rect& aRect) : mRect(aRect) {}
CommandType GetType() const override { return PushClipRectCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(PushClipRectCommand)(mRect);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->PushClipRect(mRect);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[PushClipRect rect=" << mRect << "]";
}
static const bool AffectsSnapshot = false;
static const CommandType Type = CommandType::PUSHCLIPRECT;
private:
Rect mRect;
};
class PushLayerCommand : public DrawingCommand {
public:
PushLayerCommand(const bool aOpaque, const Float aOpacity,
SourceSurface* aMask, const Matrix& aMaskTransform,
const IntRect& aBounds, bool aCopyBackground)
: mOpaque(aOpaque),
mOpacity(aOpacity),
mMask(aMask),
mMaskTransform(aMaskTransform),
mBounds(aBounds),
mCopyBackground(aCopyBackground) {}
CommandType GetType() const override { return PushLayerCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(PushLayerCommand)
(mOpaque, mOpacity, mMask, mMaskTransform, mBounds, mCopyBackground);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->PushLayer(mOpaque, mOpacity, mMask, mMaskTransform, mBounds,
mCopyBackground);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[PushLayer opaque=" << mOpaque;
aStream << " opacity=" << mOpacity;
aStream << " mask=" << mMask;
aStream << " maskTransform=" << mMaskTransform;
aStream << " bounds=" << mBounds;
aStream << " copyBackground=" << mCopyBackground;
aStream << "]";
}
static const bool AffectsSnapshot = false;
static const CommandType Type = CommandType::PUSHLAYER;
private:
bool mOpaque;
float mOpacity;
RefPtr<SourceSurface> mMask;
Matrix mMaskTransform;
IntRect mBounds;
bool mCopyBackground;
};
class PopClipCommand : public DrawingCommand {
public:
PopClipCommand() = default;
CommandType GetType() const override { return PopClipCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(PopClipCommand)();
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->PopClip();
}
void Log(TreeLog<>& aStream) const override { aStream << "[PopClip]"; }
static const bool AffectsSnapshot = false;
static const CommandType Type = CommandType::POPCLIP;
};
class PopLayerCommand : public DrawingCommand {
public:
PopLayerCommand() = default;
CommandType GetType() const override { return PopLayerCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(PopLayerCommand)();
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->PopLayer();
}
void Log(TreeLog<>& aStream) const override { aStream << "[PopLayer]"; }
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::POPLAYER;
};
class SetTransformCommand : public DrawingCommand {
friend class DrawTargetCaptureImpl;
public:
explicit SetTransformCommand(const Matrix& aTransform)
: mTransform(aTransform) {}
CommandType GetType() const override { return SetTransformCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(SetTransformCommand)(mTransform);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix* aMatrix) const override {
if (aMatrix) {
aDT->SetTransform(mTransform * (*aMatrix));
} else {
aDT->SetTransform(mTransform);
}
}
void Log(TreeLog<>& aStream) const override {
aStream << "[SetTransform transform=" << mTransform << "]";
}
static const bool AffectsSnapshot = false;
static const CommandType Type = CommandType::SETTRANSFORM;
private:
Matrix mTransform;
};
class SetPermitSubpixelAACommand : public DrawingCommand {
friend class DrawTargetCaptureImpl;
public:
explicit SetPermitSubpixelAACommand(bool aPermitSubpixelAA)
: mPermitSubpixelAA(aPermitSubpixelAA) {}
CommandType GetType() const override {
return SetPermitSubpixelAACommand::Type;
}
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(SetPermitSubpixelAACommand)(mPermitSubpixelAA);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix* aMatrix) const override {
aDT->SetPermitSubpixelAA(mPermitSubpixelAA);
}
void Log(TreeLog<>& aStream) const override {
aStream << "[SetPermitSubpixelAA permitSubpixelAA=" << mPermitSubpixelAA
<< "]";
}
static const bool AffectsSnapshot = false;
static const CommandType Type = CommandType::SETPERMITSUBPIXELAA;
private:
bool mPermitSubpixelAA;
};
class FlushCommand : public DrawingCommand {
public:
FlushCommand() = default;
CommandType GetType() const override { return FlushCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(FlushCommand)();
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->Flush();
}
void Log(TreeLog<>& aStream) const override { aStream << "[Flush]"; }
static const bool AffectsSnapshot = false;
static const CommandType Type = CommandType::FLUSH;
};
class BlurCommand : public DrawingCommand {
public:
explicit BlurCommand(const AlphaBoxBlur& aBlur) : mBlur(aBlur) {}
CommandType GetType() const override { return BlurCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(BlurCommand)(mBlur);
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->Blur(mBlur);
}
void Log(TreeLog<>& aStream) const override { aStream << "[Blur]"; }
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::BLUR;
private:
AlphaBoxBlur mBlur;
};
class PadEdgesCommand : public DrawingCommand {
public:
explicit PadEdgesCommand(const IntRegion& aRegion) : mRegion(aRegion) {}
CommandType GetType() const override { return PadEdgesCommand::Type; }
void CloneInto(CaptureCommandList* aList) override {
CLONE_INTO(PadEdgesCommand)(IntRegion(mRegion));
}
void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
aDT->PadEdges(mRegion);
}
void Log(TreeLog<>& aStream) const override { aStream << "[PADEDGES]"; }
static const bool AffectsSnapshot = true;
static const CommandType Type = CommandType::PADEDGES;
private:
IntRegion mRegion;
};
#undef CLONE_INTO
} // namespace gfx
} // namespace mozilla
#endif /* MOZILLA_GFX_DRAWCOMMANDS_H_ */

View File

@ -5,12 +5,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "2D.h"
#include "Blur.h"
#include "Logging.h"
#include "PathHelpers.h"
#include "Tools.h"
#include "DrawTargetCapture.h"
#include "BufferEdgePad.h"
#include "BufferUnrotate.h"
@ -157,17 +156,6 @@ static void ComputeLinearRGBLuminanceMask(
}
}
void DrawTarget::DrawCapturedDT(DrawTargetCapture* aCaptureDT,
const Matrix& aTransform) {
if (aTransform.HasNonIntegerTranslation()) {
gfxWarning() << "Non integer translations are not supported for "
"DrawCaptureDT at this time!";
return;
}
static_cast<DrawTargetCaptureImpl*>(aCaptureDT)
->ReplayToDrawTarget(this, aTransform);
}
void DrawTarget::PushDeviceSpaceClipRects(const IntRect* aRects,
uint32_t aCount) {
Matrix oldTransform = GetTransform();

View File

@ -1,399 +0,0 @@
/* -*- 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 "DrawTargetCapture.h"
#include "DrawCommand.h"
#include "DrawCommands.h"
#include "gfxPlatform.h"
#include "SourceSurfaceCapture.h"
#include "FilterNodeCapture.h"
#include "PathCapture.h"
namespace mozilla {
namespace gfx {
DrawTargetCaptureImpl::~DrawTargetCaptureImpl() {
if (mSnapshot && !mSnapshot->hasOneRef()) {
mSnapshot->DrawTargetWillDestroy();
mSnapshot = nullptr;
}
}
DrawTargetCaptureImpl::DrawTargetCaptureImpl(gfx::DrawTarget* aTarget,
size_t aFlushBytes)
: mSnapshot(nullptr),
mStride(0),
mSurfaceAllocationSize(0),
mFlushBytes(aFlushBytes) {
mSize = aTarget->GetSize();
mCurrentClipBounds.push(IntRect(IntPoint(0, 0), mSize));
mFormat = aTarget->GetFormat();
SetPermitSubpixelAA(aTarget->GetPermitSubpixelAA());
mRefDT = aTarget;
}
DrawTargetCaptureImpl::DrawTargetCaptureImpl(BackendType aBackend,
const IntSize& aSize,
SurfaceFormat aFormat)
: mSize(aSize),
mSnapshot(nullptr),
mStride(0),
mSurfaceAllocationSize(0),
mFlushBytes(0) {
RefPtr<DrawTarget> screenRefDT =
gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
mCurrentClipBounds.push(IntRect(IntPoint(0, 0), aSize));
mFormat = aFormat;
SetPermitSubpixelAA(IsOpaque(mFormat));
if (aBackend == screenRefDT->GetBackendType()) {
mRefDT = screenRefDT;
} else {
// This situation can happen if a blur operation decides to
// use an unaccelerated path even if the system backend is
// Direct2D.
//
// We don't really want to encounter the reverse scenario:
// we shouldn't pick an accelerated backend if the system
// backend is skia.
if (aBackend == BackendType::DIRECT2D1_1) {
gfxWarning() << "Creating a RefDT in DrawTargetCapture.";
}
// Create a 1x1 size ref dt to create assets
// If we have to snapshot, we'll just create the real DT
IntSize size(1, 1);
mRefDT = Factory::CreateDrawTarget(aBackend, size, mFormat);
}
}
bool DrawTargetCaptureImpl::Init(const IntSize& aSize, DrawTarget* aRefDT) {
if (!aRefDT) {
return false;
}
mRefDT = aRefDT;
mSize = aSize;
mCurrentClipBounds.push(IntRect(IntPoint(0, 0), aSize));
mFormat = aRefDT->GetFormat();
SetPermitSubpixelAA(IsOpaque(mFormat));
return true;
}
void DrawTargetCaptureImpl::InitForData(int32_t aStride,
size_t aSurfaceAllocationSize) {
MOZ_ASSERT(!mFlushBytes);
mStride = aStride;
mSurfaceAllocationSize = aSurfaceAllocationSize;
}
already_AddRefed<SourceSurface> DrawTargetCaptureImpl::Snapshot() {
if (!mSnapshot) {
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, 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();
}
RefPtr<SourceSurfaceCapture> surface = new SourceSurfaceCapture(
const_cast<DrawTargetCaptureImpl*>(this), aSurface);
return surface.forget();
}
void DrawTargetCaptureImpl::DetachAllSnapshots() { MarkChanged(); }
#define AppendCommand(arg) new (AppendToCommandList<arg>()) arg
#define ReuseOrAppendCommand(arg) new (ReuseOrAppendToCommandList<arg>()) arg
void DrawTargetCaptureImpl::SetPermitSubpixelAA(bool aPermitSubpixelAA) {
// Save memory by eliminating state changes with no effect
if (mPermitSubpixelAA == aPermitSubpixelAA) {
return;
}
ReuseOrAppendCommand(SetPermitSubpixelAACommand)(aPermitSubpixelAA);
// Have to update mPermitSubpixelAA for this DT
// because some code paths query the current setting
// to determine subpixel AA eligibility.
DrawTarget::SetPermitSubpixelAA(aPermitSubpixelAA);
}
void DrawTargetCaptureImpl::DrawSurface(SourceSurface* aSurface,
const Rect& aDest, const Rect& aSource,
const DrawSurfaceOptions& aSurfOptions,
const DrawOptions& aOptions) {
aSurface->GuaranteePersistance();
AppendCommand(DrawSurfaceCommand)(aSurface, aDest, aSource, aSurfOptions,
aOptions);
}
void DrawTargetCaptureImpl::DrawSurfaceWithShadow(
SourceSurface* aSurface, const Point& aDest, const DeviceColor& aColor,
const Point& aOffset, Float aSigma, CompositionOp aOperator) {
aSurface->GuaranteePersistance();
AppendCommand(DrawSurfaceWithShadowCommand)(aSurface, aDest, aColor, aOffset,
aSigma, aOperator);
}
void DrawTargetCaptureImpl::DrawFilter(FilterNode* aNode,
const Rect& aSourceRect,
const Point& aDestPoint,
const DrawOptions& aOptions) {
// @todo XXX - this won't work properly long term yet due to filternodes not
// being immutable.
AppendCommand(DrawFilterCommand)(aNode, aSourceRect, aDestPoint, aOptions);
}
void DrawTargetCaptureImpl::ClearRect(const Rect& aRect) {
AppendCommand(ClearRectCommand)(aRect);
}
void DrawTargetCaptureImpl::MaskSurface(const Pattern& aSource,
SourceSurface* aMask, Point aOffset,
const DrawOptions& aOptions) {
aMask->GuaranteePersistance();
AppendCommand(MaskSurfaceCommand)(aSource, aMask, aOffset, aOptions);
}
void DrawTargetCaptureImpl::CopySurface(SourceSurface* aSurface,
const IntRect& aSourceRect,
const IntPoint& aDestination) {
aSurface->GuaranteePersistance();
AppendCommand(CopySurfaceCommand)(aSurface, aSourceRect, aDestination);
}
void DrawTargetCaptureImpl::CopyRect(const IntRect& aSourceRect,
const IntPoint& aDestination) {
AppendCommand(CopyRectCommand)(aSourceRect, aDestination);
}
void DrawTargetCaptureImpl::FillRect(const Rect& aRect, const Pattern& aPattern,
const DrawOptions& aOptions) {
AppendCommand(FillRectCommand)(aRect, aPattern, aOptions);
}
void DrawTargetCaptureImpl::FillRoundedRect(const RoundedRect& aRect,
const Pattern& aPattern,
const DrawOptions& aOptions) {
AppendCommand(FillRoundedRectCommand)(aRect, aPattern, aOptions);
}
void DrawTargetCaptureImpl::StrokeRect(const Rect& aRect,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions) {
AppendCommand(StrokeRectCommand)(aRect, aPattern, aStrokeOptions, aOptions);
}
void DrawTargetCaptureImpl::StrokeLine(const Point& aStart, const Point& aEnd,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions) {
AppendCommand(StrokeLineCommand)(aStart, aEnd, aPattern, aStrokeOptions,
aOptions);
}
void DrawTargetCaptureImpl::Stroke(const Path* aPath, const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions) {
AppendCommand(StrokeCommand)(aPath, aPattern, aStrokeOptions, aOptions);
}
void DrawTargetCaptureImpl::Fill(const Path* aPath, const Pattern& aPattern,
const DrawOptions& aOptions) {
AppendCommand(FillCommand)(aPath, aPattern, aOptions);
}
void DrawTargetCaptureImpl::FillGlyphs(ScaledFont* aFont,
const GlyphBuffer& aBuffer,
const Pattern& aPattern,
const DrawOptions& aOptions) {
AppendCommand(FillGlyphsCommand)(aFont, aBuffer, aPattern, aOptions);
}
void DrawTargetCaptureImpl::StrokeGlyphs(ScaledFont* aFont,
const GlyphBuffer& aBuffer,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions) {
AppendCommand(StrokeGlyphsCommand)(aFont, aBuffer, aPattern, aStrokeOptions,
aOptions);
}
void DrawTargetCaptureImpl::Mask(const Pattern& aSource, const Pattern& aMask,
const DrawOptions& aOptions) {
AppendCommand(MaskCommand)(aSource, aMask, aOptions);
}
void DrawTargetCaptureImpl::PushClip(const Path* aPath) {
// We need Pushes and Pops to match so instead of trying
// to compute the bounds of the path just repush the current
// bounds.
mCurrentClipBounds.push(mCurrentClipBounds.top());
AppendCommand(PushClipCommand)(aPath);
}
void DrawTargetCaptureImpl::PushClipRect(const Rect& aRect) {
IntRect deviceRect = RoundedOut(mTransform.TransformBounds(aRect));
mCurrentClipBounds.push(mCurrentClipBounds.top().Intersect(deviceRect));
AppendCommand(PushClipRectCommand)(aRect);
}
void DrawTargetCaptureImpl::PushLayer(bool aOpaque, Float aOpacity,
SourceSurface* aMask,
const Matrix& aMaskTransform,
const IntRect& aBounds,
bool aCopyBackground) {
// Have to update mPermitSubpixelAA for this DT
// because some code paths query the current setting
// to determine subpixel AA eligibility.
PushedLayer layer(GetPermitSubpixelAA());
mPushedLayers.push_back(layer);
DrawTarget::SetPermitSubpixelAA(aOpaque);
if (aMask) {
aMask->GuaranteePersistance();
}
AppendCommand(PushLayerCommand)(aOpaque, aOpacity, aMask, aMaskTransform,
aBounds, aCopyBackground);
}
void DrawTargetCaptureImpl::PopLayer() {
MOZ_ASSERT(mPushedLayers.size());
DrawTarget::SetPermitSubpixelAA(mPushedLayers.back().mOldPermitSubpixelAA);
mPushedLayers.pop_back();
AppendCommand(PopLayerCommand)();
}
void DrawTargetCaptureImpl::PopClip() {
mCurrentClipBounds.pop();
AppendCommand(PopClipCommand)();
}
void DrawTargetCaptureImpl::SetTransform(const Matrix& aTransform) {
// Save memory by eliminating state changes with no effect
if (mTransform.ExactlyEquals(aTransform)) {
return;
}
ReuseOrAppendCommand(SetTransformCommand)(aTransform);
// Have to update the transform for this DT
// because some code paths query the current transform
// to render specific things.
DrawTarget::SetTransform(aTransform);
}
void DrawTargetCaptureImpl::Blur(const AlphaBoxBlur& aBlur) {
// gfxAlphaBoxBlur should not use this if it takes the accelerated path.
MOZ_ASSERT(GetBackendType() == BackendType::SKIA);
AppendCommand(BlurCommand)(aBlur);
}
void DrawTargetCaptureImpl::PadEdges(const IntRegion& aRegion) {
AppendCommand(PadEdgesCommand)(aRegion);
}
void DrawTargetCaptureImpl::ReplayToDrawTarget(DrawTarget* aDT,
const Matrix& aTransform) {
for (CaptureCommandList::iterator iter(mCommands); !iter.Done();
iter.Next()) {
DrawingCommand* cmd = iter.Get();
cmd->ExecuteOnDT(aDT, &aTransform);
}
}
void DrawTargetCaptureImpl::MarkChanged() {
if (!mSnapshot) {
return;
}
if (mSnapshot->hasOneRef()) {
mSnapshot = nullptr;
return;
}
mSnapshot->DrawTargetWillChange();
mSnapshot = nullptr;
}
already_AddRefed<DrawTarget> DrawTargetCaptureImpl::CreateSimilarDrawTarget(
const IntSize& aSize, SurfaceFormat aFormat) const {
return MakeAndAddRef<DrawTargetCaptureImpl>(GetBackendType(), aSize, aFormat);
}
RefPtr<DrawTarget> DrawTargetCaptureImpl::CreateClippedDrawTarget(
const Rect& aBounds, SurfaceFormat aFormat) {
IntRect& bounds = mCurrentClipBounds.top();
auto dt = MakeRefPtr<DrawTargetCaptureImpl>(GetBackendType(), bounds.Size(),
aFormat);
RefPtr<DrawTarget> result =
gfx::Factory::CreateOffsetDrawTarget(dt, bounds.TopLeft());
result->SetTransform(mTransform);
return result;
}
RefPtr<DrawTarget> DrawTargetCaptureImpl::CreateSimilarRasterTarget(
const IntSize& aSize, SurfaceFormat aFormat) const {
MOZ_ASSERT(!mRefDT->IsCaptureDT());
return mRefDT->CreateSimilarDrawTarget(aSize, aFormat);
}
already_AddRefed<PathBuilder> DrawTargetCaptureImpl::CreatePathBuilder(
FillRule aFillRule) const {
if (mRefDT->GetBackendType() == BackendType::DIRECT2D1_1) {
return MakeRefPtr<PathBuilderCapture>(aFillRule, mRefDT).forget();
}
return mRefDT->CreatePathBuilder(aFillRule);
}
already_AddRefed<FilterNode> DrawTargetCaptureImpl::CreateFilter(
FilterType aType) {
if (mRefDT->GetBackendType() == BackendType::DIRECT2D1_1) {
return MakeRefPtr<FilterNodeCapture>(aType).forget();
} else {
return mRefDT->CreateFilter(aType);
}
}
bool DrawTargetCaptureImpl::IsEmpty() const { return mCommands.IsEmpty(); }
void DrawTargetCaptureImpl::Dump() {
TreeLog<> output;
output << "DrawTargetCapture(" << (void*)(this) << ")\n";
TreeAutoIndent<> indent(output);
mCommands.Log(output);
output << "\n";
}
} // namespace gfx
} // namespace mozilla

View File

@ -1,202 +0,0 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_DRAWTARGETCAPTURE_H_
#define MOZILLA_GFX_DRAWTARGETCAPTURE_H_
#include <vector>
#include <stack>
#include "2D.h"
#include "CaptureCommandList.h"
#include "Filters.h"
namespace mozilla {
namespace gfx {
class DrawingCommand;
class SourceSurfaceCapture;
class AlphaBoxBlur;
class DrawTargetCaptureImpl final : public DrawTargetCapture {
friend class SourceSurfaceCapture;
public:
DrawTargetCaptureImpl(gfx::DrawTarget* aTarget, size_t aFlushBytes);
DrawTargetCaptureImpl(BackendType aBackend, const IntSize& aSize,
SurfaceFormat aFormat);
bool Init(const IntSize& aSize, DrawTarget* aRefDT);
void InitForData(int32_t aStride, size_t aSurfaceAllocationSize);
BackendType GetBackendType() const override {
return mRefDT->GetBackendType();
}
DrawTargetType GetType() const override { return mRefDT->GetType(); }
bool IsCaptureDT() const override { return true; }
already_AddRefed<SourceSurface> Snapshot() override;
already_AddRefed<SourceSurface> IntoLuminanceSource(
LuminanceType aLuminanceType, float aOpacity) override;
void SetPermitSubpixelAA(bool aPermitSubpixelAA) override;
void DetachAllSnapshots() override;
IntSize GetSize() const override { return mSize; }
void Flush() override {}
void DrawSurface(SourceSurface* aSurface, const Rect& aDest,
const Rect& aSource, const DrawSurfaceOptions& aSurfOptions,
const DrawOptions& aOptions) override;
void DrawFilter(FilterNode* aNode, const Rect& aSourceRect,
const Point& aDestPoint,
const DrawOptions& aOptions = DrawOptions()) override;
void DrawSurfaceWithShadow(SourceSurface* aSurface, const Point& aDest,
const DeviceColor& aColor, const Point& aOffset,
Float aSigma, CompositionOp aOperator) override;
void ClearRect(const Rect& aRect) override;
void MaskSurface(const Pattern& aSource, SourceSurface* aMask, Point aOffset,
const DrawOptions& aOptions = DrawOptions()) override;
void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect,
const IntPoint& aDestination) override;
void CopyRect(const IntRect& aSourceRect,
const IntPoint& aDestination) override;
void FillRect(const Rect& aRect, const Pattern& aPattern,
const DrawOptions& aOptions = DrawOptions()) override;
void FillRoundedRect(const RoundedRect& aRect, const Pattern& aPattern,
const DrawOptions& aOptions = DrawOptions()) override;
void StrokeRect(const Rect& aRect, const Pattern& aPattern,
const StrokeOptions& aStrokeOptions = StrokeOptions(),
const DrawOptions& aOptions = DrawOptions()) override;
void StrokeLine(const Point& aStart, const Point& aEnd,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions = StrokeOptions(),
const DrawOptions& aOptions = DrawOptions()) override;
void Stroke(const Path* aPath, const Pattern& aPattern,
const StrokeOptions& aStrokeOptions = StrokeOptions(),
const DrawOptions& aOptions = DrawOptions()) override;
void Fill(const Path* aPath, const Pattern& aPattern,
const DrawOptions& aOptions = DrawOptions()) override;
void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
const Pattern& aPattern,
const DrawOptions& aOptions = DrawOptions()) override;
void StrokeGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions = StrokeOptions(),
const DrawOptions& aOptions = DrawOptions()) override;
void Mask(const Pattern& aSource, const Pattern& aMask,
const DrawOptions& aOptions = DrawOptions()) override;
void PushClip(const Path* aPath) override;
void PushClipRect(const Rect& aRect) override;
void PopClip() override;
void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
const Matrix& aMaskTransform, const IntRect& aBounds,
bool aCopyBackground) override;
void PopLayer() override;
void Blur(const AlphaBoxBlur& aBlur) override;
void PadEdges(const IntRegion& aRegion) override;
void SetTransform(const Matrix& aTransform) override;
bool SupportsRegionClipping() const override {
return mRefDT->SupportsRegionClipping();
}
already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(
unsigned char* aData, const IntSize& aSize, int32_t aStride,
SurfaceFormat aFormat) const override {
return mRefDT->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
}
already_AddRefed<SourceSurface> OptimizeSourceSurface(
SourceSurface* aSurface) const override;
already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface(
const NativeSurface& aSurface) const override {
return mRefDT->CreateSourceSurfaceFromNativeSurface(aSurface);
}
already_AddRefed<DrawTarget> CreateSimilarDrawTarget(
const IntSize& aSize, SurfaceFormat aFormat) const override;
RefPtr<DrawTarget> CreateSimilarRasterTarget(
const IntSize& aSize, SurfaceFormat aFormat) const override;
RefPtr<DrawTarget> CreateClippedDrawTarget(const Rect& aBounds,
SurfaceFormat aFormat) override;
already_AddRefed<PathBuilder> CreatePathBuilder(
FillRule aFillRule = FillRule::FILL_WINDING) const override;
already_AddRefed<GradientStops> CreateGradientStops(
GradientStop* aStops, uint32_t aNumStops,
ExtendMode aExtendMode = ExtendMode::CLAMP) const override {
return mRefDT->CreateGradientStops(aStops, aNumStops, aExtendMode);
}
already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
void ReplayToDrawTarget(DrawTarget* aDT, const Matrix& aTransform);
bool IsEmpty() const override;
void Dump() override;
protected:
virtual ~DrawTargetCaptureImpl();
void MarkChanged();
private:
void FlushCommandBuffer() {
ReplayToDrawTarget(mRefDT, Matrix());
mCommands.Clear();
}
// This storage system was used to minimize the amount of heap allocations
// that are required while recording. It should be noted there's no
// guarantees on the alignments of DrawingCommands allocated in this array.
template <typename T>
T* AppendToCommandList() {
if (T::AffectsSnapshot) {
MarkChanged();
}
if (mFlushBytes && mCommands.BufferWillAlloc<T>() &&
mCommands.BufferCapacity() > mFlushBytes) {
FlushCommandBuffer();
}
return mCommands.Append<T>();
}
template <typename T>
T* ReuseOrAppendToCommandList() {
if (T::AffectsSnapshot) {
MarkChanged();
}
if (mFlushBytes && mCommands.BufferWillAlloc<T>() &&
mCommands.BufferCapacity() > mFlushBytes) {
FlushCommandBuffer();
}
return mCommands.ReuseOrAppend<T>();
}
RefPtr<DrawTarget> mRefDT;
IntSize mSize;
RefPtr<SourceSurfaceCapture> mSnapshot;
// These are set if the draw target must be explicitly backed by data.
int32_t mStride;
size_t mSurfaceAllocationSize;
struct PushedLayer {
explicit PushedLayer(bool aOldPermitSubpixelAA)
: mOldPermitSubpixelAA(aOldPermitSubpixelAA) {}
bool mOldPermitSubpixelAA;
};
std::vector<PushedLayer> mPushedLayers;
std::stack<IntRect> mCurrentClipBounds;
CaptureCommandList mCommands;
size_t mFlushBytes;
};
} // namespace gfx
} // namespace mozilla
#endif /* MOZILLA_GFX_DRAWTARGETCAPTURE_H_ */

View File

@ -10,12 +10,10 @@
#include "DrawTargetD2D1.h"
#include "FilterNodeSoftware.h"
#include "GradientStopsD2D.h"
#include "SourceSurfaceCapture.h"
#include "SourceSurfaceD2D1.h"
#include "SourceSurfaceDual.h"
#include "ConicGradientEffectD2D1.h"
#include "RadialGradientEffectD2D1.h"
#include "PathCapture.h"
#include "HelpersD2D.h"
#include "FilterNodeD2D1.h"
@ -664,10 +662,6 @@ void DrawTargetD2D1::Stroke(const Path* aPath, const Pattern& aPattern,
const StrokeOptions& aStrokeOptions,
const DrawOptions& aOptions) {
const Path* path = aPath;
if (aPath->GetBackendType() == BackendType::CAPTURE) {
path = static_cast<const PathCapture*>(aPath)->GetRealizedPath();
}
if (path->GetBackendType() != BackendType::DIRECT2D1_1) {
gfxDebug() << *this << ": Ignoring drawing call for incompatible path.";
return;
@ -693,10 +687,6 @@ void DrawTargetD2D1::Stroke(const Path* aPath, const Pattern& aPattern,
void DrawTargetD2D1::Fill(const Path* aPath, const Pattern& aPattern,
const DrawOptions& aOptions) {
const Path* path = aPath;
if (aPath && aPath->GetBackendType() == BackendType::CAPTURE) {
path = static_cast<const PathCapture*>(aPath)->GetRealizedPath();
}
if (!path || path->GetBackendType() != BackendType::DIRECT2D1_1) {
gfxDebug() << *this << ": Ignoring drawing call for incompatible path.";
return;
@ -904,10 +894,6 @@ void DrawTargetD2D1::PushClipGeometry(ID2D1Geometry* aGeometry,
void DrawTargetD2D1::PushClip(const Path* aPath) {
const Path* path = aPath;
if (aPath->GetBackendType() == BackendType::CAPTURE) {
path = static_cast<const PathCapture*>(aPath)->GetRealizedPath();
}
if (path->GetBackendType() != BackendType::DIRECT2D1_1) {
gfxDebug() << *this << ": Ignoring clipping call for incompatible path.";
return;
@ -2117,15 +2103,6 @@ already_AddRefed<ID2D1Brush> DrawTargetD2D1::CreateBrushForPattern(
RefPtr<SourceSurface> surf = pat->mSurface;
if (pat->mSurface->GetType() == SurfaceType::CAPTURE) {
SourceSurfaceCapture* capture =
static_cast<SourceSurfaceCapture*>(pat->mSurface.get());
RefPtr<SourceSurface> resolved = capture->Resolve(GetBackendType());
if (resolved) {
surf = resolved;
}
}
RefPtr<ID2D1Image> image = GetImageForSurface(
surf, mat, pat->mExtendMode,
!pat->mSamplingRect.IsEmpty() ? &pat->mSamplingRect : nullptr);
@ -2240,17 +2217,6 @@ already_AddRefed<ID2D1Image> DrawTargetD2D1::GetImageForSurface(
}
switch (surface->GetType()) {
case SurfaceType::CAPTURE: {
SourceSurfaceCapture* capture =
static_cast<SourceSurfaceCapture*>(surface.get());
RefPtr<SourceSurface> resolved = capture->Resolve(GetBackendType());
if (!resolved) {
return nullptr;
}
MOZ_ASSERT(resolved->GetType() != SurfaceType::CAPTURE);
return GetImageForSurface(resolved, aSourceTransform, aExtendMode,
aSourceRect, aUserSpace);
} break;
case SurfaceType::D2D1_1_IMAGE: {
SourceSurfaceD2D1* surf = static_cast<SourceSurfaceD2D1*>(surface.get());
image = surf->GetImage();
@ -2299,18 +2265,6 @@ already_AddRefed<SourceSurface> DrawTargetD2D1::OptimizeSourceSurface(
return nullptr;
}
// Special case captures so we don't resolve them to a data surface.
if (aSurface->GetType() == SurfaceType::CAPTURE) {
SourceSurfaceCapture* capture =
static_cast<SourceSurfaceCapture*>(aSurface);
RefPtr<SourceSurface> resolved = capture->Resolve(GetBackendType());
if (!resolved) {
return nullptr;
}
MOZ_ASSERT(resolved->GetType() != SurfaceType::CAPTURE);
return OptimizeSourceSurface(resolved);
}
RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();
std::optional<SurfaceFormat> convertTo;

View File

@ -55,9 +55,6 @@ class DrawTargetOffset : public DrawTarget {
// We'll pestimistically return true here
virtual bool IsTiledDrawTarget() const override { return true; }
virtual bool IsCaptureDT() const override {
return mDrawTarget->IsCaptureDT();
}
virtual DrawTargetType GetType() const override {
return mDrawTarget->GetType();
}

View File

@ -27,7 +27,6 @@
#include "Tools.h"
#include "DataSurfaceHelpers.h"
#include "PathHelpers.h"
#include "SourceSurfaceCapture.h"
#include "Swizzle.h"
#include <algorithm>
@ -232,17 +231,6 @@ static sk_sp<SkImage> GetSkImageForSurface(SourceSurface* aSurface,
return nullptr;
}
if (aSurface->GetType() == SurfaceType::CAPTURE) {
SourceSurfaceCapture* capture =
static_cast<SourceSurfaceCapture*>(aSurface);
RefPtr<SourceSurface> resolved = capture->Resolve(BackendType::SKIA);
if (!resolved) {
return nullptr;
}
MOZ_ASSERT(resolved->GetType() != SurfaceType::CAPTURE);
return GetSkImageForSurface(resolved, aLock, aBounds, aMatrix);
}
if (aSurface->GetType() == SurfaceType::SKIA) {
return static_cast<SourceSurfaceSkia*>(aSurface)->GetImage(aLock);
}

View File

@ -36,9 +36,6 @@ class DrawTargetTiled : public DrawTarget {
bool IsTiledDrawTarget() const override { return true; }
bool IsCaptureDT() const override {
return mTiles[0].mDrawTarget->IsCaptureDT();
}
DrawTargetType GetType() const override {
return mTiles[0].mDrawTarget->GetType();
}

View File

@ -52,7 +52,6 @@
# include "nsWindowsHelpers.h"
#endif
#include "DrawTargetCapture.h"
#include "DrawTargetDual.h"
#include "DrawTargetTiled.h"
#include "DrawTargetOffset.h"
@ -422,32 +421,6 @@ already_AddRefed<DrawTarget> Factory::CreateRecordingDrawTarget(
return MakeAndAddRef<DrawTargetRecording>(aRecorder, aDT, aRect);
}
already_AddRefed<DrawTargetCapture> Factory::CreateCaptureDrawTargetForTarget(
gfx::DrawTarget* aTarget, size_t aFlushBytes) {
return MakeAndAddRef<DrawTargetCaptureImpl>(aTarget, aFlushBytes);
}
already_AddRefed<DrawTargetCapture> Factory::CreateCaptureDrawTarget(
BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat) {
return MakeAndAddRef<DrawTargetCaptureImpl>(aBackend, aSize, aFormat);
}
already_AddRefed<DrawTargetCapture> Factory::CreateCaptureDrawTargetForData(
BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat,
int32_t aStride, size_t aSurfaceAllocationSize) {
MOZ_ASSERT(aSurfaceAllocationSize && aStride);
BackendType type = aBackend;
if (!Factory::DoesBackendSupportDataDrawtarget(aBackend)) {
type = BackendType::SKIA;
}
RefPtr<DrawTargetCaptureImpl> dt =
new DrawTargetCaptureImpl(type, aSize, aFormat);
dt->InitForData(aStride, aSurfaceAllocationSize);
return dt.forget();
}
already_AddRefed<DrawTarget> Factory::CreateDrawTargetForData(
BackendType aBackend, unsigned char* aData, const IntSize& aSize,
int32_t aStride, SurfaceFormat aFormat, bool aUninitialized) {
@ -525,7 +498,6 @@ bool Factory::DoesBackendSupportDataDrawtarget(BackendType aType) {
case BackendType::DIRECT2D:
case BackendType::DIRECT2D1_1:
case BackendType::RECORDING:
case BackendType::CAPTURE:
case BackendType::NONE:
case BackendType::BACKEND_LAST:
case BackendType::WEBRENDER_TEXT:

View File

@ -1,96 +0,0 @@
/* -*- 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 "FilterNodeCapture.h"
namespace mozilla {
namespace gfx {
struct Setter {
Setter(FilterNode* aNode, DrawTarget* aDT, bool aInputsChanged)
: mNode{aNode}, mIndex{0}, mDT{aDT}, mInputsChanged{aInputsChanged} {}
template <typename T>
void operator()(T& aValue) {
mNode->SetAttribute(mIndex, aValue);
}
FilterNode* mNode;
uint32_t mIndex;
DrawTarget* mDT;
bool mInputsChanged;
};
template <>
void Setter::operator()<std::vector<Float>>(std::vector<Float>& aValue) {
mNode->SetAttribute(mIndex, aValue.data(), aValue.size());
}
template <>
void Setter::operator()<RefPtr<SourceSurface>>(
RefPtr<SourceSurface>& aSurface) {
if (!mInputsChanged) {
return;
}
mNode->SetInput(mIndex, aSurface);
}
template <>
void Setter::operator()<RefPtr<FilterNode>>(RefPtr<FilterNode>& aNode) {
RefPtr<FilterNode> node = aNode;
if (node->GetBackendType() == FilterBackend::FILTER_BACKEND_CAPTURE) {
FilterNodeCapture* captureNode =
static_cast<FilterNodeCapture*>(node.get());
node = captureNode->Validate(mDT);
}
if (!mInputsChanged) {
return;
}
mNode->SetInput(mIndex, node);
}
RefPtr<FilterNode> FilterNodeCapture::Validate(DrawTarget* aDT) {
if (!mFilterNodeInternal) {
mFilterNodeInternal = aDT->CreateFilter(mType);
}
if (!mFilterNodeInternal) {
return nullptr;
}
Setter setter(mFilterNodeInternal, aDT, mInputsChanged);
for (auto attribute : mAttributes) {
setter.mIndex = attribute.first;
// Variant's matching doesn't seem to compile to terribly efficient code,
// this is probably fine since this happens on the paint thread, if ever
// needed it would be fairly simple to write something more optimized.
attribute.second.match(setter);
}
mAttributes.clear();
for (auto input : mInputs) {
setter.mIndex = input.first;
input.second.match(setter);
}
mInputsChanged = false;
return mFilterNodeInternal.get();
}
void FilterNodeCapture::SetAttribute(uint32_t aIndex, const Float* aValues,
uint32_t aSize) {
std::vector<Float> vec(aSize);
memcpy(vec.data(), aValues, sizeof(Float) * aSize);
AttributeValue att(std::move(vec));
auto result = mAttributes.insert({aIndex, att});
if (!result.second) {
result.first->second = att;
}
}
} // namespace gfx
} // namespace mozilla

View File

@ -1,114 +0,0 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_FILTERNODECAPTURE_H_
#define MOZILLA_GFX_FILTERNODECAPTURE_H_
#include "2D.h"
#include "Filters.h"
#include <unordered_map>
#include <vector>
#include "mozilla/Variant.h"
namespace mozilla {
namespace gfx {
class FilterNodeCapture final : public FilterNode {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeCapture, override)
explicit FilterNodeCapture(FilterType aType)
: mType{aType}, mInputsChanged{true} {}
FilterBackend GetBackendType() override { return FILTER_BACKEND_CAPTURE; }
RefPtr<FilterNode> Validate(DrawTarget* aDT);
template <typename T, typename C>
void Replace(uint32_t aIndex, const T& aValue, C& aContainer) {
// This replace function avoids generating the hash twice.
auto result = aContainer.insert({aIndex, typename C::mapped_type(aValue)});
if (!result.second) {
result.first->second = typename C::mapped_type(aValue);
}
}
void SetInput(uint32_t aIndex, SourceSurface* aSurface) override {
mInputsChanged = true;
Replace(aIndex, RefPtr<SourceSurface>(aSurface), mInputs);
}
void SetInput(uint32_t aIndex, FilterNode* aFilter) override {
mInputsChanged = true;
Replace(aIndex, RefPtr<FilterNode>(aFilter), mInputs);
}
using AttributeValue = Variant<uint32_t, Float, Point, Matrix5x4, Point3D,
Size, IntSize, DeviceColor, Rect, IntRect,
bool, std::vector<Float>, IntPoint, Matrix>;
void SetAttribute(uint32_t aIndex, uint32_t aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, Float aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, const Point& aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, const Matrix5x4& aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, const Point3D& aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, const Size& aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, const IntSize& aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, const DeviceColor& aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, const Rect& aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, const IntRect& aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, bool aValue) override {
Replace(aIndex, aValue, mAttributes);
}
virtual void SetAttribute(uint32_t aIndex, const Float* aValues,
uint32_t aSize) override;
void SetAttribute(uint32_t aIndex, const IntPoint& aValue) override {
Replace(aIndex, aValue, mAttributes);
}
void SetAttribute(uint32_t aIndex, const Matrix& aValue) override {
Replace(aIndex, aValue, mAttributes);
}
private:
FilterType mType;
RefPtr<FilterNode> mFilterNodeInternal;
// This only contains attributes that were set since the last validation.
std::unordered_map<uint32_t, AttributeValue> mAttributes;
// This always contains all inputs, so that Validate may be called on input
// filter nodes.
std::unordered_map<uint32_t,
Variant<RefPtr<SourceSurface>, RefPtr<FilterNode>>>
mInputs;
// This is true if SetInput was called since the last validation.
bool mInputsChanged;
};
} // namespace gfx
} // namespace mozilla
#endif

View File

@ -146,8 +146,7 @@ D2D1_CHANNEL_SELECTOR D2DChannelSelector(uint32_t aMode) {
already_AddRefed<ID2D1Image> GetImageForSourceSurface(DrawTarget* aDT,
SourceSurface* aSurface) {
if (aDT->IsTiledDrawTarget() || aDT->IsDualDrawTarget() ||
aDT->IsCaptureDT()) {
if (aDT->IsTiledDrawTarget() || aDT->IsDualDrawTarget()) {
gfxDevCrash(LogReason::FilterNodeD2D1Target)
<< "Incompatible draw target type! " << (int)aDT->IsTiledDrawTarget()
<< " " << (int)aDT->IsDualDrawTarget();

View File

@ -1,218 +0,0 @@
/* -*- 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 "PathCapture.h"
namespace mozilla {
namespace gfx {
void PathBuilderCapture::MoveTo(const Point& aPoint) {
PathOp op;
op.mType = PathOp::OP_MOVETO;
op.mP1 = aPoint;
mPathOps.push_back(op);
mCurrentPoint = aPoint;
mBeginPoint = aPoint;
}
void PathBuilderCapture::LineTo(const Point& aPoint) {
PathOp op;
op.mType = PathOp::OP_LINETO;
op.mP1 = aPoint;
mPathOps.push_back(op);
mCurrentPoint = aPoint;
}
void PathBuilderCapture::BezierTo(const Point& aCP1, const Point& aCP2,
const Point& aCP3) {
PathOp op;
op.mType = PathOp::OP_BEZIERTO;
op.mP1 = aCP1;
op.mP2 = aCP2;
op.mP3 = aCP3;
mPathOps.push_back(op);
mCurrentPoint = aCP3;
}
void PathBuilderCapture::QuadraticBezierTo(const Point& aCP1,
const Point& aCP2) {
PathOp op;
op.mType = PathOp::OP_QUADRATICBEZIERTO;
op.mP1 = aCP1;
op.mP2 = aCP2;
mPathOps.push_back(op);
mCurrentPoint = aCP2;
}
void PathBuilderCapture::Arc(const Point& aCenter, float aRadius,
float aStartAngle, float aEndAngle,
bool aAntiClockwise) {
PathOp op;
op.mType = PathOp::OP_ARC;
op.mP1 = aCenter;
op.mRadius = aRadius;
op.mStartAngle = aStartAngle;
op.mEndAngle = aEndAngle;
op.mAntiClockwise = aAntiClockwise;
mPathOps.push_back(op);
mCurrentPoint = Point(aCenter.x + aRadius * cosf(aEndAngle),
aCenter.y + aRadius * sinf(aEndAngle));
}
void PathBuilderCapture::Close() {
PathOp op;
op.mType = PathOp::OP_CLOSE;
mPathOps.push_back(op);
mCurrentPoint = mBeginPoint;
}
already_AddRefed<Path> PathBuilderCapture::Finish() {
Point currentPoint = mCurrentPoint;
Point beginPoint = mBeginPoint;
mCurrentPoint = Point(0.0, 0.0);
mBeginPoint = Point(0.0, 0.0);
return MakeAndAddRef<PathCapture>(std::move(mPathOps), mFillRule, mDT,
currentPoint, beginPoint);
}
already_AddRefed<PathBuilder> PathCapture::CopyToBuilder(
FillRule aFillRule) const {
RefPtr<PathBuilderCapture> capture = new PathBuilderCapture(aFillRule, mDT);
capture->mPathOps = mPathOps;
capture->mCurrentPoint = mCurrentPoint;
capture->mBeginPoint = mBeginPoint;
return capture.forget();
}
already_AddRefed<PathBuilder> PathCapture::TransformedCopyToBuilder(
const Matrix& aTransform, FillRule aFillRule) const {
RefPtr<PathBuilderCapture> capture = new PathBuilderCapture(aFillRule, mDT);
typedef std::vector<PathOp> pathOpVec;
for (pathOpVec::const_iterator iter = mPathOps.begin();
iter != mPathOps.end(); iter++) {
PathOp newPathOp;
newPathOp.mType = iter->mType;
if (newPathOp.mType == PathOp::OpType::OP_ARC) {
struct ArcTransformer {
ArcTransformer(pathOpVec& aVector, const Matrix& aTransform)
: mVector(&aVector), mTransform(&aTransform) {}
void BezierTo(const Point& aCP1, const Point& aCP2, const Point& aCP3) {
PathOp newPathOp;
newPathOp.mType = PathOp::OP_BEZIERTO;
newPathOp.mP1 = mTransform->TransformPoint(aCP1);
newPathOp.mP2 = mTransform->TransformPoint(aCP2);
newPathOp.mP3 = mTransform->TransformPoint(aCP3);
mVector->push_back(newPathOp);
}
void LineTo(const Point& aPoint) {
PathOp newPathOp;
newPathOp.mType = PathOp::OP_LINETO;
newPathOp.mP1 = mTransform->TransformPoint(aPoint);
mVector->push_back(newPathOp);
}
pathOpVec* mVector;
const Matrix* mTransform;
};
ArcTransformer arcTransformer(capture->mPathOps, aTransform);
ArcToBezier(&arcTransformer, iter->mP1,
Size(iter->mRadius, iter->mRadius), iter->mStartAngle,
iter->mEndAngle, iter->mAntiClockwise);
} else {
if (sPointCount[newPathOp.mType] >= 1) {
newPathOp.mP1 = aTransform.TransformPoint(iter->mP1);
}
if (sPointCount[newPathOp.mType] >= 2) {
newPathOp.mP2 = aTransform.TransformPoint(iter->mP2);
}
if (sPointCount[newPathOp.mType] >= 3) {
newPathOp.mP3 = aTransform.TransformPoint(iter->mP3);
}
capture->mPathOps.push_back(newPathOp);
}
}
capture->mCurrentPoint = aTransform.TransformPoint(mCurrentPoint);
capture->mBeginPoint = aTransform.TransformPoint(mBeginPoint);
return capture.forget();
}
bool PathCapture::ContainsPoint(const Point& aPoint,
const Matrix& aTransform) const {
if (!EnsureRealizedPath()) {
return false;
}
return mRealizedPath->ContainsPoint(aPoint, aTransform);
}
bool PathCapture::StrokeContainsPoint(const StrokeOptions& aStrokeOptions,
const Point& aPoint,
const Matrix& aTransform) const {
if (!EnsureRealizedPath()) {
return false;
}
return mRealizedPath->StrokeContainsPoint(aStrokeOptions, aPoint, aTransform);
}
Rect PathCapture::GetBounds(const Matrix& aTransform) const {
if (!EnsureRealizedPath()) {
return Rect();
}
return mRealizedPath->GetBounds(aTransform);
}
Rect PathCapture::GetStrokedBounds(const StrokeOptions& aStrokeOptions,
const Matrix& aTransform) const {
if (!EnsureRealizedPath()) {
return Rect();
}
return mRealizedPath->GetStrokedBounds(aStrokeOptions, aTransform);
}
void PathCapture::StreamToSink(PathSink* aSink) const {
for (const PathOp& op : mPathOps) {
switch (op.mType) {
case PathOp::OP_MOVETO:
aSink->MoveTo(op.mP1);
break;
case PathOp::OP_LINETO:
aSink->LineTo(op.mP1);
break;
case PathOp::OP_BEZIERTO:
aSink->BezierTo(op.mP1, op.mP2, op.mP3);
break;
case PathOp::OP_QUADRATICBEZIERTO:
aSink->QuadraticBezierTo(op.mP1, op.mP2);
break;
case PathOp::OP_ARC:
aSink->Arc(op.mP1, op.mRadius, op.mStartAngle, op.mEndAngle,
op.mAntiClockwise);
break;
case PathOp::OP_CLOSE:
aSink->Close();
break;
}
}
}
bool PathCapture::EnsureRealizedPath() const {
RefPtr<PathBuilder> builder = mDT->CreatePathBuilder(mFillRule);
if (!builder) {
return false;
}
StreamToSink(builder);
mRealizedPath = builder->Finish();
return true;
}
Path* PathCapture::GetRealizedPath() const {
if (!EnsureRealizedPath()) {
return nullptr;
}
return mRealizedPath.get();
}
} // namespace gfx
} // namespace mozilla

View File

@ -1,114 +0,0 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_PATHCAPTURE_H_
#define MOZILLA_GFX_PATHCAPTURE_H_
#include "2D.h"
#include <vector>
#include <ostream>
#include "PathHelpers.h"
namespace mozilla {
namespace gfx {
class PathCapture;
class PathBuilderCapture : public PathBuilder {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilderCapture, override)
PathBuilderCapture(FillRule aFillRule, DrawTarget* aDT)
: mFillRule(aFillRule), mDT(aDT) {}
/* Move the current point in the path, any figure currently being drawn will
* be considered closed during fill operations, however when stroking the
* closing line segment will not be drawn.
*/
virtual void MoveTo(const Point& aPoint) override;
/* Add a linesegment to the current figure */
virtual void LineTo(const Point& aPoint) override;
/* Add a cubic bezier curve to the current figure */
virtual void BezierTo(const Point& aCP1, const Point& aCP2,
const Point& aCP3) override;
/* Add a quadratic bezier curve to the current figure */
virtual void QuadraticBezierTo(const Point& aCP1, const Point& aCP2) override;
/* Add an arc to the current figure */
virtual void Arc(const Point& aOrigin, float aRadius, float aStartAngle,
float aEndAngle, bool aAntiClockwise) override;
/* Close the current figure, this will essentially generate a line segment
* from the current point to the starting point for the current figure
*/
virtual void Close() override;
virtual already_AddRefed<Path> Finish() override;
virtual BackendType GetBackendType() const override {
return BackendType::CAPTURE;
}
private:
friend class PathCapture;
FillRule mFillRule;
std::vector<PathOp> mPathOps;
RefPtr<DrawTarget> mDT;
};
class PathCapture : public Path {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathCapture, override)
PathCapture(const std::vector<PathOp> aOps, FillRule aFillRule,
DrawTarget* aDT, const Point& aCurrentPoint,
const Point& aBeginPoint)
: mPathOps(aOps),
mFillRule(aFillRule),
mDT(aDT),
mCurrentPoint(aCurrentPoint),
mBeginPoint(aBeginPoint) {}
virtual BackendType GetBackendType() const override {
return BackendType::CAPTURE;
}
virtual already_AddRefed<PathBuilder> CopyToBuilder(
FillRule aFillRule) const override;
virtual already_AddRefed<PathBuilder> TransformedCopyToBuilder(
const Matrix& aTransform, FillRule aFillRule) const override;
virtual bool ContainsPoint(const Point& aPoint,
const Matrix& aTransform) const override;
virtual bool StrokeContainsPoint(const StrokeOptions& aStrokeOptions,
const Point& aPoint,
const Matrix& aTransform) const override;
virtual Rect GetBounds(const Matrix& aTransform = Matrix()) const override;
virtual Rect GetStrokedBounds(
const StrokeOptions& aStrokeOptions,
const Matrix& aTransform = Matrix()) const override;
virtual void StreamToSink(PathSink* aSink) const override;
virtual FillRule GetFillRule() const override { return mFillRule; }
Path* GetRealizedPath() const;
private:
bool EnsureRealizedPath() const;
mutable RefPtr<Path> mRealizedPath;
std::vector<PathOp> mPathOps;
FillRule mFillRule;
RefPtr<DrawTarget> mDT;
Point mCurrentPoint;
Point mBeginPoint;
};
} // namespace gfx
} // namespace mozilla
#endif /* MOZILLA_GFX_PATHCAPTURE_H_ */

View File

@ -1923,7 +1923,7 @@ RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream)
: RecordedEventDerived(DRAWTARGETCREATION), mExistingData(nullptr) {
ReadElement(aStream, mRefPtr);
ReadElementConstrained(aStream, mBackendType, BackendType::NONE,
BackendType::CAPTURE);
BackendType::WEBRENDER_TEXT);
ReadElement(aStream, mRect);
ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
SurfaceFormat::UNKNOWN);

View File

@ -196,12 +196,6 @@ void ScaledFontDWrite::CopyGlyphsToBuilder(const GlyphBuffer& aBuffer,
PathBuilder* aBuilder,
const Matrix* aTransformHint) {
BackendType backendType = aBuilder->GetBackendType();
if (backendType == BackendType::CAPTURE) {
StreamingGeometrySink sink(aBuilder);
CopyGlyphsToSink(aBuffer, &sink);
return;
}
if (backendType != BackendType::DIRECT2D &&
backendType != BackendType::DIRECT2D1_1) {
ScaledFontBase::CopyGlyphsToBuilder(aBuffer, aBuilder, aTransformHint);

View File

@ -1,219 +0,0 @@
/* -*- 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 "SourceSurfaceCapture.h"
#include "DrawCommand.h"
#include "DrawTargetCapture.h"
#include "MainThreadUtils.h"
#include "mozilla/gfx/Logging.h"
namespace mozilla {
namespace gfx {
SourceSurfaceCapture::SourceSurfaceCapture(DrawTargetCaptureImpl* aOwner)
: mOwner(aOwner),
mHasCommandList(false),
mShouldResolveToLuminance{false},
mLuminanceType{LuminanceType::LUMINANCE},
mOpacity{1.0f},
mLock("SourceSurfaceCapture.mLock") {
mSize = mOwner->GetSize();
mFormat = mOwner->GetFormat();
mRefDT = mOwner->mRefDT;
mStride = mOwner->mStride;
mSurfaceAllocationSize = mOwner->mSurfaceAllocationSize;
}
SourceSurfaceCapture::SourceSurfaceCapture(
DrawTargetCaptureImpl* aOwner,
LuminanceType aLuminanceType /* = LuminanceType::LINEARRGB */,
Float aOpacity /* = 1.0f */)
: mOwner{aOwner},
mHasCommandList{false},
mShouldResolveToLuminance{true},
mLuminanceType{aLuminanceType},
mOpacity{aOpacity},
mLock{"SourceSurfaceCapture.mLock"} {
mSize = mOwner->GetSize();
mFormat = mOwner->GetFormat();
mRefDT = mOwner->mRefDT;
mStride = mOwner->mStride;
mSurfaceAllocationSize = mOwner->mSurfaceAllocationSize;
// In this case our DrawTarget will not track us, so copy its drawing
// commands.
DrawTargetWillChange();
}
SourceSurfaceCapture::SourceSurfaceCapture(DrawTargetCaptureImpl* aOwner,
SourceSurface* aSurfToOptimize)
: mOwner{aOwner},
mHasCommandList{false},
mShouldResolveToLuminance{false},
mLuminanceType{LuminanceType::LUMINANCE},
mOpacity{1.0f},
mLock{"SourceSurfaceCapture.mLock"},
mSurfToOptimize(aSurfToOptimize) {
mSize = aSurfToOptimize->GetSize();
mFormat = aSurfToOptimize->GetFormat();
mRefDT = mOwner->mRefDT;
}
SourceSurfaceCapture::~SourceSurfaceCapture() = default;
void SourceSurfaceCapture::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
SizeOfInfo& aInfo) const {
MutexAutoLock lock(mLock);
aInfo.AddType(SurfaceType::CAPTURE);
if (mSurfToOptimize) {
mSurfToOptimize->SizeOfExcludingThis(aMallocSizeOf, aInfo);
return;
}
if (mResolved) {
mResolved->SizeOfExcludingThis(aMallocSizeOf, aInfo);
return;
}
if (mHasCommandList) {
aInfo.mHeapBytes += mCommands.BufferCapacity();
return;
}
}
bool SourceSurfaceCapture::IsValid() const {
// We must either be able to source a command list, or we must have a cached
// and rasterized surface.
MutexAutoLock lock(mLock);
if (mSurfToOptimize) {
// We were given a surface, but we haven't tried to optimize it yet
// with the reference draw target.
return mSurfToOptimize->IsValid();
}
if (mResolved) {
// We were given a surface, and we already optimized it with the
// reference draw target.
return mResolved->IsValid();
}
// We have no underlying surface, so it must be a set of drawing commands.
return mOwner || mHasCommandList;
}
RefPtr<SourceSurface> SourceSurfaceCapture::Resolve(BackendType aBackendType) {
MutexAutoLock lock(mLock);
if (mSurfToOptimize) {
mResolved = mRefDT->OptimizeSourceSurface(mSurfToOptimize);
mSurfToOptimize = nullptr;
}
if (mResolved || (!mOwner && !mHasCommandList)) {
// We are already resolved, or there is no way we can rasterize
// anything, we don't have a source DrawTarget and we don't have
// a command list. Return whatever our cached surface is.
return mResolved;
}
BackendType backendType = aBackendType;
if (backendType == BackendType::NONE) {
backendType = mRefDT->GetBackendType();
}
// Note: SurfaceType is not 1:1 with BackendType, so we can't easily decide
// that they match. Instead we just cache the first thing to be requested.
// We ensured no mResolved existed before.
mResolved = ResolveImpl(backendType);
return mResolved;
}
RefPtr<SourceSurface> SourceSurfaceCapture::ResolveImpl(
BackendType aBackendType) {
RefPtr<DrawTarget> dt;
uint8_t* data = nullptr;
if (!mSurfaceAllocationSize) {
if (aBackendType == mRefDT->GetBackendType()) {
dt = mRefDT->CreateSimilarDrawTarget(mSize, mFormat);
} else {
dt = Factory::CreateDrawTarget(aBackendType, mSize, mFormat);
}
} else {
data = static_cast<uint8_t*>(calloc(1, mSurfaceAllocationSize));
if (!data) {
return nullptr;
}
BackendType type = Factory::DoesBackendSupportDataDrawtarget(aBackendType)
? aBackendType
: BackendType::SKIA;
dt = Factory::CreateDrawTargetForData(type, data, mSize, mStride, mFormat);
if (!dt || !dt->IsValid()) {
free(data);
return nullptr;
}
}
if (!dt || !dt->IsValid()) {
// Make sure we haven't allocated and aren't leaking something, the code
// right anove here should have guaranteed that.
MOZ_ASSERT(!data);
return nullptr;
}
// If we're still attached to a DrawTarget, use its command list rather than
// 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);
}
RefPtr<SourceSurface> surf;
if (!mShouldResolveToLuminance) {
surf = dt->Snapshot();
} else {
surf = dt->IntoLuminanceSource(mLuminanceType, mOpacity);
}
if (data) {
surf->AddUserData(reinterpret_cast<UserDataKey*>(dt.get()), data, free);
}
return surf;
}
already_AddRefed<DataSourceSurface> SourceSurfaceCapture::GetDataSurface() {
RefPtr<SourceSurface> surface = Resolve();
if (!surface) {
return nullptr;
}
return surface->GetDataSurface();
}
void SourceSurfaceCapture::DrawTargetWillDestroy() {
MutexAutoLock lock(mLock);
// The source DrawTarget is going away, so we can just steal its commands.
mCommands = std::move(mOwner->mCommands);
mHasCommandList = true;
mOwner = nullptr;
}
void SourceSurfaceCapture::DrawTargetWillChange() {
MutexAutoLock lock(mLock);
for (CaptureCommandList::iterator iter(mOwner->mCommands); !iter.Done();
iter.Next()) {
DrawingCommand* cmd = iter.Get();
cmd->CloneInto(&mCommands);
}
mHasCommandList = true;
mOwner = nullptr;
}
} // namespace gfx
} // namespace mozilla

View File

@ -1,76 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_gfx_2d_SourceSurfaceCapture_h
#define mozilla_gfx_2d_SourceSurfaceCapture_h
#include "2D.h"
#include "CaptureCommandList.h"
#include "mozilla/Mutex.h"
namespace mozilla {
namespace gfx {
class DrawTargetCaptureImpl;
class SourceSurfaceCapture : public SourceSurface {
friend class DrawTargetCaptureImpl;
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceCapture, override)
explicit SourceSurfaceCapture(DrawTargetCaptureImpl* aOwner);
SourceSurfaceCapture(DrawTargetCaptureImpl* aOwner,
LuminanceType aLuminanceType, float aOpacity);
SourceSurfaceCapture(DrawTargetCaptureImpl* aOwner,
SourceSurface* aSurfToOptimize);
virtual ~SourceSurfaceCapture();
SurfaceType GetType() const override { return SurfaceType::CAPTURE; }
IntSize GetSize() const override { return mSize; }
SurfaceFormat GetFormat() const override { return mFormat; }
void SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
SizeOfInfo& aInfo) const override;
bool IsValid() const override;
already_AddRefed<DataSourceSurface> GetDataSurface() override;
// The backend hint is not guaranteed to be honored, so callers must check
// the resulting type if needed.
RefPtr<SourceSurface> Resolve(BackendType aBackendType = BackendType::NONE);
protected:
RefPtr<SourceSurface> ResolveImpl(BackendType aBackendType);
void DrawTargetWillDestroy();
void DrawTargetWillChange();
private:
IntSize mSize;
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;
RefPtr<SourceSurface> mSurfToOptimize;
};
} // namespace gfx
} // namespace mozilla
#endif // mozilla_gfx_2d_SourceSurfaceCapture_h

View File

@ -21,34 +21,15 @@ void SourceSurfaceRawData::InitWrappingData(
mSize = aSize;
mStride = aStride;
mFormat = aFormat;
if (aDeallocator) {
mOwnData = true;
}
mDeallocator = aDeallocator;
mClosure = aClosure;
}
void SourceSurfaceRawData::GuaranteePersistance() {
if (mOwnData) {
return;
}
MOZ_ASSERT(!mDeallocator);
uint8_t* oldData = mRawData;
mRawData = new uint8_t[mStride * mSize.height];
memcpy(mRawData, oldData, mStride * mSize.height);
mOwnData = true;
}
void SourceSurfaceRawData::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
SizeOfInfo& aInfo) const {
aInfo.AddType(SurfaceType::DATA);
if (mDeallocator) {
aInfo.mUnknownBytes = mStride * mSize.height;
} else if (mOwnData) {
aInfo.mHeapBytes = mStride * mSize.height;
}
}

View File

@ -37,8 +37,6 @@ class SourceSurfaceMappedData final : public DataSourceSurface {
mMap.GetSurface()->SizeOfExcludingThis(aMallocSizeOf, aInfo);
}
void GuaranteePersistance() final {}
const DataSourceSurface* GetScopedSurface() const {
return mMap.GetSurface();
}
@ -57,16 +55,12 @@ class SourceSurfaceRawData : public DataSourceSurface {
: mRawData(0),
mStride(0),
mFormat(SurfaceFormat::UNKNOWN),
mOwnData(false),
mDeallocator(nullptr),
mClosure(nullptr) {}
virtual ~SourceSurfaceRawData() {
if (mDeallocator) {
mDeallocator(mClosure);
} else if (mOwnData) {
// The buffer is created from GuaranteePersistance().
delete[] mRawData;
}
}
@ -80,8 +74,6 @@ class SourceSurfaceRawData : public DataSourceSurface {
void SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
SizeOfInfo& aInfo) const override;
virtual void GuaranteePersistance() override;
private:
friend class Factory;
@ -98,7 +90,6 @@ class SourceSurfaceRawData : public DataSourceSurface {
SurfaceFormat mFormat;
IntSize mSize;
bool mOwnData;
Factory::SourceSurfaceDeallocator mDeallocator;
void* mClosure;
};

View File

@ -38,7 +38,6 @@ enum class SurfaceType : int8_t {
WRAP_AND_RECORD, /* Surface used for wrap and record */
TILED, /* Surface from a tiled DrawTarget */
DATA_SHARED, /* Data surface using shared memory */
CAPTURE, /* Data from a DrawTargetCapture */
DATA_RECYCLING_SHARED, /* Data surface using shared memory */
OFFSET, /* Offset */
DATA_ALIGNED, /* Data surface using aligned heap memory */
@ -554,7 +553,6 @@ enum class BackendType : int8_t {
RECORDING,
DIRECT2D1_1,
WEBRENDER_TEXT,
CAPTURE, // Used for paths
// Add new entries above this line.
BACKEND_LAST

View File

@ -52,7 +52,6 @@ EXPORTS.mozilla.gfx += [
"ScaleFactor.h",
"ScaleFactors2D.h",
"SourceSurfaceCairo.h",
"SourceSurfaceCapture.h",
"SourceSurfaceRawData.h",
"StackArray.h",
"Swizzle.h",
@ -162,19 +161,16 @@ UNIFIED_SOURCES += [
"Blur.cpp",
"BufferEdgePad.cpp",
"BufferUnrotate.cpp",
"CaptureCommandList.cpp",
"DataSourceSurface.cpp",
"DataSurfaceHelpers.cpp",
"DrawEventRecorder.cpp",
"DrawTarget.cpp",
"DrawTargetCairo.cpp",
"DrawTargetCapture.cpp",
"DrawTargetDual.cpp",
"DrawTargetOffset.cpp",
"DrawTargetRecording.cpp",
"DrawTargetTiled.cpp",
"DrawTargetWrapAndRecord.cpp",
"FilterNodeCapture.cpp",
"FilterNodeSoftware.cpp",
"FilterProcessing.cpp",
"FilterProcessingScalar.cpp",
@ -183,7 +179,6 @@ UNIFIED_SOURCES += [
"NativeFontResource.cpp",
"Path.cpp",
"PathCairo.cpp",
"PathCapture.cpp",
"PathHelpers.cpp",
"PathRecording.cpp",
"Quaternion.cpp",
@ -192,7 +187,6 @@ UNIFIED_SOURCES += [
"ScaledFontBase.cpp",
"SFNTData.cpp",
"SourceSurfaceCairo.cpp",
"SourceSurfaceCapture.cpp",
"SourceSurfaceRawData.cpp",
"Swizzle.cpp",
"Types.cpp",

View File

@ -160,10 +160,6 @@ bool SourceSurfaceSharedData::Init(const IntSize& aSize, int32_t aStride,
return true;
}
void SourceSurfaceSharedData::GuaranteePersistance() {
// Shared memory is not unmapped until we release SourceSurfaceSharedData.
}
void SourceSurfaceSharedData::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
SizeOfInfo& aInfo) const {
MutexAutoLock lock(mMutex);

View File

@ -155,8 +155,6 @@ class SourceSurfaceSharedData : public DataSourceSurface {
IntSize GetSize() const final { return mSize; }
SurfaceFormat GetFormat() const final { return mFormat; }
void GuaranteePersistance() final;
void SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
SizeOfInfo& aInfo) const final;

View File

@ -29,10 +29,6 @@ bool SourceSurfaceVolatileData::Init(const IntSize& aSize, int32_t aStride,
return true;
}
void SourceSurfaceVolatileData::GuaranteePersistance() {
MOZ_ASSERT_UNREACHABLE("Should use SourceSurfaceRawData wrapper!");
}
void SourceSurfaceVolatileData::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
SizeOfInfo& aInfo) const {
aInfo.AddType(SurfaceType::DATA);

View File

@ -42,8 +42,6 @@ class SourceSurfaceVolatileData : public DataSourceSurface {
IntSize GetSize() const override { return mSize; }
SurfaceFormat GetFormat() const override { return mFormat; }
void GuaranteePersistance() override;
void SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
SizeOfInfo& aInfo) const override;

View File

@ -72,9 +72,6 @@ class SourceSurfaceCanvasRecording final : public gfx::SourceSurface {
return do_AddRef(mDataSourceSurface);
}
protected:
void GuaranteePersistance() final { EnsureDataSurfaceOnMainThread(); }
private:
void EnsureDataSurfaceOnMainThread() {
// The data can only be retrieved on the main thread.

View File

@ -70,18 +70,8 @@ already_AddRefed<DrawTarget> gfxAlphaBoxBlur::InitDrawTarget(
mAccelerated = true;
}
if (aReferenceDT->IsCaptureDT()) {
if (mAccelerated) {
mDrawTarget = Factory::CreateCaptureDrawTarget(backend, mBlur.GetSize(),
SurfaceFormat::A8);
} else {
mDrawTarget = Factory::CreateCaptureDrawTargetForData(
backend, mBlur.GetSize(), SurfaceFormat::A8, mBlur.GetStride(),
blurDataSize);
}
} else if (mAccelerated) {
// Note: CreateShadowDrawTarget is only implemented for Cairo, so we don't
// care about mimicking this in the DrawTargetCapture case.
// Note: CreateShadowDrawTarget is only implemented for Cairo.
mDrawTarget = aReferenceDT->CreateShadowDrawTarget(
mBlur.GetSize(), SurfaceFormat::A8,
AlphaBoxBlur::CalculateBlurSigma(aBlurRadius.width));
@ -145,9 +135,6 @@ already_AddRefed<SourceSurface> gfxAlphaBoxBlur::DoBlur(
AlphaBoxBlur::CalculateBlurSigma(mBlur.GetBlurRadius().width),
CompositionOp::OP_OVER);
blurMask = blurDT->Snapshot();
} else if (mDrawTarget->IsCaptureDT()) {
mDrawTarget->Blur(mBlur);
blurMask = mDrawTarget->Snapshot();
}
if (!aShadowColor) {
@ -166,7 +153,7 @@ already_AddRefed<SourceSurface> gfxAlphaBoxBlur::DoBlur(
}
void gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx) {
if ((mDrawTarget && !mDrawTarget->IsCaptureDT()) && !mAccelerated && !mData) {
if (mDrawTarget && !mAccelerated && !mData) {
return;
}

View File

@ -188,8 +188,7 @@ void gfxContext::SetPath(Path* path) {
MOZ_ASSERT(path->GetBackendType() == mDT->GetBackendType() ||
path->GetBackendType() == BackendType::RECORDING ||
(mDT->GetBackendType() == BackendType::DIRECT2D1_1 &&
path->GetBackendType() == BackendType::DIRECT2D) ||
path->GetBackendType() == BackendType::CAPTURE);
path->GetBackendType() == BackendType::DIRECT2D));
mPath = path;
mPathBuilder = nullptr;
mPathIsRect = false;

View File

@ -137,8 +137,6 @@ inline const char* GetBackendName(mozilla::gfx::BackendType aBackend) {
return "direct2d 1.1";
case mozilla::gfx::BackendType::WEBRENDER_TEXT:
return "webrender text";
case mozilla::gfx::BackendType::CAPTURE:
return "capture";
case mozilla::gfx::BackendType::NONE:
return "none";
case mozilla::gfx::BackendType::BACKEND_LAST:

View File

@ -19,7 +19,7 @@ CGContextRef gfxQuartzNativeDrawing::BeginNativeDrawing() {
"BeginNativeDrawing called when drawing already in progress");
DrawTarget* dt = mDrawTarget;
if (dt->IsDualDrawTarget() || dt->IsTiledDrawTarget() || dt->IsCaptureDT() ||
if (dt->IsDualDrawTarget() || dt->IsTiledDrawTarget() ||
dt->GetBackendType() != BackendType::SKIA || dt->IsRecording()) {
// We need a DrawTarget that we can get a CGContextRef from:
Matrix transform = dt->GetTransform();

View File

@ -406,7 +406,6 @@ class TextDrawTarget : public DrawTarget {
}
bool IsRecording() const override { return true; }
bool IsCaptureDT() const override { return false; }
already_AddRefed<SourceSurface> Snapshot() override {
MOZ_CRASH("TextDrawTarget: Method shouldn't be called");
@ -423,11 +422,6 @@ class TextDrawTarget : public DrawTarget {
MOZ_CRASH("TextDrawTarget: Method shouldn't be called");
}
void DrawCapturedDT(DrawTargetCapture* aCaptureDT,
const Matrix& aTransform) override {
MOZ_CRASH("TextDrawTarget: Method shouldn't be called");
}
void DrawSurface(SourceSurface* aSurface, const Rect& aDest,
const Rect& aSource, const DrawSurfaceOptions& aSurfOptions,
const DrawOptions& aOptions) override {