Bug 1556548 - Move nsDisplayRemote to nsSubDocumentFrame.cpp. r=mattwoodrow

nsDisplayRemote no longer has any direct ties to RenderFrame and should
be moved to nsSubDocumentFrame.cpp where it's actually used/created.

Differential Revision: https://phabricator.services.mozilla.com/D33563

--HG--
extra : rebase_source : ae2e03108820bd14b5f2771da17cabfd95706f94
extra : source : b301161ab461cd46cea3f91749896686c50e9b9f
extra : histedit_source : 1c80f83d26734e56bd6353f0a50dcbc4bf894b4b
This commit is contained in:
Ryan Hunt 2019-06-02 13:00:16 -04:00
Родитель 298a301151
Коммит 4386b68e1c
5 изменённых файлов: 262 добавлений и 250 удалений

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

@ -16,7 +16,7 @@
#include "mozilla/StaticPrefs.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/HTMLFrameElement.h"
#include "mozilla/layout/RenderFrame.h"
#include "mozilla/dom/BrowserParent.h"
#include "nsCOMPtr.h"
#include "nsGenericHTMLElement.h"
@ -45,7 +45,14 @@
#include "nsQueryObject.h"
#include "RetainedDisplayListBuilder.h"
#include "Layers.h"
#include "BasicLayers.h"
#include "mozilla/layers/WebRenderUserData.h"
#include "mozilla/layers/WebRenderScrollData.h"
#include "mozilla/layers/RenderRootStateManager.h"
using namespace mozilla;
using namespace mozilla::layers;
using mozilla::dom::Document;
static bool sShowPreviousPage = true;
@ -1336,3 +1343,200 @@ nsIFrame* nsSubDocumentFrame::ObtainIntrinsicSizeFrame() {
}
return nullptr;
}
/**
* 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 mozilla::LayoutDeviceIntPoint GetContentRectLayerOffset(
nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuilder) {
nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
// 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 mozilla::LayoutDeviceIntPoint::FromAppUnitsToNearest(frameOffset,
auPerDevPixel);
}
// 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
// widget, and hence in non-retained mode.
inline static bool IsTempLayerManager(LayerManager* aManager) {
return (LayersBackend::LAYERS_BASIC == aManager->GetBackendType() &&
!static_cast<BasicLayerManager*>(aManager)->IsRetained());
}
nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
nsSubDocumentFrame* aFrame)
: nsPaintedDisplayItem(aBuilder, aFrame),
mTabId{0},
mEventRegionsOverride(EventRegionsOverride::NoOverride) {
bool frameIsPointerEventsNone = aFrame->StyleUI()->GetEffectivePointerEvents(
aFrame) == NS_STYLE_POINTER_EVENTS_NONE;
if (aBuilder->IsInsidePointerEventsNoneDoc() || frameIsPointerEventsNone) {
mEventRegionsOverride |= EventRegionsOverride::ForceEmptyHitRegion;
}
if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(
aFrame->PresShell())) {
mEventRegionsOverride |= EventRegionsOverride::ForceDispatchToContent;
}
nsFrameLoader* frameLoader = GetFrameLoader();
MOZ_ASSERT(frameLoader && frameLoader->IsRemoteFrame());
mLayersId = frameLoader->GetLayersId();
if (nsFrameLoader* frameLoader = GetFrameLoader()) {
// TODO: We need to handle acquiring a TabId in the remote sub-frame case
// for fission.
if (BrowserParent* browser = BrowserParent::GetFrom(frameLoader)) {
mTabId = browser->GetTabId();
}
}
}
mozilla::LayerState nsDisplayRemote::GetLayerState(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aParameters) {
if (IsTempLayerManager(aManager)) {
return mozilla::LayerState::LAYER_NONE;
}
return mozilla::LayerState::LAYER_ACTIVE_FORCE;
}
already_AddRefed<mozilla::layers::Layer> nsDisplayRemote::BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) {
MOZ_ASSERT(mFrame, "Makes no sense to have a shadow tree without a frame");
if (IsTempLayerManager(aManager)) {
// This can happen if aManager is a "temporary" manager, or if the
// widget's layer manager changed out from under us. We need to
// FIXME handle the former case somehow, probably with an API to
// draw a manager's subtree. The latter is bad bad bad, but the the
// MOZ_ASSERT() above will flag it. Returning nullptr here will just
// cause the shadow subtree not to be rendered.
NS_WARNING("Remote iframe not rendered");
return nullptr;
}
if (!mLayersId.IsValid()) {
return nullptr;
}
if (RefPtr<RemoteBrowser> remoteBrowser =
GetFrameLoader()->GetRemoteBrowser()) {
// Generate an effects update notifying the browser it is visible
aBuilder->AddEffectUpdate(remoteBrowser, EffectsInfo::FullyVisible());
// FrameLayerBuilder will take care of notifying the browser when it is no
// longer visible
}
RefPtr<Layer> layer =
aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, this);
if (!layer) {
layer = aManager->CreateRefLayer();
}
if (!layer || !layer->AsRefLayer()) {
// Probably a temporary layer manager that doesn't know how to
// use ref layers.
return nullptr;
}
RefLayer* refLayer = layer->AsRefLayer();
LayoutDeviceIntPoint offset = GetContentRectLayerOffset(Frame(), aBuilder);
// We can only have an offset if we're a child of an inactive
// container, but our display item is LAYER_ACTIVE_FORCE which
// forces all layers above to be active.
MOZ_ASSERT(aContainerParameters.mOffset == nsIntPoint());
Matrix4x4 m = Matrix4x4::Translation(offset.x, offset.y, 0.0);
// Remote content can't be repainted by us, so we multiply down
// the resolution that our container expects onto our container.
m.PreScale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);
refLayer->SetBaseTransform(m);
refLayer->SetEventRegionsOverride(mEventRegionsOverride);
refLayer->SetReferentId(mLayersId);
return layer.forget();
}
void nsDisplayRemote::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
DrawTarget* target = aCtx->GetDrawTarget();
if (!target->IsRecording() || mTabId == 0) {
NS_WARNING("Remote iframe not rendered");
return;
}
int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
Rect destRect = mozilla::NSRectToSnappedRect(GetContentRect(),
appUnitsPerDevPixel, *target);
target->DrawDependentSurface(mTabId, destRect);
}
bool nsDisplayRemote::CreateWebRenderCommands(
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::RenderRootStateManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) {
if (!mLayersId.IsValid()) {
return true;
}
if (RefPtr<RemoteBrowser> remoteBrowser =
GetFrameLoader()->GetRemoteBrowser()) {
// Generate an effects update notifying the browser it is visible
aDisplayListBuilder->AddEffectUpdate(remoteBrowser,
EffectsInfo::FullyVisible());
// Create a WebRenderRemoteData to notify the RemoteBrowser when it is no
// longer visible
RefPtr<WebRenderRemoteData> userData =
aManager->CommandBuilder()
.CreateOrRecycleWebRenderUserData<WebRenderRemoteData>(
this, aBuilder.GetRenderRoot(), nullptr);
userData->SetRemoteBrowser(remoteBrowser);
}
mOffset = GetContentRectLayerOffset(mFrame, aDisplayListBuilder);
LayoutDeviceRect rect = LayoutDeviceRect::FromAppUnits(
mFrame->GetContentRectRelativeToSelf(),
mFrame->PresContext()->AppUnitsPerDevPixel());
rect += mOffset;
aBuilder.PushIFrame(mozilla::wr::ToRoundedLayoutRect(rect),
!BackfaceIsHidden(), mozilla::wr::AsPipelineId(mLayersId),
/*ignoreMissingPipelines*/ true);
return true;
}
bool nsDisplayRemote::UpdateScrollData(
mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData) {
if (!mLayersId.IsValid()) {
return true;
}
if (aLayerData) {
aLayerData->SetReferentId(mLayersId);
aLayerData->SetTransform(
mozilla::gfx::Matrix4x4::Translation(mOffset.x, mOffset.y, 0.0));
aLayerData->SetEventRegionsOverride(mEventRegionsOverride);
}
return true;
}
nsFrameLoader* nsDisplayRemote::GetFrameLoader() const {
return mFrame ? static_cast<nsSubDocumentFrame*>(mFrame)->FrameLoader()
: nullptr;
}

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

