Bug 1240065 - Throttle repaints when pinch zooming r=botond

This commit is contained in:
Randall Barker 2016-05-26 14:39:04 -07:00
parent f9b51c3c01
commit 92bf505262
4 changed files with 41 additions and 2 deletions

View File

@ -365,6 +365,12 @@ typedef GenericFlingAnimation FlingAnimation;
* \li\b apz.zoom_animation_duration_ms
* This controls how long the zoom-to-rect animation takes.\n
* Units: ms
*
* \li\b apz.scale_repaint_delay_ms
* How long to delay between repaint requests during a scale.
* A negative number prevents repaint requests during a scale.\n
* Units: ms
*
*/
/**
@ -703,6 +709,7 @@ AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId,
mState(NOTHING),
mNotificationBlockers(0),
mInputQueue(aInputQueue),
mPinchPaintTimerSet(false),
mAPZCId(sAsyncPanZoomControllerCount++),
mSharedLock(nullptr),
mAsyncTransformAppliedToContent(false),
@ -1281,6 +1288,7 @@ nsEventStatus AsyncPanZoomController::OnTouchCancel(const MultiTouchInput& aEven
nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEvent) {
APZC_LOG("%p got a scale-begin in state %d\n", this, mState);
mPinchPaintTimerSet = false;
// Note that there may not be a touch block at this point, if we received the
// PinchGestureEvent directly from widget code without any touch events.
if (HasReadyTouchBlock() && !CurrentTouchBlock()->TouchActionAllowsPinchZoom()) {
@ -1375,8 +1383,21 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
}
ScheduleComposite();
// We don't want to redraw on every scale, so don't use
// RequestContentRepaint()
// We don't want to redraw on every scale, so throttle it.
if (!mPinchPaintTimerSet) {
const int delay = gfxPrefs::APZScaleRepaintDelay();
if (delay >= 0) {
if (RefPtr<GeckoContentController> controller = GetGeckoContentController()) {
mPinchPaintTimerSet = true;
controller->PostDelayedTask(
NewRunnableMethod(this,
&AsyncPanZoomController::DoDelayedRequestContentRepaint),
delay);
}
}
}
UpdateSharedCompositorFrameMetrics();
}
@ -1389,6 +1410,8 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
nsEventStatus AsyncPanZoomController::OnScaleEnd(const PinchGestureInput& aEvent) {
APZC_LOG("%p got a scale-end in state %d\n", this, mState);
mPinchPaintTimerSet = false;
if (HasReadyTouchBlock() && !CurrentTouchBlock()->TouchActionAllowsPinchZoom()) {
return nsEventStatus_eIgnore;
}
@ -1613,6 +1636,15 @@ AsyncPanZoomController::AllowScrollHandoffInCurrentBlock() const
return result;
}
void AsyncPanZoomController::DoDelayedRequestContentRepaint()
{
if (!IsDestroyed() && mPinchPaintTimerSet) {
ReentrantMonitorAutoEnter lock(mMonitor);
RequestContentRepaint();
}
mPinchPaintTimerSet = false;
}
static ScrollInputMethod
ScrollInputMethodForWheelDeltaType(ScrollWheelInput::ScrollDeltaType aDeltaType)
{

View File

@ -898,6 +898,8 @@ private:
ParentLayerPoint mLastFlingVelocity;
// The time at which the most recent fling started.
TimeStamp mLastFlingTime;
// Indicates if the repaint-during-pinch timer is currently set
bool mPinchPaintTimerSet;
// Deal with overscroll resulting from a fling animation. This is only ever
// called on APZC instances that were actually performing a fling.
@ -921,6 +923,9 @@ private:
// Returns whether overscroll is allowed during an event.
bool AllowScrollHandoffInCurrentBlock() const;
// Invoked by the pinch repaint timer.
void DoDelayedRequestContentRepaint();
/* ===================================================================
* The functions and members in this section are used to make ancestor chains
* out of APZC instances. These chains can only be walked or manipulated

View File

@ -187,6 +187,7 @@ private:
DECL_GFX_PREF(Live, "apz.y_skate_size_multiplier", APZYSkateSizeMultiplier, float, 2.5f);
DECL_GFX_PREF(Live, "apz.y_stationary_size_multiplier", APZYStationarySizeMultiplier, float, 3.5f);
DECL_GFX_PREF(Live, "apz.zoom_animation_duration_ms", APZZoomAnimationDuration, int32_t, 250);
DECL_GFX_PREF(Live, "apz.scale_repaint_delay_ms", APZScaleRepaintDelay, int32_t, 500);
DECL_GFX_PREF(Live, "browser.ui.zoom.force-user-scalable", ForceUserScalable, bool, false);
DECL_GFX_PREF(Live, "browser.viewport.desktopWidth", DesktopViewportWidth, int32_t, 980);

View File

@ -644,6 +644,7 @@ pref("apz.y_skate_size_multiplier", "3.5");
pref("apz.x_stationary_size_multiplier", "1.5");
pref("apz.y_stationary_size_multiplier", "3.5");
pref("apz.zoom_animation_duration_ms", 250);
pref("apz.scale_repaint_delay_ms", 500);
#if defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID)
// Mobile prefs