mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
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:
parent
44e5432f64
commit
bcd10ea75c
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user