@ -7,7 +7,11 @@
#ifndef NSSUBDOCUMENTFRAME_H_
#define NSSUBDOCUMENTFRAME_H_
#include "Layers.h"
#include "LayerState.h"
#include "mozilla/Attributes.h"
#include "mozilla/layers/WebRenderScrollData.h"
#include "nsDisplayList.h"
#include "nsAtomicContainerFrame.h"
#include "nsIReflowCallback.h"
#include "nsFrameLoader.h"
@ -161,4 +165,56 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
WeakFrame mPreviousCaret;
};
/**
* A nsDisplayRemote will graft a remote frame's shadow layer tree (for a given
* nsFrameLoader) into its parent frame's layer tree.
*/
class nsDisplayRemote final : public nsPaintedDisplayItem {
typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
typedef mozilla::dom::TabId TabId;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef mozilla::layers::EventRegionsOverride EventRegionsOverride;
typedef mozilla::layers::Layer Layer;
typedef mozilla::layers::LayersId LayersId;
typedef mozilla::layers::RefLayer RefLayer;
typedef mozilla::layers::StackingContextHelper StackingContextHelper;
typedef mozilla::LayerState LayerState;
typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
public:
nsDisplayRemote(nsDisplayListBuilder* aBuilder, nsSubDocumentFrame* aFrame);
LayerState GetLayerState(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
already_AddRefed<Layer> BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
bool CreateWebRenderCommands(
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::RenderRootStateManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override;
bool UpdateScrollData(
mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
NS_DISPLAY_DECL_NAME("Remote", TYPE_REMOTE)
private:
friend class nsDisplayItemBase;
nsFrameLoader* GetFrameLoader() const;
TabId mTabId;
LayersId mLayersId;
LayoutDeviceIntPoint mOffset;
EventRegionsOverride mEventRegionsOverride;
};
#endif /* NSSUBDOCUMENTFRAME_H_ */

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

@ -129,201 +129,3 @@ void RenderFrame::GetTextureFactoryIdentifier(
} // namespace layout
} // namespace mozilla
/**
* 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 mozilla::LayoutDeviceIntPoint GetContentRectLayerOffset(
nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuilder) {
nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
// 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 mozilla::LayoutDeviceIntPoint::FromAppUnitsToNearest(frameOffset,
auPerDevPixel);
}
// 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
// widget, and hence in non-retained mode.
inline static bool IsTempLayerManager(mozilla::layers::LayerManager* aManager) {
return (mozilla::layers::LayersBackend::LAYERS_BASIC ==
aManager->GetBackendType() &&
!static_cast<BasicLayerManager*>(aManager)->IsRetained());
}
nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
nsSubDocumentFrame* aFrame)
: nsPaintedDisplayItem(aBuilder, aFrame),
mTabId{0},
mEventRegionsOverride(EventRegionsOverride::NoOverride) {
bool frameIsPointerEventsNone = aFrame->StyleUI()->GetEffectivePointerEvents(
aFrame) == NS_STYLE_POINTER_EVENTS_NONE;
if (aBuilder->IsInsidePointerEventsNoneDoc() || frameIsPointerEventsNone) {
mEventRegionsOverride |= EventRegionsOverride::ForceEmptyHitRegion;
}
if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(
aFrame->PresShell())) {
mEventRegionsOverride |= EventRegionsOverride::ForceDispatchToContent;
}
nsFrameLoader* frameLoader = GetFrameLoader();
MOZ_ASSERT(frameLoader && frameLoader->IsRemoteFrame());
mLayersId = frameLoader->GetLayersId();
if (nsFrameLoader* frameLoader = GetFrameLoader()) {
// TODO: We need to handle acquiring a TabId in the remote sub-frame case
// for fission.
if (BrowserParent* browser = BrowserParent::GetFrom(frameLoader)) {
mTabId = browser->GetTabId();
}
}
}
mozilla::LayerState nsDisplayRemote::GetLayerState(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aParameters) {
if (IsTempLayerManager(aManager)) {
return mozilla::LayerState::LAYER_NONE;
}
return mozilla::LayerState::LAYER_ACTIVE_FORCE;
}
already_AddRefed<Layer> nsDisplayRemote::BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) {
MOZ_ASSERT(mFrame, "Makes no sense to have a shadow tree without a frame");
if (IsTempLayerManager(aManager)) {
// This can happen if aManager is a "temporary" manager, or if the
// widget's layer manager changed out from under us. We need to
// FIXME handle the former case somehow, probably with an API to
// draw a manager's subtree. The latter is bad bad bad, but the the
// MOZ_ASSERT() above will flag it. Returning nullptr here will just
// cause the shadow subtree not to be rendered.
NS_WARNING("Remote iframe not rendered");
return nullptr;
}
if (!mLayersId.IsValid()) {
return nullptr;
}
if (RefPtr<RemoteBrowser> remoteBrowser =
GetFrameLoader()->GetRemoteBrowser()) {
// Generate an effects update notifying the browser it is visible
aBuilder->AddEffectUpdate(remoteBrowser, EffectsInfo::FullyVisible());
// FrameLayerBuilder will take care of notifying the browser when it is no
// longer visible
}
RefPtr<Layer> layer =
aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, this);
if (!layer) {
layer = aManager->CreateRefLayer();
}
if (!layer || !layer->AsRefLayer()) {
// Probably a temporary layer manager that doesn't know how to
// use ref layers.
return nullptr;
}
RefLayer* refLayer = layer->AsRefLayer();
LayoutDeviceIntPoint offset = GetContentRectLayerOffset(Frame(), aBuilder);
// We can only have an offset if we're a child of an inactive
// container, but our display item is LAYER_ACTIVE_FORCE which
// forces all layers above to be active.
MOZ_ASSERT(aContainerParameters.mOffset == nsIntPoint());
Matrix4x4 m = Matrix4x4::Translation(offset.x, offset.y, 0.0);
// Remote content can't be repainted by us, so we multiply down
// the resolution that our container expects onto our container.
m.PreScale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);
refLayer->SetBaseTransform(m);
refLayer->SetEventRegionsOverride(mEventRegionsOverride);
refLayer->SetReferentId(mLayersId);
return layer.forget();
}
void nsDisplayRemote::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
DrawTarget* target = aCtx->GetDrawTarget();
if (!target->IsRecording() || mTabId == 0) {
NS_WARNING("Remote iframe not rendered");
return;
}
int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
Rect destRect = mozilla::NSRectToSnappedRect(GetContentRect(),
appUnitsPerDevPixel, *target);
target->DrawDependentSurface(mTabId, destRect);
}
bool nsDisplayRemote::CreateWebRenderCommands(
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::RenderRootStateManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) {
if (!mLayersId.IsValid()) {
return true;
}
if (RefPtr<RemoteBrowser> remoteBrowser =
GetFrameLoader()->GetRemoteBrowser()) {
// Generate an effects update notifying the browser it is visible
aDisplayListBuilder->AddEffectUpdate(remoteBrowser,
EffectsInfo::FullyVisible());
// Create a WebRenderRemoteData to notify the RemoteBrowser when it is no
// longer visible
RefPtr<WebRenderRemoteData> userData =
aManager->CommandBuilder()
.CreateOrRecycleWebRenderUserData<WebRenderRemoteData>(
this, aBuilder.GetRenderRoot(), nullptr);
userData->SetRemoteBrowser(remoteBrowser);
}
mOffset = GetContentRectLayerOffset(mFrame, aDisplayListBuilder);
LayoutDeviceRect rect = LayoutDeviceRect::FromAppUnits(
mFrame->GetContentRectRelativeToSelf(),
mFrame->PresContext()->AppUnitsPerDevPixel());
rect += mOffset;
aBuilder.PushIFrame(mozilla::wr::ToRoundedLayoutRect(rect),
!BackfaceIsHidden(), mozilla::wr::AsPipelineId(mLayersId),
/*ignoreMissingPipelines*/ true);
return true;
}
bool nsDisplayRemote::UpdateScrollData(
mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData) {
if (!mLayersId.IsValid()) {
return true;
}
if (aLayerData) {
aLayerData->SetReferentId(mLayersId);
aLayerData->SetTransform(
mozilla::gfx::Matrix4x4::Translation(mOffset.x, mOffset.y, 0.0));
aLayerData->SetEventRegionsOverride(mEventRegionsOverride);
}
return true;
}
nsFrameLoader* nsDisplayRemote::GetFrameLoader() const {
return mFrame ? static_cast<nsSubDocumentFrame*>(mFrame)->FrameLoader()
: nullptr;
}

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

