Bug 1511740 - Use nsDisplayAsyncZoom items to insert zooming animations in WR. r=jrmuizel,botond

The way we control APZ zooming in WebRender is by inserting an animation
property placeholder on a WR stacking context, and then having APZ
update the animation transform value with the proper matrix at composite
time.

Previously, the stacking context being used was the rootmost
stacking context in the content process. However this doesn't work for
zoomable content in the UI process (e.g. about:support), and after
recent changes, also wraps display items that should not be affected by
zoom (e.g. scrollbars or the background color item).

This patch moves the animation property placeholder so that it
corresponds to the newly added nsDisplayAsyncZoom display item, which
corrects both of the above problems and is conceptually in line with the
desired behaviour.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kartikaya Gupta 2019-03-04 20:55:46 +00:00
parent f4063ee685
commit fecd1d365c
4 changed files with 38 additions and 36 deletions

View File

@ -1439,12 +1439,6 @@ void WebRenderCommandBuilder::BuildWebRenderCommands(
mClipManager.BeginBuild(mManager, aBuilder);
{
if (!mZoomProp && gfxPrefs::APZAllowZooming() && XRE_IsContentProcess()) {
mZoomProp.emplace();
mZoomProp->effect_type = wr::WrAnimationType::Transform;
mZoomProp->id = AnimationHelper::GetNextCompositorAnimationsId();
}
nsPresContext* presContext =
aDisplayListBuilder->RootReferenceFrame()->PresContext();
bool isTopLevelContent =
@ -1453,7 +1447,6 @@ void WebRenderCommandBuilder::BuildWebRenderCommands(
wr::StackingContextParams params;
params.mFilters = std::move(aFilters.filters);
params.mFilterDatas = std::move(aFilters.filter_datas);
params.animation = mZoomProp.ptrOr(nullptr);
params.cache_tiles = isTopLevelContent;
params.clip =
wr::WrStackingContextClip::ClipChain(aBuilder.CurrentClipChainId());
@ -1472,9 +1465,6 @@ void WebRenderCommandBuilder::BuildWebRenderCommands(
// Make a "root" layer data that has everything else as descendants
mLayerScrollData.emplace_back();
mLayerScrollData.back().InitializeRoot(mLayerScrollData.size() - 1);
if (mZoomProp) {
mLayerScrollData.back().SetZoomAnimationId(mZoomProp->id);
}
auto callback =
[&aScrollData](ScrollableLayerGuid::ViewID aScrollId) -> bool {
return aScrollData.HasMetadataFor(aScrollId).isSome();

View File

@ -194,10 +194,6 @@ class WebRenderCommandBuilder {
wr::usize mBuilderDumpIndex;
wr::usize mDumpIndent;
// When zooming is enabled, this stores the animation property that we use
// to manipulate the zoom from APZ.
Maybe<wr::WrAnimationProperty> mZoomProp;
public:
// Whether consecutive inactive display items should be grouped into one
// blob image.

View File

@ -6360,6 +6360,10 @@ bool nsDisplayOwnLayer::IsScrollbarContainer() const {
layers::ScrollbarLayerType::Container;
}
bool nsDisplayOwnLayer::IsZoomingLayer() const {
return GetType() == DisplayItemType::TYPE_ASYNC_ZOOM;
}
bool nsDisplayOwnLayer::ShouldBuildLayerEvenIfInvisible(
nsDisplayListBuilder* aBuilder) const {
// Render scroll thumb layers even if they are invisible, because async
@ -6392,10 +6396,12 @@ bool nsDisplayOwnLayer::CreateWebRenderCommands(
const StackingContextHelper& aSc, RenderRootStateManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) {
Maybe<wr::WrAnimationProperty> prop;
if (aManager->LayerManager()->AsyncPanZoomEnabled() && IsScrollThumbLayer()) {
// APZ is enabled and this is a scroll thumb, so we need to create and
// set an animation id. That way APZ can move this scrollthumb around as
// needed.
bool needsProp = aManager->LayerManager()->AsyncPanZoomEnabled() &&
(IsScrollThumbLayer() || IsZoomingLayer());
if (needsProp) {
// APZ is enabled and this is a scroll thumb or zooming layer, so we need
// to create and set an animation id. That way APZ can adjust the position/
// zoom of this content asynchronously as needed.
RefPtr<WebRenderAnimationData> animationData =
aManager->CommandBuilder()
.CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
@ -6423,25 +6429,34 @@ bool nsDisplayOwnLayer::CreateWebRenderCommands(
bool nsDisplayOwnLayer::UpdateScrollData(
mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData) {
bool ret = false;
if (IsScrollThumbLayer() || IsScrollbarContainer()) {
ret = true;
if (aLayerData) {
aLayerData->SetScrollbarData(mScrollbarData);
if (IsScrollThumbLayer()) {
aLayerData->SetScrollbarAnimationId(mWrAnimationId);
LayoutDeviceRect bounds = LayoutDeviceIntRect::FromAppUnits(
mBounds, mFrame->PresContext()->AppUnitsPerDevPixel());
// Assume a resolution of 1.0 for now because this is a WebRender
// codepath and we don't really handle resolution on the Gecko side
LayerIntRect layerBounds =
RoundedOut(bounds * LayoutDeviceToLayerScale(1.0f));
aLayerData->SetVisibleRegion(LayerIntRegion(layerBounds));
}
}
bool isRelevantToApz =
(IsScrollThumbLayer() || IsScrollbarContainer() || IsZoomingLayer());
if (!isRelevantToApz) {
return false;
}
return ret;
if (!aLayerData) {
return true;
}
if (IsZoomingLayer()) {
aLayerData->SetZoomAnimationId(mWrAnimationId);
return true;
}
aLayerData->SetScrollbarData(mScrollbarData);
if (IsScrollThumbLayer()) {
aLayerData->SetScrollbarAnimationId(mWrAnimationId);
LayoutDeviceRect bounds = LayoutDeviceIntRect::FromAppUnits(
mBounds, mFrame->PresContext()->AppUnitsPerDevPixel());
// We use a resolution of 1.0 because this is a WebRender codepath which
// always uses containerless scrolling, and so resolution doesn't apply to
// scrollbars.
LayerIntRect layerBounds =
RoundedOut(bounds * LayoutDeviceToLayerScale(1.0f));
aLayerData->SetVisibleRegion(LayerIntRegion(layerBounds));
}
return true;
}
void nsDisplayOwnLayer::WriteDebugInfo(std::stringstream& aStream) {

View File

@ -5727,6 +5727,7 @@ class nsDisplayOwnLayer : public nsDisplayWrapList {
nsDisplayOwnLayerFlags GetFlags() { return mFlags; }
bool IsScrollThumbLayer() const;
bool IsScrollbarContainer() const;
bool IsZoomingLayer() const;
protected:
nsDisplayOwnLayerFlags mFlags;