1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_layers_APZUtils_h 8 #define mozilla_layers_APZUtils_h 9 10 #include <stdint.h> // for uint32_t 11 #include <type_traits> 12 #include "gfxTypes.h" 13 #include "FrameMetrics.h" 14 #include "LayersTypes.h" 15 #include "UnitTransforms.h" 16 #include "mozilla/gfx/CompositorHitTestInfo.h" 17 #include "mozilla/gfx/Point.h" 18 #include "mozilla/DefineEnum.h" 19 #include "mozilla/EnumSet.h" 20 #include "mozilla/FloatingPoint.h" 21 22 namespace mozilla { 23 24 struct ExternalPixel; 25 26 template <> 27 struct IsPixel<ExternalPixel> : std::true_type {}; 28 29 typedef gfx::CoordTyped<ExternalPixel> ExternalCoord; 30 typedef gfx::IntCoordTyped<ExternalPixel> ExternalIntCoord; 31 typedef gfx::PointTyped<ExternalPixel> ExternalPoint; 32 typedef gfx::IntPointTyped<ExternalPixel> ExternalIntPoint; 33 typedef gfx::SizeTyped<ExternalPixel> ExternalSize; 34 typedef gfx::IntSizeTyped<ExternalPixel> ExternalIntSize; 35 typedef gfx::RectTyped<ExternalPixel> ExternalRect; 36 typedef gfx::IntRectTyped<ExternalPixel> ExternalIntRect; 37 typedef gfx::MarginTyped<ExternalPixel> ExternalMargin; 38 typedef gfx::IntMarginTyped<ExternalPixel> ExternalIntMargin; 39 typedef gfx::IntRegionTyped<ExternalPixel> ExternalIntRegion; 40 41 typedef gfx::Matrix4x4Typed<ExternalPixel, ParentLayerPixel> 42 ExternalToParentLayerMatrix4x4; 43 44 struct ExternalPixel {}; 45 46 namespace layers { 47 48 class AsyncPanZoomController; 49 50 enum CancelAnimationFlags : uint32_t { 51 Default = 0x0, /* Cancel all animations */ 52 ExcludeOverscroll = 0x1, /* Don't clear overscroll */ 53 ScrollSnap = 0x2, /* Snap to snap points */ 54 ExcludeWheel = 0x4, /* Don't stop wheel smooth-scroll animations */ 55 TriggeredExternally = 0x8, /* Cancellation was not triggered by APZ in 56 response to an input event */ 57 }; 58 59 inline CancelAnimationFlags operator|(CancelAnimationFlags a, 60 CancelAnimationFlags b) { 61 return static_cast<CancelAnimationFlags>(static_cast<int>(a) | 62 static_cast<int>(b)); 63 } 64 65 typedef EnumSet<ScrollDirection> ScrollDirections; 66 67 // clang-format off 68 enum class ScrollSource { 69 // scrollTo() or something similar. 70 DOM, 71 72 // Touch-screen or trackpad with gesture support. 73 Touch, 74 75 // Mouse wheel. 76 Wheel, 77 78 // Keyboard 79 Keyboard, 80 }; 81 82 MOZ_DEFINE_ENUM_CLASS_WITH_BASE(APZWheelAction, uint8_t, ( 83 Scroll, 84 PinchZoom 85 )) 86 // clang-format on 87 88 // Epsilon to be used when comparing 'float' coordinate values 89 // with FuzzyEqualsAdditive. The rationale is that 'float' has 7 decimal 90 // digits of precision, and coordinate values should be no larger than in the 91 // ten thousands. Note also that the smallest legitimate difference in page 92 // coordinates is 1 app unit, which is 1/60 of a (CSS pixel), so this epsilon 93 // isn't too large. 94 const float COORDINATE_EPSILON = 0.01f; 95 96 template <typename Units> 97 static bool IsZero(const gfx::PointTyped<Units>& aPoint) { 98 return FuzzyEqualsAdditive(aPoint.x, 0.0f, COORDINATE_EPSILON) && 99 FuzzyEqualsAdditive(aPoint.y, 0.0f, COORDINATE_EPSILON); 100 } 101 102 // Deem an AsyncTransformComponentMatrix (obtained by multiplying together 103 // one or more AsyncTransformComponentMatrix objects) as constituting a 104 // complete async transform. 105 inline AsyncTransformMatrix CompleteAsyncTransform( 106 const AsyncTransformComponentMatrix& aMatrix) { 107 return ViewAs<AsyncTransformMatrix>( 108 aMatrix, PixelCastJustification::MultipleAsyncTransforms); 109 } 110 111 struct TargetConfirmationFlags final { 112 explicit TargetConfirmationFlags(bool aTargetConfirmed) 113 : mTargetConfirmed(aTargetConfirmed), 114 mRequiresTargetConfirmation(false) {} 115 116 explicit TargetConfirmationFlags( 117 const gfx::CompositorHitTestInfo& aHitTestInfo) 118 : mTargetConfirmed( 119 (aHitTestInfo != gfx::CompositorHitTestInvisibleToHit) && 120 (aHitTestInfo & gfx::CompositorHitTestDispatchToContent).isEmpty()), 121 mRequiresTargetConfirmation(aHitTestInfo.contains( 122 gfx::CompositorHitTestFlags::eRequiresTargetConfirmation)) {} 123 124 bool mTargetConfirmed : 1; 125 bool mRequiresTargetConfirmation : 1; 126 }; 127 128 enum class AsyncTransformComponent { eLayout, eVisual }; 129 130 using AsyncTransformComponents = EnumSet<AsyncTransformComponent>; 131 132 constexpr AsyncTransformComponents LayoutAndVisual( 133 AsyncTransformComponent::eLayout, AsyncTransformComponent::eVisual); 134 135 namespace apz { 136 137 /** 138 * Initializes the global state used in AsyncPanZoomController. 139 * This is normally called when it is first needed in the constructor 140 * of APZCTreeManager, but can be called manually to force it to be 141 * initialized earlier. 142 */ 143 void InitializeGlobalState(); 144 145 /** 146 * See AsyncPanZoomController::CalculatePendingDisplayPort. This 147 * function simply delegates to that one, so that non-layers code 148 * never needs to include AsyncPanZoomController.h 149 */ 150 const ScreenMargin CalculatePendingDisplayPort( 151 const FrameMetrics& aFrameMetrics, const ParentLayerPoint& aVelocity); 152 153 /** 154 * Is aAngle within the given threshold of the horizontal axis? 155 * @param aAngle an angle in radians in the range [0, pi] 156 * @param aThreshold an angle in radians in the range [0, pi/2] 157 */ 158 bool IsCloseToHorizontal(float aAngle, float aThreshold); 159 160 // As above, but for the vertical axis. 161 bool IsCloseToVertical(float aAngle, float aThreshold); 162 163 // Determine the amount of overlap between the 1D vector |aTranslation| 164 // and the interval [aMin, aMax]. 165 gfxFloat IntervalOverlap(gfxFloat aTranslation, gfxFloat aMin, gfxFloat aMax); 166 167 // Returns true if a sticky layer with async translation |aTranslation| is 168 // stuck with a bottom margin. The inner/outer ranges are produced by the main 169 // thread at the last paint, and so |aTranslation| only needs to be the 170 // async translation from the last paint. 171 bool IsStuckAtBottom(gfxFloat aTranslation, 172 const LayerRectAbsolute& aInnerRange, 173 const LayerRectAbsolute& aOuterRange); 174 175 // Returns true if a sticky layer with async translation |aTranslation| is 176 // stuck with a top margin. 177 bool IsStuckAtTop(gfxFloat aTranslation, const LayerRectAbsolute& aInnerRange, 178 const LayerRectAbsolute& aOuterRange); 179 180 } // namespace apz 181 182 } // namespace layers 183 } // namespace mozilla 184 185 #endif // mozilla_layers_APZUtils_h 186