зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1369552. Split out DrawTargetWrapAndRecord and DrawTargetRecording. r=Bas
DrawTargetRecording will stop playing back durin recording. --HG-- rename : gfx/2d/DrawTargetRecording.cpp => gfx/2d/DrawTargetWrapAndRecord.cpp rename : gfx/2d/DrawTargetRecording.h => gfx/2d/DrawTargetWrapAndRecord.h extra : rebase_source : fd41326974905946318489cc801929328331ae73
This commit is contained in:
Родитель
32235488fc
Коммит
63724b1070
|
@ -1495,6 +1495,9 @@ public:
|
|||
static already_AddRefed<DrawTarget>
|
||||
CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
|
||||
|
||||
static already_AddRefed<DrawTarget>
|
||||
CreateWrapAndRecordDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT);
|
||||
|
||||
static already_AddRefed<DrawTarget>
|
||||
CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ void RecordingSourceSurfaceUserDataFunc(void *aUserData)
|
|||
}
|
||||
|
||||
static void
|
||||
StoreSourceSurface(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
|
||||
StoreSourceSurfaceRecording(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
|
||||
DataSourceSurface *aDataSurf, const char *reason)
|
||||
{
|
||||
if (!aDataSurf) {
|
||||
|
@ -57,7 +57,7 @@ StoreSourceSurface(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
|
|||
}
|
||||
|
||||
static void
|
||||
EnsureSurfaceStored(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
|
||||
EnsureSurfaceStoredRecording(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
|
||||
const char *reason)
|
||||
{
|
||||
if (aRecorder->HasStoredObject(aSurface)) {
|
||||
|
@ -65,7 +65,7 @@ EnsureSurfaceStored(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface
|
|||
}
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurf = aSurface->GetDataSurface();
|
||||
StoreSourceSurface(aRecorder, aSurface, dataSurf, reason);
|
||||
StoreSourceSurfaceRecording(aRecorder, aSurface, dataSurf, reason);
|
||||
aRecorder->AddStoredObject(aSurface);
|
||||
aRecorder->AddSourceSurface(aSurface);
|
||||
|
||||
|
@ -125,7 +125,7 @@ public:
|
|||
};
|
||||
|
||||
static SourceSurface *
|
||||
GetSourceSurface(SourceSurface *aSurface)
|
||||
GetSourceSurfaceRecording(SourceSurface *aSurface)
|
||||
{
|
||||
if (aSurface->GetType() != SurfaceType::RECORDING) {
|
||||
return aSurface;
|
||||
|
@ -135,7 +135,7 @@ GetSourceSurface(SourceSurface *aSurface)
|
|||
}
|
||||
|
||||
static GradientStops *
|
||||
GetGradientStops(GradientStops *aStops)
|
||||
GetGradientStopsRecording(GradientStops *aStops)
|
||||
{
|
||||
if (aStops->GetBackendType() != BackendType::RECORDING) {
|
||||
return aStops;
|
||||
|
@ -175,10 +175,10 @@ public:
|
|||
|
||||
virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) override
|
||||
{
|
||||
EnsureSurfaceStored(mRecorder, aSurface, "SetInput");
|
||||
EnsureSurfaceStoredRecording(mRecorder, aSurface, "SetInput");
|
||||
|
||||
mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aSurface));
|
||||
mFinalFilterNode->SetInput(aIndex, GetSourceSurface(aSurface));
|
||||
mFinalFilterNode->SetInput(aIndex, GetSourceSurfaceRecording(aSurface));
|
||||
}
|
||||
virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) override
|
||||
{
|
||||
|
@ -222,15 +222,15 @@ public:
|
|||
RefPtr<DrawEventRecorderPrivate> mRecorder;
|
||||
};
|
||||
|
||||
struct AdjustedPattern
|
||||
struct AdjustedPatternRecording
|
||||
{
|
||||
explicit AdjustedPattern(const Pattern &aPattern)
|
||||
explicit AdjustedPatternRecording(const Pattern &aPattern)
|
||||
: mPattern(nullptr)
|
||||
{
|
||||
mOrigPattern = const_cast<Pattern*>(&aPattern);
|
||||
}
|
||||
|
||||
~AdjustedPattern() {
|
||||
~AdjustedPatternRecording() {
|
||||
if (mPattern) {
|
||||
mPattern->~Pattern();
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ struct AdjustedPattern
|
|||
{
|
||||
SurfacePattern *surfPat = static_cast<SurfacePattern*>(mOrigPattern);
|
||||
mPattern =
|
||||
new (mSurfPat) SurfacePattern(GetSourceSurface(surfPat->mSurface),
|
||||
new (mSurfPat) SurfacePattern(GetSourceSurfaceRecording(surfPat->mSurface),
|
||||
surfPat->mExtendMode, surfPat->mMatrix,
|
||||
surfPat->mSamplingFilter,
|
||||
surfPat->mSamplingRect);
|
||||
|
@ -256,7 +256,7 @@ struct AdjustedPattern
|
|||
LinearGradientPattern *linGradPat = static_cast<LinearGradientPattern*>(mOrigPattern);
|
||||
mPattern =
|
||||
new (mLinGradPat) LinearGradientPattern(linGradPat->mBegin, linGradPat->mEnd,
|
||||
GetGradientStops(linGradPat->mStops),
|
||||
GetGradientStopsRecording(linGradPat->mStops),
|
||||
linGradPat->mMatrix);
|
||||
return mPattern;
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ struct AdjustedPattern
|
|||
mPattern =
|
||||
new (mRadGradPat) RadialGradientPattern(radGradPat->mCenter1, radGradPat->mCenter2,
|
||||
radGradPat->mRadius1, radGradPat->mRadius2,
|
||||
GetGradientStops(radGradPat->mStops),
|
||||
GetGradientStopsRecording(radGradPat->mStops),
|
||||
radGradPat->mMatrix);
|
||||
return mPattern;
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ DrawTargetRecording::FillRect(const Rect &aRect,
|
|||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
mRecorder->RecordEvent(RecordedFillRect(this, aRect, aPattern, aOptions));
|
||||
mFinalDT->FillRect(aRect, *AdjustedPattern(aPattern), aOptions);
|
||||
mFinalDT->FillRect(aRect, *AdjustedPatternRecording(aPattern), aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -337,7 +337,7 @@ DrawTargetRecording::StrokeRect(const Rect &aRect,
|
|||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
mRecorder->RecordEvent(RecordedStrokeRect(this, aRect, aPattern, aStrokeOptions, aOptions));
|
||||
mFinalDT->StrokeRect(aRect, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
|
||||
mFinalDT->StrokeRect(aRect, *AdjustedPatternRecording(aPattern), aStrokeOptions, aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -350,7 +350,7 @@ DrawTargetRecording::StrokeLine(const Point &aBegin,
|
|||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
mRecorder->RecordEvent(RecordedStrokeLine(this, aBegin, aEnd, aPattern, aStrokeOptions, aOptions));
|
||||
mFinalDT->StrokeLine(aBegin, aEnd, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
|
||||
mFinalDT->StrokeLine(aBegin, aEnd, *AdjustedPatternRecording(aPattern), aStrokeOptions, aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -362,7 +362,7 @@ DrawTargetRecording::Fill(const Path *aPath,
|
|||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
mRecorder->RecordEvent(RecordedFill(this, pathRecording, aPattern, aOptions));
|
||||
mFinalDT->Fill(pathRecording->mPath, *AdjustedPattern(aPattern), aOptions);
|
||||
mFinalDT->Fill(pathRecording->mPath, *AdjustedPatternRecording(aPattern), aOptions);
|
||||
}
|
||||
|
||||
struct RecordingFontUserData
|
||||
|
@ -427,7 +427,7 @@ DrawTargetRecording::FillGlyphs(ScaledFont *aFont,
|
|||
}
|
||||
|
||||
mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs));
|
||||
mFinalDT->FillGlyphs(aFont, aBuffer, *AdjustedPattern(aPattern), aOptions, aRenderingOptions);
|
||||
mFinalDT->FillGlyphs(aFont, aBuffer, *AdjustedPatternRecording(aPattern), aOptions, aRenderingOptions);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -439,7 +439,7 @@ DrawTargetRecording::Mask(const Pattern &aSource,
|
|||
EnsurePatternDependenciesStored(aMask);
|
||||
|
||||
mRecorder->RecordEvent(RecordedMask(this, aSource, aMask, aOptions));
|
||||
mFinalDT->Mask(*AdjustedPattern(aSource), *AdjustedPattern(aMask), aOptions);
|
||||
mFinalDT->Mask(*AdjustedPatternRecording(aSource), *AdjustedPatternRecording(aMask), aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -449,10 +449,10 @@ DrawTargetRecording::MaskSurface(const Pattern &aSource,
|
|||
const DrawOptions &aOptions)
|
||||
{
|
||||
EnsurePatternDependenciesStored(aSource);
|
||||
EnsureSurfaceStored(mRecorder, aMask, "MaskSurface");
|
||||
EnsureSurfaceStoredRecording(mRecorder, aMask, "MaskSurface");
|
||||
|
||||
mRecorder->RecordEvent(RecordedMaskSurface(this, aSource, aMask, aOffset, aOptions));
|
||||
mFinalDT->MaskSurface(*AdjustedPattern(aSource), GetSourceSurface(aMask), aOffset, aOptions);
|
||||
mFinalDT->MaskSurface(*AdjustedPatternRecording(aSource), GetSourceSurfaceRecording(aMask), aOffset, aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -465,7 +465,7 @@ DrawTargetRecording::Stroke(const Path *aPath,
|
|||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
mRecorder->RecordEvent(RecordedStroke(this, pathRecording, aPattern, aStrokeOptions, aOptions));
|
||||
mFinalDT->Stroke(pathRecording->mPath, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
|
||||
mFinalDT->Stroke(pathRecording->mPath, *AdjustedPatternRecording(aPattern), aStrokeOptions, aOptions);
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface>
|
||||
|
@ -505,10 +505,10 @@ DrawTargetRecording::DrawSurface(SourceSurface *aSurface,
|
|||
const DrawSurfaceOptions &aSurfOptions,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
EnsureSurfaceStored(mRecorder, aSurface, "DrawSurface");
|
||||
EnsureSurfaceStoredRecording(mRecorder, aSurface, "DrawSurface");
|
||||
|
||||
mRecorder->RecordEvent(RecordedDrawSurface(this, aSurface, aDest, aSource, aSurfOptions, aOptions));
|
||||
mFinalDT->DrawSurface(GetSourceSurface(aSurface), aDest, aSource, aSurfOptions, aOptions);
|
||||
mFinalDT->DrawSurface(GetSourceSurfaceRecording(aSurface), aDest, aSource, aSurfOptions, aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -519,10 +519,10 @@ DrawTargetRecording::DrawSurfaceWithShadow(SourceSurface *aSurface,
|
|||
Float aSigma,
|
||||
CompositionOp aOp)
|
||||
{
|
||||
EnsureSurfaceStored(mRecorder, aSurface, "DrawSurfaceWithShadow");
|
||||
EnsureSurfaceStoredRecording(mRecorder, aSurface, "DrawSurfaceWithShadow");
|
||||
|
||||
mRecorder->RecordEvent(RecordedDrawSurfaceWithShadow(this, aSurface, aDest, aColor, aOffset, aSigma, aOp));
|
||||
mFinalDT->DrawSurfaceWithShadow(GetSourceSurface(aSurface), aDest, aColor, aOffset, aSigma, aOp);
|
||||
mFinalDT->DrawSurfaceWithShadow(GetSourceSurfaceRecording(aSurface), aDest, aColor, aOffset, aSigma, aOp);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -561,10 +561,10 @@ DrawTargetRecording::CopySurface(SourceSurface *aSurface,
|
|||
const IntRect &aSourceRect,
|
||||
const IntPoint &aDestination)
|
||||
{
|
||||
EnsureSurfaceStored(mRecorder, aSurface, "CopySurface");
|
||||
EnsureSurfaceStoredRecording(mRecorder, aSurface, "CopySurface");
|
||||
|
||||
mRecorder->RecordEvent(RecordedCopySurface(this, aSurface, aSourceRect, aDestination));
|
||||
mFinalDT->CopySurface(GetSourceSurface(aSurface), aSourceRect, aDestination);
|
||||
mFinalDT->CopySurface(GetSourceSurfaceRecording(aSurface), aSourceRect, aDestination);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -597,7 +597,7 @@ DrawTargetRecording::PushLayer(bool aOpaque, Float aOpacity,
|
|||
const IntRect& aBounds, bool aCopyBackground)
|
||||
{
|
||||
if (aMask) {
|
||||
EnsureSurfaceStored(mRecorder, aMask, "PushLayer");
|
||||
EnsureSurfaceStoredRecording(mRecorder, aMask, "PushLayer");
|
||||
}
|
||||
|
||||
mRecorder->RecordEvent(RecordedPushLayer(this, aOpaque, aOpacity, aMask,
|
||||
|
@ -643,7 +643,7 @@ DrawTargetRecording::OptimizeSourceSurface(SourceSurface *aSurface) const
|
|||
dataSurf = aSurface->GetDataSurface();
|
||||
}
|
||||
|
||||
StoreSourceSurface(mRecorder, retSurf, dataSurf, "OptimizeSourceSurface");
|
||||
StoreSourceSurfaceRecording(mRecorder, retSurf, dataSurf, "OptimizeSourceSurface");
|
||||
|
||||
return retSurf.forget();
|
||||
}
|
||||
|
@ -656,7 +656,7 @@ DrawTargetRecording::CreateSourceSurfaceFromNativeSurface(const NativeSurface &a
|
|||
RefPtr<SourceSurface> retSurf = new SourceSurfaceRecording(surf, mRecorder);
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface();
|
||||
StoreSourceSurface(mRecorder, retSurf, dataSurf, "CreateSourceSurfaceFromNativeSurface");
|
||||
StoreSourceSurfaceRecording(mRecorder, retSurf, dataSurf, "CreateSourceSurfaceFromNativeSurface");
|
||||
|
||||
return retSurf.forget();
|
||||
}
|
||||
|
@ -749,7 +749,7 @@ DrawTargetRecording::EnsurePatternDependenciesStored(const Pattern &aPattern)
|
|||
case PatternType::SURFACE:
|
||||
{
|
||||
const SurfacePattern *pat = static_cast<const SurfacePattern*>(&aPattern);
|
||||
EnsureSurfaceStored(mRecorder, pat->mSurface, "EnsurePatternDependenciesStored");
|
||||
EnsureSurfaceStoredRecording(mRecorder, pat->mSurface, "EnsurePatternDependenciesStored");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,759 @@
|
|||
/* -*- Mode: C++; tab-width: 20; 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 "DrawTargetWrapAndRecord.h"
|
||||
#include "PathRecording.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Logging.h"
|
||||
#include "Tools.h"
|
||||
#include "Filters.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "RecordingTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
struct WrapAndRecordSourceSurfaceUserData
|
||||
{
|
||||
void *refPtr;
|
||||
RefPtr<DrawEventRecorderPrivate> recorder;
|
||||
};
|
||||
|
||||
void WrapAndRecordSourceSurfaceUserDataFunc(void *aUserData)
|
||||
{
|
||||
WrapAndRecordSourceSurfaceUserData *userData =
|
||||
static_cast<WrapAndRecordSourceSurfaceUserData*>(aUserData);
|
||||
|
||||
userData->recorder->RemoveSourceSurface((SourceSurface*)userData->refPtr);
|
||||
userData->recorder->RemoveStoredObject(userData->refPtr);
|
||||
userData->recorder->RecordEvent(
|
||||
RecordedSourceSurfaceDestruction(userData->refPtr));
|
||||
|
||||
delete userData;
|
||||
}
|
||||
|
||||
static void
|
||||
StoreSourceSurface(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
|
||||
DataSourceSurface *aDataSurf, const char *reason)
|
||||
{
|
||||
if (!aDataSurf) {
|
||||
gfxWarning() << "Recording failed to record SourceSurface for " << reason;
|
||||
// Insert a bogus source surface.
|
||||
int32_t stride = aSurface->GetSize().width * BytesPerPixel(aSurface->GetFormat());
|
||||
UniquePtr<uint8_t[]> sourceData(new uint8_t[stride * aSurface->GetSize().height]());
|
||||
aRecorder->RecordEvent(
|
||||
RecordedSourceSurfaceCreation(aSurface, sourceData.get(), stride,
|
||||
aSurface->GetSize(), aSurface->GetFormat()));
|
||||
} else {
|
||||
DataSourceSurface::ScopedMap map(aDataSurf, DataSourceSurface::READ);
|
||||
aRecorder->RecordEvent(
|
||||
RecordedSourceSurfaceCreation(aSurface, map.GetData(), map.GetStride(),
|
||||
aDataSurf->GetSize(), aDataSurf->GetFormat()));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
EnsureSurfaceStored(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface,
|
||||
const char *reason)
|
||||
{
|
||||
if (aRecorder->HasStoredObject(aSurface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurf = aSurface->GetDataSurface();
|
||||
StoreSourceSurface(aRecorder, aSurface, dataSurf, reason);
|
||||
aRecorder->AddStoredObject(aSurface);
|
||||
aRecorder->AddSourceSurface(aSurface);
|
||||
|
||||
WrapAndRecordSourceSurfaceUserData *userData = new WrapAndRecordSourceSurfaceUserData;
|
||||
userData->refPtr = aSurface;
|
||||
userData->recorder = aRecorder;
|
||||
aSurface->AddUserData(reinterpret_cast<UserDataKey*>(aRecorder),
|
||||
userData, &WrapAndRecordSourceSurfaceUserDataFunc);
|
||||
return;
|
||||
}
|
||||
|
||||
class SourceSurfaceWrapAndRecord : public SourceSurface
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceWrapAndRecord)
|
||||
SourceSurfaceWrapAndRecord(SourceSurface *aFinalSurface, DrawEventRecorderPrivate *aRecorder)
|
||||
: mFinalSurface(aFinalSurface), mRecorder(aRecorder)
|
||||
{
|
||||
mRecorder->AddStoredObject(this);
|
||||
}
|
||||
|
||||
~SourceSurfaceWrapAndRecord()
|
||||
{
|
||||
mRecorder->RemoveStoredObject(this);
|
||||
mRecorder->RecordEvent(RecordedSourceSurfaceDestruction(this));
|
||||
}
|
||||
|
||||
virtual SurfaceType GetType() const { return SurfaceType::RECORDING; }
|
||||
virtual IntSize GetSize() const { return mFinalSurface->GetSize(); }
|
||||
virtual SurfaceFormat GetFormat() const { return mFinalSurface->GetFormat(); }
|
||||
virtual already_AddRefed<DataSourceSurface> GetDataSurface() { return mFinalSurface->GetDataSurface(); }
|
||||
|
||||
RefPtr<SourceSurface> mFinalSurface;
|
||||
RefPtr<DrawEventRecorderPrivate> mRecorder;
|
||||
};
|
||||
|
||||
class GradientStopsWrapAndRecord : public GradientStops
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsWrapAndRecord)
|
||||
GradientStopsWrapAndRecord(GradientStops *aFinalGradientStops, DrawEventRecorderPrivate *aRecorder)
|
||||
: mFinalGradientStops(aFinalGradientStops), mRecorder(aRecorder)
|
||||
{
|
||||
mRecorder->AddStoredObject(this);
|
||||
}
|
||||
|
||||
~GradientStopsWrapAndRecord()
|
||||
{
|
||||
mRecorder->RemoveStoredObject(this);
|
||||
mRecorder->RecordEvent(RecordedGradientStopsDestruction(this));
|
||||
}
|
||||
|
||||
virtual BackendType GetBackendType() const { return BackendType::RECORDING; }
|
||||
|
||||
RefPtr<GradientStops> mFinalGradientStops;
|
||||
RefPtr<DrawEventRecorderPrivate> mRecorder;
|
||||
};
|
||||
|
||||
static SourceSurface *
|
||||
GetSourceSurface(SourceSurface *aSurface)
|
||||
{
|
||||
if (aSurface->GetType() != SurfaceType::RECORDING) {
|
||||
return aSurface;
|
||||
}
|
||||
|
||||
return static_cast<SourceSurfaceWrapAndRecord*>(aSurface)->mFinalSurface;
|
||||
}
|
||||
|
||||
static GradientStops *
|
||||
GetGradientStops(GradientStops *aStops)
|
||||
{
|
||||
if (aStops->GetBackendType() != BackendType::RECORDING) {
|
||||
return aStops;
|
||||
}
|
||||
|
||||
return static_cast<GradientStopsWrapAndRecord*>(aStops)->mFinalGradientStops;
|
||||
}
|
||||
|
||||
class FilterNodeWrapAndRecord : public FilterNode
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeWrapAndRecord, override)
|
||||
using FilterNode::SetAttribute;
|
||||
|
||||
FilterNodeWrapAndRecord(FilterNode *aFinalFilterNode, DrawEventRecorderPrivate *aRecorder)
|
||||
: mFinalFilterNode(aFinalFilterNode), mRecorder(aRecorder)
|
||||
{
|
||||
mRecorder->AddStoredObject(this);
|
||||
}
|
||||
|
||||
~FilterNodeWrapAndRecord()
|
||||
{
|
||||
mRecorder->RemoveStoredObject(this);
|
||||
mRecorder->RecordEvent(RecordedFilterNodeDestruction(this));
|
||||
}
|
||||
|
||||
static FilterNode*
|
||||
GetFilterNode(FilterNode* aNode)
|
||||
{
|
||||
if (aNode->GetBackendType() != FILTER_BACKEND_RECORDING) {
|
||||
gfxWarning() << "Non recording filter node used with recording DrawTarget!";
|
||||
return aNode;
|
||||
}
|
||||
|
||||
return static_cast<FilterNodeWrapAndRecord*>(aNode)->mFinalFilterNode;
|
||||
}
|
||||
|
||||
virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) override
|
||||
{
|
||||
EnsureSurfaceStored(mRecorder, aSurface, "SetInput");
|
||||
|
||||
mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aSurface));
|
||||
mFinalFilterNode->SetInput(aIndex, GetSourceSurface(aSurface));
|
||||
}
|
||||
virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) override
|
||||
{
|
||||
MOZ_ASSERT(mRecorder->HasStoredObject(aFilter));
|
||||
|
||||
mRecorder->RecordEvent(RecordedFilterNodeSetInput(this, aIndex, aFilter));
|
||||
mFinalFilterNode->SetInput(aIndex, GetFilterNode(aFilter));
|
||||
}
|
||||
|
||||
|
||||
#define FORWARD_SET_ATTRIBUTE(type, argtype) \
|
||||
virtual void SetAttribute(uint32_t aIndex, type aValue) override { \
|
||||
mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aValue, RecordedFilterNodeSetAttribute::ARGTYPE_##argtype)); \
|
||||
mFinalFilterNode->SetAttribute(aIndex, aValue); \
|
||||
}
|
||||
|
||||
FORWARD_SET_ATTRIBUTE(bool, BOOL);
|
||||
FORWARD_SET_ATTRIBUTE(uint32_t, UINT32);
|
||||
FORWARD_SET_ATTRIBUTE(Float, FLOAT);
|
||||
FORWARD_SET_ATTRIBUTE(const Size&, SIZE);
|
||||
FORWARD_SET_ATTRIBUTE(const IntSize&, INTSIZE);
|
||||
FORWARD_SET_ATTRIBUTE(const IntPoint&, INTPOINT);
|
||||
FORWARD_SET_ATTRIBUTE(const Rect&, RECT);
|
||||
FORWARD_SET_ATTRIBUTE(const IntRect&, INTRECT);
|
||||
FORWARD_SET_ATTRIBUTE(const Point&, POINT);
|
||||
FORWARD_SET_ATTRIBUTE(const Matrix&, MATRIX);
|
||||
FORWARD_SET_ATTRIBUTE(const Matrix5x4&, MATRIX5X4);
|
||||
FORWARD_SET_ATTRIBUTE(const Point3D&, POINT3D);
|
||||
FORWARD_SET_ATTRIBUTE(const Color&, COLOR);
|
||||
|
||||
#undef FORWARD_SET_ATTRIBUTE
|
||||
|
||||
virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) override {
|
||||
mRecorder->RecordEvent(RecordedFilterNodeSetAttribute(this, aIndex, aFloat, aSize));
|
||||
mFinalFilterNode->SetAttribute(aIndex, aFloat, aSize);
|
||||
}
|
||||
|
||||
virtual FilterBackend GetBackendType() override { return FILTER_BACKEND_RECORDING; }
|
||||
|
||||
RefPtr<FilterNode> mFinalFilterNode;
|
||||
RefPtr<DrawEventRecorderPrivate> mRecorder;
|
||||
};
|
||||
|
||||
struct AdjustedPattern
|
||||
{
|
||||
explicit AdjustedPattern(const Pattern &aPattern)
|
||||
: mPattern(nullptr)
|
||||
{
|
||||
mOrigPattern = const_cast<Pattern*>(&aPattern);
|
||||
}
|
||||
|
||||
~AdjustedPattern() {
|
||||
if (mPattern) {
|
||||
mPattern->~Pattern();
|
||||
}
|
||||
}
|
||||
|
||||
operator Pattern*()
|
||||
{
|
||||
switch(mOrigPattern->GetType()) {
|
||||
case PatternType::COLOR:
|
||||
return mOrigPattern;
|
||||
case PatternType::SURFACE:
|
||||
{
|
||||
SurfacePattern *surfPat = static_cast<SurfacePattern*>(mOrigPattern);
|
||||
mPattern =
|
||||
new (mSurfPat) SurfacePattern(GetSourceSurface(surfPat->mSurface),
|
||||
surfPat->mExtendMode, surfPat->mMatrix,
|
||||
surfPat->mSamplingFilter,
|
||||
surfPat->mSamplingRect);
|
||||
return mPattern;
|
||||
}
|
||||
case PatternType::LINEAR_GRADIENT:
|
||||
{
|
||||
LinearGradientPattern *linGradPat = static_cast<LinearGradientPattern*>(mOrigPattern);
|
||||
mPattern =
|
||||
new (mLinGradPat) LinearGradientPattern(linGradPat->mBegin, linGradPat->mEnd,
|
||||
GetGradientStops(linGradPat->mStops),
|
||||
linGradPat->mMatrix);
|
||||
return mPattern;
|
||||
}
|
||||
case PatternType::RADIAL_GRADIENT:
|
||||
{
|
||||
RadialGradientPattern *radGradPat = static_cast<RadialGradientPattern*>(mOrigPattern);
|
||||
mPattern =
|
||||
new (mRadGradPat) RadialGradientPattern(radGradPat->mCenter1, radGradPat->mCenter2,
|
||||
radGradPat->mRadius1, radGradPat->mRadius2,
|
||||
GetGradientStops(radGradPat->mStops),
|
||||
radGradPat->mMatrix);
|
||||
return mPattern;
|
||||
}
|
||||
default:
|
||||
return new (mColPat) ColorPattern(Color());
|
||||
}
|
||||
|
||||
return mPattern;
|
||||
}
|
||||
|
||||
union {
|
||||
char mColPat[sizeof(ColorPattern)];
|
||||
char mLinGradPat[sizeof(LinearGradientPattern)];
|
||||
char mRadGradPat[sizeof(RadialGradientPattern)];
|
||||
char mSurfPat[sizeof(SurfacePattern)];
|
||||
};
|
||||
|
||||
Pattern *mOrigPattern;
|
||||
Pattern *mPattern;
|
||||
};
|
||||
|
||||
DrawTargetWrapAndRecord::DrawTargetWrapAndRecord(DrawEventRecorder *aRecorder, DrawTarget *aDT, bool aHasData)
|
||||
: mRecorder(static_cast<DrawEventRecorderPrivate*>(aRecorder))
|
||||
, mFinalDT(aDT)
|
||||
{
|
||||
RefPtr<SourceSurface> snapshot = aHasData ? mFinalDT->Snapshot() : nullptr;
|
||||
mRecorder->RecordEvent(RecordedDrawTargetCreation(this,
|
||||
mFinalDT->GetBackendType(),
|
||||
mFinalDT->GetSize(),
|
||||
mFinalDT->GetFormat(),
|
||||
aHasData, snapshot));
|
||||
mFormat = mFinalDT->GetFormat();
|
||||
}
|
||||
|
||||
DrawTargetWrapAndRecord::DrawTargetWrapAndRecord(const DrawTargetWrapAndRecord *aDT,
|
||||
DrawTarget *aSimilarDT)
|
||||
: mRecorder(aDT->mRecorder)
|
||||
, mFinalDT(aSimilarDT)
|
||||
{
|
||||
mRecorder->RecordEvent(RecordedCreateSimilarDrawTarget(this,
|
||||
mFinalDT->GetSize(),
|
||||
mFinalDT->GetFormat()));
|
||||
mFormat = mFinalDT->GetFormat();
|
||||
}
|
||||
|
||||
DrawTargetWrapAndRecord::~DrawTargetWrapAndRecord()
|
||||
{
|
||||
mRecorder->RecordEvent(RecordedDrawTargetDestruction(this));
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::FillRect(const Rect &aRect,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
mRecorder->RecordEvent(RecordedFillRect(this, aRect, aPattern, aOptions));
|
||||
mFinalDT->FillRect(aRect, *AdjustedPattern(aPattern), aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::StrokeRect(const Rect &aRect,
|
||||
const Pattern &aPattern,
|
||||
const StrokeOptions &aStrokeOptions,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
mRecorder->RecordEvent(RecordedStrokeRect(this, aRect, aPattern, aStrokeOptions, aOptions));
|
||||
mFinalDT->StrokeRect(aRect, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::StrokeLine(const Point &aBegin,
|
||||
const Point &aEnd,
|
||||
const Pattern &aPattern,
|
||||
const StrokeOptions &aStrokeOptions,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
mRecorder->RecordEvent(RecordedStrokeLine(this, aBegin, aEnd, aPattern, aStrokeOptions, aOptions));
|
||||
mFinalDT->StrokeLine(aBegin, aEnd, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::Fill(const Path *aPath,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
RefPtr<PathRecording> pathWrapAndRecord = EnsurePathStored(aPath);
|
||||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
mRecorder->RecordEvent(RecordedFill(this, pathWrapAndRecord, aPattern, aOptions));
|
||||
mFinalDT->Fill(pathWrapAndRecord->mPath, *AdjustedPattern(aPattern), aOptions);
|
||||
}
|
||||
|
||||
struct WrapAndRecordFontUserData
|
||||
{
|
||||
void *refPtr;
|
||||
RefPtr<DrawEventRecorderPrivate> recorder;
|
||||
};
|
||||
|
||||
void WrapAndRecordFontUserDataDestroyFunc(void *aUserData)
|
||||
{
|
||||
WrapAndRecordFontUserData *userData =
|
||||
static_cast<WrapAndRecordFontUserData*>(aUserData);
|
||||
|
||||
userData->recorder->RecordEvent(RecordedScaledFontDestruction(userData->refPtr));
|
||||
userData->recorder->RemoveScaledFont((ScaledFont*)userData->refPtr);
|
||||
delete userData;
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::FillGlyphs(ScaledFont *aFont,
|
||||
const GlyphBuffer &aBuffer,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions,
|
||||
const GlyphRenderingOptions *aRenderingOptions)
|
||||
{
|
||||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
UserDataKey* userDataKey = reinterpret_cast<UserDataKey*>(mRecorder.get());
|
||||
if (!aFont->GetUserData(userDataKey)) {
|
||||
UnscaledFont* unscaledFont = aFont->GetUnscaledFont();
|
||||
if (!mRecorder->HasStoredObject(unscaledFont)) {
|
||||
RecordedFontData fontData(unscaledFont);
|
||||
RecordedFontDetails fontDetails;
|
||||
if (fontData.GetFontDetails(fontDetails)) {
|
||||
// Try to serialise the whole font, just in case this is a web font that
|
||||
// is not present on the system.
|
||||
if (!mRecorder->HasStoredFontData(fontDetails.fontDataKey)) {
|
||||
mRecorder->RecordEvent(fontData);
|
||||
mRecorder->AddStoredFontData(fontDetails.fontDataKey);
|
||||
}
|
||||
mRecorder->RecordEvent(RecordedUnscaledFontCreation(unscaledFont, fontDetails));
|
||||
} else {
|
||||
// If that fails, record just the font description and try to load it from
|
||||
// the system on the other side.
|
||||
RecordedFontDescriptor fontDesc(unscaledFont);
|
||||
if (fontDesc.IsValid()) {
|
||||
mRecorder->RecordEvent(fontDesc);
|
||||
} else {
|
||||
gfxWarning() << "DrawTargetWrapAndRecord::FillGlyphs failed to serialise UnscaledFont";
|
||||
}
|
||||
}
|
||||
mRecorder->AddStoredObject(unscaledFont);
|
||||
}
|
||||
|
||||
mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, unscaledFont));
|
||||
|
||||
WrapAndRecordFontUserData *userData = new WrapAndRecordFontUserData;
|
||||
userData->refPtr = aFont;
|
||||
userData->recorder = mRecorder;
|
||||
aFont->AddUserData(userDataKey, userData, &WrapAndRecordFontUserDataDestroyFunc);
|
||||
userData->recorder->AddScaledFont(aFont);
|
||||
}
|
||||
|
||||
mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs));
|
||||
mFinalDT->FillGlyphs(aFont, aBuffer, *AdjustedPattern(aPattern), aOptions, aRenderingOptions);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
EnsurePatternDependenciesStored(aSource);
|
||||
EnsurePatternDependenciesStored(aMask);
|
||||
|
||||
mRecorder->RecordEvent(RecordedMask(this, aSource, aMask, aOptions));
|
||||
mFinalDT->Mask(*AdjustedPattern(aSource), *AdjustedPattern(aMask), aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::MaskSurface(const Pattern &aSource,
|
||||
SourceSurface *aMask,
|
||||
Point aOffset,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
EnsurePatternDependenciesStored(aSource);
|
||||
EnsureSurfaceStored(mRecorder, aMask, "MaskSurface");
|
||||
|
||||
mRecorder->RecordEvent(RecordedMaskSurface(this, aSource, aMask, aOffset, aOptions));
|
||||
mFinalDT->MaskSurface(*AdjustedPattern(aSource), GetSourceSurface(aMask), aOffset, aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::Stroke(const Path *aPath,
|
||||
const Pattern &aPattern,
|
||||
const StrokeOptions &aStrokeOptions,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
RefPtr<PathRecording> pathWrapAndRecord = EnsurePathStored(aPath);
|
||||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
mRecorder->RecordEvent(RecordedStroke(this, pathWrapAndRecord, aPattern, aStrokeOptions, aOptions));
|
||||
mFinalDT->Stroke(pathWrapAndRecord->mPath, *AdjustedPattern(aPattern), aStrokeOptions, aOptions);
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface>
|
||||
DrawTargetWrapAndRecord::Snapshot()
|
||||
{
|
||||
RefPtr<SourceSurface> surf = mFinalDT->Snapshot();
|
||||
|
||||
RefPtr<SourceSurface> retSurf = new SourceSurfaceWrapAndRecord(surf, mRecorder);
|
||||
|
||||
mRecorder->RecordEvent(RecordedSnapshot(retSurf, this));
|
||||
|
||||
return retSurf.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface>
|
||||
DrawTargetWrapAndRecord::IntoLuminanceSource(LuminanceType aLuminanceType, float aOpacity)
|
||||
{
|
||||
RefPtr<SourceSurface> surf = mFinalDT->IntoLuminanceSource(aLuminanceType, aOpacity);
|
||||
|
||||
RefPtr<SourceSurface> retSurf = new SourceSurfaceWrapAndRecord(surf, mRecorder);
|
||||
|
||||
mRecorder->RecordEvent(RecordedIntoLuminanceSource(retSurf, this, aLuminanceType, aOpacity));
|
||||
|
||||
return retSurf.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::DetachAllSnapshots()
|
||||
{
|
||||
mFinalDT->DetachAllSnapshots();
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::DrawSurface(SourceSurface *aSurface,
|
||||
const Rect &aDest,
|
||||
const Rect &aSource,
|
||||
const DrawSurfaceOptions &aSurfOptions,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
EnsureSurfaceStored(mRecorder, aSurface, "DrawSurface");
|
||||
|
||||
mRecorder->RecordEvent(RecordedDrawSurface(this, aSurface, aDest, aSource, aSurfOptions, aOptions));
|
||||
mFinalDT->DrawSurface(GetSourceSurface(aSurface), aDest, aSource, aSurfOptions, aOptions);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::DrawSurfaceWithShadow(SourceSurface *aSurface,
|
||||
const Point &aDest,
|
||||
const Color &aColor,
|
||||
const Point &aOffset,
|
||||
Float aSigma,
|
||||
CompositionOp aOp)
|
||||
{
|
||||
EnsureSurfaceStored(mRecorder, aSurface, "DrawSurfaceWithShadow");
|
||||
|
||||
mRecorder->RecordEvent(RecordedDrawSurfaceWithShadow(this, aSurface, aDest, aColor, aOffset, aSigma, aOp));
|
||||
mFinalDT->DrawSurfaceWithShadow(GetSourceSurface(aSurface), aDest, aColor, aOffset, aSigma, aOp);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::DrawFilter(FilterNode *aNode,
|
||||
const Rect &aSourceRect,
|
||||
const Point &aDestPoint,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
MOZ_ASSERT(mRecorder->HasStoredObject(aNode));
|
||||
|
||||
mRecorder->RecordEvent(RecordedDrawFilter(this, aNode, aSourceRect, aDestPoint, aOptions));
|
||||
mFinalDT->DrawFilter(FilterNodeWrapAndRecord::GetFilterNode(aNode), aSourceRect, aDestPoint, aOptions);
|
||||
}
|
||||
|
||||
already_AddRefed<FilterNode>
|
||||
DrawTargetWrapAndRecord::CreateFilter(FilterType aType)
|
||||
{
|
||||
RefPtr<FilterNode> node = mFinalDT->CreateFilter(aType);
|
||||
|
||||
RefPtr<FilterNode> retNode = new FilterNodeWrapAndRecord(node, mRecorder);
|
||||
|
||||
mRecorder->RecordEvent(RecordedFilterNodeCreation(retNode, aType));
|
||||
|
||||
return retNode.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::ClearRect(const Rect &aRect)
|
||||
{
|
||||
mRecorder->RecordEvent(RecordedClearRect(this, aRect));
|
||||
mFinalDT->ClearRect(aRect);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::CopySurface(SourceSurface *aSurface,
|
||||
const IntRect &aSourceRect,
|
||||
const IntPoint &aDestination)
|
||||
{
|
||||
EnsureSurfaceStored(mRecorder, aSurface, "CopySurface");
|
||||
|
||||
mRecorder->RecordEvent(RecordedCopySurface(this, aSurface, aSourceRect, aDestination));
|
||||
mFinalDT->CopySurface(GetSourceSurface(aSurface), aSourceRect, aDestination);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::PushClip(const Path *aPath)
|
||||
{
|
||||
RefPtr<PathRecording> pathWrapAndRecord = EnsurePathStored(aPath);
|
||||
|
||||
mRecorder->RecordEvent(RecordedPushClip(this, pathWrapAndRecord));
|
||||
mFinalDT->PushClip(pathWrapAndRecord->mPath);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::PushClipRect(const Rect &aRect)
|
||||
{
|
||||
mRecorder->RecordEvent(RecordedPushClipRect(this, aRect));
|
||||
mFinalDT->PushClipRect(aRect);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::PopClip()
|
||||
{
|
||||
mRecorder->RecordEvent(RecordedPopClip(this));
|
||||
mFinalDT->PopClip();
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::PushLayer(bool aOpaque, Float aOpacity,
|
||||
SourceSurface* aMask,
|
||||
const Matrix& aMaskTransform,
|
||||
const IntRect& aBounds, bool aCopyBackground)
|
||||
{
|
||||
if (aMask) {
|
||||
EnsureSurfaceStored(mRecorder, aMask, "PushLayer");
|
||||
}
|
||||
|
||||
mRecorder->RecordEvent(RecordedPushLayer(this, aOpaque, aOpacity, aMask,
|
||||
aMaskTransform, aBounds,
|
||||
aCopyBackground));
|
||||
mFinalDT->PushLayer(aOpaque, aOpacity, aMask, aMaskTransform, aBounds,
|
||||
aCopyBackground);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::PopLayer()
|
||||
{
|
||||
mRecorder->RecordEvent(RecordedPopLayer(this));
|
||||
mFinalDT->PopLayer();
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface>
|
||||
DrawTargetWrapAndRecord::CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat) const
|
||||
{
|
||||
RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat);
|
||||
|
||||
RefPtr<SourceSurface> retSurf = new SourceSurfaceWrapAndRecord(surf, mRecorder);
|
||||
|
||||
mRecorder->RecordEvent(RecordedSourceSurfaceCreation(retSurf, aData, aStride, aSize, aFormat));
|
||||
|
||||
return retSurf.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface>
|
||||
DrawTargetWrapAndRecord::OptimizeSourceSurface(SourceSurface *aSurface) const
|
||||
{
|
||||
RefPtr<SourceSurface> surf = mFinalDT->OptimizeSourceSurface(aSurface);
|
||||
|
||||
RefPtr<SourceSurface> retSurf = new SourceSurfaceWrapAndRecord(surf, mRecorder);
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface();
|
||||
|
||||
if (!dataSurf) {
|
||||
// Let's try get it off the original surface.
|
||||
dataSurf = aSurface->GetDataSurface();
|
||||
}
|
||||
|
||||
StoreSourceSurface(mRecorder, retSurf, dataSurf, "OptimizeSourceSurface");
|
||||
|
||||
return retSurf.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<SourceSurface>
|
||||
DrawTargetWrapAndRecord::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
|
||||
{
|
||||
RefPtr<SourceSurface> surf = mFinalDT->CreateSourceSurfaceFromNativeSurface(aSurface);
|
||||
|
||||
RefPtr<SourceSurface> retSurf = new SourceSurfaceWrapAndRecord(surf, mRecorder);
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurf = surf->GetDataSurface();
|
||||
StoreSourceSurface(mRecorder, retSurf, dataSurf, "CreateSourceSurfaceFromNativeSurface");
|
||||
|
||||
return retSurf.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
DrawTargetWrapAndRecord::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
|
||||
{
|
||||
RefPtr<DrawTarget> similarDT =
|
||||
mFinalDT->CreateSimilarDrawTarget(aSize, aFormat);
|
||||
if (!similarDT) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
similarDT = new DrawTargetWrapAndRecord(this, similarDT);
|
||||
return similarDT.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<PathBuilder>
|
||||
DrawTargetWrapAndRecord::CreatePathBuilder(FillRule aFillRule) const
|
||||
{
|
||||
RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(aFillRule);
|
||||
return MakeAndAddRef<PathBuilderRecording>(builder, aFillRule);
|
||||
}
|
||||
|
||||
already_AddRefed<GradientStops>
|
||||
DrawTargetWrapAndRecord::CreateGradientStops(GradientStop *aStops,
|
||||
uint32_t aNumStops,
|
||||
ExtendMode aExtendMode) const
|
||||
{
|
||||
RefPtr<GradientStops> stops = mFinalDT->CreateGradientStops(aStops, aNumStops, aExtendMode);
|
||||
|
||||
RefPtr<GradientStops> retStops = new GradientStopsWrapAndRecord(stops, mRecorder);
|
||||
|
||||
mRecorder->RecordEvent(RecordedGradientStopsCreation(retStops, aStops, aNumStops, aExtendMode));
|
||||
|
||||
return retStops.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::SetTransform(const Matrix &aTransform)
|
||||
{
|
||||
mRecorder->RecordEvent(RecordedSetTransform(this, aTransform));
|
||||
DrawTarget::SetTransform(aTransform);
|
||||
mFinalDT->SetTransform(aTransform);
|
||||
}
|
||||
|
||||
already_AddRefed<PathRecording>
|
||||
DrawTargetWrapAndRecord::EnsurePathStored(const Path *aPath)
|
||||
{
|
||||
RefPtr<PathRecording> pathWrapAndRecord;
|
||||
if (aPath->GetBackendType() == BackendType::RECORDING) {
|
||||
pathWrapAndRecord = const_cast<PathRecording*>(static_cast<const PathRecording*>(aPath));
|
||||
if (mRecorder->HasStoredObject(aPath)) {
|
||||
return pathWrapAndRecord.forget();
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(!mRecorder->HasStoredObject(aPath));
|
||||
FillRule fillRule = aPath->GetFillRule();
|
||||
RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(fillRule);
|
||||
RefPtr<PathBuilderRecording> builderWrapAndRecord =
|
||||
new PathBuilderRecording(builder, fillRule);
|
||||
aPath->StreamToSink(builderWrapAndRecord);
|
||||
pathWrapAndRecord = builderWrapAndRecord->Finish().downcast<PathRecording>();
|
||||
}
|
||||
|
||||
mRecorder->RecordEvent(RecordedPathCreation(pathWrapAndRecord));
|
||||
mRecorder->AddStoredObject(pathWrapAndRecord);
|
||||
pathWrapAndRecord->mStoredRecorders.push_back(mRecorder);
|
||||
|
||||
return pathWrapAndRecord.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetWrapAndRecord::EnsurePatternDependenciesStored(const Pattern &aPattern)
|
||||
{
|
||||
switch (aPattern.GetType()) {
|
||||
case PatternType::COLOR:
|
||||
// No dependencies here.
|
||||
return;
|
||||
case PatternType::LINEAR_GRADIENT:
|
||||
{
|
||||
MOZ_ASSERT(mRecorder->HasStoredObject(static_cast<const LinearGradientPattern*>(&aPattern)->mStops));
|
||||
return;
|
||||
}
|
||||
case PatternType::RADIAL_GRADIENT:
|
||||
{
|
||||
MOZ_ASSERT(mRecorder->HasStoredObject(static_cast<const RadialGradientPattern*>(&aPattern)->mStops));
|
||||
return;
|
||||
}
|
||||
case PatternType::SURFACE:
|
||||
{
|
||||
const SurfacePattern *pat = static_cast<const SurfacePattern*>(&aPattern);
|
||||
EnsureSurfaceStored(mRecorder, pat->mSurface, "EnsurePatternDependenciesStored");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,338 @@
|
|||
/* -*- Mode: C++; tab-width: 20; 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_DRAWTARGETWRAPANDRECORD_H_
|
||||
#define MOZILLA_GFX_DRAWTARGETWRAPANDRECORD_H_
|
||||
|
||||
#include "2D.h"
|
||||
#include "DrawEventRecorder.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class DrawTargetWrapAndRecord : public DrawTarget
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetWrapAndRecord, override)
|
||||
DrawTargetWrapAndRecord(DrawEventRecorder *aRecorder, DrawTarget *aDT, bool aHasData = false);
|
||||
|
||||
~DrawTargetWrapAndRecord();
|
||||
|
||||
virtual DrawTargetType GetType() const override { return mFinalDT->GetType(); }
|
||||
virtual BackendType GetBackendType() const override { return mFinalDT->GetBackendType(); }
|
||||
virtual bool IsRecording() const override { return true; }
|
||||
|
||||
virtual already_AddRefed<SourceSurface> Snapshot() override;
|
||||
virtual already_AddRefed<SourceSurface> IntoLuminanceSource(LuminanceType aLuminanceType, float aOpacity) override;
|
||||
|
||||
virtual void DetachAllSnapshots() override;
|
||||
|
||||
virtual IntSize GetSize() override { return mFinalDT->GetSize(); }
|
||||
|
||||
/* Ensure that the DrawTarget backend has flushed all drawing operations to
|
||||
* this draw target. This must be called before using the backing surface of
|
||||
* this draw target outside of GFX 2D code.
|
||||
*/
|
||||
virtual void Flush() override { mFinalDT->Flush(); }
|
||||
|
||||
/*
|
||||
* Draw a surface to the draw target. Possibly doing partial drawing or
|
||||
* applying scaling. No sampling happens outside the source.
|
||||
*
|
||||
* aSurface Source surface to draw
|
||||
* aDest Destination rectangle that this drawing operation should draw to
|
||||
* aSource Source rectangle in aSurface coordinates, this area of aSurface
|
||||
* will be stretched to the size of aDest.
|
||||
* aOptions General draw options that are applied to the operation
|
||||
* aSurfOptions DrawSurface options that are applied
|
||||
*/
|
||||
virtual void DrawSurface(SourceSurface *aSurface,
|
||||
const Rect &aDest,
|
||||
const Rect &aSource,
|
||||
const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
virtual void DrawFilter(FilterNode *aNode,
|
||||
const Rect &aSourceRect,
|
||||
const Point &aDestPoint,
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
/*
|
||||
* Blend a surface to the draw target with a shadow. The shadow is drawn as a
|
||||
* gaussian blur using a specified sigma. The shadow is clipped to the size
|
||||
* of the input surface, so the input surface should contain a transparent
|
||||
* border the size of the approximate coverage of the blur (3 * aSigma).
|
||||
* NOTE: This function works in device space!
|
||||
*
|
||||
* aSurface Source surface to draw.
|
||||
* aDest Destination point that this drawing operation should draw to.
|
||||
* aColor Color of the drawn shadow
|
||||
* aOffset Offset of the shadow
|
||||
* aSigma Sigma used for the guassian filter kernel
|
||||
* aOperator Composition operator used
|
||||
*/
|
||||
virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
|
||||
const Point &aDest,
|
||||
const Color &aColor,
|
||||
const Point &aOffset,
|
||||
Float aSigma,
|
||||
CompositionOp aOperator) override;
|
||||
|
||||
/*
|
||||
* Clear a rectangle on the draw target to transparent black. This will
|
||||
* respect the clipping region and transform.
|
||||
*
|
||||
* aRect Rectangle to clear
|
||||
*/
|
||||
virtual void ClearRect(const Rect &aRect) override;
|
||||
|
||||
/*
|
||||
* This is essentially a 'memcpy' between two surfaces. It moves a pixel
|
||||
* aligned area from the source surface unscaled directly onto the
|
||||
* drawtarget. This ignores both transform and clip.
|
||||
*
|
||||
* aSurface Surface to copy from
|
||||
* aSourceRect Source rectangle to be copied
|
||||
* aDest Destination point to copy the surface to
|
||||
*/
|
||||
virtual void CopySurface(SourceSurface *aSurface,
|
||||
const IntRect &aSourceRect,
|
||||
const IntPoint &aDestination) override;
|
||||
|
||||
/*
|
||||
* Fill a rectangle on the DrawTarget with a certain source pattern.
|
||||
*
|
||||
* aRect Rectangle that forms the mask of this filling operation
|
||||
* aPattern Pattern that forms the source of this filling operation
|
||||
* aOptions Options that are applied to this operation
|
||||
*/
|
||||
virtual void FillRect(const Rect &aRect,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
/*
|
||||
* Stroke a rectangle on the DrawTarget with a certain source pattern.
|
||||
*
|
||||
* aRect Rectangle that forms the mask of this stroking operation
|
||||
* aPattern Pattern that forms the source of this stroking operation
|
||||
* aOptions Options that are applied to this operation
|
||||
*/
|
||||
virtual void StrokeRect(const Rect &aRect,
|
||||
const Pattern &aPattern,
|
||||
const StrokeOptions &aStrokeOptions = StrokeOptions(),
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
/*
|
||||
* Stroke a line on the DrawTarget with a certain source pattern.
|
||||
*
|
||||
* aStart Starting point of the line
|
||||
* aEnd End point of the line
|
||||
* aPattern Pattern that forms the source of this stroking operation
|
||||
* aOptions Options that are applied to this operation
|
||||
*/
|
||||
virtual void StrokeLine(const Point &aStart,
|
||||
const Point &aEnd,
|
||||
const Pattern &aPattern,
|
||||
const StrokeOptions &aStrokeOptions = StrokeOptions(),
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
/*
|
||||
* Stroke a path on the draw target with a certain source pattern.
|
||||
*
|
||||
* aPath Path that is to be stroked
|
||||
* aPattern Pattern that should be used for the stroke
|
||||
* aStrokeOptions Stroke options used for this operation
|
||||
* aOptions Draw options used for this operation
|
||||
*/
|
||||
virtual void Stroke(const Path *aPath,
|
||||
const Pattern &aPattern,
|
||||
const StrokeOptions &aStrokeOptions = StrokeOptions(),
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
/*
|
||||
* Fill a path on the draw target with a certain source pattern.
|
||||
*
|
||||
* aPath Path that is to be filled
|
||||
* aPattern Pattern that should be used for the fill
|
||||
* aOptions Draw options used for this operation
|
||||
*/
|
||||
virtual void Fill(const Path *aPath,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
/*
|
||||
* Fill a series of clyphs on the draw target with a certain source pattern.
|
||||
*/
|
||||
virtual void FillGlyphs(ScaledFont *aFont,
|
||||
const GlyphBuffer &aBuffer,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions = DrawOptions(),
|
||||
const GlyphRenderingOptions *aRenderingOptions = nullptr) override;
|
||||
|
||||
/*
|
||||
* This takes a source pattern and a mask, and composites the source pattern
|
||||
* onto the destination surface using the alpha channel of the mask pattern
|
||||
* as a mask for the operation.
|
||||
*
|
||||
* aSource Source pattern
|
||||
* aMask Mask pattern
|
||||
* aOptions Drawing options
|
||||
*/
|
||||
virtual void Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
virtual void MaskSurface(const Pattern &aSource,
|
||||
SourceSurface *aMask,
|
||||
Point aOffset,
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
/*
|
||||
* Push a clip to the DrawTarget.
|
||||
*
|
||||
* aPath The path to clip to
|
||||
*/
|
||||
virtual void PushClip(const Path *aPath) override;
|
||||
|
||||
/*
|
||||
* Push an axis-aligned rectangular clip to the DrawTarget. This rectangle
|
||||
* is specified in user space.
|
||||
*
|
||||
* aRect The rect to clip to
|
||||
*/
|
||||
virtual void PushClipRect(const Rect &aRect) override;
|
||||
|
||||
/* Pop a clip from the DrawTarget. A pop without a corresponding push will
|
||||
* be ignored.
|
||||
*/
|
||||
virtual void PopClip() override;
|
||||
|
||||
/**
|
||||
* Push a 'layer' to the DrawTarget, a layer is a temporary surface that all
|
||||
* drawing will be redirected to, this is used for example to support group
|
||||
* opacity or the masking of groups. Clips must be balanced within a layer,
|
||||
* i.e. between a matching PushLayer/PopLayer pair there must be as many
|
||||
* PushClip(Rect) calls as there are PopClip calls.
|
||||
*
|
||||
* @param aOpaque Whether the layer will be opaque
|
||||
* @param aOpacity Opacity of the layer
|
||||
* @param aMask Mask applied to the layer
|
||||
* @param aMaskTransform Transform applied to the layer mask
|
||||
* @param aBounds Optional bounds in device space to which the layer is
|
||||
* limited in size.
|
||||
* @param aCopyBackground Whether to copy the background into the layer, this
|
||||
* is only supported when aOpaque is true.
|
||||
*/
|
||||
virtual void PushLayer(bool aOpaque, Float aOpacity,
|
||||
SourceSurface* aMask,
|
||||
const Matrix& aMaskTransform,
|
||||
const IntRect& aBounds = IntRect(),
|
||||
bool aCopyBackground = false) override;
|
||||
|
||||
/**
|
||||
* This balances a call to PushLayer and proceeds to blend the layer back
|
||||
* onto the background. This blend will blend the temporary surface back
|
||||
* onto the target in device space using POINT sampling and operator over.
|
||||
*/
|
||||
virtual void PopLayer() override;
|
||||
|
||||
/*
|
||||
* Create a SourceSurface optimized for use with this DrawTarget from
|
||||
* existing bitmap data in memory.
|
||||
*
|
||||
* The SourceSurface does not take ownership of aData, and may be freed at any time.
|
||||
*/
|
||||
virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat) const override;
|
||||
|
||||
/*
|
||||
* Create a SourceSurface optimized for use with this DrawTarget from
|
||||
* an arbitrary other SourceSurface. This may return aSourceSurface or some
|
||||
* other existing surface.
|
||||
*/
|
||||
virtual already_AddRefed<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const override;
|
||||
|
||||
/*
|
||||
* Create a SourceSurface for a type of NativeSurface. This may fail if the
|
||||
* draw target does not know how to deal with the type of NativeSurface passed
|
||||
* in.
|
||||
*/
|
||||
virtual already_AddRefed<SourceSurface>
|
||||
CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const override;
|
||||
|
||||
/*
|
||||
* Create a DrawTarget whose snapshot is optimized for use with this DrawTarget.
|
||||
*/
|
||||
virtual already_AddRefed<DrawTarget>
|
||||
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const override;
|
||||
|
||||
/*
|
||||
* Create a path builder with the specified fillmode.
|
||||
*
|
||||
* We need the fill mode up front because of Direct2D.
|
||||
* ID2D1SimplifiedGeometrySink requires the fill mode
|
||||
* to be set before calling BeginFigure().
|
||||
*/
|
||||
virtual already_AddRefed<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const override;
|
||||
|
||||
/*
|
||||
* Create a GradientStops object that holds information about a set of
|
||||
* gradient stops, this object is required for linear or radial gradient
|
||||
* patterns to represent the color stops in the gradient.
|
||||
*
|
||||
* aStops An array of gradient stops
|
||||
* aNumStops Number of stops in the array aStops
|
||||
* aExtendNone This describes how to extend the stop color outside of the
|
||||
* gradient area.
|
||||
*/
|
||||
virtual already_AddRefed<GradientStops>
|
||||
CreateGradientStops(GradientStop *aStops,
|
||||
uint32_t aNumStops,
|
||||
ExtendMode aExtendMode = ExtendMode::CLAMP) const override;
|
||||
|
||||
virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
|
||||
|
||||
/*
|
||||
* Set a transform on the surface, this transform is applied at drawing time
|
||||
* to both the mask and source of the operation.
|
||||
*/
|
||||
virtual void SetTransform(const Matrix &aTransform) override;
|
||||
|
||||
/* Tries to get a native surface for a DrawTarget, this may fail if the
|
||||
* draw target cannot convert to this surface type.
|
||||
*/
|
||||
virtual void *GetNativeSurface(NativeSurfaceType aType) override { return mFinalDT->GetNativeSurface(aType); }
|
||||
|
||||
virtual bool IsCurrentGroupOpaque() override {
|
||||
return mFinalDT->IsCurrentGroupOpaque();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Used for creating a DrawTargetWrapAndRecord for a CreateSimilarDrawTarget call.
|
||||
* We have to call CreateSimilarDrawTarget on mFinalDT up front and pass it in
|
||||
* as it can fail.
|
||||
*
|
||||
* @param aDT DrawTargetWrapAndRecord on which CreateSimilarDrawTarget was called
|
||||
* @param aSimilarDT Similar DrawTarget created from aDT.mFinalDT.
|
||||
*/
|
||||
DrawTargetWrapAndRecord(const DrawTargetWrapAndRecord *aDT,
|
||||
DrawTarget *aSimilarDT);
|
||||
|
||||
Path *GetPathForPathRecording(const Path *aPath) const;
|
||||
already_AddRefed<PathRecording> EnsurePathStored(const Path *aPath);
|
||||
void EnsurePatternDependenciesStored(const Pattern &aPattern);
|
||||
|
||||
RefPtr<DrawEventRecorderPrivate> mRecorder;
|
||||
RefPtr<DrawTarget> mFinalDT;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* MOZILLA_GFX_DRAWTARGETWRAPANDRECORD_H_ */
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
#include "DrawTargetDual.h"
|
||||
#include "DrawTargetTiled.h"
|
||||
#include "DrawTargetWrapAndRecord.h"
|
||||
#include "DrawTargetRecording.h"
|
||||
|
||||
#include "SourceSurfaceRawData.h"
|
||||
|
@ -388,7 +389,7 @@ Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFor
|
|||
}
|
||||
|
||||
if (mRecorder && retVal) {
|
||||
return MakeAndAddRef<DrawTargetRecording>(mRecorder, retVal);
|
||||
return MakeAndAddRef<DrawTargetWrapAndRecord>(mRecorder, retVal);
|
||||
}
|
||||
|
||||
if (!retVal) {
|
||||
|
@ -399,6 +400,12 @@ Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFor
|
|||
return retVal.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
Factory::CreateWrapAndRecordDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT)
|
||||
{
|
||||
return MakeAndAddRef<DrawTargetWrapAndRecord>(aRecorder, aDT);
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
Factory::CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT)
|
||||
{
|
||||
|
@ -450,7 +457,7 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
|
|||
}
|
||||
|
||||
if (mRecorder && retVal) {
|
||||
return MakeAndAddRef<DrawTargetRecording>(mRecorder, retVal, true);
|
||||
return MakeAndAddRef<DrawTargetWrapAndRecord>(mRecorder, retVal, true);
|
||||
}
|
||||
|
||||
if (!retVal) {
|
||||
|
@ -641,7 +648,7 @@ Factory::CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB)
|
|||
RefPtr<DrawTarget> retVal = newTarget;
|
||||
|
||||
if (mRecorder) {
|
||||
retVal = new DrawTargetRecording(mRecorder, retVal);
|
||||
retVal = new DrawTargetWrapAndRecord(mRecorder, retVal);
|
||||
}
|
||||
|
||||
return retVal.forget();
|
||||
|
@ -737,7 +744,7 @@ Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceForma
|
|||
RefPtr<DrawTarget> retVal = newTarget;
|
||||
|
||||
if (mRecorder) {
|
||||
retVal = new DrawTargetRecording(mRecorder, retVal, true);
|
||||
retVal = new DrawTargetWrapAndRecord(mRecorder, retVal, true);
|
||||
}
|
||||
|
||||
return retVal.forget();
|
||||
|
@ -918,7 +925,7 @@ Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSiz
|
|||
}
|
||||
|
||||
if (mRecorder && retVal) {
|
||||
return MakeAndAddRef<DrawTargetRecording>(mRecorder, retVal, true);
|
||||
return MakeAndAddRef<DrawTargetWrapAndRecord>(mRecorder, retVal, true);
|
||||
}
|
||||
#endif
|
||||
return retVal.forget();
|
||||
|
|
|
@ -125,6 +125,7 @@ public:
|
|||
static void ReadPathToBuilder(std::istream &aStream, PathBuilder *aBuilder);
|
||||
|
||||
private:
|
||||
friend class DrawTargetWrapAndRecord;
|
||||
friend class DrawTargetRecording;
|
||||
friend class RecordedPathCreation;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ EXPORTS.mozilla.gfx += [
|
|||
'DrawEventRecorder.h',
|
||||
'DrawTargetRecording.h',
|
||||
'DrawTargetTiled.h',
|
||||
'DrawTargetWrapAndRecord.h',
|
||||
'Filters.h',
|
||||
'FontVariation.h',
|
||||
'Helpers.h',
|
||||
|
@ -175,6 +176,7 @@ UNIFIED_SOURCES += [
|
|||
'DrawTargetDual.cpp',
|
||||
'DrawTargetRecording.cpp',
|
||||
'DrawTargetTiled.cpp',
|
||||
'DrawTargetWrapAndRecord.cpp',
|
||||
'FilterNodeSoftware.cpp',
|
||||
'FilterProcessing.cpp',
|
||||
'FilterProcessingScalar.cpp',
|
||||
|
|
|
@ -82,7 +82,7 @@ PrintTarget::MakeDrawTarget(const IntSize& aSize,
|
|||
}
|
||||
|
||||
if (aRecorder) {
|
||||
dt = CreateRecordingDrawTarget(aRecorder, dt);
|
||||
dt = CreateWrapAndRecordDrawTarget(aRecorder, dt);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ PrintTarget::GetReferenceDrawTarget(DrawEventRecorder* aRecorder)
|
|||
|
||||
if (aRecorder) {
|
||||
if (!mRecordingRefDT) {
|
||||
RefPtr<DrawTarget> dt = CreateRecordingDrawTarget(aRecorder, mRefDT);
|
||||
RefPtr<DrawTarget> dt = CreateWrapAndRecordDrawTarget(aRecorder, mRefDT);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ PrintTarget::GetReferenceDrawTarget(DrawEventRecorder* aRecorder)
|
|||
}
|
||||
|
||||
/* static */ already_AddRefed<DrawTarget>
|
||||
PrintTarget::CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
|
||||
PrintTarget::CreateWrapAndRecordDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget)
|
||||
{
|
||||
MOZ_ASSERT(aRecorder);
|
||||
|
@ -171,7 +171,7 @@ PrintTarget::CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
|
|||
|
||||
if (aRecorder) {
|
||||
// It doesn't really matter what we pass as the DrawTarget here.
|
||||
dt = gfx::Factory::CreateRecordingDrawTarget(aRecorder, aDrawTarget);
|
||||
dt = gfx::Factory::CreateWrapAndRecordDrawTarget(aRecorder, aDrawTarget);
|
||||
}
|
||||
|
||||
if (!dt || !dt->IsValid()) {
|
||||
|
|
|
@ -144,8 +144,8 @@ protected:
|
|||
virtual ~PrintTarget();
|
||||
|
||||
static already_AddRefed<DrawTarget>
|
||||
CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget);
|
||||
CreateWrapAndRecordDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget);
|
||||
|
||||
cairo_surface_t* mCairoSurface;
|
||||
RefPtr<DrawTarget> mRefDT; // reference DT
|
||||
|
|
|
@ -99,7 +99,7 @@ PrintTargetCG::GetReferenceDrawTarget(DrawEventRecorder* aRecorder)
|
|||
|
||||
if (aRecorder) {
|
||||
if (!mRecordingRefDT) {
|
||||
RefPtr<DrawTarget> dt = CreateRecordingDrawTarget(aRecorder, mRefDT);
|
||||
RefPtr<DrawTarget> dt = CreateWrapAndRecordDrawTarget(aRecorder, mRefDT);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ PrintTargetRecording::CreateOrNull(const IntSize& aSize)
|
|||
}
|
||||
|
||||
// Perhaps surprisingly, this surface is never actually drawn to. This class
|
||||
// creates a DrawTargetRecording using CreateRecordingDrawTarget, and that
|
||||
// creates a DrawTargetWrapAndRecord using CreateWrapAndRecordDrawTarget, and that
|
||||
// needs another DrawTarget to be passed to it. You might expect the type of
|
||||
// the DrawTarget that is passed to matter because it would seem logical to
|
||||
// encoded its type in the recording, and on replaying the recording a
|
||||
|
@ -44,7 +44,7 @@ PrintTargetRecording::CreateOrNull(const IntSize& aSize)
|
|||
// available on all platforms and doesn't require allocating a
|
||||
// potentially large surface.
|
||||
//
|
||||
// * Since we need a DrawTarget to pass to CreateRecordingDrawTarget we
|
||||
// * Since we need a DrawTarget to pass to CreateWrapAndRecordDrawTarget we
|
||||
// might as well leverage our base class's machinery to create a
|
||||
// DrawTarget (it's as good a way as any other that will work), and to do
|
||||
// that we need a cairo_surface_t.
|
||||
|
@ -80,7 +80,7 @@ PrintTargetRecording::MakeDrawTarget(const IntSize& aSize,
|
|||
|
||||
RefPtr<DrawTarget> dt = PrintTarget::MakeDrawTarget(aSize, nullptr);
|
||||
if (dt) {
|
||||
dt = CreateRecordingDrawTarget(aRecorder, dt);
|
||||
dt = CreateWrapAndRecordDrawTarget(aRecorder, dt);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -90,8 +90,8 @@ PrintTargetRecording::MakeDrawTarget(const IntSize& aSize,
|
|||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
PrintTargetRecording::CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget)
|
||||
PrintTargetRecording::CreateWrapAndRecordDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget)
|
||||
{
|
||||
MOZ_ASSERT(aRecorder);
|
||||
MOZ_ASSERT(aDrawTarget);
|
||||
|
@ -100,7 +100,7 @@ PrintTargetRecording::CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
|
|||
|
||||
if (aRecorder) {
|
||||
// It doesn't really matter what we pass as the DrawTarget here.
|
||||
dt = gfx::Factory::CreateRecordingDrawTarget(aRecorder, aDrawTarget);
|
||||
dt = gfx::Factory::CreateWrapAndRecordDrawTarget(aRecorder, aDrawTarget);
|
||||
}
|
||||
|
||||
if (!dt || !dt->IsValid()) {
|
||||
|
|
|
@ -33,8 +33,8 @@ private:
|
|||
const IntSize& aSize);
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
CreateRecordingDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget);
|
||||
CreateWrapAndRecordDrawTarget(DrawEventRecorder* aRecorder,
|
||||
DrawTarget* aDrawTarget);
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -147,7 +147,7 @@ PrintTargetSkPDF::GetReferenceDrawTarget(DrawEventRecorder* aRecorder)
|
|||
|
||||
if (aRecorder) {
|
||||
if (!mRecordingRefDT) {
|
||||
RefPtr<DrawTarget> dt = CreateRecordingDrawTarget(aRecorder, mRefDT);
|
||||
RefPtr<DrawTarget> dt = CreateWrapAndRecordDrawTarget(aRecorder, mRefDT);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ PrintTargetThebes::MakeDrawTarget(const IntSize& aSize,
|
|||
}
|
||||
|
||||
if (aRecorder) {
|
||||
dt = CreateRecordingDrawTarget(aRecorder, dt);
|
||||
dt = CreateWrapAndRecordDrawTarget(aRecorder, dt);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ PrintTargetThebes::GetReferenceDrawTarget(DrawEventRecorder* aRecorder)
|
|||
|
||||
if (aRecorder) {
|
||||
if (!mRecordingRefDT) {
|
||||
RefPtr<DrawTarget> dt = CreateRecordingDrawTarget(aRecorder, mRefDT);
|
||||
RefPtr<DrawTarget> dt = CreateWrapAndRecordDrawTarget(aRecorder, mRefDT);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ nsDeviceContextSpecProxy::MakePrintTarget()
|
|||
|
||||
// The type of PrintTarget that we return here shouldn't really matter since
|
||||
// our implementation of GetDrawEventRecorder returns an object, which means
|
||||
// the DrawTarget returned by the PrintTarget will be a DrawTargetRecording.
|
||||
// the DrawTarget returned by the PrintTarget will be a DrawTargetWrapAndRecord.
|
||||
// The recording will be serialized and sent over to the parent process where
|
||||
// PrintTranslator::TranslateRecording will call MakePrintTarget (indirectly
|
||||
// via PrintTranslator::CreateDrawTarget) on whatever type of
|
||||
|
|
Загрузка…
Ссылка в новой задаче