Bug 1253860 - Add machinery to update APZ's scroll offset without a main-thread paint. r=botond

MozReview-Commit-ID: Chy40f6VNIQ
This commit is contained in:
Kartikaya Gupta 2016-03-09 22:57:14 -05:00
parent 419b25a231
commit 73a7b93fd0
6 changed files with 71 additions and 2 deletions

View File

@ -233,6 +233,12 @@ public:
mDoSmoothScroll = aOther.mDoSmoothScroll;
}
void UpdateScrollInfo(uint32_t aScrollGeneration, const CSSPoint& aScrollOffset)
{
mScrollOffset = aScrollOffset;
mScrollGeneration = aScrollGeneration;
}
// Make a copy of this FrameMetrics object which does not have any pointers
// to heap-allocated memory (i.e. is Plain Old Data, or 'POD'), and is
// therefore safe to be placed into shared memory.

View File

@ -3257,9 +3257,9 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
if (!aThisLayerTreeUpdated && !isDefault) {
// No new information here, skip it. Note that this is not just an
// optimization; it's correctness too. In the case where we get one of these
// stale aLayerMetrics *after* a call to UpdateScrollOffset, processing the
// stale aLayerMetrics *after* a call to NotifyScrollUpdated, processing the
// stale aLayerMetrics would clobber the more up-to-date information from
// UpdateScrollOffset.
// NotifyScrollUpdated.
MOZ_ASSERT(aLayerMetrics == mLastContentPaintMetrics);
APZC_LOG("%p NotifyLayersUpdated short-circuit\n", this);
return;
@ -3466,6 +3466,35 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
UpdateSharedCompositorFrameMetrics();
}
void
AsyncPanZoomController::NotifyScrollUpdated(uint32_t aScrollGeneration,
const CSSPoint& aScrollOffset)
{
APZThreadUtils::AssertOnCompositorThread();
ReentrantMonitorAutoEnter lock(mMonitor);
APZC_LOG("%p NotifyScrollUpdated(%d, %s)\n", this, aScrollGeneration,
Stringify(aScrollOffset).c_str());
bool scrollOffsetUpdated = aScrollGeneration != mFrameMetrics.GetScrollGeneration();
if (!scrollOffsetUpdated) {
return;
}
APZC_LOG("%p updating scroll offset from %s to %s\n", this,
Stringify(mFrameMetrics.GetScrollOffset()).c_str(),
Stringify(aScrollOffset).c_str());
mFrameMetrics.UpdateScrollInfo(aScrollGeneration, aScrollOffset);
AcknowledgeScrollUpdate();
mExpectedGeckoMetrics.UpdateScrollInfo(aScrollGeneration, aScrollOffset);
CancelAnimation();
RequestContentRepaint();
UpdateSharedCompositorFrameMetrics();
// We don't call ScheduleComposite() here because that happens higher up
// in the call stack, when LayerTransactionParent handles this message.
// If we did it here it would incur an extra message posting unnecessarily.
}
void
AsyncPanZoomController::AcknowledgeScrollUpdate() const
{

View File

@ -187,6 +187,13 @@ public:
void NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint,
bool aThisLayerTreeUpdated);
/**
* A lightweight version of NotifyLayersUpdated that allows just the scroll
* offset and scroll generation from the main thread to be propagated to APZ.
*/
void NotifyScrollUpdated(uint32_t aScrollGeneration,
const CSSPoint& aScrollOffset);
/**
* The platform implementation must set the compositor parent so that we can
* request composites.

View File

@ -798,6 +798,25 @@ GetAPZCForViewID(Layer* aLayer, FrameMetrics::ViewID aScrollID)
return nullptr;
}
bool
LayerTransactionParent::RecvUpdateScrollOffset(
const FrameMetrics::ViewID& aScrollID,
const uint32_t& aScrollGeneration,
const CSSPoint& aScrollOffset)
{
if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
return false;
}
AsyncPanZoomController* controller = GetAPZCForViewID(mRoot, aScrollID);
if (!controller) {
return false;
}
controller->NotifyScrollUpdated(aScrollGeneration, aScrollOffset);
mShadowLayersManager->ForceComposite(this);
return true;
}
bool
LayerTransactionParent::RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollID,
const float& aX, const float& aY)

View File

@ -128,6 +128,9 @@ protected:
virtual bool RecvGetAnimationTransform(PLayerParent* aParent,
MaybeTransform* aTransform)
override;
virtual bool RecvUpdateScrollOffset(const FrameMetrics::ViewID& aScrollId,
const uint32_t& aScrollGeneration,
const CSSPoint& aScrollOffset) override;
virtual bool RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aId,
const float& aX, const float& aY) override;
virtual bool RecvSetAsyncZoom(const FrameMetrics::ViewID& aId,

View File

@ -22,6 +22,7 @@ using class mozilla::layers::APZTestData from "mozilla/layers/APZTestData.h";
using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
using mozilla::CSSPoint from "Units.h";
/**
* The layers protocol is spoken between thread contexts that manage
@ -89,6 +90,10 @@ parent:
// be void_t.
sync GetAnimationTransform(PLayer layer) returns (MaybeTransform transform);
// Updates the scroll offset and generation counter on the APZC for the
// given scroll id.
sync UpdateScrollOffset(ViewID id, uint32_t generation, CSSPoint offset);
// The next time the layer tree is composited, add this async scroll offset in
// CSS pixels for the given ViewID.
// Useful for testing rendering of async scrolling.