Bug 1556556 - Apply the visual-to-layout transform during display list building and display list based hit testing. r=kats,mattwoodrow

Differential Revision: https://phabricator.services.mozilla.com/D68728
This commit is contained in:
Botond Ballo 2020-04-28 01:36:34 +00:00
parent af40ffccfd
commit 480ee775c9
3 changed files with 62 additions and 14 deletions

View File

@ -44,6 +44,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/PresShell.h"
#include "mozilla/ScrollbarPreferences.h"
#include "mozilla/ViewportUtils.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
@ -3667,8 +3668,22 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
scrolledRectClipState.SetClippedToDisplayPort();
}
nsRect visibleRectForChildren = visibleRect;
nsRect dirtyRectForChildren = dirtyRect;
// If we are entering the RCD-RSF, we are crossing the async zoom
// container boundary, and need to convert from visual to layout
// coordinates.
if (willBuildAsyncZoomContainer && aBuilder->IsForEventDelivery()) {
MOZ_ASSERT(ViewportUtils::IsZoomedContentRoot(mScrolledFrame));
visibleRectForChildren = ViewportUtils::VisualToLayout(
visibleRectForChildren, mOuter->PresShell());
dirtyRectForChildren = ViewportUtils::VisualToLayout(
dirtyRectForChildren, mOuter->PresShell());
}
nsDisplayListBuilder::AutoBuildingDisplayList building(
aBuilder, mOuter, visibleRect, dirtyRect);
aBuilder, mOuter, visibleRectForChildren, dirtyRectForChildren);
mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, set);

View File

@ -34,6 +34,7 @@
#include "mozilla/StaticPrefs_gfx.h"
#include "mozilla/StaticPrefs_layers.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/ViewportUtils.h"
#include "nsCSSRendering.h"
#include "nsCSSRenderingGradients.h"
#include "nsRegion.h"
@ -101,6 +102,7 @@
#include "nsFocusManager.h"
#include "ClientLayerManager.h"
#include "mozilla/layers/AnimationHelper.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TreeTraversal.h"
@ -1838,8 +1840,29 @@ void nsDisplayListBuilder::MarkFramesForDisplayList(
const DisplayItemClipChain* combinedClipChain =
mClipState.GetCurrentCombinedClipChain(this);
const ActiveScrolledRoot* asr = mCurrentActiveScrolledRoot;
nsRect visibleRect = GetVisibleRect();
nsRect dirtyRect = GetDirtyRect();
// If we are entering content that is fixed to the RCD-RSF, we are
// crossing the async zoom container boundary, and need to convert from
// visual to layout coordinates.
if (ViewportFrame* viewportFrame = do_QueryFrame(aDirtyFrame)) {
if (IsForEventDelivery() && ShouldBuildAsyncZoomContainer() &&
viewportFrame->PresContext()->IsRootContentDocument()) {
#ifdef DEBUG
for (nsIFrame* f : aFrames) {
MOZ_ASSERT(ViewportUtils::IsZoomedContentRoot(f));
}
#endif
visibleRect = ViewportUtils::VisualToLayout(visibleRect,
viewportFrame->PresShell());
dirtyRect = ViewportUtils::VisualToLayout(dirtyRect,
viewportFrame->PresShell());
}
}
OutOfFlowDisplayData* data = new OutOfFlowDisplayData(
clipChain, combinedClipChain, asr, GetVisibleRect(), GetDirtyRect());
clipChain, combinedClipChain, asr, visibleRect, dirtyRect);
aDirtyFrame->SetProperty(
nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
mFramesWithOOFData.AppendElement(aDirtyFrame);
@ -7148,14 +7171,6 @@ nsDisplayResolution::nsDisplayResolution(nsDisplayListBuilder* aBuilder,
MOZ_COUNT_CTOR(nsDisplayResolution);
}
void nsDisplayResolution::HitTest(nsDisplayListBuilder* aBuilder,
const nsRect& aRect, HitTestState* aState,
nsTArray<nsIFrame*>* aOutFrames) {
PresShell* presShell = mFrame->PresShell();
nsRect rect = aRect.RemoveResolution(presShell->GetResolution());
mList.HitTest(aBuilder, rect, aState, aOutFrames);
}
already_AddRefed<Layer> nsDisplayResolution::BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) {
@ -7890,6 +7905,18 @@ nsDisplayAsyncZoom::~nsDisplayAsyncZoom() {
}
#endif
void nsDisplayAsyncZoom::HitTest(nsDisplayListBuilder* aBuilder,
const nsRect& aRect, HitTestState* aState,
nsTArray<nsIFrame*>* aOutFrames) {
#ifdef DEBUG
nsIScrollableFrame* scrollFrame = do_QueryFrame(mFrame);
MOZ_ASSERT(scrollFrame && ViewportUtils::IsZoomedContentRoot(
scrollFrame->GetScrolledFrame()));
#endif
nsRect rect = ViewportUtils::VisualToLayout(aRect, mFrame->PresShell());
mList.HitTest(aBuilder, rect, aState, aOutFrames);
}
already_AddRefed<Layer> nsDisplayAsyncZoom::BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) {

View File

@ -1517,6 +1517,12 @@ class nsDisplayListBuilder {
const DisplayItemClipChain*
mCombinedClipChain; // only necessary for the special case of top layer
const ActiveScrolledRoot* mContainingBlockActiveScrolledRoot;
// If this OutOfFlowDisplayData is associated with the ViewportFrame
// of a document that has a resolution (creating separate visual and
// layout viewports with their own coordinate spaces), these rects
// are in layout coordinates. Similarly, GetVisibleRectForFrame() in
// such a case returns a quantity in layout coordinates.
nsRect mVisibleRect;
nsRect mDirtyRect;
@ -6175,8 +6181,6 @@ class nsDisplayResolution : public nsDisplaySubDocument {
NS_DISPLAY_DECL_NAME("Resolution", TYPE_RESOLUTION)
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override;
already_AddRefed<Layer> BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
@ -6504,10 +6508,12 @@ class nsDisplayAsyncZoom : public nsDisplayOwnLayer {
NS_DISPLAY_DECL_NAME("AsyncZoom", TYPE_ASYNC_ZOOM)
virtual already_AddRefed<Layer> BuildLayer(
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override;
already_AddRefed<Layer> BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
virtual LayerState GetLayerState(
LayerState GetLayerState(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aParameters) override {
return mozilla::LayerState::LAYER_ACTIVE_FORCE;