summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/src/APZUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/apz/src/APZUtils.cpp')
-rw-r--r--gfx/layers/apz/src/APZUtils.cpp118
1 files changed, 118 insertions, 0 deletions
diff --git a/gfx/layers/apz/src/APZUtils.cpp b/gfx/layers/apz/src/APZUtils.cpp
new file mode 100644
index 0000000000..843046c34a
--- /dev/null
+++ b/gfx/layers/apz/src/APZUtils.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/layers/APZUtils.h"
+
+#include "mozilla/StaticPrefs_apz.h"
+#include "mozilla/StaticPrefs_layers.h"
+
+namespace mozilla {
+namespace layers {
+
+namespace apz {
+
+bool IsCloseToHorizontal(float aAngle, float aThreshold) {
+ return (aAngle < aThreshold || aAngle > (M_PI - aThreshold));
+}
+
+bool IsCloseToVertical(float aAngle, float aThreshold) {
+ return (fabs(aAngle - (M_PI / 2)) < aThreshold);
+}
+
+bool IsStuckAtBottom(gfxFloat aTranslation,
+ const LayerRectAbsolute& aInnerRange,
+ const LayerRectAbsolute& aOuterRange) {
+ // The item will be stuck at the bottom if the async scroll delta is in
+ // the range [aOuterRange.Y(), aInnerRange.Y()]. Since the translation
+ // is negated with repect to the async scroll delta (i.e. scrolling down
+ // produces a positive scroll delta and negative translation), we invert it
+ // and check to see if it falls in the specified range.
+ return aOuterRange.Y() <= -aTranslation && -aTranslation <= aInnerRange.Y();
+}
+
+bool IsStuckAtTop(gfxFloat aTranslation, const LayerRectAbsolute& aInnerRange,
+ const LayerRectAbsolute& aOuterRange) {
+ // Same as IsStuckAtBottom, except we want to check for the range
+ // [aInnerRange.YMost(), aOuterRange.YMost()].
+ return aInnerRange.YMost() <= -aTranslation &&
+ -aTranslation <= aOuterRange.YMost();
+}
+
+ScreenPoint ComputeFixedMarginsOffset(
+ const ScreenMargin& aCompositorFixedLayerMargins, SideBits aFixedSides,
+ const ScreenMargin& aGeckoFixedLayerMargins) {
+ // Work out the necessary translation, in screen space.
+ ScreenPoint translation;
+
+ ScreenMargin effectiveMargin =
+ aCompositorFixedLayerMargins - aGeckoFixedLayerMargins;
+ if ((aFixedSides & SideBits::eLeftRight) == SideBits::eLeftRight) {
+ translation.x += (effectiveMargin.left - effectiveMargin.right) / 2;
+ } else if (aFixedSides & SideBits::eRight) {
+ translation.x -= effectiveMargin.right;
+ } else if (aFixedSides & SideBits::eLeft) {
+ translation.x += effectiveMargin.left;
+ }
+
+ if ((aFixedSides & SideBits::eTopBottom) == SideBits::eTopBottom) {
+ translation.y += (effectiveMargin.top - effectiveMargin.bottom) / 2;
+ } else if (aFixedSides & SideBits::eBottom) {
+ translation.y -= effectiveMargin.bottom;
+ } else if (aFixedSides & SideBits::eTop) {
+ translation.y += effectiveMargin.top;
+ }
+
+ return translation;
+}
+
+bool AboutToCheckerboard(const FrameMetrics& aPaintedMetrics,
+ const FrameMetrics& aCompositorMetrics) {
+ // The main-thread code to compute the painted area can introduce some
+ // rounding error due to multiple unit conversions, so we inflate the rect by
+ // one app unit to account for that.
+ CSSRect painted = aPaintedMetrics.GetDisplayPort() +
+ aPaintedMetrics.GetLayoutScrollOffset();
+ painted.Inflate(CSSMargin::FromAppUnits(nsMargin(1, 1, 1, 1)));
+
+ // Inflate the rect by the danger zone. See the description of the danger zone
+ // prefs in AsyncPanZoomController.cpp for an explanation of this.
+ CSSRect visible =
+ CSSRect(aCompositorMetrics.GetVisualScrollOffset(),
+ aCompositorMetrics.CalculateBoundedCompositedSizeInCssPixels());
+ visible.Inflate(ScreenSize(StaticPrefs::apz_danger_zone_x(),
+ StaticPrefs::apz_danger_zone_y()) /
+ aCompositorMetrics.DisplayportPixelsPerCSSPixel());
+
+ // Clamp both rects to the scrollable rect, because having either of those
+ // exceed the scrollable rect doesn't make sense, and could lead to false
+ // positives.
+ painted = painted.Intersect(aPaintedMetrics.GetScrollableRect());
+ visible = visible.Intersect(aPaintedMetrics.GetScrollableRect());
+
+ return !painted.Contains(visible);
+}
+
+SideBits GetOverscrollSideBits(const ParentLayerPoint& aOverscrollAmount) {
+ SideBits sides = SideBits::eNone;
+
+ if (aOverscrollAmount.x < 0) {
+ sides |= SideBits::eLeft;
+ } else if (aOverscrollAmount.x > 0) {
+ sides |= SideBits::eRight;
+ }
+
+ if (aOverscrollAmount.y < 0) {
+ sides |= SideBits::eTop;
+ } else if (aOverscrollAmount.y > 0) {
+ sides |= SideBits::eBottom;
+ }
+
+ return sides;
+}
+
+} // namespace apz
+} // namespace layers
+} // namespace mozilla