Bug 1396489 - Part 3. Use gfxContext::GetClipExtents(false) when clipped rect in device space is needed.
MozReview-Commit-ID: YO4JACFK9O
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -91,34 +91,31 @@ BasicLayerManager::PushGroupForLayer(gfx
bool canPushGroup = aGroupResult.mOperator == CompositionOp::OP_OVER ||
(aGroupResult.mOperator == CompositionOp::OP_SOURCE && (aLayer->CanUseOpaqueSurface() || aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA));
if (!canPushGroup) {
aContext->Save();
gfxUtils::ClipToRegion(aGroupResult.mFinalTarget, aGroupResult.mVisibleRegion);
// PushGroup/PopGroup do not support non operator over.
- gfxMatrix oldMat = aContext->CurrentMatrix();
- aContext->SetMatrix(gfxMatrix());
- gfxRect rect = aContext->GetClipExtents();
- aContext->SetMatrix(oldMat);
+ gfxRect rect = aContext->GetClipExtents(gfxContext::eDeviceSpace);
rect.RoundOut();
IntRect surfRect;
ToRect(rect).ToIntRect(&surfRect);
if (!surfRect.IsEmpty()) {
RefPtr<DrawTarget> dt = aContext->GetDrawTarget()->CreateSimilarDrawTarget(surfRect.Size(), SurfaceFormat::B8G8R8A8);
RefPtr<gfxContext> ctx =
gfxContext::CreateOrNull(dt, ToRect(rect).TopLeft());
if (!ctx) {
gfxCriticalNote << "BasicLayerManager context problem in PushGroupForLayer " << gfx::hexa(dt);
return false;
}
- ctx->SetMatrix(oldMat);
+ ctx->SetMatrix(aContext->CurrentMatrix());
aGroupResult.mGroupOffset = surfRect.TopLeft();
aGroupResult.mGroupTarget = ctx;
aGroupResult.mMaskSurface = GetMaskForLayer(aLayer, &aGroupResult.mMaskTransform);
return true;
}
aContext->Restore();
@@ -599,23 +596,18 @@ BasicLayerManager::EndTransactionInterna
if (mRoot->GetMaskLayer()) {
ToData(mRoot->GetMaskLayer())->Validate(aCallback, aCallbackData, nullptr);
}
}
if (mTarget && mRoot &&
!(aFlags & END_NO_IMMEDIATE_REDRAW) &&
!(aFlags & END_NO_COMPOSITE)) {
- IntRect clipRect;
-
- {
- gfxContextMatrixAutoSaveRestore save(mTarget);
- mTarget->SetMatrix(gfxMatrix());
- clipRect = ToOutsideIntRect(mTarget->GetClipExtents());
- }
+ IntRect clipRect =
+ ToOutsideIntRect(mTarget->GetClipExtents(gfxContext::eDeviceSpace));
if (IsRetained()) {
nsIntRegion region;
MarkLayersHidden(mRoot, clipRect, clipRect, region, ALLOW_OPAQUE);
if (mUsingDefaultTarget && mDoubleBuffering != BufferMode::BUFFER_NONE) {
ApplyDoubleBuffering(mRoot, clipRect);
}
}
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -813,32 +813,23 @@ gfxContext::Paint(gfxFloat alpha)
}
void
gfxContext::PushGroupForBlendBack(gfxContentType content, Float aOpacity, SourceSurface* aMask, const Matrix& aMaskTransform)
{
mDT->PushLayer(content == gfxContentType::COLOR, aOpacity, aMask, aMaskTransform);
}
-static gfxRect
-GetRoundOutDeviceClipExtents(gfxContext* aCtx)
-{
- gfxContextMatrixAutoSaveRestore save(aCtx);
- aCtx->SetMatrix(gfxMatrix());
- gfxRect r = aCtx->GetClipExtents();
- r.RoundOut();
- return r;
-}
-
void
gfxContext::PushGroupAndCopyBackground(gfxContentType content, Float aOpacity, SourceSurface* aMask, const Matrix& aMaskTransform)
{
IntRect clipExtents;
if (mDT->GetFormat() != SurfaceFormat::B8G8R8X8) {
- gfxRect clipRect = GetRoundOutDeviceClipExtents(this);
+ gfxRect clipRect = GetClipExtents(gfxContext::eDeviceSpace);
+ clipRect.RoundOut();
clipExtents = IntRect::Truncate(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
}
bool pushOpaqueWithCopiedBG = (mDT->GetFormat() == SurfaceFormat::B8G8R8X8 ||
mDT->GetOpaqueRect().Contains(clipExtents)) &&
!mDT->GetUserData(&sDontUseAsSourceKey);
if (pushOpaqueWithCopiedBG) {
mDT->PushLayer(true, aOpacity, aMask, aMaskTransform, IntRect(), true);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -780,24 +780,18 @@ GenerateAndPushTextMask(nsIFrame* aFrame
nsLayoutUtils::PaintFrame(aContext, aFrame,
nsRect(nsPoint(0, 0), aFrame->GetSize()),
NS_RGB(255, 255, 255),
nsDisplayListBuilderMode::PAINTING_SELECTION_BACKGROUND);
}
// Evaluate required surface size.
- IntRect drawRect;
- {
- gfxContextMatrixAutoSaveRestore matRestore(sourceCtx);
-
- sourceCtx->SetMatrix(gfxMatrix());
- gfxRect clipRect = sourceCtx->GetClipExtents();
- drawRect = RoundedOut(ToRect(clipRect));
- }
+ IntRect drawRect =
+ RoundedOut(ToRect(sourceCtx->GetClipExtents(gfxContext::eDeviceSpace)));
// Create a mask surface.
RefPtr<DrawTarget> sourceTarget = sourceCtx->GetDrawTarget();
RefPtr<DrawTarget> maskDT =
sourceTarget->CreateSimilarDrawTarget(drawRect.Size(),
SurfaceFormat::A8);
if (!maskDT || !maskDT->IsValid()) {
return false;
@@ -8597,21 +8591,19 @@ bool nsDisplaySVGEffects::ValidateSVGFra
}
return true;
}
static IntRect
ComputeClipExtsInDeviceSpace(gfxContext& aCtx)
{
- gfxContextMatrixAutoSaveRestore matRestore(&aCtx);
-
// Get the clip extents in device space.
- aCtx.SetMatrix(gfxMatrix());
- gfxRect clippedFrameSurfaceRect = aCtx.GetClipExtents();
+ gfxRect clippedFrameSurfaceRect =
+ aCtx.GetClipExtents(gfxContext::eDeviceSpace);
clippedFrameSurfaceRect.RoundOut();
IntRect result;
ToRect(clippedFrameSurfaceRect).ToIntRect(&result);
return mozilla::gfx::Factory::CheckSurfaceSize(result.Size()) ? result
: IntRect();
}
@@ -8703,25 +8695,24 @@ ComputeMaskGeometry(PaintFramesParams& a
appUnitsPerDevPixel,
&clipState);
currentMaskSurfaceRect = clipState.mDirtyRectInDevPx;
}
maskInUserSpace = maskInUserSpace.Union(currentMaskSurfaceRect);
}
- ctx.Save();
+ gfxContextAutoSaveRestore autoSR;
if (!maskInUserSpace.IsEmpty()) {
+ autoSR.SetContext(&ctx);
ctx.Clip(maskInUserSpace);
}
IntRect result = ComputeClipExtsInDeviceSpace(ctx);
- ctx.Restore();
-
aParams.maskRect = result;
}
nsDisplayMask::nsDisplayMask(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList,
bool aHandleOpacity,
const ActiveScrolledRoot* aActiveScrolledRoot)
: nsDisplaySVGEffects(aBuilder, aFrame, aList, aHandleOpacity, aActiveScrolledRoot)
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -80,21 +80,18 @@ nsSVGClipPathFrame::ApplyClipPath(gfxCon
aContext.Clip(Rect());
}
}
already_AddRefed<DrawTarget>
nsSVGClipPathFrame::CreateClipMask(gfxContext& aReferenceContext,
IntPoint& aOffset)
{
- gfxContextMatrixAutoSaveRestore autoRestoreMatrix(&aReferenceContext);
-
- aReferenceContext.SetMatrix(gfxMatrix());
- gfxRect rect = aReferenceContext.GetClipExtents();
- IntRect bounds = RoundedOut(ToRect(rect));
+ IntRect bounds =
+ RoundedOut(ToRect(aReferenceContext.GetClipExtents(gfxContext::eDeviceSpace)));
if (bounds.IsEmpty()) {
// We don't need to create a mask surface, all drawing is clipped anyway.
return nullptr;
}
DrawTarget* referenceDT = aReferenceContext.GetDrawTarget();
RefPtr<DrawTarget> maskDT =
referenceDT->CreateSimilarDrawTarget(bounds.Size(), SurfaceFormat::A8);
--- a/layout/svg/nsSVGMaskFrame.cpp
+++ b/layout/svg/nsSVGMaskFrame.cpp
@@ -58,18 +58,17 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(Ma
gfxRect maskArea = GetMaskArea(aParams.maskedFrame);
gfxContext* context = aParams.ctx;
// Get the clip extents in device space:
// Minimizing the mask surface extents (using both the current clip extents
// and maskArea) is important for performance.
context->Save();
nsSVGUtils::SetClipRect(context, aParams.toUserSpace, maskArea);
- context->SetMatrix(gfxMatrix());
- gfxRect maskSurfaceRect = context->GetClipExtents();
+ gfxRect maskSurfaceRect = context->GetClipExtents(gfxContext::eDeviceSpace);
maskSurfaceRect.RoundOut();
context->Restore();
bool resultOverflows;
IntSize maskSurfaceSize =
nsSVGUtils::ConvertToSurfaceSize(maskSurfaceRect.Size(), &resultOverflows);
if (resultOverflows || maskSurfaceSize.IsEmpty()) {
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -634,18 +634,18 @@ private:
overflowRect = overflowRect + mFrame->GetPosition();
}
mSourceCtx->Clip(NSRectToSnappedRect(overflowRect,
mFrame->PresContext()->AppUnitsPerDevPixel(),
*mSourceCtx->GetDrawTarget()));
}
// Get the clip extents in device space.
- mSourceCtx->SetMatrix(gfxMatrix());
- gfxRect clippedFrameSurfaceRect = mSourceCtx->GetClipExtents();
+ gfxRect clippedFrameSurfaceRect =
+ mSourceCtx->GetClipExtents(gfxContext::eDeviceSpace);
clippedFrameSurfaceRect.RoundOut();
IntRect result;
ToRect(clippedFrameSurfaceRect).ToIntRect(&result);
return Factory::CheckSurfaceSize(result.Size()) ? result : IntRect();
}