Bug 1561743. DrawTargetRecording IntRect. r=nical

This lets us record at arbitratry offsets. Without it gfxContext::GetClip()
would break because it uses DrawTarget::GetRect() as the initial rect that it
intersects subsequent clips with. We also can't just use a DrawTargetOffset
because that applies a transform to the inner DrawTarget and will impact the
recorded commands.

Differential Revision: https://phabricator.services.mozilla.com/D37075

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jeff Muizelaar 2019-07-10 13:49:08 +00:00
parent 44e5432f64
commit bcd10ea75c
9 changed files with 44 additions and 39 deletions

View File

@ -1649,7 +1649,7 @@ class GFX2D_API Factory {
DrawEventRecorder* aRecorder, DrawTarget* aDT);
static already_AddRefed<DrawTarget> CreateRecordingDrawTarget(
DrawEventRecorder* aRecorder, DrawTarget* aDT, IntSize aSize);
DrawEventRecorder* aRecorder, DrawTarget* aDT, IntRect aRect);
static already_AddRefed<DrawTarget> CreateDrawTargetForData(
BackendType aBackend, unsigned char* aData, const IntSize& aSize,

View File

@ -211,21 +211,21 @@ class FilterNodeRecording : public FilterNode {
};
DrawTargetRecording::DrawTargetRecording(DrawEventRecorder* aRecorder,
DrawTarget* aDT, IntSize aSize,
DrawTarget* aDT, IntRect aRect,
bool aHasData)
: mRecorder(static_cast<DrawEventRecorderPrivate*>(aRecorder)),
mFinalDT(aDT),
mSize(aSize) {
mRect(aRect) {
RefPtr<SourceSurface> snapshot = aHasData ? mFinalDT->Snapshot() : nullptr;
mRecorder->RecordEvent(
RecordedDrawTargetCreation(this, mFinalDT->GetBackendType(), mSize,
RecordedDrawTargetCreation(this, mFinalDT->GetBackendType(), mRect,
mFinalDT->GetFormat(), aHasData, snapshot));
mFormat = mFinalDT->GetFormat();
}
DrawTargetRecording::DrawTargetRecording(const DrawTargetRecording* aDT,
IntSize aSize, SurfaceFormat aFormat)
: mRecorder(aDT->mRecorder), mFinalDT(aDT->mFinalDT), mSize(aSize) {
IntRect aRect, SurfaceFormat aFormat)
: mRecorder(aDT->mRecorder), mFinalDT(aDT->mFinalDT), mRect(aRect) {
mFormat = aFormat;
}
@ -361,7 +361,7 @@ void DrawTargetRecording::Stroke(const Path* aPath, const Pattern& aPattern,
already_AddRefed<SourceSurface> DrawTargetRecording::Snapshot() {
RefPtr<SourceSurface> retSurf =
new SourceSurfaceRecording(mSize, mFormat, mRecorder);
new SourceSurfaceRecording(mRect.Size(), mFormat, mRecorder);
mRecorder->RecordEvent(RecordedSnapshot(retSurf, this));
@ -371,7 +371,7 @@ already_AddRefed<SourceSurface> DrawTargetRecording::Snapshot() {
already_AddRefed<SourceSurface> DrawTargetRecording::IntoLuminanceSource(
LuminanceType aLuminanceType, float aOpacity) {
RefPtr<SourceSurface> retSurf =
new SourceSurfaceRecording(mSize, SurfaceFormat::A8, mRecorder);
new SourceSurfaceRecording(mRect.Size(), SurfaceFormat::A8, mRecorder);
mRecorder->RecordEvent(
RecordedIntoLuminanceSource(retSurf, this, aLuminanceType, aOpacity));
@ -519,7 +519,8 @@ already_AddRefed<DrawTarget> DrawTargetRecording::CreateSimilarDrawTarget(
const IntSize& aSize, SurfaceFormat aFormat) const {
RefPtr<DrawTarget> similarDT;
if (mFinalDT->CanCreateSimilarDrawTarget(aSize, aFormat)) {
similarDT = new DrawTargetRecording(this, aSize, aFormat);
similarDT =
new DrawTargetRecording(this, IntRect(IntPoint(0, 0), aSize), aFormat);
mRecorder->RecordEvent(
RecordedCreateSimilarDrawTarget(similarDT.get(), aSize, aFormat));
} else if (XRE_IsContentProcess()) {
@ -542,7 +543,7 @@ bool DrawTargetRecording::CanCreateSimilarDrawTarget(
RefPtr<DrawTarget> DrawTargetRecording::CreateClippedDrawTarget(
const Rect& aBounds, SurfaceFormat aFormat) {
RefPtr<DrawTarget> similarDT;
similarDT = new DrawTargetRecording(this, mSize, aFormat);
similarDT = new DrawTargetRecording(this, mRect, aFormat);
mRecorder->RecordEvent(
RecordedCreateClippedDrawTarget(similarDT.get(), aBounds, aFormat));
similarDT->SetTransform(mTransform);
@ -555,7 +556,8 @@ DrawTargetRecording::CreateSimilarDrawTargetForFilter(
FilterNode* aSource, const Rect& aSourceRect, const Point& aDestPoint) {
RefPtr<DrawTarget> similarDT;
if (mFinalDT->CanCreateSimilarDrawTarget(aMaxSize, aFormat)) {
similarDT = new DrawTargetRecording(this, aMaxSize, aFormat);
similarDT = new DrawTargetRecording(this, IntRect(IntPoint(0, 0), aMaxSize),
aFormat);
mRecorder->RecordEvent(RecordedCreateDrawTargetForFilter(
this, similarDT.get(), aMaxSize, aFormat, aFilter, aSource, aSourceRect,
aDestPoint));
@ -623,7 +625,7 @@ void DrawTargetRecording::FlushItem(const IntRect& aBounds) {
// Tell the new recording about our draw target
// This code should match what happens in the DrawTargetRecording constructor.
mRecorder->RecordEvent(
RecordedDrawTargetCreation(this, mFinalDT->GetBackendType(), mSize,
RecordedDrawTargetCreation(this, mFinalDT->GetBackendType(), mRect,
mFinalDT->GetFormat(), false, nullptr));
// Add the current transform to the new recording
mRecorder->RecordEvent(

View File

@ -17,7 +17,7 @@ class DrawTargetRecording : public DrawTarget {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetRecording, override)
DrawTargetRecording(DrawEventRecorder* aRecorder, DrawTarget* aDT,
IntSize aSize, bool aHasData = false);
IntRect aRect, bool aHasData = false);
~DrawTargetRecording();
@ -35,7 +35,8 @@ class DrawTargetRecording : public DrawTarget {
virtual void DetachAllSnapshots() override;
virtual IntSize GetSize() const override { return mSize; }
virtual IntSize GetSize() const override { return mRect.Size(); }
virtual IntRect GetRect() const override { return mRect; }
virtual void Flush() override;
@ -354,7 +355,7 @@ class DrawTargetRecording : public DrawTarget {
* @param aSize size of the the similar DrawTarget
* @param aFormat format of the similar DrawTarget
*/
DrawTargetRecording(const DrawTargetRecording* aDT, IntSize aSize,
DrawTargetRecording(const DrawTargetRecording* aDT, IntRect aRect,
SurfaceFormat aFormat);
Path* GetPathForPathRecording(const Path* aPath) const;
@ -363,7 +364,7 @@ class DrawTargetRecording : public DrawTarget {
RefPtr<DrawEventRecorderPrivate> mRecorder;
RefPtr<DrawTarget> mFinalDT;
IntSize mSize;
IntRect mRect;
};
} // namespace gfx

View File

@ -282,7 +282,7 @@ DrawTargetWrapAndRecord::DrawTargetWrapAndRecord(DrawEventRecorder* aRecorder,
mFinalDT(aDT) {
RefPtr<SourceSurface> snapshot = aHasData ? mFinalDT->Snapshot() : nullptr;
mRecorder->RecordEvent(RecordedDrawTargetCreation(
this, mFinalDT->GetBackendType(), mFinalDT->GetSize(),
this, mFinalDT->GetBackendType(), mFinalDT->GetRect(),
mFinalDT->GetFormat(), aHasData, snapshot));
mFormat = mFinalDT->GetFormat();
}

View File

@ -411,8 +411,8 @@ already_AddRefed<DrawTarget> Factory::CreateWrapAndRecordDrawTarget(
}
already_AddRefed<DrawTarget> Factory::CreateRecordingDrawTarget(
DrawEventRecorder* aRecorder, DrawTarget* aDT, IntSize aSize) {
return MakeAndAddRef<DrawTargetRecording>(aRecorder, aDT, aSize);
DrawEventRecorder* aRecorder, DrawTarget* aDT, IntRect aRect) {
return MakeAndAddRef<DrawTargetRecording>(aRecorder, aDT, aRect);
}
already_AddRefed<DrawTargetCapture> Factory::CreateCaptureDrawTargetForTarget(

View File

@ -41,13 +41,13 @@ class RecordedDrawTargetCreation
: public RecordedEventDerived<RecordedDrawTargetCreation> {
public:
RecordedDrawTargetCreation(ReferencePtr aRefPtr, BackendType aType,
const IntSize& aSize, SurfaceFormat aFormat,
const IntRect& aRect, SurfaceFormat aFormat,
bool aHasExistingData = false,
SourceSurface* aExistingData = nullptr)
: RecordedEventDerived(DRAWTARGETCREATION),
mRefPtr(aRefPtr),
mBackendType(aType),
mSize(aSize),
mRect(aRect),
mFormat(aFormat),
mHasExistingData(aHasExistingData),
mExistingData(aExistingData) {}
@ -63,7 +63,7 @@ class RecordedDrawTargetCreation
ReferencePtr mRefPtr;
BackendType mBackendType;
IntSize mSize;
IntRect mRect;
SurfaceFormat mFormat;
bool mHasExistingData;
RefPtr<SourceSurface> mExistingData;
@ -1731,7 +1731,7 @@ void RecordedDrawingEvent<T>::Record(S& aStream) const {
inline bool RecordedDrawTargetCreation::PlayEvent(
Translator* aTranslator) const {
RefPtr<DrawTarget> newDT =
aTranslator->CreateDrawTarget(mRefPtr, mSize, mFormat);
aTranslator->CreateDrawTarget(mRefPtr, mRect.Size(), mFormat);
// If we couldn't create a DrawTarget this will probably cause us to crash
// with nullptr later in the playback, so return false to abort.
@ -1752,19 +1752,19 @@ template <class S>
void RecordedDrawTargetCreation::Record(S& aStream) const {
WriteElement(aStream, mRefPtr);
WriteElement(aStream, mBackendType);
WriteElement(aStream, mSize);
WriteElement(aStream, mRect);
WriteElement(aStream, mFormat);
WriteElement(aStream, mHasExistingData);
if (mHasExistingData) {
MOZ_ASSERT(mExistingData);
MOZ_ASSERT(mExistingData->GetSize() == mSize);
MOZ_ASSERT(mExistingData->GetSize() == mRect.Size());
RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface();
DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
for (int y = 0; y < mSize.height; y++) {
for (int y = 0; y < mRect.height; y++) {
aStream.write((const char*)map.GetData() + y * map.GetStride(),
BytesPerPixel(mFormat) * mSize.width);
BytesPerPixel(mFormat) * mRect.width);
}
}
}
@ -1774,13 +1774,13 @@ RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream)
: RecordedEventDerived(DRAWTARGETCREATION), mExistingData(nullptr) {
ReadElement(aStream, mRefPtr);
ReadElement(aStream, mBackendType);
ReadElement(aStream, mSize);
ReadElement(aStream, mRect);
ReadElement(aStream, mFormat);
ReadElement(aStream, mHasExistingData);
if (mHasExistingData) {
RefPtr<DataSourceSurface> dataSurf =
Factory::CreateDataSourceSurface(mSize, mFormat);
Factory::CreateDataSourceSurface(mRect.Size(), mFormat);
if (!dataSurf) {
gfxWarning()
<< "RecordedDrawTargetCreation had to reset mHasExistingData";
@ -1789,9 +1789,9 @@ RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream)
}
DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
for (int y = 0; y < mSize.height; y++) {
for (int y = 0; y < mRect.height; y++) {
aStream.read((char*)map.GetData() + y * map.GetStride(),
BytesPerPixel(mFormat) * mSize.width);
BytesPerPixel(mFormat) * mRect.width);
}
mExistingData = dataSurf;
}
@ -1800,8 +1800,8 @@ RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream)
inline void RecordedDrawTargetCreation::OutputSimpleEventInfo(
std::stringstream& aStringStream) const {
aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: "
<< NameFromBackend(mBackendType) << ", Size: " << mSize.width
<< "x" << mSize.height << ")";
<< NameFromBackend(mBackendType) << ", Size: " << mRect.width
<< "x" << mRect.height << ")";
}
inline bool RecordedDrawTargetDestruction::PlayEvent(

View File

@ -86,8 +86,8 @@ PaintFragment PaintFragment::Record(nsIDocShell* aDocShell,
// TODO: This may OOM crash if the content is complex enough
RefPtr<DrawEventRecorderMemory> recorder =
MakeAndAddRef<DrawEventRecorderMemory>(nullptr);
RefPtr<DrawTarget> dt =
Factory::CreateRecordingDrawTarget(recorder, referenceDt, surfaceSize);
RefPtr<DrawTarget> dt = Factory::CreateRecordingDrawTarget(
recorder, referenceDt, IntRect(IntPoint(0, 0), surfaceSize));
// Perform the actual rendering
{

View File

@ -9,6 +9,8 @@
#include "MainThreadUtils.h"
#include "mozilla/gfx/DrawTargetRecording.h"
#include "mozilla/gfx/Tools.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/layers/CanvasDrawEventRecorder.h"
#include "RecordedCanvasEventImpl.h"
@ -104,7 +106,7 @@ already_AddRefed<gfx::DrawTarget> CanvasChild::CreateDrawTarget(
RefPtr<gfx::DrawTarget> dummyDt = gfx::Factory::CreateDrawTarget(
gfx::BackendType::SKIA, gfx::IntSize(1, 1), aFormat);
RefPtr<gfx::DrawTarget> dt =
MakeAndAddRef<gfx::DrawTargetRecording>(mRecorder, dummyDt, aSize);
MakeAndAddRef<gfx::DrawTargetRecording>(mRecorder, dummyDt, gfx::IntRect(gfx::IntPoint(0, 0), aSize));
return dt.forget();
}

View File

@ -677,7 +677,7 @@ struct DIGroup {
gfx::BackendType::SKIA, gfx::IntSize(1, 1), format);
RefPtr<gfx::DrawTarget> dt =
gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, dtSize);
gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, IntRect(IntPoint(0, 0), dtSize));
// Setup the gfxContext
RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
GP("ctx-offset %f %f\n", bounds.x, bounds.y);
@ -2267,7 +2267,7 @@ WebRenderCommandBuilder::GenerateFallbackData(
RefPtr<gfx::DrawTarget> dummyDt = gfx::Factory::CreateDrawTarget(
gfx::BackendType::SKIA, gfx::IntSize(1, 1), format);
RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(
recorder, dummyDt, dtSize.ToUnknownSize());
recorder, dummyDt, IntRect(IntPoint(0, 0), dtSize.ToUnknownSize()));
if (!fallbackData->mBasicLayerManager) {
fallbackData->mBasicLayerManager =
new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
@ -2487,7 +2487,7 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
RefPtr<DrawTarget> dummyDt = Factory::CreateDrawTarget(
BackendType::SKIA, IntSize(1, 1), SurfaceFormat::A8);
RefPtr<DrawTarget> dt =
Factory::CreateRecordingDrawTarget(recorder, dummyDt, size);
Factory::CreateRecordingDrawTarget(recorder, dummyDt, IntRect(IntPoint(0, 0), size));
RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
MOZ_ASSERT(context);