Bug 1675709. Make sure to only call NotifyApzTransaction on scroll frames after the paint transaction is complete in the webrender case. r=mattwoodrow
In bug 1674935 we encountered a situation where NotifyApzTransaction was called more than once on a scroll frame in one paint transaction, clearing the scroll updates before they should have been. In that bug I moved the NotifyApzTransaction calls to happen at the end of one transaction for the non-wr code path., but I left the wr code path alone to reduce risk becase we didn't have proof the same could happen with wr. In this bug I will change how the wr code path works to ensure that this problem cannot happen. Differential Revision: https://phabricator.services.mozilla.com/D96165
This commit is contained in:
@@ -1552,7 +1552,7 @@ void WebRenderCommandBuilder::BuildWebRenderCommands(
|
|||||||
AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_WRDisplayList);
|
AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_WRDisplayList);
|
||||||
|
|
||||||
StackingContextHelper sc;
|
StackingContextHelper sc;
|
||||||
aScrollData = WebRenderScrollData(mManager);
|
aScrollData = WebRenderScrollData(mManager, aDisplayListBuilder);
|
||||||
MOZ_ASSERT(mLayerScrollData.empty());
|
MOZ_ASSERT(mLayerScrollData.empty());
|
||||||
mClipManager.BeginBuild(mManager, aBuilder);
|
mClipManager.BeginBuild(mManager, aBuilder);
|
||||||
mBuilderDumpIndex = 0;
|
mBuilderDumpIndex = 0;
|
||||||
@@ -1926,8 +1926,6 @@ bool BuildLayer(nsDisplayItem* aItem, BlobItemData* aData,
|
|||||||
RefPtr<Layer> root = aItem->AsPaintedDisplayItem()->BuildLayer(
|
RefPtr<Layer> root = aItem->AsPaintedDisplayItem()->BuildLayer(
|
||||||
aDisplayListBuilder, blm, param);
|
aDisplayListBuilder, blm, param);
|
||||||
|
|
||||||
aDisplayListBuilder->NotifyAndClearScrollFrames();
|
|
||||||
|
|
||||||
if (root) {
|
if (root) {
|
||||||
blm->SetRoot(root);
|
blm->SetRoot(root);
|
||||||
layerBuilder->WillEndTransaction();
|
layerBuilder->WillEndTransaction();
|
||||||
@@ -1970,8 +1968,6 @@ static bool PaintByLayer(nsDisplayItem* aItem,
|
|||||||
RefPtr<Layer> root = aItem->AsPaintedDisplayItem()->BuildLayer(
|
RefPtr<Layer> root = aItem->AsPaintedDisplayItem()->BuildLayer(
|
||||||
aDisplayListBuilder, aManager, param);
|
aDisplayListBuilder, aManager, param);
|
||||||
|
|
||||||
aDisplayListBuilder->NotifyAndClearScrollFrames();
|
|
||||||
|
|
||||||
if (root) {
|
if (root) {
|
||||||
aManager->SetRoot(root);
|
aManager->SetRoot(root);
|
||||||
layerBuilder->WillEndTransaction();
|
layerBuilder->WillEndTransaction();
|
||||||
|
|||||||
@@ -358,6 +358,8 @@ void WebRenderLayerManager::EndTransactionWithoutLayer(
|
|||||||
builder, resourceUpdates, aDisplayList, aDisplayListBuilder,
|
builder, resourceUpdates, aDisplayList, aDisplayListBuilder,
|
||||||
mScrollData, std::move(aFilters));
|
mScrollData, std::move(aFilters));
|
||||||
|
|
||||||
|
aDisplayListBuilder->NotifyAndClearScrollFrames();
|
||||||
|
|
||||||
builderDumpIndex = mWebRenderCommandBuilder.GetBuilderDumpIndex();
|
builderDumpIndex = mWebRenderCommandBuilder.GetBuilderDumpIndex();
|
||||||
containsSVGGroup = mWebRenderCommandBuilder.GetContainsSVGGroup();
|
containsSVGGroup = mWebRenderCommandBuilder.GetContainsSVGGroup();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ void WebRenderLayerScrollData::Initialize(
|
|||||||
Maybe<ScrollMetadata> metadata =
|
Maybe<ScrollMetadata> metadata =
|
||||||
asr->mScrollableFrame->ComputeScrollMetadata(
|
asr->mScrollableFrame->ComputeScrollMetadata(
|
||||||
aOwner.GetManager(), aItem->ReferenceFrame(), Nothing(), nullptr);
|
aOwner.GetManager(), aItem->ReferenceFrame(), Nothing(), nullptr);
|
||||||
asr->mScrollableFrame->NotifyApzTransaction();
|
aOwner.GetBuilder()->AddScrollFrameToNotify(asr->mScrollableFrame);
|
||||||
if (metadata) {
|
if (metadata) {
|
||||||
MOZ_ASSERT(metadata->GetMetrics().GetScrollId() == scrollId);
|
MOZ_ASSERT(metadata->GetMetrics().GetScrollId() == scrollId);
|
||||||
mScrollIds.AppendElement(aOwner.AddMetadata(metadata.ref()));
|
mScrollIds.AppendElement(aOwner.AddMetadata(metadata.ref()));
|
||||||
@@ -163,13 +163,21 @@ void WebRenderLayerScrollData::Dump(std::ostream& aOut,
|
|||||||
WebRenderScrollData::WebRenderScrollData()
|
WebRenderScrollData::WebRenderScrollData()
|
||||||
: mManager(nullptr), mIsFirstPaint(false), mPaintSequenceNumber(0) {}
|
: mManager(nullptr), mIsFirstPaint(false), mPaintSequenceNumber(0) {}
|
||||||
|
|
||||||
WebRenderScrollData::WebRenderScrollData(WebRenderLayerManager* aManager)
|
WebRenderScrollData::WebRenderScrollData(WebRenderLayerManager* aManager,
|
||||||
: mManager(aManager), mIsFirstPaint(false), mPaintSequenceNumber(0) {}
|
nsDisplayListBuilder* aBuilder)
|
||||||
|
: mManager(aManager),
|
||||||
|
mBuilder(aBuilder),
|
||||||
|
mIsFirstPaint(false),
|
||||||
|
mPaintSequenceNumber(0) {}
|
||||||
|
|
||||||
WebRenderLayerManager* WebRenderScrollData::GetManager() const {
|
WebRenderLayerManager* WebRenderScrollData::GetManager() const {
|
||||||
return mManager;
|
return mManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsDisplayListBuilder* WebRenderScrollData::GetBuilder() const {
|
||||||
|
return mBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
size_t WebRenderScrollData::AddMetadata(const ScrollMetadata& aMetadata) {
|
size_t WebRenderScrollData::AddMetadata(const ScrollMetadata& aMetadata) {
|
||||||
ScrollableLayerGuid::ViewID scrollId = aMetadata.GetMetrics().GetScrollId();
|
ScrollableLayerGuid::ViewID scrollId = aMetadata.GetMetrics().GetScrollId();
|
||||||
auto p = mScrollIdMap.lookupForAdd(scrollId);
|
auto p = mScrollIdMap.lookupForAdd(scrollId);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "nsTArrayForwardDeclare.h"
|
#include "nsTArrayForwardDeclare.h"
|
||||||
|
|
||||||
|
class nsDisplayListBuilder;
|
||||||
class nsDisplayItem;
|
class nsDisplayItem;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@@ -211,10 +212,13 @@ class WebRenderLayerScrollData final {
|
|||||||
class WebRenderScrollData final {
|
class WebRenderScrollData final {
|
||||||
public:
|
public:
|
||||||
WebRenderScrollData();
|
WebRenderScrollData();
|
||||||
explicit WebRenderScrollData(WebRenderLayerManager* aManager);
|
explicit WebRenderScrollData(WebRenderLayerManager* aManager,
|
||||||
|
nsDisplayListBuilder* aBuilder);
|
||||||
|
|
||||||
WebRenderLayerManager* GetManager() const;
|
WebRenderLayerManager* GetManager() const;
|
||||||
|
|
||||||
|
nsDisplayListBuilder* GetBuilder() const;
|
||||||
|
|
||||||
// Add the given ScrollMetadata if it doesn't already exist. Return an index
|
// Add the given ScrollMetadata if it doesn't already exist. Return an index
|
||||||
// that can be used to look up the metadata later.
|
// that can be used to look up the metadata later.
|
||||||
size_t AddMetadata(const ScrollMetadata& aMetadata);
|
size_t AddMetadata(const ScrollMetadata& aMetadata);
|
||||||
@@ -259,6 +263,11 @@ class WebRenderScrollData final {
|
|||||||
// outlive |this|.
|
// outlive |this|.
|
||||||
WebRenderLayerManager* MOZ_NON_OWNING_REF mManager;
|
WebRenderLayerManager* MOZ_NON_OWNING_REF mManager;
|
||||||
|
|
||||||
|
// Pointer to the display list builder; if this is non-null, it will always be
|
||||||
|
// valid, because the nsDisplayListBuilder that created the layer manager will
|
||||||
|
// outlive |this|.
|
||||||
|
nsDisplayListBuilder* MOZ_NON_OWNING_REF mBuilder;
|
||||||
|
|
||||||
// Internal data structure used to maintain uniqueness of mScrollMetadatas.
|
// Internal data structure used to maintain uniqueness of mScrollMetadatas.
|
||||||
// This is not serialized/deserialized over IPC, but it is rebuilt on the
|
// This is not serialized/deserialized over IPC, but it is rebuilt on the
|
||||||
// parent side when mScrollMetadatas is deserialized. So it should always be
|
// parent side when mScrollMetadatas is deserialized. So it should always be
|
||||||
|
|||||||
@@ -5044,8 +5044,8 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
|
|||||||
nsDisplayScrollInfoLayer* scrollItem =
|
nsDisplayScrollInfoLayer* scrollItem =
|
||||||
static_cast<nsDisplayScrollInfoLayer*>(item);
|
static_cast<nsDisplayScrollInfoLayer*>(item);
|
||||||
newLayerEntry->mOpaqueForAnimatedGeometryRootParent = false;
|
newLayerEntry->mOpaqueForAnimatedGeometryRootParent = false;
|
||||||
newLayerEntry->mBaseScrollMetadata =
|
newLayerEntry->mBaseScrollMetadata = scrollItem->ComputeScrollMetadata(
|
||||||
scrollItem->ComputeScrollMetadata(ownLayer->Manager(), mParameters);
|
mBuilder, ownLayer->Manager(), mParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7177,7 +7177,7 @@ LayerState nsDisplayScrollInfoLayer::GetLayerState(
|
|||||||
}
|
}
|
||||||
|
|
||||||
UniquePtr<ScrollMetadata> nsDisplayScrollInfoLayer::ComputeScrollMetadata(
|
UniquePtr<ScrollMetadata> nsDisplayScrollInfoLayer::ComputeScrollMetadata(
|
||||||
LayerManager* aLayerManager,
|
nsDisplayListBuilder* aBuilder, LayerManager* aLayerManager,
|
||||||
const ContainerLayerParameters& aContainerParameters) {
|
const ContainerLayerParameters& aContainerParameters) {
|
||||||
ScrollMetadata metadata = nsLayoutUtils::ComputeScrollMetadata(
|
ScrollMetadata metadata = nsLayoutUtils::ComputeScrollMetadata(
|
||||||
mScrolledFrame, mScrollFrame, mScrollFrame->GetContent(),
|
mScrolledFrame, mScrollFrame, mScrollFrame->GetContent(),
|
||||||
@@ -7186,7 +7186,7 @@ UniquePtr<ScrollMetadata> nsDisplayScrollInfoLayer::ComputeScrollMetadata(
|
|||||||
metadata.GetMetrics().SetIsScrollInfoLayer(true);
|
metadata.GetMetrics().SetIsScrollInfoLayer(true);
|
||||||
nsIScrollableFrame* scrollableFrame = mScrollFrame->GetScrollTargetFrame();
|
nsIScrollableFrame* scrollableFrame = mScrollFrame->GetScrollTargetFrame();
|
||||||
if (scrollableFrame) {
|
if (scrollableFrame) {
|
||||||
scrollableFrame->NotifyApzTransaction();
|
aBuilder->AddScrollFrameToNotify(scrollableFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
return UniquePtr<ScrollMetadata>(new ScrollMetadata(metadata));
|
return UniquePtr<ScrollMetadata>(new ScrollMetadata(metadata));
|
||||||
@@ -7196,8 +7196,8 @@ bool nsDisplayScrollInfoLayer::UpdateScrollData(
|
|||||||
mozilla::layers::WebRenderScrollData* aData,
|
mozilla::layers::WebRenderScrollData* aData,
|
||||||
mozilla::layers::WebRenderLayerScrollData* aLayerData) {
|
mozilla::layers::WebRenderLayerScrollData* aLayerData) {
|
||||||
if (aLayerData) {
|
if (aLayerData) {
|
||||||
UniquePtr<ScrollMetadata> metadata =
|
UniquePtr<ScrollMetadata> metadata = ComputeScrollMetadata(
|
||||||
ComputeScrollMetadata(aData->GetManager(), ContainerLayerParameters());
|
aData->GetBuilder(), aData->GetManager(), ContainerLayerParameters());
|
||||||
MOZ_ASSERT(aData);
|
MOZ_ASSERT(aData);
|
||||||
MOZ_ASSERT(metadata);
|
MOZ_ASSERT(metadata);
|
||||||
aLayerData->AppendScrollMetadata(*aData, *metadata);
|
aLayerData->AppendScrollMetadata(*aData, *metadata);
|
||||||
|
|||||||
@@ -6308,7 +6308,7 @@ class nsDisplayScrollInfoLayer : public nsDisplayWrapList {
|
|||||||
|
|
||||||
void WriteDebugInfo(std::stringstream& aStream) override;
|
void WriteDebugInfo(std::stringstream& aStream) override;
|
||||||
mozilla::UniquePtr<ScrollMetadata> ComputeScrollMetadata(
|
mozilla::UniquePtr<ScrollMetadata> ComputeScrollMetadata(
|
||||||
LayerManager* aLayerManager,
|
nsDisplayListBuilder* aBuilder, LayerManager* aLayerManager,
|
||||||
const ContainerLayerParameters& aContainerParameters);
|
const ContainerLayerParameters& aContainerParameters);
|
||||||
bool UpdateScrollData(
|
bool UpdateScrollData(
|
||||||
mozilla::layers::WebRenderScrollData* aData,
|
mozilla::layers::WebRenderScrollData* aData,
|
||||||
|
|||||||
Reference in New Issue
Block a user