Bug 1815404 - Eliminate gfxContext::CreatePreservingTransformOrNull, and replace callers with stack-allocated gfxContext. r=gfx-reviewers,lsalzman

Depends on D170369

Differential Revision: https://phabricator.services.mozilla.com/D170370
This commit is contained in:
Jonathan Kew 2023-02-21 07:28:24 +00:00
parent 1b3e69f8aa
commit 5b9588f1aa
10 changed files with 59 additions and 95 deletions

View File

@ -3857,14 +3857,8 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor final
return;
}
UniquePtr<gfxContext> thebes =
gfxContext::CreatePreservingTransformOrNull(target);
if (!thebes) {
// If CreatePreservingTransformOrNull returns null, it will also have
// issued a gfxCriticalNote already, so here we'll just bail out.
return;
}
gfxTextRun::DrawParams params(thebes.get());
gfxContext thebes(target, /* aPreserveTransform */ true);
gfxTextRun::DrawParams params(&thebes);
params.allowGDI = false;

View File

@ -52,18 +52,24 @@ PatternFromState::operator mozilla::gfx::Pattern&() {
gfxContext::gfxContext(DrawTarget* aTarget, const Point& aDeviceOffset)
: mPathIsRect(false), mTransformChanged(false), mDT(aTarget) {
if (!aTarget) {
gfxCriticalError() << "Don't create a gfxContext without a DrawTarget";
}
mStateStack.SetLength(1);
CurrentState().deviceOffset = aDeviceOffset;
mDT->SetTransform(GetDTTransform());
}
gfxContext::gfxContext(DrawTarget* aTarget, bool aPreserveTransform)
: mPathIsRect(false), mTransformChanged(false), mDT(aTarget) {
mStateStack.SetLength(1);
if (aPreserveTransform) {
SetMatrix(aTarget->GetTransform());
} else {
mDT->SetTransform(GetDTTransform());
}
}
/* static */
UniquePtr<gfxContext> gfxContext::CreateOrNull(
DrawTarget* aTarget, const mozilla::gfx::Point& aDeviceOffset) {
UniquePtr<gfxContext> gfxContext::CreateOrNull(DrawTarget* aTarget,
const Point& aDeviceOffset) {
if (!aTarget || !aTarget->IsValid()) {
gfxCriticalNote << "Invalid target in gfxContext::CreateOrNull "
<< hexa(aTarget);
@ -73,23 +79,6 @@ UniquePtr<gfxContext> gfxContext::CreateOrNull(
return MakeUnique<gfxContext>(aTarget, aDeviceOffset);
}
/* static */
UniquePtr<gfxContext> gfxContext::CreatePreservingTransformOrNull(
DrawTarget* aTarget) {
if (!aTarget || !aTarget->IsValid()) {
gfxCriticalNote
<< "Invalid target in gfxContext::CreatePreservingTransformOrNull "
<< hexa(aTarget);
return nullptr;
}
auto transform = aTarget->GetTransform();
auto result = MakeUnique<gfxContext>(aTarget);
result->SetMatrix(transform);
return result;
}
gfxContext::~gfxContext() {
for (int i = mStateStack.Length() - 1; i >= 0; i--) {
for (unsigned int c = 0; c < mStateStack[i].pushedClips.Length(); c++) {

View File

@ -59,16 +59,18 @@ class gfxContext final {
public:
/**
* Initialize this context from a DrawTarget.
* Strips any transform from aTarget.
* aTarget will be flushed in the gfxContext's destructor. Use the static
* ContextForDrawTargetNoTransform() when you want this behavior, as that
* version deals with null DrawTarget better.
* Initialize this context from a DrawTarget, which must be non-null.
* Strips any transform from aTarget, unless aPreserveTransform is true.
* aTarget will be flushed in the gfxContext's destructor.
*/
MOZ_NONNULL(2)
explicit gfxContext(
mozilla::gfx::DrawTarget* aTarget,
const mozilla::gfx::Point& aDeviceOffset = mozilla::gfx::Point());
MOZ_NONNULL(2)
gfxContext(mozilla::gfx::DrawTarget* aTarget, bool aPreserveTransform);
~gfxContext();
/**
@ -82,16 +84,6 @@ class gfxContext final {
mozilla::gfx::DrawTarget* aTarget,
const mozilla::gfx::Point& aDeviceOffset = mozilla::gfx::Point());
/**
* Create a new gfxContext wrapping aTarget and preserving aTarget's
* transform. Note that the transform is moved from aTarget to the resulting
* gfxContext, aTarget will no longer have its transform.
* If aTarget is null or invalid, nullptr is returned. The caller
* is responsible for handling this scenario as appropriate.
*/
static mozilla::UniquePtr<gfxContext> CreatePreservingTransformOrNull(
mozilla::gfx::DrawTarget* aTarget);
mozilla::gfx::DrawTarget* GetDrawTarget() { return mDT; }
/**

View File

@ -208,19 +208,21 @@ void FallbackRenderer::EndTransactionWithList(nsDisplayListBuilder* aBuilder,
RefPtr<DrawTarget> dest =
gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(
backend, dt->GetSize(), dt->GetFormat());
UniquePtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(dest);
if (dest) {
gfxContext ctx(dest, /* aPreserveTransform */ true);
nsRegion opaque = aList->GetOpaqueRegion(aBuilder);
if (opaque.Contains(aList->GetComponentAlphaBounds(aBuilder))) {
dest->SetPermitSubpixelAA(true);
nsRegion opaque = aList->GetOpaqueRegion(aBuilder);
if (opaque.Contains(aList->GetComponentAlphaBounds(aBuilder))) {
dest->SetPermitSubpixelAA(true);
}
aList->Paint(aBuilder, &ctx, aAppUnitsPerDevPixel);
RefPtr<SourceSurface> snapshot = dest->Snapshot();
dt->DrawSurface(snapshot, Rect(dest->GetRect()), Rect(dest->GetRect()),
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_SOURCE));
}
aList->Paint(aBuilder, ctx.get(), aAppUnitsPerDevPixel);
RefPtr<SourceSurface> snapshot = dest->Snapshot();
dt->DrawSurface(snapshot, Rect(dest->GetRect()), Rect(dest->GetRect()),
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_SOURCE));
mAnimationReadyTime = TimeStamp::Now();
}

View File

@ -315,14 +315,12 @@ static bool GenerateAndPushTextMask(nsIFrame* aFrame, gfxContext* aContext,
if (!maskDT || !maskDT->IsValid()) {
return false;
}
UniquePtr<gfxContext> maskCtx =
gfxContext::CreatePreservingTransformOrNull(maskDT);
MOZ_ASSERT(maskCtx);
maskCtx->Multiply(Matrix::Translation(bounds.TopLeft().ToUnknownPoint()));
gfxContext maskCtx(maskDT, /* aPreserveTransform */ true);
maskCtx.Multiply(Matrix::Translation(bounds.TopLeft().ToUnknownPoint()));
// Shade text shape into mask A8 surface.
nsLayoutUtils::PaintFrame(
maskCtx.get(), aFrame, nsRect(nsPoint(0, 0), aFrame->GetSize()),
&maskCtx, aFrame, nsRect(nsPoint(0, 0), aFrame->GetSize()),
NS_RGB(255, 255, 255), nsDisplayListBuilderMode::GenerateGlyph);
// Push the generated mask into aContext, so that the caller can pop and
@ -5066,9 +5064,9 @@ void nsDisplayBlendMode::Paint(nsDisplayListBuilder* aBuilder,
return;
}
UniquePtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(temp);
gfxContext ctx(temp, /* aPreserveTransform */ true);
GetChildren()->Paint(aBuilder, ctx.get(),
GetChildren()->Paint(aBuilder, &ctx,
mFrame->PresContext()->AppUnitsPerDevPixel());
// Draw the temporary DT to the real destination, applying the blend mode, but
@ -6869,8 +6867,7 @@ void nsDisplayTransform::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx,
untransformedDT->SetTransform(
Matrix::Translation(-Point(pixelBounds.X(), pixelBounds.Y())));
UniquePtr<gfxContext> groupTarget =
gfxContext::CreatePreservingTransformOrNull(untransformedDT);
gfxContext groupTarget(untransformedDT, /* aPreserveTransform */ true);
if (aPolygon) {
RefPtr<gfx::Path> path =
@ -6878,7 +6875,7 @@ void nsDisplayTransform::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx,
aCtx->GetDrawTarget()->PushClip(path);
}
GetChildren()->Paint(aBuilder, groupTarget.get(),
GetChildren()->Paint(aBuilder, &groupTarget,
mFrame->PresContext()->AppUnitsPerDevPixel());
if (aPolygon) {

View File

@ -475,7 +475,7 @@ ImgDrawResult nsImageRenderer::Draw(nsPresContext* aPresContext,
nsLayoutUtils::GetSamplingFilterForFrame(mForFrame);
ImgDrawResult result = ImgDrawResult::SUCCESS;
gfxContext* ctx = &aRenderingContext;
UniquePtr<gfxContext> tempCtx;
Maybe<gfxContext> tempCtx;
IntRect tmpDTRect;
if (ctx->CurrentOp() != CompositionOp::OP_OVER ||
@ -494,8 +494,8 @@ ImgDrawResult nsImageRenderer::Draw(nsPresContext* aPresContext,
}
tempDT->SetTransform(ctx->GetDrawTarget()->GetTransform() *
Matrix::Translation(-tmpDTRect.TopLeft()));
tempCtx = gfxContext::CreatePreservingTransformOrNull(tempDT);
ctx = tempCtx.get();
tempCtx.emplace(tempDT, /* aPreserveTransform */ true);
ctx = &tempCtx.ref();
if (!ctx) {
gfxDevCrash(LogReason::InvalidContext)
<< "ImageRenderer::Draw problem " << gfx::hexa(tempDT);

View File

@ -232,14 +232,8 @@ already_AddRefed<SourceSurface> SVGClipPathFrame::GetClipMask(
return nullptr;
}
UniquePtr<gfxContext> maskContext =
gfxContext::CreatePreservingTransformOrNull(maskDT);
if (!maskContext) {
gfxCriticalError() << "SVGClipPath context problem " << gfx::hexa(maskDT);
return nullptr;
}
PaintClipMask(*maskContext, aClippedFrame, aMatrix, aExtraMask);
gfxContext maskContext(maskDT, /* aPreserveTransform */ true);
PaintClipMask(maskContext, aClippedFrame, aMatrix, aExtraMask);
RefPtr<SourceSurface> surface = maskDT->Snapshot();
return surface.forget();

View File

@ -466,9 +466,7 @@ static bool PaintMaskSurface(const PaintFramesParams& aParams,
gfxPoint devPixelOffsetToUserSpace = nsLayoutUtils::PointToGfxPoint(
aOffsetToUserSpace, presContext->AppUnitsPerDevPixel());
UniquePtr<gfxContext> maskContext =
gfxContext::CreatePreservingTransformOrNull(aMaskDT);
MOZ_ASSERT(maskContext);
gfxContext maskContext(aMaskDT, /* aPreserveTransform */ true);
bool isMaskComplete = true;
@ -486,7 +484,7 @@ static bool PaintMaskSurface(const PaintFramesParams& aParams,
// maskFrame == nullptr means we get an image mask.
if (maskFrame) {
SVGMaskFrame::MaskParams params(
maskContext->GetDrawTarget(), aParams.frame, cssPxToDevPxMatrix,
maskContext.GetDrawTarget(), aParams.frame, cssPxToDevPxMatrix,
aOpacity, svgReset->mMask.mLayers[i].mMaskMode, aParams.imgParams);
RefPtr<SourceSurface> svgMask = maskFrame->GetMaskForMaskedFrame(params);
if (svgMask) {
@ -498,9 +496,9 @@ static bool PaintMaskSurface(const PaintFramesParams& aParams,
aMaskDT->SetTransform(tmp);
}
} else if (svgReset->mMask.mLayers[i].mImage.IsResolved()) {
gfxContextMatrixAutoSaveRestore matRestore(maskContext.get());
gfxContextMatrixAutoSaveRestore matRestore(&maskContext);
maskContext->Multiply(gfxMatrix::Translation(-devPixelOffsetToUserSpace));
maskContext.Multiply(gfxMatrix::Translation(-devPixelOffsetToUserSpace));
nsCSSRendering::PaintBGParams params =
nsCSSRendering::PaintBGParams::ForSingleLayer(
*presContext, aParams.dirtyRect, aParams.borderArea,
@ -510,7 +508,7 @@ static bool PaintMaskSurface(const PaintFramesParams& aParams,
i, compositionOp, aOpacity);
aParams.imgParams.result &= nsCSSRendering::PaintStyleImageLayerWithSC(
params, *maskContext, aSC, *aParams.frame->StyleBorder());
params, maskContext, aSC, *aParams.frame->StyleBorder());
} else {
isMaskComplete = false;
}

View File

@ -78,9 +78,7 @@ already_AddRefed<SourceSurface> SVGMaskFrame::GetMaskForMaskedFrame(
return nullptr;
}
UniquePtr<gfxContext> tmpCtx =
gfxContext::CreatePreservingTransformOrNull(maskDT);
MOZ_ASSERT(tmpCtx); // already checked the draw target above
gfxContext tmpCtx(maskDT, /* aPreserveTransform */ true);
mMatrixForChildren =
GetMaskTransform(aParams.maskedFrame) * aParams.toUserSpace;
@ -95,7 +93,7 @@ already_AddRefed<SourceSurface> SVGMaskFrame::GetMaskForMaskedFrame(
m = SVGUtils::GetTransformMatrixInUserSpace(kid) * m;
}
SVGUtils::PaintFrameWithEffects(kid, *tmpCtx, m, aParams.imgParams);
SVGUtils::PaintFrameWithEffects(kid, tmpCtx, m, aParams.imgParams);
}
RefPtr<SourceSurface> surface;

View File

@ -3852,7 +3852,7 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) {
if (!dt || !dt->IsValid()) {
return FALSE;
}
UniquePtr<gfxContext> ctx;
Maybe<gfxContext> ctx;
IntRect boundsRect = region.GetBounds().ToUnknownRect();
IntPoint offset(0, 0);
if (dt->GetSize() == boundsRect.Size()) {
@ -3878,12 +3878,11 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) {
return FALSE;
}
destDT->SetTransform(Matrix::Translation(-boundsRect.TopLeft()));
ctx = gfxContext::CreatePreservingTransformOrNull(destDT);
ctx.emplace(destDT, /* aPreserveTransform */ true);
} else {
gfxUtils::ClipToRegion(dt, region.ToUnknownRegion());
ctx = gfxContext::CreatePreservingTransformOrNull(dt);
ctx.emplace(dt, /* aPreserveTransform */ true);
}
MOZ_ASSERT(ctx); // checked both dt and destDT valid draw target above
# if 0
// NOTE: Paint flashing region would be wrong for cairo, since
@ -3908,7 +3907,8 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) {
// reused SHM image. See bug 1258086.
dt->ClearRect(Rect(boundsRect));
}
AutoLayerManagerSetup setupLayerManager(this, ctx.get(), layerBuffering);
AutoLayerManagerSetup setupLayerManager(
this, ctx.isNothing() ? nullptr : &ctx.ref(), layerBuffering);
painted = listener->PaintWindow(this, region);
// Re-get the listener since the will paint notification might have
@ -3936,7 +3936,7 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) {
}
}
ctx = nullptr;
ctx.reset();
dt->PopClip();
#endif // MOZ_X11