diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp index 60915284a848..b6fa72a97e25 100644 --- a/dom/ipc/BrowserChild.cpp +++ b/dom/ipc/BrowserChild.cpp @@ -2741,7 +2741,7 @@ bool BrowserChild::IsVisible() { } void BrowserChild::UpdateVisibility(bool aForceRepaint) { - bool shouldBeVisible = mIsTopLevel ? mRenderLayers : mEffectsInfo.mVisible; + bool shouldBeVisible = mIsTopLevel ? mRenderLayers : mEffectsInfo.IsVisible(); bool isVisible = IsVisible(); if (shouldBeVisible != isVisible) { diff --git a/dom/ipc/EffectsInfo.h b/dom/ipc/EffectsInfo.h index 86da4a725145..e7bcbb11848e 100644 --- a/dom/ipc/EffectsInfo.h +++ b/dom/ipc/EffectsInfo.h @@ -7,6 +7,8 @@ #ifndef mozilla_dom_EffectsInfo_h #define mozilla_dom_EffectsInfo_h +#include "nsRect.h" + namespace mozilla { namespace dom { @@ -14,29 +16,37 @@ namespace dom { * An EffectsInfo contains information for a remote browser about the graphical * effects that are being applied to it by ancestor browsers in different * processes. - * - * TODO: This struct currently only reports visibility, and should be extended - * with information on clipping and scaling. */ class EffectsInfo { public: EffectsInfo() { *this = EffectsInfo::FullyHidden(); } - static EffectsInfo FullyVisible() { return EffectsInfo{true}; } - static EffectsInfo FullyHidden() { return EffectsInfo{false}; } + + static EffectsInfo VisibleWithinRect(const nsRect& aVisibleRect, + float aScaleX, float aScaleY) { + return EffectsInfo{aVisibleRect, aScaleX, aScaleY}; + } + static EffectsInfo FullyHidden() { return EffectsInfo{nsRect(), 1.0f, 1.0f}; } bool operator==(const EffectsInfo& aOther) { - return mVisible == aOther.mVisible; + return mVisibleRect == aOther.mVisibleRect && mScaleX == aOther.mScaleX && + mScaleY == aOther.mScaleY; } bool operator!=(const EffectsInfo& aOther) { return !(*this == aOther); } - // If you add new state here, you must also update operator== - bool mVisible; - /* - * TODO: Add information for ancestor scaling and clipping. - */ + bool IsVisible() const { return !mVisibleRect.IsEmpty(); } + + // The visible rect of this browser relative to the root frame. If this is + // empty then the browser can be considered invisible. + nsRect mVisibleRect; + // The desired scale factors to apply to rasterized content to match + // transforms applied in ancestor browsers. + float mScaleX; + float mScaleY; + // If you add new fields here, you must also update operator== private: - explicit EffectsInfo(bool aVisible) : mVisible(aVisible) {} + EffectsInfo(const nsRect& aVisibleRect, float aScaleX, float aScaleY) + : mVisibleRect(aVisibleRect), mScaleX(aScaleX), mScaleY(aScaleY) {} }; } // namespace dom diff --git a/dom/ipc/TabMessageUtils.h b/dom/ipc/TabMessageUtils.h index cb0944976bc0..f058c1ce13eb 100644 --- a/dom/ipc/TabMessageUtils.h +++ b/dom/ipc/TabMessageUtils.h @@ -81,12 +81,16 @@ struct ParamTraits { typedef mozilla::dom::EffectsInfo paramType; static void Write(Message* aMsg, const paramType& aParam) { - WriteParam(aMsg, aParam.mVisible); + WriteParam(aMsg, aParam.mVisibleRect); + WriteParam(aMsg, aParam.mScaleX); + WriteParam(aMsg, aParam.mScaleY); } static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { - return ReadParam(aMsg, aIter, &aResult->mVisible); + return ReadParam(aMsg, aIter, &aResult->mVisibleRect) && + ReadParam(aMsg, aIter, &aResult->mScaleX) && + ReadParam(aMsg, aIter, &aResult->mScaleY); } }; diff --git a/layout/generic/nsSubDocumentFrame.cpp b/layout/generic/nsSubDocumentFrame.cpp index 073ab3590c99..1797916be2a6 100644 --- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -14,6 +14,7 @@ #include "mozilla/Preferences.h" #include "mozilla/PresShell.h" #include "mozilla/StaticPrefs.h" +#include "mozilla/Unused.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/HTMLFrameElement.h" #include "mozilla/dom/BrowserParent.h" @@ -1404,8 +1405,20 @@ already_AddRefed nsDisplayRemote::BuildLayer( if (RefPtr remoteBrowser = GetFrameLoader()->GetRemoteBrowser()) { + // Adjust mItemVisibleRect, which is relative to the reference frame, to be + // relative to this frame + nsRect visibleRect; + if (aContainerParameters.mItemVisibleRect) { + visibleRect = *aContainerParameters.mItemVisibleRect - ToReferenceFrame(); + } else { + visibleRect = mFrame->GetContentRectRelativeToSelf(); + } + // Generate an effects update notifying the browser it is visible - aBuilder->AddEffectUpdate(remoteBrowser, EffectsInfo::FullyVisible()); + aBuilder->AddEffectUpdate(remoteBrowser, + EffectsInfo::VisibleWithinRect( + visibleRect, aContainerParameters.mXScale, + aContainerParameters.mYScale)); // FrameLayerBuilder will take care of notifying the browser when it is no // longer visible } @@ -1465,8 +1478,10 @@ bool nsDisplayRemote::CreateWebRenderCommands( if (RefPtr remoteBrowser = GetFrameLoader()->GetRemoteBrowser()) { // Generate an effects update notifying the browser it is visible - aDisplayListBuilder->AddEffectUpdate(remoteBrowser, - EffectsInfo::FullyVisible()); + // TODO - Gather visibleRect and scaling factors + aDisplayListBuilder->AddEffectUpdate( + remoteBrowser, EffectsInfo::VisibleWithinRect( + mFrame->GetContentRectRelativeToSelf(), 1.0f, 1.0f)); // Create a WebRenderRemoteData to notify the RemoteBrowser when it is no // longer visible diff --git a/layout/painting/FrameLayerBuilder.cpp b/layout/painting/FrameLayerBuilder.cpp index 56bd229ea040..4e2612f93201 100644 --- a/layout/painting/FrameLayerBuilder.cpp +++ b/layout/painting/FrameLayerBuilder.cpp @@ -4657,6 +4657,7 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) { transformNode = transformNode->Parent(); } + nsRect itemVisibleRectAu = itemContent; if (transformNode) { // If we are within transform, transform itemContent and itemDrawRect. MOZ_ASSERT(transformNode); @@ -4818,6 +4819,15 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) { ContainerLayerParameters params = mParameters; params.mBackgroundColor = uniformColor; params.mLayerCreationHint = GetLayerCreationHint(itemAGR); + if (!transformNode) { + params.mItemVisibleRect = &itemVisibleRectAu; + } else { + // We only use mItemVisibleRect for getting the visible rect for + // remote browsers (which should never have inactive transforms), so we + // avoid doing transforms on itemVisibleRectAu above and can't report + // an accurate bounds here. + params.mItemVisibleRect = nullptr; + } params.mScrollMetadataASR = ActiveScrolledRoot::IsAncestor(scrollMetadataASR, mContainerScrollMetadataASR) diff --git a/layout/painting/FrameLayerBuilder.h b/layout/painting/FrameLayerBuilder.h index 491c37a151b2..3a64053d426d 100644 --- a/layout/painting/FrameLayerBuilder.h +++ b/layout/painting/FrameLayerBuilder.h @@ -285,6 +285,7 @@ struct ContainerLayerParameters { : mXScale(aXScale), mYScale(aYScale), mLayerContentsVisibleRect(nullptr), + mItemVisibleRect(nullptr), mBackgroundColor(NS_RGBA(0, 0, 0, 0)), mScrollMetadataASR(nullptr), mCompositorASR(nullptr), @@ -298,6 +299,7 @@ struct ContainerLayerParameters { : mXScale(aXScale), mYScale(aYScale), mLayerContentsVisibleRect(nullptr), + mItemVisibleRect(nullptr), mOffset(aOffset), mBackgroundColor(aParent.mBackgroundColor), mScrollMetadataASR(aParent.mScrollMetadataASR), @@ -320,6 +322,11 @@ struct ContainerLayerParameters { */ nsIntRect* mLayerContentsVisibleRect; + /** + * If non-null, the rectangle which stores the item's visible rect. + */ + nsRect* mItemVisibleRect; + /** * An offset to apply to all child layers created. */