Backed out 2 changesets (bug 1420996) for marionette failures.
authorNarcis Beleuzu <nbeleuzu@mozilla.com>
Thu, 30 Aug 2018 10:26:42 +0300
changeset 491800 fe26ccb3ec3b981c2321951df210402a6f58bff8
parent 491799 a278fa75aa70031a56ded21803f59868861cff23
child 491801 09de350001f07965f787c19f298fd0cd6cd839fa
child 491830 fb2c0eb9ad707ed11f05e7159ba3a132ead10879
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1420996
milestone63.0a1
backs out413bd039c1263f3b9cef04e19b538e8d4097b721
01ed229650de691ba2a555401d504fcb471e62fa
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 2 changesets (bug 1420996) for marionette failures. Backed out changeset 413bd039c126 (bug 1420996) Backed out changeset 01ed229650de (bug 1420996)
gfx/ipc/GfxMessageUtils.h
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZUtils.h
gfx/layers/apz/src/HitTestingTreeNode.cpp
gfx/layers/apz/test/gtest/TestEventRegions.cpp
gfx/layers/apz/testutil/APZTestData.cpp
gfx/layers/wr/WebRenderCommandBuilder.cpp
gfx/src/CompositorHitTestInfo.h
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/src/bindings.rs
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/painting/FrameLayerBuilder.cpp
layout/painting/nsDisplayList.cpp
mfbt/EnumSet.h
--- a/gfx/ipc/GfxMessageUtils.h
+++ b/gfx/ipc/GfxMessageUtils.h
@@ -15,16 +15,17 @@
 #include "chrome/common/ipc_message_utils.h"
 #include "gfxFeature.h"
 #include "gfxFallback.h"
 #include "gfxPoint.h"
 #include "gfxRect.h"
 #include "gfxTelemetry.h"
 #include "gfxTypes.h"
 #include "ipc/IPCMessageUtils.h"
+#include "mozilla/gfx/CompositorHitTestInfo.h"
 #include "mozilla/gfx/Matrix.h"
 #include "nsRect.h"
 #include "nsRegion.h"
 #include "mozilla/Array.h"
 
 #include <stdint.h>
 
 #ifdef _MSC_VER
@@ -944,11 +945,18 @@ struct ParamTraits<mozilla::Array<T, Len
       if (!ReadParam<T>(aMsg, aIter, &aResult->operator[](i))) {
         return false;
       }
     }
     return true;
   }
 };
 
+template <>
+struct ParamTraits<mozilla::gfx::CompositorHitTestInfo>
+  : public BitFlagsEnumSerializer<mozilla::gfx::CompositorHitTestInfo,
+                                  mozilla::gfx::CompositorHitTestInfo::ALL_BITS>
+{
+};
+
 } /* namespace IPC */
 
 #endif /* __GFXMESSAGEUTILS_H__ */
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -243,16 +243,17 @@ private:
 
 APZCTreeManager::APZCTreeManager(LayersId aRootLayersId)
     : mInputQueue(new InputQueue()),
       mRootLayersId(aRootLayersId),
       mSampler(nullptr),
       mUpdater(nullptr),
       mTreeLock("APZCTreeLock"),
       mMapLock("APZCMapLock"),