@ -85,54 +85,4 @@ class RenderFrame final {
} // namespace layout
} // namespace mozilla
/**
* A nsDisplayRemote will graft a remote frame's shadow layer tree (for a given
* nsFrameLoader) into its parent frame's layer tree.
*/
class nsDisplayRemote final : public nsPaintedDisplayItem {
typedef mozilla::dom::TabId TabId;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef mozilla::layers::EventRegionsOverride EventRegionsOverride;
typedef mozilla::layers::Layer Layer;
typedef mozilla::layers::LayersId LayersId;
typedef mozilla::layers::RefLayer RefLayer;
typedef mozilla::layout::RenderFrame RenderFrame;
typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
public:
nsDisplayRemote(nsDisplayListBuilder* aBuilder, nsSubDocumentFrame* aFrame);
LayerState GetLayerState(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
already_AddRefed<Layer> BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
bool CreateWebRenderCommands(
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::RenderRootStateManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override;
bool UpdateScrollData(
mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
NS_DISPLAY_DECL_NAME("Remote", TYPE_REMOTE)
private:
friend class nsDisplayItemBase;
nsFrameLoader* GetFrameLoader() const;
TabId mTabId;
LayersId mLayersId;
LayoutDeviceIntPoint mOffset;
EventRegionsOverride mEventRegionsOverride;
};
#endif // mozilla_layout_RenderFrame_h

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

@ -61,6 +61,7 @@
#include "ImageLayers.h"
#include "ImageContainer.h"
#include "nsCanvasFrame.h"
#include "nsSubDocumentFrame.h"
#include "StickyScrollContainer.h"
#include "mozilla/AnimationPerformanceWarning.h"
#include "mozilla/AnimationUtils.h"
@ -102,7 +103,6 @@
#include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/layers/WebRenderMessages.h"
#include "mozilla/layers/WebRenderScrollData.h"
#include "mozilla/layout/RenderFrame.h"
using namespace mozilla;
using namespace mozilla::layers;