Bug 1677324 - Add the ability for subdocuments to keep painting another remote subdoc. r=mattwoodrow
Differential Revision: https://phabricator.services.mozilla.com/D121197
This commit is contained in:
@@ -184,7 +184,7 @@ void nsFrameLoaderOwner::ChangeFrameLoaderCommon(Element* aOwner) {
|
||||
// Now that we've got a new FrameLoader, we need to reset our
|
||||
// nsSubDocumentFrame to use the new FrameLoader.
|
||||
if (nsSubDocumentFrame* ourFrame = do_QueryFrame(aOwner->GetPrimaryFrame())) {
|
||||
ourFrame->ResetFrameLoader();
|
||||
ourFrame->ResetFrameLoader(nsSubDocumentFrame::RetainPaintData::No);
|
||||
}
|
||||
|
||||
// If the element is focused, or the current mouse over target then
|
||||
|
||||
@@ -940,12 +940,43 @@ nsFrameLoader* nsSubDocumentFrame::FrameLoader() const {
|
||||
return mFrameLoader;
|
||||
}
|
||||
|
||||
void nsSubDocumentFrame::ResetFrameLoader() {
|
||||
auto nsSubDocumentFrame::GetRemotePaintData() const -> RemoteFramePaintData {
|
||||
if (mRetainedRemoteFrame) {
|
||||
return *mRetainedRemoteFrame;
|
||||
}
|
||||
|
||||
RemoteFramePaintData data;
|
||||
nsFrameLoader* fl = FrameLoader();
|
||||
if (!fl) {
|
||||
return data;
|
||||
}
|
||||
|
||||
auto* rb = fl->GetRemoteBrowser();
|
||||
if (!rb) {
|
||||
return data;
|
||||
}
|
||||
data.mLayersId = rb->GetLayersId();
|
||||
data.mTabId = rb->GetTabId();
|
||||
return data;
|
||||
}
|
||||
|
||||
void nsSubDocumentFrame::ResetFrameLoader(RetainPaintData aRetain) {
|
||||
if (aRetain == RetainPaintData::Yes && mFrameLoader) {
|
||||
mRetainedRemoteFrame = Some(GetRemotePaintData());
|
||||
} else {
|
||||
mRetainedRemoteFrame.reset();
|
||||
}
|
||||
mFrameLoader = nullptr;
|
||||
ClearDisplayItems();
|
||||
nsContentUtils::AddScriptRunner(new AsyncFrameInit(this));
|
||||
}
|
||||
|
||||
void nsSubDocumentFrame::ClearRetainedPaintData() {
|
||||
mRetainedRemoteFrame.reset();
|
||||
ClearDisplayItems();
|
||||
InvalidateFrameSubtree();
|
||||
}
|
||||
|
||||
// XXX this should be called ObtainDocShell or something like that,
|
||||
// to indicate that it could have side effects
|
||||
nsIDocShell* nsSubDocumentFrame::GetDocShell() const {
|
||||
@@ -1213,7 +1244,6 @@ inline static bool IsTempLayerManager(LayerManager* aManager) {
|
||||
nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
|
||||
nsSubDocumentFrame* aFrame)
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame),
|
||||
mTabId{0},
|
||||
mEventRegionsOverride(EventRegionsOverride::NoOverride) {
|
||||
bool frameIsPointerEventsNone = aFrame->StyleUI()->GetEffectivePointerEvents(
|
||||
aFrame) == StylePointerEvents::None;
|
||||
@@ -1225,12 +1255,7 @@ nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
|
||||
mEventRegionsOverride |= EventRegionsOverride::ForceDispatchToContent;
|
||||
}
|
||||
|
||||
nsFrameLoader* frameLoader = GetFrameLoader();
|
||||
MOZ_ASSERT(frameLoader && frameLoader->IsRemoteFrame());
|
||||
if (frameLoader->GetRemoteBrowser()) {
|
||||
mLayersId = frameLoader->GetLayersId();
|
||||
mTabId = frameLoader->GetRemoteBrowser()->GetTabId();
|
||||
}
|
||||
mPaintData = aFrame->GetRemotePaintData();
|
||||
}
|
||||
|
||||
mozilla::LayerState nsDisplayRemote::GetLayerState(
|
||||
@@ -1268,7 +1293,7 @@ already_AddRefed<mozilla::layers::Layer> nsDisplayRemote::BuildLayer(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mLayersId.IsValid()) {
|
||||
if (!mPaintData.mLayersId.IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1325,7 +1350,7 @@ already_AddRefed<mozilla::layers::Layer> nsDisplayRemote::BuildLayer(
|
||||
m.PostScale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);
|
||||
refLayer->SetBaseTransform(m);
|
||||
refLayer->SetEventRegionsOverride(mEventRegionsOverride);
|
||||
refLayer->SetReferentId(mLayersId);
|
||||
refLayer->SetReferentId(mPaintData.mLayersId);
|
||||
refLayer->SetRemoteDocumentSize(GetFrameSize(mFrame));
|
||||
|
||||
return layer.forget();
|
||||
@@ -1342,7 +1367,7 @@ void nsDisplayRemote::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
|
||||
}
|
||||
|
||||
DrawTarget* target = aCtx->GetDrawTarget();
|
||||
if (!target->IsRecording() || mTabId == 0) {
|
||||
if (!target->IsRecording() || mPaintData.mTabId == 0) {
|
||||
NS_WARNING("Remote iframe not rendered");
|
||||
return;
|
||||
}
|
||||
@@ -1350,7 +1375,7 @@ void nsDisplayRemote::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
|
||||
int32_t appUnitsPerDevPixel = pc->AppUnitsPerDevPixel();
|
||||
Rect destRect =
|
||||
NSRectToSnappedRect(GetContentRect(), appUnitsPerDevPixel, *target);
|
||||
target->DrawDependentSurface(mTabId, destRect);
|
||||
target->DrawDependentSurface(mPaintData.mTabId, destRect);
|
||||
}
|
||||
|
||||
bool nsDisplayRemote::CreateWebRenderCommands(
|
||||
@@ -1359,7 +1384,7 @@ bool nsDisplayRemote::CreateWebRenderCommands(
|
||||
const StackingContextHelper& aSc,
|
||||
mozilla::layers::RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
if (!mLayersId.IsValid()) {
|
||||
if (!mPaintData.mLayersId.IsValid()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1410,7 +1435,7 @@ bool nsDisplayRemote::CreateWebRenderCommands(
|
||||
rect += mOffset;
|
||||
|
||||
aBuilder.PushIFrame(mozilla::wr::ToLayoutRect(rect), !BackfaceIsHidden(),
|
||||
mozilla::wr::AsPipelineId(mLayersId),
|
||||
mozilla::wr::AsPipelineId(mPaintData.mLayersId),
|
||||
/*ignoreMissingPipelines*/ true);
|
||||
|
||||
return true;
|
||||
@@ -1419,12 +1444,12 @@ bool nsDisplayRemote::CreateWebRenderCommands(
|
||||
bool nsDisplayRemote::UpdateScrollData(
|
||||
mozilla::layers::WebRenderScrollData* aData,
|
||||
mozilla::layers::WebRenderLayerScrollData* aLayerData) {
|
||||
if (!mLayersId.IsValid()) {
|
||||
if (!mPaintData.mLayersId.IsValid()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aLayerData) {
|
||||
aLayerData->SetReferentId(mLayersId);
|
||||
aLayerData->SetReferentId(mPaintData.mLayersId);
|
||||
|
||||
// Apply the top level resolution if we are in the same process of the top
|
||||
// level document. We don't need to apply it in cases where we are in OOP
|
||||
@@ -1447,8 +1472,7 @@ bool nsDisplayRemote::UpdateScrollData(
|
||||
}
|
||||
|
||||
nsFrameLoader* nsDisplayRemote::GetFrameLoader() const {
|
||||
return mFrame ? static_cast<nsSubDocumentFrame*>(mFrame)->FrameLoader()
|
||||
: nullptr;
|
||||
return static_cast<nsSubDocumentFrame*>(mFrame)->FrameLoader();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -129,7 +129,10 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
|
||||
}
|
||||
|
||||
nsFrameLoader* FrameLoader() const;
|
||||
void ResetFrameLoader();
|
||||
|
||||
enum class RetainPaintData : bool { No, Yes };
|
||||
void ResetFrameLoader(RetainPaintData);
|
||||
void ClearRetainedPaintData();
|
||||
|
||||
void PropagateIsUnderHiddenEmbedderElementToSubView(
|
||||
bool aIsUnderHiddenEmbedderElement);
|
||||
@@ -138,6 +141,13 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
|
||||
|
||||
void SubdocumentIntrinsicSizeOrRatioChanged();
|
||||
|
||||
struct RemoteFramePaintData {
|
||||
mozilla::layers::LayersId mLayersId;
|
||||
mozilla::dom::TabId mTabId{0};
|
||||
};
|
||||
|
||||
RemoteFramePaintData GetRemotePaintData() const;
|
||||
|
||||
protected:
|
||||
friend class AsyncFrameInit;
|
||||
|
||||
@@ -170,10 +180,14 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
|
||||
nsView* mOuterView;
|
||||
nsView* mInnerView;
|
||||
|
||||
bool mIsInline;
|
||||
bool mPostedReflowCallback;
|
||||
bool mDidCreateDoc;
|
||||
bool mCallingShow;
|
||||
// When process-switching a remote tab, we might temporarily paint the old
|
||||
// one.
|
||||
Maybe<RemoteFramePaintData> mRetainedRemoteFrame;
|
||||
|
||||
bool mIsInline : 1;
|
||||
bool mPostedReflowCallback : 1;
|
||||
bool mDidCreateDoc : 1;
|
||||
bool mCallingShow : 1;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
@@ -222,10 +236,11 @@ class nsDisplayRemote final : public nsPaintedDisplayItem {
|
||||
|
||||
private:
|
||||
friend class nsDisplayItem;
|
||||
using RemoteFramePaintData = nsSubDocumentFrame::RemoteFramePaintData;
|
||||
|
||||
nsFrameLoader* GetFrameLoader() const;
|
||||
|
||||
TabId mTabId;
|
||||
LayersId mLayersId;
|
||||
RemoteFramePaintData mPaintData;
|
||||
LayoutDevicePoint mOffset;
|
||||
EventRegionsOverride mEventRegionsOverride;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user