+      mHitResultForInputBlock(CompositorHitTestInfo::eInvisibleToHitTest),
       mRetainedTouchIdentifier(-1),
       mInScrollbarTouchDrag(false),
       mApzcTreeLog("apzctree"),
       mTestDataLock("APZTestDataLock"),
       mDPI(160.0)
 {
   RefPtr<APZCTreeManager> self(this);
   NS_DispatchToMainThread(
@@ -1172,17 +1173,17 @@ APZCTreeManager::ReceiveInputEvent(Input
 #endif // (MOZ_WIDGET_ANDROID)
 
   // Initialize aOutInputBlockId to a sane value, and then later we overwrite
   // it if the input event goes into a block.
   if (aOutInputBlockId) {
     *aOutInputBlockId = InputBlockState::NO_BLOCK_ID;
   }
   nsEventStatus result = nsEventStatus_eIgnore;
-  CompositorHitTestInfo hitResult = CompositorHitTestInvisibleToHit;
+  CompositorHitTestInfo hitResult = CompositorHitTestInfo::eInvisibleToHitTest;
   switch (aEvent.mInputType) {
     case MULTITOUCH_INPUT: {
       MultiTouchInput& touchInput = aEvent.AsMultiTouchInput();
       result = ProcessTouchInput(touchInput, aOutTargetGuid, aOutInputBlockId);
       break;
     } case MOUSE_INPUT: {
       MouseInput& mouseInput = aEvent.AsMouseInput();
       mouseInput.mHandledByAPZ = true;
@@ -1279,17 +1280,17 @@ APZCTreeManager::ReceiveInputEvent(Input
       wheelInput.mHandledByAPZ = WillHandleInput(wheelInput);
       if (!wheelInput.mHandledByAPZ) {
         return result;
       }
 
       RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(wheelInput.mOrigin,
                                                             &hitResult);
       if (apzc) {
-        MOZ_ASSERT(hitResult != CompositorHitTestInvisibleToHit);
+        MOZ_ASSERT(hitResult != CompositorHitTestInfo::eInvisibleToHitTest);
 
         if (wheelInput.mAPZAction == APZWheelAction::PinchZoom) {
           // The mousewheel may have hit a subframe, but we want to send the
           // pinch-zoom events to the root-content APZC.
           {
             RecursiveMutexAutoLock lock(mTreeLock);
             apzc = FindRootContentApzcForLayersId(apzc->GetLayersId());
           }
@@ -1344,17 +1345,17 @@ APZCTreeManager::ReceiveInputEvent(Input
       WidgetWheelEvent wheelEvent = panInput.ToWidgetWheelEvent(nullptr);
       EventStateManager::GetUserPrefsForWheelEvent(&wheelEvent,
         &panInput.mUserDeltaMultiplierX,
         &panInput.mUserDeltaMultiplierY);
 
       RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(panInput.mPanStartPoint,
                                                             &hitResult);
       if (apzc) {
-        MOZ_ASSERT(hitResult != CompositorHitTestInvisibleToHit);
+        MOZ_ASSERT(hitResult != CompositorHitTestInfo::eInvisibleToHitTest);
 
         // For pan gesture events, the call to ReceiveInputEvent below may result in
         // scrolling, which changes the async transform. However, the event we
         // want to pass to gecko should be the pre-scroll event coordinates,
         // transformed into the gecko space. (pre-scroll because the mouse
         // cursor is stationary during pan gesture scrolling, unlike touchmove
         // events). Since we just flushed the pending repaints the transform to
         // gecko space should only consist of overscroll-cancelling transforms.
@@ -1383,17 +1384,17 @@ APZCTreeManager::ReceiveInputEvent(Input
             apzc->OverscrollBehaviorAllowsSwipe();
       }
       break;
     } case PINCHGESTURE_INPUT: {  // note: no one currently sends these
       PinchGestureInput& pinchInput = aEvent.AsPinchGestureInput();
       RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(pinchInput.mFocusPoint,
                                                             &hitResult);
       if (apzc) {
-        MOZ_ASSERT(hitResult != CompositorHitTestInvisibleToHit);
+        MOZ_ASSERT(hitResult != CompositorHitTestInfo::eInvisibleToHitTest);
 
         ScreenToScreenMatrix4x4 outTransform = GetScreenToApzcTransform(apzc)
                                              * GetApzcToGeckoTransform(apzc);
         Maybe<ScreenPoint> untransformedFocusPoint = UntransformBy(
           outTransform, pinchInput.mFocusPoint);
 
         if (!untransformedFocusPoint) {
           return result;
@@ -1409,17 +1410,17 @@ APZCTreeManager::ReceiveInputEvent(Input
         pinchInput.mFocusPoint = *untransformedFocusPoint;
       }
       break;
     } case TAPGESTURE_INPUT: {  // note: no one currently sends these
       TapGestureInput& tapInput = aEvent.AsTapGestureInput();
       RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(tapInput.mPoint,
                                                             &hitResult);
       if (apzc) {
-        MOZ_ASSERT(hitResult != CompositorHitTestInvisibleToHit);
+        MOZ_ASSERT(hitResult != CompositorHitTestInfo::eInvisibleToHitTest);
 
         ScreenToScreenMatrix4x4 outTransform = GetScreenToApzcTransform(apzc)
                                              * GetApzcToGeckoTransform(apzc);
         Maybe<ScreenIntPoint> untransformedPoint =
           UntransformBy(outTransform, tapInput.mPoint);
 
         if (!untransformedPoint) {
           return result;
@@ -1524,38 +1525,38 @@ APZCTreeManager::ReceiveInputEvent(Input
 
       break;
     }
   }
   return result;
 }
 
 static TouchBehaviorFlags
-ConvertToTouchBehavior(const CompositorHitTestInfo& info)
+ConvertToTouchBehavior(CompositorHitTestInfo info)
 {
   TouchBehaviorFlags result = AllowedTouchBehavior::UNKNOWN;
-  if (info == CompositorHitTestInvisibleToHit) {
+  if (info == CompositorHitTestInfo::eInvisibleToHitTest) {
     result = AllowedTouchBehavior::NONE;
-  } else if (info.contains(CompositorHitTestFlags::eDispatchToContent)) {
+  } else if (info & CompositorHitTestInfo::eDispatchToContent) {
     result = AllowedTouchBehavior::UNKNOWN;
   } else {
     result = AllowedTouchBehavior::VERTICAL_PAN
            | AllowedTouchBehavior::HORIZONTAL_PAN
            | AllowedTouchBehavior::PINCH_ZOOM
            | AllowedTouchBehavior::DOUBLE_TAP_ZOOM;
-    if (info.contains(CompositorHitTestFlags::eTouchActionPanXDisabled)) {
+    if (info & CompositorHitTestInfo::eTouchActionPanXDisabled) {
       result &= ~AllowedTouchBehavior::HORIZONTAL_PAN;
     }
-    if (info.contains(CompositorHitTestFlags::eTouchActionPanYDisabled)) {
+    if (info & CompositorHitTestInfo::eTouchActionPanYDisabled) {
       result &= ~AllowedTouchBehavior::VERTICAL_PAN;
     }
-    if (info.contains(CompositorHitTestFlags::eTouchActionPinchZoomDisabled)) {
+    if (info & CompositorHitTestInfo::eTouchActionPinchZoomDisabled) {
       result &= ~AllowedTouchBehavior::PINCH_ZOOM;
     }
-    if (info.contains(CompositorHitTestFlags::eTouchActionDoubleTapZoomDisabled)) {
+    if (info & CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled) {
       result &= ~AllowedTouchBehavior::DOUBLE_TAP_ZOOM;
     }
   }
   return result;
 }
 
 already_AddRefed<AsyncPanZoomController>
 APZCTreeManager::GetTouchInputBlockAPZC(const MultiTouchInput& aEvent,
@@ -1616,17 +1617,17 @@ APZCTreeManager::ProcessTouchInput(Multi
         mApzcForInputBlock->IsInPanningState() &&
         BuildOverscrollHandoffChain(mApzcForInputBlock)->HasOverscrolledApzc()) {
       if (mRetainedTouchIdentifier == -1) {
         mRetainedTouchIdentifier = mApzcForInputBlock->GetLastTouchIdentifier();
       }
       return nsEventStatus_eConsumeNoDefault;
     }
 
-    mHitResultForInputBlock = CompositorHitTestInvisibleToHit;
+    mHitResultForInputBlock = CompositorHitTestInfo::eInvisibleToHitTest;
     mApzcForInputBlock = GetTouchInputBlockAPZC(aInput, &touchBehaviors,
         &mHitResultForInputBlock, &hitScrollbarNode);
 
     // Check if this event starts a scrollbar touch-drag. The conditions
     // checked are similar to the ones we check for MOUSE_INPUT starting
     // a scrollbar mouse-drag.
     mInScrollbarTouchDrag = gfxPrefs::APZDragEnabled() &&
                             gfxPrefs::APZTouchDragEnabled() && hitScrollbarNode &&
@@ -1675,17 +1676,17 @@ APZCTreeManager::ProcessTouchInput(Multi
         }
       }
       if (aInput.mTouches.IsEmpty()) {
         return nsEventStatus_eConsumeNoDefault;
       }
     }
 
     if (mApzcForInputBlock) {
-      MOZ_ASSERT(mHitResultForInputBlock != CompositorHitTestInvisibleToHit);
+      MOZ_ASSERT(mHitResultForInputBlock != CompositorHitTestInfo::eInvisibleToHitTest);
 
       mApzcForInputBlock->GetGuid(aOutTargetGuid);
       uint64_t inputBlockId = 0;
       result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock,
           TargetConfirmationFlags{mHitResultForInputBlock},
           aInput, &inputBlockId);
       if (aOutInputBlockId) {
         *aOutInputBlockId = inputBlockId;
@@ -1714,17 +1715,17 @@ APZCTreeManager::ProcessTouchInput(Multi
   }
 
   mTouchCounter.Update(aInput);
 
   // If it's the end of the touch sequence then clear out variables so we
   // don't keep dangling references and leak things.
   if (mTouchCounter.GetActiveTouchCount() == 0) {
     mApzcForInputBlock = nullptr;
-    mHitResultForInputBlock = CompositorHitTestInvisibleToHit;
+    mHitResultForInputBlock = CompositorHitTestInfo::eInvisibleToHitTest;
     mRetainedTouchIdentifier = -1;
     mInScrollbarTouchDrag = false;
   }
 
   return result;
 }
 
 MouseInput::MouseType
@@ -1968,23 +1969,23 @@ void
 APZCTreeManager::ProcessUnhandledEvent(LayoutDeviceIntPoint* aRefPoint,
                                         ScrollableLayerGuid*  aOutTargetGuid,
                                         uint64_t*             aOutFocusSequenceNumber)
 {
   APZThreadUtils::AssertOnControllerThread();
 
   // Transform the aRefPoint.
   // If the event hits an overscrolled APZC, instruct the caller to ignore it.
-  CompositorHitTestInfo hitResult = CompositorHitTestInvisibleToHit;
+  CompositorHitTestInfo hitResult = CompositorHitTestInfo::eInvisibleToHitTest;
   PixelCastJustification LDIsScreen = PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent;
   ScreenIntPoint refPointAsScreen =
     ViewAs<ScreenPixel>(*aRefPoint, LDIsScreen);
   RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(refPointAsScreen, &hitResult);
   if (apzc) {
-    MOZ_ASSERT(hitResult != CompositorHitTestInvisibleToHit);
+    MOZ_ASSERT(hitResult != CompositorHitTestInfo::eInvisibleToHitTest);
     apzc->GetGuid(aOutTargetGuid);
     ScreenToParentLayerMatrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
     ParentLayerToScreenMatrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
     ScreenToScreenMatrix4x4 outTransform = transformToApzc * transformToGecko;
     Maybe<ScreenIntPoint> untransformedRefPoint =
       UntransformBy(outTransform, refPointAsScreen);
     if (untransformedRefPoint) {
       *aRefPoint =
@@ -2464,17 +2465,17 @@ APZCTreeManager::GetTargetNode(const Scr
 
 already_AddRefed<AsyncPanZoomController>
 APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint,
                                CompositorHitTestInfo* aOutHitResult,
                                HitTestingTreeNodeAutoLock* aOutScrollbarNode)
 {
   RecursiveMutexAutoLock lock(mTreeLock);
 
-  CompositorHitTestInfo hitResult;
+  CompositorHitTestInfo hitResult = CompositorHitTestInfo::eInvisibleToHitTest;
   HitTestingTreeNode* scrollbarNode = nullptr;
   RefPtr<AsyncPanZoomController> target;
   if (gfx::gfxVars::UseWebRender()) {
     target = GetAPZCAtPointWR(aPoint, &hitResult, &scrollbarNode);
   } else {
     target = GetAPZCAtPoint(mRootNode, aPoint, &hitResult, &scrollbarNode);
   }
 
@@ -2500,17 +2501,17 @@ APZCTreeManager::GetAPZCAtPointWR(const 
   RefPtr<wr::WebRenderAPI> wr = GetWebRenderAPI();
   if (!wr) {
     // If WebRender isn't running, fall back to the root APZC.
     // This is mostly for the benefit of GTests which do not
     // run a WebRender instance, but gracefully falling back
     // here allows those tests which are not specifically
     // testing the hit-test algorithm to still work.
     result = FindRootApzcForLayersId(mRootLayersId);
-    *aOutHitResult = CompositorHitTestFlags::eVisibleToHitTest;
+    *aOutHitResult = CompositorHitTestInfo::eVisibleToHitTest;
     return result.forget();
   }
 
   wr::WrPipelineId pipelineId;
   FrameMetrics::ViewID scrollId;
   gfx::CompositorHitTestInfo hitInfo;
   bool hitSomething = wr->HitTest(wr::ToWorldPoint(aHitTestPoint),
       pipelineId, scrollId, hitInfo);
@@ -2522,19 +2523,19 @@ APZCTreeManager::GetAPZCAtPointWR(const 
   result = GetTargetAPZC(layersId, scrollId);
   if (!result) {
     // It falls back to the root
     MOZ_ASSERT(scrollId == FrameMetrics::NULL_SCROLL_ID);
     result = FindRootApzcForLayersId(layersId);
     MOZ_ASSERT(result);
   }
 
-  const bool isScrollbar = hitInfo.contains(gfx::CompositorHitTestFlags::eScrollbar);
-  const bool isScrollbarThumb = hitInfo.contains(gfx::CompositorHitTestFlags::eScrollbarThumb);
-  const ScrollDirection direction = hitInfo.contains(gfx::CompositorHitTestFlags::eScrollbarVertical)
+  bool isScrollbar = bool(hitInfo & gfx::CompositorHitTestInfo::eScrollbar);
+  bool isScrollbarThumb = bool(hitInfo & gfx::CompositorHitTestInfo::eScrollbarThumb);
+  ScrollDirection direction = (hitInfo & gfx::CompositorHitTestInfo::eScrollbarVertical)
                             ? ScrollDirection::eVertical
                             : ScrollDirection::eHorizontal;
   if (isScrollbar || isScrollbarThumb) {
     *aOutScrollbarNode = BreadthFirstSearch<ReverseIterator>(mRootNode.get(),
       [&](HitTestingTreeNode* aNode) {
         return (aNode->GetLayersId() == layersId) &&
                (aNode->IsScrollbarNode() == isScrollbar) &&
                (aNode->IsScrollThumbNode() == isScrollbarThumb) &&
@@ -2694,36 +2695,36 @@ APZCTreeManager::GetAPZCAtPoint(HitTesti
         hitTestPoints.push(hitTestPoint.ref());
         return TraversalFlag::Continue;
       },
       [&resultNode, &hitTestPoints, &aOutHitResult](HitTestingTreeNode* aNode) {
         CompositorHitTestInfo hitResult = aNode->HitTest(hitTestPoints.top());
         hitTestPoints.pop();
         APZCTM_LOG("Testing Layer point %s against node %p\n",
                 Stringify(hitTestPoints.top()).c_str(), aNode);
-        if (hitResult != CompositorHitTestInvisibleToHit) {
+        if (hitResult != CompositorHitTestInfo::eInvisibleToHitTest) {
           resultNode = aNode;
           *aOutHitResult = hitResult;
           return TraversalFlag::Abort;
         }
         return TraversalFlag::Continue;
       }
   );
 
-  if (*aOutHitResult != CompositorHitTestInvisibleToHit) {
+  if (*aOutHitResult != CompositorHitTestInfo::eInvisibleToHitTest) {
     MOZ_ASSERT(resultNode);
     for (HitTestingTreeNode* n = resultNode; n; n = n->GetParent()) {
       if (n->IsScrollbarNode()) {
         *aOutScrollbarNode = n;
-        *aOutHitResult += CompositorHitTestFlags::eScrollbar;
+        *aOutHitResult |= CompositorHitTestInfo::eScrollbar;
         if (n->IsScrollThumbNode()) {
-          *aOutHitResult += CompositorHitTestFlags::eScrollbarThumb;
+          *aOutHitResult |= CompositorHitTestInfo::eScrollbarThumb;
         }
         if (n->GetScrollbarDirection() == ScrollDirection::eVertical) {
-          *aOutHitResult += CompositorHitTestFlags::eScrollbarVertical;
+          *aOutHitResult |= CompositorHitTestInfo::eScrollbarVertical;
         }
 
         // If we hit a scrollbar, target the APZC for the content scrolled
         // by the scrollbar. (The scrollbar itself doesn't scroll with the
         // scrolled content, so it doesn't carry the scrolled content's
         // scroll metadata).
         RefPtr<AsyncPanZoomController> scrollTarget =
             GetTargetAPZC(n->GetLayersId(), n->GetScrollTargetId());
--- a/gfx/layers/apz/src/APZUtils.h
+++ b/gfx/layers/apz/src/APZUtils.h
@@ -85,20 +85,20 @@ CompleteAsyncTransform(const AsyncTransf
 }
 
 struct TargetConfirmationFlags {
   explicit TargetConfirmationFlags(bool aTargetConfirmed)
     : mTargetConfirmed(aTargetConfirmed)
     , mRequiresTargetConfirmation(false)
   {}
 
-  explicit TargetConfirmationFlags(const gfx::CompositorHitTestInfo& aHitTestInfo)
-    : mTargetConfirmed((aHitTestInfo != gfx::CompositorHitTestInvisibleToHit) &&
-                       !aHitTestInfo.contains(gfx::CompositorHitTestFlags::eDispatchToContent))
-    , mRequiresTargetConfirmation(aHitTestInfo.contains(gfx::CompositorHitTestFlags::eRequiresTargetConfirmation))
+  explicit TargetConfirmationFlags(gfx::CompositorHitTestInfo aHitTestInfo)
+    : mTargetConfirmed(aHitTestInfo != gfx::CompositorHitTestInfo::eInvisibleToHitTest &&
+                       !(aHitTestInfo & gfx::CompositorHitTestInfo::eDispatchToContent))
+    , mRequiresTargetConfirmation(aHitTestInfo & gfx::CompositorHitTestInfo::eRequiresTargetConfirmation)
   {}
 
   bool mTargetConfirmed : 1;
   bool mRequiresTargetConfirmation : 1;
 };
 
 /**
  * An RAII class to temporarily apply async test attributes to the provided
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -13,19 +13,16 @@
 #include "mozilla/layers/AsyncDragMetrics.h"            // for AsyncDragMetrics
 #include "nsPrintfCString.h"                            // for nsPrintfCString
 #include "UnitTransforms.h"                             // for ViewAs
 
 namespace mozilla {
 namespace layers {
 
 using gfx::CompositorHitTestInfo;
-using gfx::CompositorHitTestFlags;
-using gfx::CompositorHitTestTouchActionMask;
-using gfx::CompositorHitTestInvisibleToHit;
 
 HitTestingTreeNode::HitTestingTreeNode(AsyncPanZoomController* aApzc,
                                        bool aIsPrimaryHolder,
                                        LayersId aLayersId)
   : mApzc(aApzc)
   , mIsPrimaryApzcHolder(aIsPrimaryHolder)
   , mLockCount(0)
   , mLayersId(aLayersId)
@@ -289,17 +286,17 @@ HitTestingTreeNode::Untransform(const Pa
     return UntransformBy(inverse.ref(), aPoint);
   }
   return Nothing();
 }
 
 CompositorHitTestInfo
 HitTestingTreeNode::HitTest(const LayerPoint& aPoint) const
 {
-  CompositorHitTestInfo result = CompositorHitTestInvisibleToHit;
+  CompositorHitTestInfo result = CompositorHitTestInfo::eInvisibleToHitTest;
 
   if (mOverride & EventRegionsOverride::ForceEmptyHitRegion) {
     return result;
   }
 
   auto point = LayerIntPoint::Round(aPoint);
 
   // If the layer's backface is showing and it's hidden, don't hit it.
@@ -309,46 +306,46 @@ HitTestingTreeNode::HitTest(const LayerP
     return result;
   }
 
   // test against event regions in Layer coordinate space
   if (!mEventRegions.mHitRegion.Contains(point.x, point.y)) {
     return result;
   }
 
-  result = CompositorHitTestFlags::eVisibleToHitTest;
+  result |= CompositorHitTestInfo::eVisibleToHitTest;
 
   if ((mOverride & EventRegionsOverride::ForceDispatchToContent) ||
       mEventRegions.mDispatchToContentHitRegion.Contains(point.x, point.y))
   {
-    result += CompositorHitTestFlags::eDispatchToContent;
+    result |= CompositorHitTestInfo::eDispatchToContent;
     if (mEventRegions.mDTCRequiresTargetConfirmation) {
-      result += CompositorHitTestFlags::eRequiresTargetConfirmation;
+      result |= CompositorHitTestInfo::eRequiresTargetConfirmation;
     }
   } else if (gfxPrefs::TouchActionEnabled()) {
     if (mEventRegions.mNoActionRegion.Contains(point.x, point.y)) {
       // set all the touch-action flags as disabled
-      result += CompositorHitTestTouchActionMask;
+      result |= CompositorHitTestInfo::eTouchActionMask;
     } else {
       bool panX = mEventRegions.mHorizontalPanRegion.Contains(point.x, point.y);
       bool panY = mEventRegions.mVerticalPanRegion.Contains(point.x, point.y);
       if (panX && panY) {
         // touch-action: pan-x pan-y
-        result += CompositorHitTestFlags::eTouchActionDoubleTapZoomDisabled;
-        result += CompositorHitTestFlags::eTouchActionPinchZoomDisabled;
+        result |= CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled
+                | CompositorHitTestInfo::eTouchActionPinchZoomDisabled;
       } else if (panX) {
         // touch-action: pan-x
-        result += CompositorHitTestFlags::eTouchActionPanYDisabled;
-        result += CompositorHitTestFlags::eTouchActionPinchZoomDisabled;
-        result += CompositorHitTestFlags::eTouchActionDoubleTapZoomDisabled;
+        result |= CompositorHitTestInfo::eTouchActionPanYDisabled
+                | CompositorHitTestInfo::eTouchActionPinchZoomDisabled
+                | CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled;
       } else if (panY) {
         // touch-action: pan-y
-        result += CompositorHitTestFlags::eTouchActionPanXDisabled;
-        result += CompositorHitTestFlags::eTouchActionPinchZoomDisabled;
-        result += CompositorHitTestFlags::eTouchActionDoubleTapZoomDisabled;
+        result |= CompositorHitTestInfo::eTouchActionPanXDisabled
+                | CompositorHitTestInfo::eTouchActionPinchZoomDisabled
+                | CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled;
       } // else we're in the touch-action: auto or touch-action: manipulation
         // cases and we'll allow all actions. Technically we shouldn't allow
         // double-tap zooming in the manipulation case but apparently this has
         // been broken since the dawn of time.
     }
   }
 
   // The scrollbar flags are set at the call site in GetAPZCAtPoint, because
--- a/gfx/layers/apz/test/gtest/TestEventRegions.cpp
+++ b/gfx/layers/apz/test/gtest/TestEventRegions.cpp
@@ -238,28 +238,28 @@ TEST_F(APZEventRegionsTester, Obscuratio
   RefPtr<TestAsyncPanZoomController> parent = ApzcOf(layers[1]);
   TestAsyncPanZoomController* child = ApzcOf(layers[2]);
 
   Pan(parent, 75, 25, PanOptions::NoFling);
 
   gfx::CompositorHitTestInfo result;
   RefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(ScreenPoint(50, 75), &result);
   EXPECT_EQ(child, hit.get());
-  EXPECT_EQ(result, CompositorHitTestFlags::eVisibleToHitTest);
+  EXPECT_EQ(CompositorHitTestInfo::eVisibleToHitTest, result);
 }
 
 TEST_F(APZEventRegionsTester, Bug1119497) {
   CreateBug1119497LayerTree();
 
   gfx::CompositorHitTestInfo result;
   RefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(ScreenPoint(50, 50), &result);
   // We should hit layers[2], so |result| will be eVisibleToHitTest but there's no
   // actual APZC on layers[2], so it will be the APZC of the root layer.
   EXPECT_EQ(ApzcOf(layers[0]), hit.get());
-  EXPECT_EQ(result, CompositorHitTestFlags::eVisibleToHitTest);
+  EXPECT_EQ(CompositorHitTestInfo::eVisibleToHitTest, result);
 }
 
 TEST_F(APZEventRegionsTester, Bug1117712) {
   CreateBug1117712LayerTree();
 
   TestAsyncPanZoomController* apzc2 = ApzcOf(layers[2]);
 
   // These touch events should hit the dispatch-to-content region of layers[3]
--- a/gfx/layers/apz/testutil/APZTestData.cpp
+++ b/gfx/layers/apz/testutil/APZTestData.cpp
@@ -64,20 +64,19 @@ struct APZTestDataToJSConverter {
   static void ConvertString(const std::string& aFrom, nsString& aOutTo) {
     aOutTo = NS_ConvertUTF8toUTF16(aFrom.c_str(), aFrom.size());
   }
 
   static void ConvertHitResult(const APZTestData::HitResult& aResult,
                                dom::APZHitResult& aOutHitResult) {
     aOutHitResult.mScreenX.Construct() = aResult.point.x;
     aOutHitResult.mScreenY.Construct() = aResult.point.y;
-    static_assert(MaxEnumValue<CompositorHitTestInfo::valueType>::value
-                  < std::numeric_limits<uint16_t>::digits,
-                  "CompositorHitTestFlags MAX value have to be less than number of bits in uint16_t");
-    aOutHitResult.mHitResult.Construct() = static_cast<uint16_t>(aResult.result.serialize());
+    static_assert(sizeof(aResult.result) == sizeof(uint16_t),
+        "Expected CompositorHitTestInfo to be 16-bit");
+    aOutHitResult.mHitResult.Construct() = static_cast<uint16_t>(aResult.result);
     aOutHitResult.mScrollId.Construct() = aResult.scrollId;
   }
 };
 
 bool
 APZTestData::ToJS(JS::MutableHandleValue aOutValue, JSContext* aContext) const
 {
   dom::APZTestData result;
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -696,18 +696,18 @@ struct DIGroup
   void PushImage(wr::DisplayListBuilder& aBuilder, const LayoutDeviceRect& bounds)
   {
     wr::LayoutRect dest = wr::ToLayoutRect(bounds);
     GP("PushImage: %f %f %f %f\n", dest.origin.x, dest.origin.y, dest.size.width, dest.size.height);
     gfx::SamplingFilter sampleFilter = gfx::SamplingFilter::LINEAR; //nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
     bool backfaceHidden = false;
 
     // Emit a dispatch-to-content hit test region covering this area
-    CompositorHitTestInfo hitInfo(CompositorHitTestFlags::eVisibleToHitTest,
-                                  CompositorHitTestFlags::eDispatchToContent);
+    auto hitInfo = CompositorHitTestInfo::eVisibleToHitTest |
+                   CompositorHitTestInfo::eDispatchToContent;
 
     // XXX - clipping the item against the paint rect breaks some content.
     // cf. Bug 1455422.
     //wr::LayoutRect clip = wr::ToLayoutRect(bounds.Intersect(mPaintRect));
 
     aBuilder.SetHitTestInfo(mScrollId, hitInfo);
     aBuilder.PushImage(dest, dest, !backfaceHidden,
                        wr::ToImageRendering(sampleFilter),
--- a/gfx/src/CompositorHitTestInfo.h
+++ b/gfx/src/CompositorHitTestInfo.h
@@ -2,90 +2,64 @@
 /* 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/. */
 
 #ifndef MOZILLA_GFX_COMPOSITORHITTESTINFO_H_
 #define MOZILLA_GFX_COMPOSITORHITTESTINFO_H_
 
-#include "mozilla/EnumSet.h"
-#include "mozilla/EnumTypeTraits.h"
+#include "mozilla/TypedEnumBits.h"
 
 namespace mozilla {
 namespace gfx {
 
 // This set of flags is used to figure out what information a frame has
 // that is relevant to hit-testing in the compositor. The flags are
 // intentionally set up so that if all of them are 0 the item is effectively
 // invisible to hit-testing, and no information for this frame needs to be
 // sent to the compositor.
-enum class CompositorHitTestFlags : uint8_t {
+enum class CompositorHitTestInfo : uint16_t {
+  // Shortcut for checking that none of the flags are set
+  eInvisibleToHitTest = 0,
+
   // The frame participates in hit-testing
-  eVisibleToHitTest = 0,
+  eVisibleToHitTest = 1 << 0,
   // The frame requires main-thread handling for events
-  eDispatchToContent,
+  eDispatchToContent = 1 << 1,
 
   // The touch action flags are set up so that the default of
   // touch-action:auto on an element leaves all the flags as 0.
-  eTouchActionPanXDisabled,
-  eTouchActionPanYDisabled,
-  eTouchActionPinchZoomDisabled,
-  eTouchActionDoubleTapZoomDisabled,
+  eTouchActionPanXDisabled = 1 << 2,
+  eTouchActionPanYDisabled = 1 << 3,
+  eTouchActionPinchZoomDisabled = 1 << 4,
+  eTouchActionDoubleTapZoomDisabled = 1 << 5,
+  // Mask to check for all the touch-action flags at once
+  eTouchActionMask = (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5),
 
   // The frame is a scrollbar or a subframe inside a scrollbar (including
   // scroll thumbs)
-  eScrollbar,
+  eScrollbar = 1 << 6,
   // The frame is a scrollthumb. If this is set then eScrollbar will also be
   // set, unless gecko somehow generates a scroll thumb without a containing
   // scrollbar.
-  eScrollbarThumb,
+  eScrollbarThumb = 1 << 7,
   // If eScrollbar is set, this flag indicates if the scrollbar is a vertical
   // one (if set) or a horizontal one (if not set)
-  eScrollbarVertical,
+  eScrollbarVertical = 1 << 8,
 
   // Events targeting this frame should only be processed if a target
   // confirmation is received from the main thread. If no such confirmation
   // is received within a timeout period, the event may be dropped.
   // Only meaningful in combination with eDispatchToContent.
-  eRequiresTargetConfirmation,
+  eRequiresTargetConfirmation = 1 << 9,
+
+  // Used for IPDL serialization. This bitmask should include all the bits
+  // that are defined in the enum.
+  ALL_BITS = (1 << 10) - 1,
 };
 
-using CompositorHitTestInfo = EnumSet<CompositorHitTestFlags>;
-
-// A CompositorHitTestInfo with none of the flags set
-const CompositorHitTestInfo CompositorHitTestInvisibleToHit;
-
-// Mask to check for all the touch-action flags at once
-const CompositorHitTestInfo CompositorHitTestTouchActionMask =
-  CompositorHitTestInfo(CompositorHitTestFlags::eTouchActionPanXDisabled) +
-  CompositorHitTestInfo(CompositorHitTestFlags::eTouchActionPanYDisabled) +
-  CompositorHitTestInfo(CompositorHitTestFlags::eTouchActionPinchZoomDisabled) +
-  CompositorHitTestInfo(CompositorHitTestFlags::eTouchActionDoubleTapZoomDisabled);
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CompositorHitTestInfo)
 
 } // namespace gfx
-
-
-// Used for IPDL serialization. The 'value' have to be the biggest enum from CompositorHitTestFlags.
-template <>
-struct MaxEnumValue<::mozilla::gfx::CompositorHitTestFlags>
-{
-  static constexpr unsigned int value = static_cast<unsigned int>(gfx::CompositorHitTestFlags::eRequiresTargetConfirmation);
-};
-
-namespace gfx {
-
-// Checks if the CompositorHitTestFlags max enum value is less than N.
-template <int N>
-static constexpr bool DoesCompositorHitTestInfoFitIntoBits()
-{
-    if (MaxEnumValue<CompositorHitTestInfo::valueType>::value < N)
-    {
-        return true;
-    }
-
-    return false;
-}
-} // namespace gfx
-
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_COMPOSITORHITTESTINFO_H_ */
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -359,27 +359,20 @@ WebRenderAPI::SendTransaction(Transactio
 }
 
 bool
 WebRenderAPI::HitTest(const wr::WorldPoint& aPoint,
                       wr::WrPipelineId& aOutPipelineId,
                       layers::FrameMetrics::ViewID& aOutScrollId,
                       gfx::CompositorHitTestInfo& aOutHitInfo)
 {
-  static_assert(DoesCompositorHitTestInfoFitIntoBits<16>(),
-                "CompositorHitTestFlags MAX value has to be less than number of bits in uint16_t");
-
-  uint16_t serialized = static_cast<uint16_t>(aOutHitInfo.serialize());
-  const bool result = wr_api_hit_test(mDocHandle, aPoint,
-    &aOutPipelineId, &aOutScrollId, &serialized);
-
-  if (result) {
-    aOutHitInfo.deserialize(serialized);
-  }
-  return result;
+  static_assert(sizeof(gfx::CompositorHitTestInfo) == sizeof(uint16_t),
+                "CompositorHitTestInfo should be u16-sized");
+  return wr_api_hit_test(mDocHandle, aPoint,
+          &aOutPipelineId, &aOutScrollId, (uint16_t*)&aOutHitInfo);
 }
 
 void
 WebRenderAPI::Readback(const TimeStamp& aStartTime,
                        gfx::IntSize size,
                        uint8_t *buffer,
                        uint32_t buffer_size)
 {
@@ -1284,20 +1277,19 @@ DisplayListBuilder::GetContainingFixedPo
       ? mActiveFixedPosTracker->GetScrollTargetForASR(aAsr)
       : Nothing();
 }
 
 void
 DisplayListBuilder::SetHitTestInfo(const layers::FrameMetrics::ViewID& aScrollId,
                                    gfx::CompositorHitTestInfo aHitInfo)
 {
-  static_assert(DoesCompositorHitTestInfoFitIntoBits<16>(),
-                "CompositorHitTestFlags MAX value has to be less than number of bits in uint16_t");
-
-  wr_set_item_tag(mWrState, aScrollId, static_cast<uint16_t>(aHitInfo.serialize()));
+  static_assert(sizeof(gfx::CompositorHitTestInfo) == sizeof(uint16_t),
+                "CompositorHitTestInfo should be u16-sized");
+  wr_set_item_tag(mWrState, aScrollId, static_cast<uint16_t>(aHitInfo));
 }
 
 void
 DisplayListBuilder::ClearHitTestInfo()
 {
   wr_clear_item_tag(mWrState);
 }
 
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -2424,18 +2424,18 @@ pub extern "C" fn wr_clear_item_tag(stat
 pub extern "C" fn wr_api_hit_test(dh: &mut DocumentHandle,
                                   point: WorldPoint,
                                   out_pipeline_id: &mut WrPipelineId,
                                   out_scroll_id: &mut u64,
                                   out_hit_info: &mut u16) -> bool {
     let result = dh.api.hit_test(dh.document_id, None, point, HitTestFlags::empty());
     for item in &result.items {
         // For now we should never be getting results back for which the tag is
-        // 0 (== CompositorHitTestInvisibleToHit). In the future if we allow this,
-        // we'll want to |continue| on the loop in this scenario.
+        // 0 (== CompositorHitTestInfo::eInvisibleToHitTest). In the future if
+        // we allow this, we'll want to |continue| on the loop in this scenario.
         debug_assert!(item.tag.1 != 0);
         *out_pipeline_id = item.pipeline;
         *out_scroll_id = item.tag.0;
         *out_hit_info = item.tag.1;
         return true;
     }
     return false;
 }
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -11236,17 +11236,17 @@ nsIFrame::AddSizeOfExcludingThisForTree(
     }
     iter.Next();
   }
 }
 
 CompositorHitTestInfo
 nsIFrame::GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder)
 {
-  CompositorHitTestInfo result = CompositorHitTestInvisibleToHit;
+  CompositorHitTestInfo result = CompositorHitTestInfo::eInvisibleToHitTest;
 
   if (aBuilder->IsInsidePointerEventsNoneDoc()) {
     // Somewhere up the parent document chain is a subdocument with pointer-
     // events:none set on it.
     return result;
   }
   if (!GetParent()) {
     MOZ_ASSERT(IsViewportFrame());
@@ -11258,110 +11258,111 @@ nsIFrame::GetCompositorHitTestInfo(nsDis
   if (pointerEvents == NS_STYLE_POINTER_EVENTS_NONE) {
     return result;
   }
   if (!StyleVisibility()->IsVisible()) {
     return result;
   }
 
   // Anything that didn't match the above conditions is visible to hit-testing.
-  result = CompositorHitTestFlags::eVisibleToHitTest;
+  result |= CompositorHitTestInfo::eVisibleToHitTest;
 
   if (aBuilder->IsBuildingNonLayerizedScrollbar() ||
       aBuilder->GetAncestorHasApzAwareEventHandler()) {
     // Scrollbars may be painted into a layer below the actual layer they will
     // scroll, and therefore wheel events may be dispatched to the outer frame
     // instead of the intended scrollframe. To address this, we force a d-t-c
     // region on scrollbar frames that won't be placed in their own layer. See
     // bug 1213324 for details.
-    result += CompositorHitTestFlags::eDispatchToContent;
+    result |= CompositorHitTestInfo::eDispatchToContent;
   } else if (IsObjectFrame()) {
     // If the frame is a plugin frame and wants to handle wheel events as
     // default action, we should add the frame to dispatch-to-content region.
     nsPluginFrame* pluginFrame = do_QueryFrame(this);
     if (pluginFrame && pluginFrame->WantsToHandleWheelEventAsDefaultAction()) {
-      result += CompositorHitTestFlags::eDispatchToContent;
+      result |= CompositorHitTestInfo::eDispatchToContent;
     }
   }
 
   nsIDocShell* docShell = nullptr;
   if (PresShell()->GetDocument()) {
     docShell = PresShell()->GetDocument()->GetDocShell();
   }
   if (dom::TouchEvent::PrefEnabled(docShell)) {
     // Inherit the touch-action flags from the parent, if there is one. We do this
     // because of how the touch-action on a frame combines the touch-action from
     // ancestor DOM elements. Refer to the documentation in TouchActionHelper.cpp
     // for details; this code is meant to be equivalent to that code, but woven
     // into the top-down recursive display list building process.
-    CompositorHitTestInfo inheritedTouchAction = CompositorHitTestInvisibleToHit;
+    CompositorHitTestInfo inheritedTouchAction = CompositorHitTestInfo::eInvisibleToHitTest;
     if (nsDisplayCompositorHitTestInfo* parentInfo = aBuilder->GetCompositorHitTestInfo()) {
-      inheritedTouchAction = parentInfo->HitTestInfo() & CompositorHitTestTouchActionMask;
+      inheritedTouchAction = (parentInfo->HitTestInfo() & CompositorHitTestInfo::eTouchActionMask);
     }
 
     nsIFrame* touchActionFrame = this;
     if (nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(this)) {
       touchActionFrame = do_QueryFrame(scrollFrame);
       // On scrollframes, stop inheriting the pan-x and pan-y flags; instead,
       // reset them back to zero to allow panning on the scrollframe unless we
       // encounter an element that disables it that's inside the scrollframe.
       // This is equivalent to the |considerPanning| variable in
       // TouchActionHelper.cpp, but for a top-down traversal.
-      CompositorHitTestInfo panMask(CompositorHitTestFlags::eTouchActionPanXDisabled,
-                                    CompositorHitTestFlags::eTouchActionPanYDisabled);
-      inheritedTouchAction -= panMask;
-    }
-
-    result += inheritedTouchAction;
+      CompositorHitTestInfo panMask = CompositorHitTestInfo::eTouchActionPanXDisabled
+                                    | CompositorHitTestInfo::eTouchActionPanYDisabled;
+      inheritedTouchAction &= ~panMask;
+    }
+
+    result |= inheritedTouchAction;
 
     const uint32_t touchAction = nsLayoutUtils::GetTouchActionFromFrame(touchActionFrame);
     // The CSS allows the syntax auto | none | [pan-x || pan-y] | manipulation
     // so we can eliminate some combinations of things.
     if (touchAction == NS_STYLE_TOUCH_ACTION_AUTO) {
       // nothing to do
     } else if (touchAction & NS_STYLE_TOUCH_ACTION_MANIPULATION) {
-      result += CompositorHitTestFlags::eTouchActionDoubleTapZoomDisabled;
+      result |= CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled;
     } else {
       // This path handles the cases none | [pan-x || pan-y] and so both
       // double-tap and pinch zoom are disabled in here.
-      result += CompositorHitTestFlags::eTouchActionPinchZoomDisabled;
-      result += CompositorHitTestFlags::eTouchActionDoubleTapZoomDisabled;
+      result |= CompositorHitTestInfo::eTouchActionPinchZoomDisabled
+              | CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled;
 
       if (!(touchAction & NS_STYLE_TOUCH_ACTION_PAN_X)) {
-        result += CompositorHitTestFlags::eTouchActionPanXDisabled;
+        result |= CompositorHitTestInfo::eTouchActionPanXDisabled;
       }
       if (!(touchAction & NS_STYLE_TOUCH_ACTION_PAN_Y)) {
-        result += CompositorHitTestFlags::eTouchActionPanYDisabled;
+        result |= CompositorHitTestInfo::eTouchActionPanYDisabled;
       }
       if (touchAction & NS_STYLE_TOUCH_ACTION_NONE) {
         // all the touch-action disabling flags will already have been set above
-        MOZ_ASSERT(result.contains(CompositorHitTestTouchActionMask));
+        MOZ_ASSERT((result & CompositorHitTestInfo::eTouchActionMask)
+                 == CompositorHitTestInfo::eTouchActionMask);
       }
     }
   }
 
   const Maybe<ScrollDirection> scrollDirection = aBuilder->GetCurrentScrollbarDirection();
   if (scrollDirection.isSome()) {
     if (GetContent()->IsXULElement(nsGkAtoms::thumb)) {
       const bool thumbGetsLayer = aBuilder->GetCurrentScrollbarTarget() !=
           layers::FrameMetrics::NULL_SCROLL_ID;
       if (thumbGetsLayer) {
-        result += CompositorHitTestFlags::eScrollbarThumb;
+        result |= CompositorHitTestInfo::eScrollbarThumb;
       } else {
-        result += CompositorHitTestFlags::eDispatchToContent;
+        result |= CompositorHitTestInfo::eDispatchToContent;
       }
     }
 
     if (*scrollDirection == ScrollDirection::eVertical) {
-      result += CompositorHitTestFlags::eScrollbarVertical;
+      result |= CompositorHitTestInfo::eScrollbarVertical;
     }
 
     // includes the ScrollbarFrame, SliderFrame, anything else that
     // might be inside the xul:scrollbar
-    result += CompositorHitTestFlags::eScrollbar;
+    result |= CompositorHitTestInfo::eScrollbar;
   }
 
   return result;
 }
 
 // Returns true if we can guarantee there is no visible descendants.
 static bool
 HasNoVisibleDescendants(const nsIFrame* aFrame)
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3646,17 +3646,17 @@ ScrollFrameHelper::BuildDisplayList(nsDi
 
     if (mWillBuildScrollableLayer) {
       // Create a hit test info item for the scrolled content that's not
       // clipped to the displayport. This ensures that within the bounds
       // of the scroll frame, the scrolled content is always hit, even
       // if we are checkerboarding.
       if (aBuilder->BuildCompositorHitTestInfo()) {
         CompositorHitTestInfo info = mScrolledFrame->GetCompositorHitTestInfo(aBuilder);
-        if (info != CompositorHitTestInvisibleToHit) {
+        if (info != CompositorHitTestInfo::eInvisibleToHitTest) {
           nsDisplayCompositorHitTestInfo* hitInfo =
               MakeDisplayItem<nsDisplayCompositorHitTestInfo>(aBuilder, mScrolledFrame, info, 1);
           aBuilder->SetCompositorHitTestInfo(hitInfo);
           scrolledContent.BorderBackground()->AppendToTop(hitInfo);
         }
       }
     }
 
@@ -3754,28 +3754,28 @@ ScrollFrameHelper::BuildDisplayList(nsDi
     aBuilder->ForceLayerForScrollParent();
   }
 
   if (couldBuildLayer) {
     // Make sure that APZ will dispatch events back to content so we can create
     // a displayport for this frame. We'll add the item later on.
     if (!mWillBuildScrollableLayer) {
       if (aBuilder->BuildCompositorHitTestInfo()) {
-        CompositorHitTestInfo info(CompositorHitTestFlags::eVisibleToHitTest,
-                                   CompositorHitTestFlags::eDispatchToContent);
+        CompositorHitTestInfo info = CompositorHitTestInfo::eVisibleToHitTest
+                                   | CompositorHitTestInfo::eDispatchToContent;
         // If the scroll frame has non-default overscroll-behavior, instruct
         // APZ to require a target confirmation before processing events that
         // hit this scroll frame (that is, to drop the events if a confirmation
         // does not arrive within the timeout period). Otherwise, APZ's
         // fallback behaviour of scrolling the enclosing scroll frame would
         // violate the specified overscroll-behavior.
         ScrollStyles scrollStyles = GetScrollStylesFromFrame();
         if (scrollStyles.mOverscrollBehaviorX != StyleOverscrollBehavior::Auto ||
             scrollStyles.mOverscrollBehaviorY != StyleOverscrollBehavior::Auto) {
-          info += CompositorHitTestFlags::eRequiresTargetConfirmation;
+          info |= CompositorHitTestInfo::eRequiresTargetConfirmation;
         }
         nsDisplayCompositorHitTestInfo* hitInfo =
             MakeDisplayItem<nsDisplayCompositorHitTestInfo>(aBuilder, mScrolledFrame, info, 1,
                 Some(mScrollPort + aBuilder->ToReferenceFrame(mOuter)));
         AppendInternalItemToTop(scrolledContent, hitInfo, Some(INT32_MAX));
       }
     }
 
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -4057,35 +4057,35 @@ PaintedLayerData::AccumulateHitTestInfo(
   }
 
   if (hasRoundedCorners || (frame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
     mMaybeHitRegion.OrWith(area);
   } else {
     mHitRegion.OrWith(area);
   }
 
-  if (aItem->HitTestInfo().contains(CompositorHitTestFlags::eDispatchToContent)) {
+  if (aItem->HitTestInfo() & CompositorHitTestInfo::eDispatchToContent) {
     mDispatchToContentHitRegion.OrWith(area);
 
-    if (aItem->HitTestInfo().contains(CompositorHitTestFlags::eRequiresTargetConfirmation)) {
+    if (aItem->HitTestInfo() & CompositorHitTestInfo::eRequiresTargetConfirmation) {
       mDTCRequiresTargetConfirmation = true;
     }
   }
 
-  const auto touchFlags = hitTestInfo & CompositorHitTestTouchActionMask;
-  if (!touchFlags.isEmpty()) {
+  auto touchFlags = hitTestInfo & CompositorHitTestInfo::eTouchActionMask;
+  if (touchFlags) {
     // If there are multiple touch-action areas, there are multiple elements with
     // touch-action properties. We don't know what the relationship is between
     // those elements in terms of DOM ancestry, and so we don't know how to
     // combine the regions properly. Instead, we just add all the areas to the
     // dispatch-to-content region, so that the APZ knows to check with the
     // main thread. See bug 1286957.
     if (mCollapsedTouchActions) {
       mDispatchToContentHitRegion.OrWith(area);
-    } else if (touchFlags == CompositorHitTestTouchActionMask) {
+    } else if (touchFlags == CompositorHitTestInfo::eTouchActionMask) {
       // everything was disabled, so touch-action:none
       mNoActionRegion.OrWith(area);
     } else {
       // The event regions code does not store enough information to actually
       // represent all the different states. Prior to the introduction of
       // CompositorHitTestInfo here in bug 1389149, the following two cases
       // were effectively getting collapsed:
       //   (1) touch-action: auto
@@ -4094,22 +4094,22 @@ PaintedLayerData::AccumulateHitTestInfo(
       // mVerticalPanRegion} were modified, and so the fact that case (2) should
       // have prevented double-tap-zooming was getting lost.
       // With CompositorHitTestInfo we can now represent that case correctly,
       // but only if we use CompositorHitTestInfo all the way to the compositor
       // (i.e. in the WebRender-enabled case). In the non-WebRender case where
       // we still use the event regions, we must collapse these two cases back
       // together. Or add another region to the event regions to fix this
       // properly.
-      if (touchFlags != CompositorHitTestFlags::eTouchActionDoubleTapZoomDisabled) {
-        if (!hitTestInfo.contains(CompositorHitTestFlags::eTouchActionPanXDisabled)) {
+      if (touchFlags != CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled) {
+        if (!(hitTestInfo & CompositorHitTestInfo::eTouchActionPanXDisabled)) {
           // pan-x is allowed
           mHorizontalPanRegion.OrWith(area);
         }
-        if (!hitTestInfo.contains(CompositorHitTestFlags::eTouchActionPanYDisabled)) {
+        if (!(hitTestInfo & CompositorHitTestInfo::eTouchActionPanYDisabled)) {
           // pan-y is allowed
           mVerticalPanRegion.OrWith(area);
         }
       } else {
         // the touch-action: manipulation case described above. To preserve the
         // existing behaviour, don't touch either mHorizontalPanRegion or
         // mVerticalPanRegion
       }
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2263,17 +2263,17 @@ nsDisplayListBuilder::BuildCompositorHit
 
 bool
 nsDisplayListBuilder::ShouldBuildCompositorHitTestInfo(const nsIFrame* aFrame,
                                                        const CompositorHitTestInfo& aInfo,
                                                        const bool aBuildNew) const
 {
   MOZ_ASSERT(mBuildCompositorHitTestInfo);
 
-  if (aInfo == CompositorHitTestInvisibleToHit) {
+  if (aInfo == CompositorHitTestInfo::eInvisibleToHitTest) {
     return false;
   }
 
   if (!mCompositorHitTestInfo || !mLessEventRegionItems || aBuildNew) {
     return true;
   }
 
   if (mCompositorHitTestInfo->HitTestInfo() != aInfo) {
@@ -5064,22 +5064,22 @@ nsDisplayCompositorHitTestInfo::nsDispla
   , mIndex(aIndex)
   , mAppUnitsPerDevPixel(mFrame->PresContext()->AppUnitsPerDevPixel())
 {
   MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo);
   // We should never even create this display item if we're not building
   // compositor hit-test info or if the computed hit info indicated the
   // frame is invisible to hit-testing
   MOZ_ASSERT(aBuilder->BuildCompositorHitTestInfo());
-  MOZ_ASSERT(mHitTestInfo != CompositorHitTestInvisibleToHit);
+  MOZ_ASSERT(mHitTestInfo != mozilla::gfx::CompositorHitTestInfo::eInvisibleToHitTest);
 
   if (aBuilder->GetCurrentScrollbarDirection().isSome()) {
     // In the case of scrollbar frames, we use the scrollbar's target scrollframe
     // instead of the scrollframe with which the scrollbar actually moves.
-    MOZ_ASSERT(mHitTestInfo.contains(CompositorHitTestFlags::eScrollbar));
+    MOZ_ASSERT(mHitTestInfo & CompositorHitTestInfo::eScrollbar);
     mScrollTarget = Some(aBuilder->GetCurrentScrollbarTarget());
   }
 
   if (aArea.isSome()) {
     mArea = *aArea;
   } else {
     mArea = GetFrameArea(aBuilder, aFrame);
   }
@@ -5127,17 +5127,17 @@ nsDisplayCompositorHitTestInfo::CreateWe
   aBuilder.ClearHitTestInfo();
 
   return true;
 }
 
 void
 nsDisplayCompositorHitTestInfo::WriteDebugInfo(std::stringstream& aStream)
 {
-  aStream << nsPrintfCString(" (hitTestInfo 0x%x)", mHitTestInfo.serialize()).get();
+  aStream << nsPrintfCString(" (hitTestInfo 0x%x)", (int)mHitTestInfo).get();
   AppendToString(aStream, mArea, " hitTestArea");
 }
 
 uint32_t
 nsDisplayCompositorHitTestInfo::GetPerFrameKey() const
 {
   return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
 }
--- a/mfbt/EnumSet.h
+++ b/mfbt/EnumSet.h
@@ -23,17 +23,16 @@ namespace mozilla {
  * using a 32 bit mask for each value so it will only work for enums with an int
  * representation less than 32. It works both for enum and enum class types.
  */
 template<typename T>
 class EnumSet
 {
 public:
   typedef uint32_t serializedType;
-  typedef T valueType;
 
   EnumSet()
     : mBitField(0)
   {
   }
 
   MOZ_IMPLICIT EnumSet(T aEnum)
     : mBitField(bitFor(aEnum))
@@ -63,22 +62,16 @@ public:
   MOZ_IMPLICIT EnumSet(std::initializer_list<T> list)
     : mBitField(0)
   {
     for (auto value : list) {
       (*this) += value;
     }
   }
 
-  void operator=(T aEnum)
-  {
-    incVersion();
-    mBitField = bitFor(aEnum);
-  }
-
   EnumSet(const EnumSet& aEnumSet)
     : mBitField(aEnumSet.mBitField)
   {
   }
 
   /**
    * Add an element
    */
@@ -96,26 +89,26 @@ public:
     EnumSet<T> result(*this);
     result += aEnum;
     return result;
   }
 
   /**
    * Union
    */
-  void operator+=(const EnumSet<T>& aEnumSet)
+  void operator+=(const EnumSet<T> aEnumSet)
   {
     incVersion();
     mBitField |= aEnumSet.mBitField;
   }
 
   /**
    * Union
    */
-  EnumSet<T> operator+(const EnumSet<T>& aEnumSet) const
+  EnumSet<T> operator+(const EnumSet<T> aEnumSet) const
   {
     EnumSet<T> result(*this);
     result += aEnumSet;
     return result;
   }
 
   /**
    * Remove an element
@@ -134,26 +127,26 @@ public:
     EnumSet<T> result(*this);
     result -= aEnum;
     return result;
   }
 
   /**
    * Remove a set of elements
    */
-  void operator-=(const EnumSet<T>& aEnumSet)
+  void operator-=(const EnumSet<T> aEnumSet)
   {
     incVersion();
     mBitField &= ~(aEnumSet.mBitField);
   }
 
   /**
    * Remove a set of elements
    */
-  EnumSet<T> operator-(const EnumSet<T>& aEnumSet) const
+  EnumSet<T> operator-(const EnumSet<T> aEnumSet) const
   {
     EnumSet<T> result(*this);
     result -= aEnumSet;
     return result;
   }
 
   /**
    * Clear
@@ -162,81 +155,49 @@ public:
   {
     incVersion();
     mBitField = 0;
   }
 
   /**
    * Intersection
    */
-  void operator&=(const EnumSet<T>& aEnumSet)
+  void operator&=(const EnumSet<T> aEnumSet)
   {
     incVersion();
     mBitField &= aEnumSet.mBitField;
   }
 
   /**
    * Intersection
    */
-  EnumSet<T> operator&(const EnumSet<T>& aEnumSet) const
+  EnumSet<T> operator&(const EnumSet<T> aEnumSet) const
   {
     EnumSet<T> result(*this);
     result &= aEnumSet;
     return result;
   }
 
   /**
    * Equality
    */
-  bool operator==(const EnumSet<T>& aEnumSet) const
+  bool operator==(const EnumSet<T> aEnumSet) const
   {
     return mBitField == aEnumSet.mBitField;
   }
 
   /**
-   * Equality
-   */
-  bool operator==(T aEnum) const
-  {
-    return mBitField == bitFor(aEnum);
-  }
-
-  /**
-   * Not equal
-   */
-  bool operator!=(const EnumSet<T>& aEnumSet) const
-  {
-    return !operator==(aEnumSet);
-  }
-
-  /**
-   * Not equal
-   */
-  bool operator!=(T aEnum) const
-  {
-    return !operator==(aEnum);
-  }
-
-  /**
-   * Test if an element is contained in the set.
+   * Test is an element is contained in the set.
    */
   bool contains(T aEnum) const
   {
     return mBitField & bitFor(aEnum);
   }
 
   /**
-   * Test if a set is contained in the set.
-   */
-  bool contains(const EnumSet<T>& aEnumSet) const
-  {
-    return (mBitField & aEnumSet.mBitField) == aEnumSet.mBitField;
-  }
-
-  /**
    * Return the number of elements in the set.
    */
   uint8_t size() const
   {
     uint8_t count = 0;
     for (uint32_t bitField = mBitField; bitField; bitField >>= 1) {
       if (bitField & 1) {
         count++;