Bug 1765331 - Account for dest rect correctly in nsDisplayRemote painting. r=tnikkel

The in-process code does this here:

  https://searchfox.org/mozilla-central/rev/4b3039b48c3cb67774270ebcc2a7d8624d888092/layout/generic/nsSubDocumentFrame.cpp#729-742

This doesn't do much for regular iframes because they have no meaningful
intrinsic ratio, but this will matter for bug 1595491.

Differential Revision: https://phabricator.services.mozilla.com/D144000
This commit is contained in:
Emilio Cobos Álvarez 2022-04-20 11:00:58 +00:00
Родитель a081e3037c
Коммит 8de3540b68
2 изменённых файлов: 27 добавлений и 54 удалений

Просмотреть файл

@ -267,6 +267,17 @@ mozilla::PresShell* nsSubDocumentFrame::GetSubdocumentPresShellForPainting(
return presShell;
}
nsRect nsSubDocumentFrame::GetDestRect() {
nsRect rect = GetContent()->IsHTMLElement(nsGkAtoms::frame)
? GetRectRelativeToSelf()
: GetContentRectRelativeToSelf();
// Adjust subdocument size, according to 'object-fit' and the subdocument's
// intrinsic size and ratio.
return nsLayoutUtils::ComputeObjectDestRect(
rect, GetIntrinsicSize(), GetIntrinsicRatio(), StylePosition());
}
ScreenIntSize nsSubDocumentFrame::GetSubdocumentSize() {
if (HasAnyStateBits(NS_FRAME_FIRST_REFLOW)) {
if (RefPtr<nsFrameLoader> frameloader = FrameLoader()) {
@ -285,24 +296,10 @@ ScreenIntSize nsSubDocumentFrame::GetSubdocumentSize() {
return ScreenIntSize(10, 10);
}
nsSize docSizeAppUnits;
nsPresContext* presContext = PresContext();
if (GetContent()->IsHTMLElement(nsGkAtoms::frame)) {
docSizeAppUnits = GetSize();
} else {
docSizeAppUnits = GetContentRect().Size();
}
// Adjust subdocument size, according to 'object-fit' and the subdocument's
// intrinsic size and ratio.
docSizeAppUnits = nsLayoutUtils::ComputeObjectDestRect(
nsRect(nsPoint(), docSizeAppUnits), GetIntrinsicSize(),
GetIntrinsicRatio(), StylePosition())
.Size();
return ScreenIntSize(
presContext->AppUnitsToDevPixels(docSizeAppUnits.width),
presContext->AppUnitsToDevPixels(docSizeAppUnits.height));
nsSize docSizeAppUnits = GetDestRect().Size();
nsPresContext* pc = PresContext();
return ScreenIntSize(pc->AppUnitsToDevPixels(docSizeAppUnits.width),
pc->AppUnitsToDevPixels(docSizeAppUnits.height));
}
static void WrapBackgroundColorInOwnLayer(nsDisplayListBuilder* aBuilder,
@ -1269,24 +1266,6 @@ void nsSubDocumentFrame::SubdocumentIntrinsicSizeOrRatioChanged() {
}
}
/**
* Gets the layer-pixel offset of aContainerFrame's content rect top-left
* from the nearest display item reference frame (which we assume will be
* inducing a ContainerLayer).
*/
static nsPoint GetContentRectLayerOffset(nsIFrame* aContainerFrame,
nsDisplayListBuilder* aBuilder) {
// Offset to the content rect in case we have borders or padding
// Note that aContainerFrame could be a reference frame itself, so
// we need to be careful here to ensure that we call ToReferenceFrame
// on aContainerFrame and not its parent.
nsPoint frameOffset =
aBuilder->ToReferenceFrame(aContainerFrame) +
aContainerFrame->GetContentRectRelativeToSelf().TopLeft();
return frameOffset;
}
// Return true iff |aManager| is a "temporary layer manager". They're
// used for small software rendering tasks, like drawWindow. That's
// currently implemented by a BasicLayerManager without a backing
@ -1308,14 +1287,6 @@ nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
mPaintData = aFrame->GetRemotePaintData();
}
LayerIntSize GetFrameSize(const nsIFrame* aFrame) {
LayoutDeviceSize size = LayoutDeviceRect::FromAppUnits(
aFrame->GetContentRectRelativeToSelf().Size(),
aFrame->PresContext()->AppUnitsPerDevPixel());
return LayerIntSize::Round(size.width, size.height);
}
namespace mozilla {
void nsDisplayRemote::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
@ -1366,6 +1337,9 @@ bool nsDisplayRemote::CreateWebRenderCommands(
nsPresContext* pc = mFrame->PresContext();
nsFrameLoader* fl = GetFrameLoader();
auto* subDocFrame = static_cast<nsSubDocumentFrame*>(mFrame);
nsRect destRect = subDocFrame->GetDestRect();
if (RefPtr<RemoteBrowser> remoteBrowser = fl->GetRemoteBrowser()) {
if (pc->GetPrintSettings()) {
// HACK(emilio): Usually we update sizing/positioning from
@ -1376,15 +1350,14 @@ bool nsDisplayRemote::CreateWebRenderCommands(
//
// UpdatePositionAndSize() can cause havoc for non-remote frames but
// luckily we don't care about those, so this is fine.
fl->UpdatePositionAndSize(static_cast<nsSubDocumentFrame*>(mFrame));
fl->UpdatePositionAndSize(subDocFrame);
}
// Adjust mItemVisibleRect, which is relative to the reference frame, to be
// relative to this frame
nsRect visibleRect = GetBuildingRect() - ToReferenceFrame();
nsRect contentRect = Frame()->GetContentRectRelativeToSelf();
visibleRect.IntersectRect(visibleRect, contentRect);
visibleRect -= contentRect.TopLeft();
visibleRect.IntersectRect(visibleRect, destRect);
visibleRect -= destRect.TopLeft();
// Generate an effects update notifying the browser it is visible
gfx::Size scale = aSc.GetInheritedScale();
@ -1411,13 +1384,11 @@ bool nsDisplayRemote::CreateWebRenderCommands(
}
nscoord auPerDevPixel = pc->AppUnitsPerDevPixel();
nsPoint layerOffset = GetContentRectLayerOffset(mFrame, aDisplayListBuilder);
nsPoint layerOffset = aDisplayListBuilder->ToReferenceFrame(mFrame) + destRect.TopLeft();
mOffset = LayoutDevicePoint::FromAppUnits(layerOffset, auPerDevPixel);
nsRect contentRect = mFrame->GetContentRectRelativeToSelf();
contentRect.MoveTo(0, 0);
LayoutDeviceRect rect =
LayoutDeviceRect::FromAppUnits(contentRect, auPerDevPixel);
destRect.MoveTo(0, 0);
auto rect = LayoutDeviceRect::FromAppUnits(destRect, auPerDevPixel);
rect += mOffset;
aBuilder.PushIFrame(mozilla::wr::ToLayoutRect(rect), !BackfaceIsHidden(),
@ -1449,10 +1420,11 @@ bool nsDisplayRemote::UpdateScrollData(
aLayerData->SetResolution(resolution);
}
auto size = static_cast<nsSubDocumentFrame*>(mFrame)->GetSubdocumentSize();
Matrix4x4 m = Matrix4x4::Translation(mOffset.x, mOffset.y, 0.0);
aLayerData->SetTransform(m);
aLayerData->SetEventRegionsOverride(mEventRegionsOverride);
aLayerData->SetRemoteDocumentSize(GetFrameSize(mFrame));
aLayerData->SetRemoteDocumentSize(LayerIntSize(size.width, size.height));
}
return true;
}

Просмотреть файл

@ -109,6 +109,7 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
nsIFrame* GetSubdocumentRootFrame();
enum { IGNORE_PAINT_SUPPRESSION = 0x1 };
mozilla::PresShell* GetSubdocumentPresShellForPainting(uint32_t aFlags);
nsRect GetDestRect();
mozilla::ScreenIntSize GetSubdocumentSize();
// nsIReflowCallback