Bug 1253860 - Skip paints for main thread scrolls if we can ask APZ to handle the scrolling for us. r=mstange

MozReview-Commit-ID: LqugzganLru
This commit is contained in:
Kartikaya Gupta 2016-03-09 22:57:15 -05:00
parent 0415065a38
commit 2c7a5f6eaf

View File

@ -63,7 +63,9 @@
#include "nsPluginFrame.h"
#include <mozilla/layers/AxisPhysicsModel.h>
#include <mozilla/layers/AxisPhysicsMSDModel.h>
#include "mozilla/layers/LayerTransactionChild.h"
#include "mozilla/layers/ScrollLinkedEffectDetector.h"
#include "mozilla/layers/ShadowLayers.h"
#include "mozilla/unused.h"
#include <algorithm>
#include <cstdlib> // for std::abs(int/long)
@ -2676,25 +2678,44 @@ ScrollFrameHelper::ScrollToImpl(nsPoint aPt, const nsRect& aRange, nsIAtom* aOri
ScrollVisual();
if (LastScrollOrigin() == nsGkAtoms::apz && gfxPrefs::APZPaintSkipping()) {
// If this was an apz scroll and the displayport (relative to the
// scrolled frame) hasn't changed, then this won't trigger
// any painting, so no need to schedule one.
bool schedulePaint = true;
if (nsLayoutUtils::AsyncPanZoomEnabled(mOuter) && gfxPrefs::APZPaintSkipping()) {
// If APZ is enabled with paint-skipping, there are certain conditions in
// which we can skip paints:
// 1) If APZ triggered this scroll, and the tile-aligned displayport is
// unchanged.
// 2) If non-APZ triggered this scroll, but we can handle it by just asking
// APZ to update the scroll position. Again we make this conditional on
// the tile-aligned displayport being unchanged.
// We do the displayport check first since it's common to all scenarios,
// and then if the displayport is unchanged, we check if APZ triggered,
// or can handle, this scroll. If so, we set schedulePaint to false and
// skip the paint.
nsRect displayPort;
DebugOnly<bool> usingDisplayPort =
bool usingDisplayPort =
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayPort);
NS_ASSERTION(usingDisplayPort, "Must have a displayport for apz scrolls!");
displayPort.MoveBy(-mScrolledFrame->GetPosition());
if (!displayPort.IsEqualEdges(oldDisplayPort)) {
mOuter->SchedulePaint();
if (needImageVisibilityUpdate) {
presContext->PresShell()->ScheduleImageVisibilityUpdate();
if (usingDisplayPort && displayPort.IsEqualEdges(oldDisplayPort)) {
if (LastScrollOrigin() == nsGkAtoms::apz) {
schedulePaint = false;
} else if (mScrollableByAPZ) {
nsIWidget* widget = presContext->GetNearestWidget();
LayerManager* manager = widget ? widget->GetLayerManager() : nullptr;
ShadowLayerForwarder* forwarder = manager ? manager->AsShadowForwarder() : nullptr;
if (forwarder && forwarder->HasShadowManager()) {
mozilla::layers::FrameMetrics::ViewID id;
DebugOnly<bool> success = nsLayoutUtils::FindIDFor(mOuter->GetContent(), &id);
MOZ_ASSERT(success); // we have a displayport, we better have an ID
forwarder->GetShadowManager()->SendUpdateScrollOffset(id,
mScrollGeneration, CSSPoint::FromAppUnits(GetScrollPosition()));
schedulePaint = false;
}
}
}
} else {
}
if (schedulePaint) {
mOuter->SchedulePaint();
if (needImageVisibilityUpdate) {