Backed out 2 changesets (bug 1420996) for marionette failures.
authorNarcis Beleuzu <nbeleuzu@mozilla.com>
Thu, 30 Aug 2018 10:26:42 +0300
changeset 482340 fe26ccb3ec3b981c2321951df210402a6f58bff8
parent 482339 a278fa75aa70031a56ded21803f59868861cff23
child 482341 fb2c0eb9ad707ed11f05e7159ba3a132ead10879
child 482356 09de350001f07965f787c19f298fd0cd6cd839fa
push id232
push userfmarier@mozilla.com
push dateWed, 05 Sep 2018 20:45:54 +0000
bugs1420996
milestone63.0a1
backs out413bd039c1263f3b9cef04e19b538e8d4097b721
01ed229650de691ba2a555401d504fcb471e62fa
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++;