зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
a081e3037c
Коммит
8de3540b68
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче