Backed out 4 changesets (bug 1510853) for TelemetryHistogramEnums.h build bustages CLOSED TREE
authorCiure Andrei <aciure@mozilla.com>
Fri, 07 Dec 2018 19:38:47 +0200
changeset 508836 9b7e80071dec2a9f5a06bcafac336c98fdf86951
parent 508835 80baa7b09930c2ea8dc819543d7f500cc9391a84
child 508837 ae37561c3bf7cc9b83c4f5aad5cf4e28ed2e332c
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1510853
milestone65.0a1
backs out80baa7b09930c2ea8dc819543d7f500cc9391a84
d1ef6db7fc285d2d914ef98452033fc8517e1914
ae190948ad730114399ac7074dbbf1cda2ebe359
0ade0aa77b2f2e04e15b4618c9ef1a74b8739777
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 4 changesets (bug 1510853) for TelemetryHistogramEnums.h build bustages CLOSED TREE Backed out changeset 80baa7b09930 (bug 1510853) Backed out changeset d1ef6db7fc28 (bug 1510853) Backed out changeset ae190948ad73 (bug 1510853) Backed out changeset 0ade0aa77b2f (bug 1510853)
gfx/ipc/CompositorWidgetVsyncObserver.cpp
gfx/ipc/CompositorWidgetVsyncObserver.h
gfx/ipc/PVsyncBridge.ipdl
gfx/ipc/VsyncBridgeChild.cpp
gfx/ipc/VsyncBridgeChild.h
gfx/ipc/VsyncBridgeParent.cpp
gfx/ipc/VsyncBridgeParent.h
gfx/layers/LayersTypes.h
gfx/layers/TransactionIdAllocator.h
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
gfx/layers/ipc/CompositorVsyncScheduler.cpp
gfx/layers/ipc/CompositorVsyncScheduler.h
gfx/layers/ipc/CompositorVsyncSchedulerOwner.h
gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
gfx/layers/ipc/LayersMessageUtils.h
gfx/layers/ipc/LayersMessages.ipdlh
gfx/layers/ipc/PWebRenderBridge.ipdl
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeChild.h
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.h
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/tests/gtest/TestVsync.cpp
gfx/thebes/VsyncSource.cpp
gfx/thebes/VsyncSource.h
gfx/webrender_bindings/RenderThread.cpp
gfx/webrender_bindings/RenderThread.h
gfx/webrender_bindings/WebRenderAPI.cpp
layout/base/nsRefreshDriver.cpp
layout/base/nsRefreshDriver.h
layout/ipc/PVsync.ipdl
layout/ipc/VsyncChild.cpp
layout/ipc/VsyncChild.h
layout/ipc/VsyncParent.cpp
layout/ipc/VsyncParent.h
toolkit/components/telemetry/Histograms.json
toolkit/recordreplay/ipc/ChildIPC.cpp
widget/VsyncDispatcher.cpp
widget/VsyncDispatcher.h
--- a/gfx/ipc/CompositorWidgetVsyncObserver.cpp
+++ b/gfx/ipc/CompositorWidgetVsyncObserver.cpp
@@ -13,19 +13,19 @@ namespace widget {
 CompositorWidgetVsyncObserver::CompositorWidgetVsyncObserver(
     RefPtr<VsyncBridgeChild> aVsyncBridge,
     const layers::LayersId& aRootLayerTreeId)
     : mVsyncBridge(aVsyncBridge), mRootLayerTreeId(aRootLayerTreeId) {
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 }
 
-bool CompositorWidgetVsyncObserver::NotifyVsync(const VsyncEvent& aVsync) {
+bool CompositorWidgetVsyncObserver::NotifyVsync(TimeStamp aTimeStamp) {
   // Vsync notifications should only arrive on the vsync thread.
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(!NS_IsMainThread());
 
-  mVsyncBridge->NotifyVsync(aVsync, mRootLayerTreeId);
+  mVsyncBridge->NotifyVsync(aTimeStamp, mRootLayerTreeId);
   return true;
 }
 
 }  // namespace widget
 }  // namespace mozilla
--- a/gfx/ipc/CompositorWidgetVsyncObserver.h
+++ b/gfx/ipc/CompositorWidgetVsyncObserver.h
@@ -19,17 +19,17 @@ namespace widget {
 
 class CompositorWidgetVsyncObserver : public VsyncObserver {
   typedef gfx::VsyncBridgeChild VsyncBridgeChild;
 
  public:
   CompositorWidgetVsyncObserver(RefPtr<VsyncBridgeChild> aVsyncBridge,
                                 const layers::LayersId& aRootLayerTreeId);
 
-  bool NotifyVsync(const VsyncEvent& aVsync) override;
+  bool NotifyVsync(TimeStamp aVsyncTimestamp) override;
 
  private:
   RefPtr<VsyncBridgeChild> mVsyncBridge;
   layers::LayersId mRootLayerTreeId;
 };
 
 }  // namespace widget
 }  // namespace mozilla
--- a/gfx/ipc/PVsyncBridge.ipdl
+++ b/gfx/ipc/PVsyncBridge.ipdl
@@ -1,24 +1,23 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
 using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
-using mozilla::VsyncEvent from "mozilla/VsyncDispatcher.h";
 
 namespace mozilla {
 namespace gfx {
 
 // This protocol only serves one purpose: deliver vsync notifications from a
 // dedicated thread in the UI process to the compositor thread in the
 // compositor process. The child side exists in the UI process, and the
 // parent side in the GPU process.
 sync protocol PVsyncBridge
 {
 parent:
-  async NotifyVsync(VsyncEvent vsync, LayersId layersId);
+  async NotifyVsync(TimeStamp vsyncTimeStamp, LayersId layersId);
 };
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/ipc/VsyncBridgeChild.cpp
+++ b/gfx/ipc/VsyncBridgeChild.cpp
@@ -41,56 +41,57 @@ void VsyncBridgeChild::Open(Endpoint<PVs
   mLoop = MessageLoop::current();
 
   // Last reference is freed in DeallocPVsyncBridgeChild.
   AddRef();
 }
 
 class NotifyVsyncTask : public Runnable {
  public:
-  NotifyVsyncTask(RefPtr<VsyncBridgeChild> aVsyncBridge,
-                  const VsyncEvent& aVsync, const layers::LayersId& aLayersId)
+  NotifyVsyncTask(RefPtr<VsyncBridgeChild> aVsyncBridge, TimeStamp aTimeStamp,
+                  const layers::LayersId& aLayersId)
       : Runnable("gfx::NotifyVsyncTask"),
         mVsyncBridge(aVsyncBridge),
-        mVsync(aVsync),
+        mTimeStamp(aTimeStamp),
         mLayersId(aLayersId) {}
 
   NS_IMETHOD Run() override {
-    mVsyncBridge->NotifyVsyncImpl(mVsync, mLayersId);
+    mVsyncBridge->NotifyVsyncImpl(mTimeStamp, mLayersId);
     return NS_OK;
   }
 
  private:
   RefPtr<VsyncBridgeChild> mVsyncBridge;
-  VsyncEvent mVsync;
+  TimeStamp mTimeStamp;
   layers::LayersId mLayersId;
 };
 
 bool VsyncBridgeChild::IsOnVsyncIOThread() const {
   return MessageLoop::current() == mLoop;
 }
 
-void VsyncBridgeChild::NotifyVsync(const VsyncEvent& aVsync,
+void VsyncBridgeChild::NotifyVsync(TimeStamp aTimeStamp,
                                    const layers::LayersId& aLayersId) {
   // This should be on the Vsync thread (not the Vsync I/O thread).
   MOZ_ASSERT(!IsOnVsyncIOThread());
 
-  RefPtr<NotifyVsyncTask> task = new NotifyVsyncTask(this, aVsync, aLayersId);
+  RefPtr<NotifyVsyncTask> task =
+      new NotifyVsyncTask(this, aTimeStamp, aLayersId);
   mLoop->PostTask(task.forget());
 }
 
-void VsyncBridgeChild::NotifyVsyncImpl(const VsyncEvent& aVsync,
+void VsyncBridgeChild::NotifyVsyncImpl(TimeStamp aTimeStamp,
                                        const layers::LayersId& aLayersId) {
   // This should be on the Vsync I/O thread.
   MOZ_ASSERT(IsOnVsyncIOThread());
 
   if (!mProcessToken) {
     return;
   }
-  SendNotifyVsync(aVsync, aLayersId);
+  SendNotifyVsync(aTimeStamp, aLayersId);
 }
 
 void VsyncBridgeChild::Close() {
   if (!IsOnVsyncIOThread()) {
     mLoop->PostTask(NewRunnableMethod("gfx::VsyncBridgeChild::Close", this,
                                       &VsyncBridgeChild::Close));
     return;
   }
--- a/gfx/ipc/VsyncBridgeChild.h
+++ b/gfx/ipc/VsyncBridgeChild.h
@@ -25,28 +25,27 @@ class VsyncBridgeChild final : public PV
       Endpoint<PVsyncBridgeChild>&& aEndpoint);
 
   void Close();
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
   void DeallocPVsyncBridgeChild() override;
   void ProcessingError(Result aCode, const char* aReason) override;
 
-  void NotifyVsync(const VsyncEvent& aVsync, const layers::LayersId& aLayersId);
+  void NotifyVsync(TimeStamp aTimeStamp, const layers::LayersId& aLayersId);
 
   virtual void HandleFatalError(const char* aMsg) const override;
 
  private:
   VsyncBridgeChild(RefPtr<VsyncIOThreadHolder>, const uint64_t& aProcessToken);
   ~VsyncBridgeChild();
 
   void Open(Endpoint<PVsyncBridgeChild>&& aEndpoint);
 
-  void NotifyVsyncImpl(const VsyncEvent& aVsync,
-                       const layers::LayersId& aLayersId);
+  void NotifyVsyncImpl(TimeStamp aTimeStamp, const layers::LayersId& aLayersId);
 
   bool IsOnVsyncIOThread() const;
 
  private:
   RefPtr<VsyncIOThreadHolder> mThread;
   MessageLoop* mLoop;
   uint64_t mProcessToken;
 };
--- a/gfx/ipc/VsyncBridgeParent.cpp
+++ b/gfx/ipc/VsyncBridgeParent.cpp
@@ -37,18 +37,18 @@ void VsyncBridgeParent::Open(Endpoint<PV
     // We can't recover from this.
     MOZ_CRASH("Failed to bind VsyncBridgeParent to endpoint");
   }
   AddRef();
   mOpen = true;
 }
 
 mozilla::ipc::IPCResult VsyncBridgeParent::RecvNotifyVsync(
-    const VsyncEvent& aVsync, const LayersId& aLayersId) {
-  CompositorBridgeParent::NotifyVsync(aVsync, aLayersId);
+    const TimeStamp& aTimeStamp, const LayersId& aLayersId) {
+  CompositorBridgeParent::NotifyVsync(aTimeStamp, aLayersId);
   return IPC_OK();
 }
 
 void VsyncBridgeParent::Shutdown() {
   MessageLoop* ccloop = CompositorThreadHolder::Loop();
   if (MessageLoop::current() != ccloop) {
     ccloop->PostTask(NewRunnableMethod("gfx::VsyncBridgeParent::ShutdownImpl",
                                        this, &VsyncBridgeParent::ShutdownImpl));
--- a/gfx/ipc/VsyncBridgeParent.h
+++ b/gfx/ipc/VsyncBridgeParent.h
@@ -18,17 +18,17 @@ namespace gfx {
 
 class VsyncBridgeParent final : public PVsyncBridgeParent {
  public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VsyncBridgeParent)
 
   static RefPtr<VsyncBridgeParent> Start(
       Endpoint<PVsyncBridgeParent>&& aEndpoint);
 
-  mozilla::ipc::IPCResult RecvNotifyVsync(const VsyncEvent& aVsync,
+  mozilla::ipc::IPCResult RecvNotifyVsync(const TimeStamp& vsyncTimeStamp,
                                           const LayersId& aLayersId) override;
   void ActorDestroy(ActorDestroyReason aWhy) override;
   void DeallocPVsyncBridgeParent() override;
 
   void Shutdown();
 
  private:
   VsyncBridgeParent();
--- a/gfx/layers/LayersTypes.h
+++ b/gfx/layers/LayersTypes.h
@@ -74,61 +74,49 @@ struct LayersId {
   //   std::unordered_map<LayersId, ValueType, LayersId::HashFn> myMap;
   struct HashFn {
     std::size_t operator()(const LayersId& aKey) const {
       return std::hash<uint64_t>{}(aKey.mId);
     }
   };
 };
 
-template <typename T>
-struct BaseTransactionId {
-  uint64_t mId = 0;
+struct TransactionId {
+  uint64_t mId;
 
   bool IsValid() const { return mId != 0; }
 
-  MOZ_MUST_USE BaseTransactionId<T> Next() const {
-    return BaseTransactionId<T>{mId + 1};
-  }
+  MOZ_MUST_USE TransactionId Next() const { return TransactionId{mId + 1}; }
 
-  MOZ_MUST_USE BaseTransactionId<T> Prev() const {
-    return BaseTransactionId<T>{mId - 1};
-  }
+  MOZ_MUST_USE TransactionId Prev() const { return TransactionId{mId - 1}; }
 
-  int64_t operator-(const BaseTransactionId<T>& aOther) const {
+  int64_t operator-(const TransactionId& aOther) const {
     return mId - aOther.mId;
   }
 
   // Allow explicit cast to a uint64_t for now
   explicit operator uint64_t() const { return mId; }
 
-  bool operator<(const BaseTransactionId<T>& aOther) const {
-    return mId < aOther.mId;
-  }
+  bool operator<(const TransactionId& aOther) const { return mId < aOther.mId; }
 
-  bool operator<=(const BaseTransactionId<T>& aOther) const {
+  bool operator<=(const TransactionId& aOther) const {
     return mId <= aOther.mId;
   }
 
-  bool operator>(const BaseTransactionId<T>& aOther) const {
-    return mId > aOther.mId;
-  }
+  bool operator>(const TransactionId& aOther) const { return mId > aOther.mId; }
 
-  bool operator>=(const BaseTransactionId<T>& aOther) const {
+  bool operator>=(const TransactionId& aOther) const {
     return mId >= aOther.mId;
   }
 
-  bool operator==(const BaseTransactionId<T>& aOther) const {
+  bool operator==(const TransactionId& aOther) const {
     return mId == aOther.mId;
   }
 };
 
-class TransactionIdType {};
-typedef BaseTransactionId<TransactionIdType> TransactionId;
-
 struct LayersObserverEpoch {
   uint64_t mId;
 
   MOZ_MUST_USE LayersObserverEpoch Next() const {
     return LayersObserverEpoch{mId + 1};
   }
 
   bool operator<=(const LayersObserverEpoch& aOther) const {
--- a/gfx/layers/TransactionIdAllocator.h
+++ b/gfx/layers/TransactionIdAllocator.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_TRANSACTION_ID_ALLOCATOR_H
 #define GFX_TRANSACTION_ID_ALLOCATOR_H
 
 #include "nsISupportsImpl.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/TimeStamp.h"
-#include "mozilla/VsyncDispatcher.h"
 
 namespace mozilla {
 namespace layers {
 
 class TransactionIdAllocator {
  protected:
   virtual ~TransactionIdAllocator() {}
 
@@ -76,16 +75,14 @@ class TransactionIdAllocator {
    * completed transactions of previous refresh driver will be ignored.
    */
   virtual void ResetInitialTransactionId(TransactionId aTransactionId) = 0;
 
   /**
    * Get the start time of the current refresh tick.
    */
   virtual mozilla::TimeStamp GetTransactionStart() = 0;
-
-  virtual VsyncId GetVsyncId() = 0;
 };
 
 }  // namespace layers
 }  // namespace mozilla
 
 #endif /* GFX_TRANSACTION_ID_ALLOCATOR_H */
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -683,21 +683,20 @@ void ClientLayerManager::ForwardTransact
   TimeStamp refreshStart = mTransactionIdAllocator->GetTransactionStart();
 
   if (gfxPrefs::AlwaysPaint() && XRE_IsContentProcess()) {
     mForwarder->SendPaintTime(mLatestTransactionId, mLastPaintTime);
   }
 
   // forward this transaction's changeset to our LayerManagerComposite
   bool sent = false;
-  bool ok = mForwarder->EndTransaction(
-      mRegionToClear, mLatestTransactionId, aScheduleComposite,
-      mPaintSequenceNumber, mIsRepeatTransaction,
-      mTransactionIdAllocator->GetVsyncId(), refreshStart, mTransactionStart,
-      mURL, &sent);
+  bool ok = mForwarder->EndTransaction(mRegionToClear, mLatestTransactionId,
+                                       aScheduleComposite, mPaintSequenceNumber,
+                                       mIsRepeatTransaction, refreshStart,
+                                       mTransactionStart, mURL, &sent);
   if (ok) {
     if (sent) {
       mNeedsComposite = false;
     }
   } else if (HasShadowManager()) {
     NS_WARNING("failed to forward Layers transaction");
   }
 
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -666,22 +666,21 @@ void CompositorBridgeParent::PauseCompos
   MonitorAutoLock lock(mPauseCompositionMonitor);
 
   if (!mPaused) {
     mPaused = true;
 
     TimeStamp now = TimeStamp::Now();
     if (mCompositor) {
       mCompositor->Pause();
-      DidComposite(VsyncId(), now, now);
+      DidComposite(now, now);
     } else if (mWrBridge) {
       mWrBridge->Pause();
       NotifyPipelineRendered(mWrBridge->PipelineId(),
-                             mWrBridge->GetCurrentEpoch(), VsyncId(), now, now,
-                             now);
+                             mWrBridge->GetCurrentEpoch(), now, now, now);
     }
   }
 
   // if anyone's waiting to make sure that composition really got paused, tell
   // them
   lock.NotifyAll();
 }
 
@@ -884,28 +883,28 @@ void CompositorBridgeParent::ScheduleCom
       layerCompositor->SetShadowOpacity(layer->GetOpacity());
       layerCompositor->SetShadowOpacitySetByAnimation(false);
     }
     layerCompositor->SetShadowVisibleRegion(layer->GetVisibleRegion());
     layerCompositor->SetShadowClipRect(layer->GetClipRect());
   });
 }
 
-void CompositorBridgeParent::CompositeToTarget(VsyncId aId, DrawTarget* aTarget,
+void CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget,
                                                const gfx::IntRect* aRect) {
   AUTO_PROFILER_TRACING("Paint", "Composite");
   AUTO_PROFILER_LABEL("CompositorBridgeParent::CompositeToTarget", GRAPHICS);
 
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
              "Composite can only be called on the compositor thread");
   TimeStamp start = TimeStamp::Now();
 
   if (!CanComposite()) {
     TimeStamp end = TimeStamp::Now();
-    DidComposite(aId, start, end);
+    DidComposite(start, end);
     return;
   }
 
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
   if (!mWaitForPluginsUntil.IsNull() && mWaitForPluginsUntil > start) {
     mHaveBlockedForPlugins = true;
     ScheduleComposition();
     return;
@@ -989,17 +988,17 @@ void CompositorBridgeParent::CompositeTo
     mLayerManager->Dump(/* aSorted = */ true);
   }
 #endif
   mLayerManager->SetDebugOverlayWantsNextFrame(false);
   mLayerManager->EndTransaction(time);
 
   if (!aTarget) {
     TimeStamp end = TimeStamp::Now();
-    DidComposite(aId, start, end);
+    DidComposite(start, end);
   }
 
   // We're not really taking advantage of the stored composite-again-time here.
   // We might be able to skip the next few composites altogether. However,
   // that's a bit complex to implement and we'll get most of the advantage
   // by skipping compositing when we detect there's nothing invalid. This is why
   // we do "composite until" rather than "composite again at".
   //
@@ -1242,17 +1241,17 @@ void CompositorBridgeParent::ShadowLayer
 
   if (root) {
     SetShadowProperties(root);
   }
   if (aInfo.scheduleComposite()) {
     ScheduleComposition();
     if (mPaused) {
       TimeStamp now = TimeStamp::Now();
-      DidComposite(VsyncId(), now, now);
+      DidComposite(now, now);
     }
   }
   mLayerManager->NotifyShadowTreeTransaction();
 }
 
 void CompositorBridgeParent::ScheduleComposite(
     LayerTransactionParent* aLayerTree) {
   ScheduleComposition();
@@ -1280,17 +1279,17 @@ bool CompositorBridgeParent::SetTestSamp
   if (testComposite) {
     AutoResolveRefLayers resolve(mCompositionManager);
     bool requestNextFrame =
         mCompositionManager->TransformShadowTree(aTime, mVsyncRate);
     if (!requestNextFrame) {
       CancelCurrentCompositeTask();
       // Pretend we composited in case someone is wating for this event.
       TimeStamp now = TimeStamp::Now();
-      DidComposite(VsyncId(), now, now);
+      DidComposite(now, now);
     }
   }
 
   return true;
 }
 
 void CompositorBridgeParent::LeaveTestMode(const LayersId& aId) {
   mTestTime = Nothing();
@@ -1310,17 +1309,17 @@ void CompositorBridgeParent::ApplyAsyncP
     TimeStamp time =
         mTestTime.valueOr(mCompositorScheduler->GetLastComposeTime());
     bool requestNextFrame =
         mCompositionManager->TransformShadowTree(time, mVsyncRate, aSkip);
     if (!requestNextFrame) {
       CancelCurrentCompositeTask();
       // Pretend we composited in case someone is waiting for this event.
       TimeStamp now = TimeStamp::Now();
-      DidComposite(VsyncId(), now, now);
+      DidComposite(now, now);
     }
   }
 }
 
 CompositorAnimationStorage* CompositorBridgeParent::GetAnimationStorage() {
   if (!mAnimationStorage) {
     mAnimationStorage = new CompositorAnimationStorage();
   }
@@ -1568,32 +1567,32 @@ CompositorBridgeParent* CompositorBridge
   if (it == sCompositorMap->end()) {
     return nullptr;
   }
   CompositorBridgeParent* retval = it->second;
   sCompositorMap->erase(it);
   return retval;
 }
 
-void CompositorBridgeParent::NotifyVsync(const VsyncEvent& aVsync,
+void CompositorBridgeParent::NotifyVsync(const TimeStamp& aTimeStamp,
                                          const LayersId& aLayersId) {
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
 
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
   auto it = sIndirectLayerTrees.find(aLayersId);
   if (it == sIndirectLayerTrees.end()) return;
 
   CompositorBridgeParent* cbp = it->second.mParent;
   if (!cbp || !cbp->mWidget) return;
 
   RefPtr<VsyncObserver> obs = cbp->mWidget->GetVsyncObserver();
   if (!obs) return;
 
-  obs->NotifyVsync(aVsync);
+  obs->NotifyVsync(aTimeStamp);
 }
 
 mozilla::ipc::IPCResult CompositorBridgeParent::RecvNotifyChildCreated(
     const LayersId& child, CompositorOptions* aOptions) {
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
   NotifyChildCreated(child);
   *aOptions = mOptions;
   return IPC_OK();
@@ -1680,18 +1679,18 @@ mozilla::ipc::IPCResult CompositorBridge
     MOZ_ASSERT(mWrBridge);
     RefPtr<wr::WebRenderAPI> api = mWrBridge->GetWebRenderAPI();
     api = api->Clone();
     wr::Epoch newEpoch = childWrBridge->UpdateWebRender(
         mWrBridge->CompositorScheduler(), api, mWrBridge->AsyncImageManager(),
         GetAnimationStorage(), mWrBridge->GetTextureFactoryIdentifier());
     // Pretend we composited, since parent CompositorBridgeParent was replaced.
     TimeStamp now = TimeStamp::Now();
-    NotifyPipelineRendered(childWrBridge->PipelineId(), newEpoch, VsyncId(),
-                           now, now, now);
+    NotifyPipelineRendered(childWrBridge->PipelineId(), newEpoch, now, now,
+                           now);
   }
 
   if (oldApzUpdater) {
     // We don't support moving a child from an APZ-enabled compositor to a
     // APZ-disabled compositor. The mOptions assertion above should already
     // ensure this, since APZ-ness is one of the things in mOptions. Note
     // however it is possible for mApzUpdater to be non-null here with
     // oldApzUpdater null, because the child may not have been previously
@@ -1972,24 +1971,29 @@ CompositorBridgeParent::LayerTreeState::
   return mCrossProcessParent;
 }
 
 MetricsSharingController*
 CompositorBridgeParent::LayerTreeState::InProcessSharingController() const {
   return mParent;
 }
 
-void CompositorBridgeParent::DidComposite(const VsyncId& aId,
+void CompositorBridgeParent::DidComposite(LayersId aId,
                                           TimeStamp& aCompositeStart,
                                           TimeStamp& aCompositeEnd) {
+  MOZ_ASSERT(aId == mRootLayerTreeID);
+  DidComposite(aCompositeStart, aCompositeEnd);
+}
+
+void CompositorBridgeParent::DidComposite(TimeStamp& aCompositeStart,
+                                          TimeStamp& aCompositeEnd) {
   if (mWrBridge) {
     MOZ_ASSERT(false);  // This should never get called for a WR compositor
   } else {
-    NotifyDidComposite(mPendingTransaction, aId, aCompositeStart,
-                       aCompositeEnd);
+    NotifyDidComposite(mPendingTransaction, aCompositeStart, aCompositeEnd);
 #if defined(ENABLE_FRAME_LATENCY_LOG)
     if (mPendingTransaction.IsValid()) {
       if (mRefreshStartTime) {
         int32_t latencyMs =
             lround((aCompositeEnd - mRefreshStartTime).ToMilliseconds());
         printf_stderr(
             "From transaction start to end of generate frame latencyMs %d this "
             "%p\n",
@@ -2008,35 +2012,33 @@ void CompositorBridgeParent::DidComposit
     mFwdTime = TimeStamp();
 #endif
     mPendingTransaction = TransactionId{0};
   }
 }
 
 void CompositorBridgeParent::NotifyPipelineRendered(
     const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch,
-    const VsyncId& aCompositeStartId, TimeStamp& aCompositeStart,
-    TimeStamp& aRenderStart, TimeStamp& aCompositeEnd,
-    wr::RendererStats* aStats) {
+    TimeStamp& aCompositeStart, TimeStamp& aRenderStart,
+    TimeStamp& aCompositeEnd, wr::RendererStats* aStats) {
   if (!mWrBridge || !mAsyncImageManager) {
     return;
   }
 
   nsTArray<FrameStats> stats;
 
   RefPtr<UiCompositorControllerParent> uiController =
       UiCompositorControllerParent::GetFromRootLayerTreeId(mRootLayerTreeID);
 
   if (mWrBridge->PipelineId() == aPipelineId) {
     mWrBridge->RemoveEpochDataPriorTo(aEpoch);
 
     if (!mPaused) {
       TransactionId transactionId = mWrBridge->FlushTransactionIdsForEpoch(
-          aEpoch, aCompositeStartId, aCompositeStart, aRenderStart,
-          aCompositeEnd, uiController);
+          aEpoch, aCompositeStart, aRenderStart, aCompositeEnd, uiController);
       Unused << SendDidComposite(LayersId{0}, transactionId, aCompositeStart,
                                  aCompositeEnd);
 
       nsTArray<ImageCompositeNotificationInfo> notifications;
       mWrBridge->ExtractImageCompositeNotifications(&notifications);
       if (!notifications.IsEmpty()) {
         Unused << ImageBridgeParent::NotifyImageComposites(notifications);
       }
@@ -2045,18 +2047,18 @@ void CompositorBridgeParent::NotifyPipel
   }
 
   auto wrBridge = mAsyncImageManager->GetWrBridge(aPipelineId);
   if (wrBridge && wrBridge->GetCompositorBridge()) {
     MOZ_ASSERT(!wrBridge->IsRootWebRenderBridgeParent());
     wrBridge->RemoveEpochDataPriorTo(aEpoch);
     if (!mPaused) {
       TransactionId transactionId = wrBridge->FlushTransactionIdsForEpoch(
-          aEpoch, aCompositeStartId, aCompositeStart, aRenderStart,
-          aCompositeEnd, uiController, aStats, &stats);
+          aEpoch, aCompositeStart, aRenderStart, aCompositeEnd, uiController,
+          aStats, &stats);
       Unused << wrBridge->GetCompositorBridge()->SendDidComposite(
           wrBridge->GetLayersId(), transactionId, aCompositeStart,
           aCompositeEnd);
     }
   }
 
   if (!stats.IsEmpty()) {
     Unused << SendNotifyFrameStats(stats);
@@ -2064,17 +2066,16 @@ void CompositorBridgeParent::NotifyPipel
 }
 
 RefPtr<AsyncImagePipelineManager>
 CompositorBridgeParent::GetAsyncImagePipelineManager() const {
   return mAsyncImageManager;
 }
 
 void CompositorBridgeParent::NotifyDidComposite(TransactionId aTransactionId,
-                                                VsyncId aId,
                                                 TimeStamp& aCompositeStart,
                                                 TimeStamp& aCompositeEnd) {
   MOZ_ASSERT(
       !mWrBridge);  // We should be going through NotifyPipelineRendered instead
 
   Unused << SendDidComposite(LayersId{0}, aTransactionId, aCompositeStart,
                              aCompositeEnd);
 
@@ -2082,23 +2083,23 @@ void CompositorBridgeParent::NotifyDidCo
     nsTArray<ImageCompositeNotificationInfo> notifications;
     mLayerManager->ExtractImageCompositeNotifications(&notifications);
     if (!notifications.IsEmpty()) {
       Unused << ImageBridgeParent::NotifyImageComposites(notifications);
     }
   }
 
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
-  ForEachIndirectLayerTree([&](LayerTreeState* lts,
-                               const LayersId& aLayersId) -> void {
-    if (lts->mCrossProcessParent && lts->mParent == this) {
-      CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent;
-      cpcp->DidCompositeLocked(aLayersId, aId, aCompositeStart, aCompositeEnd);
-    }
-  });
+  ForEachIndirectLayerTree(
+      [&](LayerTreeState* lts, const LayersId& aLayersId) -> void {
+        if (lts->mCrossProcessParent && lts->mParent == this) {
+          CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent;
+          cpcp->DidCompositeLocked(aLayersId, aCompositeStart, aCompositeEnd);
+        }
+      });
 }
 
 void CompositorBridgeParent::InvalidateRemoteLayers() {
   MOZ_ASSERT(CompositorLoop() == MessageLoop::current());
 
   Unused << PCompositorBridgeParent::SendInvalidateLayers(LayersId{0});
 
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -36,17 +36,16 @@
 #include "mozilla/layers/MetricsSharingController.h"
 #include "mozilla/layers/PCompositorBridgeParent.h"
 #include "mozilla/layers/APZTestData.h"
 #include "mozilla/webrender/WebRenderTypes.h"
 #include "mozilla/widget/CompositorWidget.h"
 #include "nsISupportsImpl.h"
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
 #include "mozilla/layers/UiCompositorControllerParent.h"
-#include "mozilla/VsyncDispatcher.h"
 
 class MessageLoop;
 class nsIWidget;
 
 namespace mozilla {
 
 class CancelableRunnable;
 
@@ -142,16 +141,19 @@ class CompositorBridgeParentBase : publi
   mozilla::ipc::IPCResult RecvSyncWithCompositor() override { return IPC_OK(); }
 
   mozilla::ipc::IPCResult Recv__delete__() override { return IPC_OK(); }
 
   virtual void ObserveLayersUpdate(LayersId aLayersId,
                                    LayersObserverEpoch aEpoch,
                                    bool aActive) = 0;
 
+  virtual void DidComposite(LayersId aId, TimeStamp& aCompositeStart,
+                            TimeStamp& aCompositeEnd) = 0;
+
   // HostIPCAllocator
   base::ProcessId GetChildProcessId() override;
   void NotifyNotUsed(PTextureParent* aTexture,
                      uint64_t aTransactionId) override;
   void SendAsyncMessage(
       const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
 
   // ShmemAllocator
@@ -306,17 +308,16 @@ class CompositorBridgeParent final : pub
   bool DeallocPTextureParent(PTextureParent* actor) override;
 
   bool IsSameProcess() const override;
 
   void NotifyWebRenderError(wr::WebRenderError aError);
   void NotifyWebRenderContextPurge();
   void NotifyPipelineRendered(const wr::PipelineId& aPipelineId,
                               const wr::Epoch& aEpoch,
-                              const VsyncId& aCompositeStartId,
                               TimeStamp& aCompositeStart,
                               TimeStamp& aRenderStart, TimeStamp& aCompositeEnd,
                               wr::RendererStats* aStats = nullptr);
   RefPtr<AsyncImagePipelineManager> GetAsyncImagePipelineManager() const;
 
   PCompositorWidgetParent* AllocPCompositorWidgetParent(
       const CompositorWidgetInitData& aInitData) override;
   bool DeallocPCompositorWidgetParent(PCompositorWidgetParent* aActor) override;
@@ -387,17 +388,18 @@ class CompositorBridgeParent final : pub
    * Returns a pointer to the CompositorBridgeParent corresponding to the given
    * ID.
    */
   static CompositorBridgeParent* GetCompositorBridgeParent(uint64_t id);
 
   /**
    * Notify the compositor for the given layer tree that vsync has occurred.
    */
-  static void NotifyVsync(const VsyncEvent& aVsync, const LayersId& aLayersId);
+  static void NotifyVsync(const TimeStamp& aTimeStamp,
+                          const LayersId& aLayersId);
 
   /**
    * Set aController as the pan/zoom callback for the subtree referred
    * to by aLayersId.
    *
    * Must run on content main thread.
    */
   static void SetControllerForLayerTree(LayersId aLayersId,
@@ -588,17 +590,17 @@ class CompositorBridgeParent final : pub
 
  protected:
   void ForceComposition();
   void CancelCurrentCompositeTask();
 
   // CompositorVsyncSchedulerOwner
   bool IsPendingComposite() override;
   void FinishPendingComposite() override;
-  void CompositeToTarget(VsyncId aId, gfx::DrawTarget* aTarget,
+  void CompositeToTarget(gfx::DrawTarget* aTarget,
                          const gfx::IntRect* aRect = nullptr) override;
 
   bool InitializeAdvancedLayers(const nsTArray<LayersBackend>& aBackendHints,
                                 TextureFactoryIdentifier* aOutIdentifier);
   RefPtr<Compositor> NewCompositor(
       const nsTArray<LayersBackend>& aBackendHints);
 
   /**
@@ -621,20 +623,21 @@ class CompositorBridgeParent final : pub
   static void FinishShutdown();
 
   /**
    * Return true if current state allows compositing, that is
    * finishing a layers transaction.
    */
   bool CanComposite();
 
-  void DidComposite(const VsyncId& aId, TimeStamp& aCompositeStart,
-                    TimeStamp& aCompositeEnd);
+  void DidComposite(LayersId aId, TimeStamp& aCompositeStart,
+                    TimeStamp& aCompositeEnd) override;
+  void DidComposite(TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd);
 
-  void NotifyDidComposite(TransactionId aTransactionId, VsyncId aId,
+  void NotifyDidComposite(TransactionId aTransactionId,
                           TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd);
 
   // The indirect layer tree lock must be held before calling this function.
   // Callback should take (LayerTreeState* aState, const LayersId& aLayersId)
   template <typename Lambda>
   inline void ForEachIndirectLayerTree(const Lambda& aCallback);
 
   RefPtr<HostLayerManager> mLayerManager;
--- a/gfx/layers/ipc/CompositorVsyncScheduler.cpp
+++ b/gfx/layers/ipc/CompositorVsyncScheduler.cpp
@@ -43,22 +43,23 @@ namespace layers {
 using namespace mozilla::gfx;
 using namespace std;
 
 CompositorVsyncScheduler::Observer::Observer(CompositorVsyncScheduler* aOwner)
     : mMutex("CompositorVsyncScheduler.Observer.Mutex"), mOwner(aOwner) {}
 
 CompositorVsyncScheduler::Observer::~Observer() { MOZ_ASSERT(!mOwner); }
 
-bool CompositorVsyncScheduler::Observer::NotifyVsync(const VsyncEvent& aVsync) {
+bool CompositorVsyncScheduler::Observer::NotifyVsync(
+    TimeStamp aVsyncTimestamp) {
   MutexAutoLock lock(mMutex);
   if (!mOwner) {
     return false;
   }
-  return mOwner->NotifyVsync(aVsync);
+  return mOwner->NotifyVsync(aVsyncTimestamp);
 }
 
 void CompositorVsyncScheduler::Observer::Destroy() {
   MutexAutoLock lock(mMutex);
   mOwner = nullptr;
 }
 
 CompositorVsyncScheduler::CompositorVsyncScheduler(
@@ -101,23 +102,22 @@ void CompositorVsyncScheduler::Destroy()
   mVsyncObserver->Destroy();
   mVsyncObserver = nullptr;
 
   mCompositeRequestedAt = TimeStamp();
   CancelCurrentCompositeTask();
 }
 
 void CompositorVsyncScheduler::PostCompositeTask(
-    VsyncId aId, TimeStamp aCompositeTimestamp) {
+    TimeStamp aCompositeTimestamp) {
   MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
   if (mCurrentCompositeTask == nullptr && CompositorThreadHolder::Loop()) {
-    RefPtr<CancelableRunnable> task =
-        NewCancelableRunnableMethod<VsyncId, TimeStamp>(
-            "layers::CompositorVsyncScheduler::Composite", this,
-            &CompositorVsyncScheduler::Composite, aId, aCompositeTimestamp);
+    RefPtr<CancelableRunnable> task = NewCancelableRunnableMethod<TimeStamp>(
+        "layers::CompositorVsyncScheduler::Composite", this,
+        &CompositorVsyncScheduler::Composite, aCompositeTimestamp);
     mCurrentCompositeTask = task;
     ScheduleTask(task.forget());
   }
 }
 
 void CompositorVsyncScheduler::PostVRTask(TimeStamp aTimestamp) {
   MonitorAutoLock lockVR(mCurrentVRTaskMonitor);
   if (mCurrentVRTask == nullptr && CompositorThreadHolder::Loop()) {
@@ -134,69 +134,68 @@ void CompositorVsyncScheduler::ScheduleC
   if (!mVsyncObserver) {
     // Destroy was already called on this object.
     return;
   }
 
   if (mAsapScheduling) {
     // Used only for performance testing purposes, and when recording/replaying
     // to ensure that graphics are up to date.
-    PostCompositeTask(VsyncId(), TimeStamp::Now());
+    PostCompositeTask(TimeStamp::Now());
 #ifdef MOZ_WIDGET_ANDROID
   } else if (mIsObservingVsync && mCompositeRequestedAt &&
              (TimeStamp::Now() - mCompositeRequestedAt) >=
                  mVsyncSchedulerOwner->GetVsyncInterval() * 2) {
     // uh-oh, we already requested a composite at least two vsyncs ago, and a
     // composite hasn't happened yet. It is possible that the vsync observation
     // is blocked on the main thread, so let's just composite ASAP and not
     // wait for the vsync. Note that this should only ever happen on Fennec
     // because there content runs in the same process as the compositor, and so
     // content can actually block the main thread in this process.
-    PostCompositeTask(VsyncId(), TimeStamp::Now());
+    PostCompositeTask(TimeStamp::Now());
 #endif
   } else {
     if (!mCompositeRequestedAt) {
       mCompositeRequestedAt = TimeStamp::Now();
     }
     if (!mIsObservingVsync && mCompositeRequestedAt) {
       ObserveVsync();
       // Starting to observe vsync is an async operation that goes
       // through the main thread of the UI process. It's possible that
       // we're blocking there waiting on a composite, so schedule an initial
       // one now to get things started.
-      PostCompositeTask(VsyncId(), TimeStamp::Now());
+      PostCompositeTask(TimeStamp::Now());
     }
   }
 }
 
-bool CompositorVsyncScheduler::NotifyVsync(const VsyncEvent& aVsync) {
+bool CompositorVsyncScheduler::NotifyVsync(TimeStamp aVsyncTimestamp) {
   // Called from the vsync dispatch thread. When in the GPU Process, that's
   // the same as the compositor thread.
   MOZ_ASSERT_IF(XRE_IsParentProcess(),
                 !CompositorThreadHolder::IsInCompositorThread());
   MOZ_ASSERT_IF(XRE_GetProcessType() == GeckoProcessType_GPU,
                 CompositorThreadHolder::IsInCompositorThread());
   MOZ_ASSERT(!NS_IsMainThread());
-  PostCompositeTask(aVsync.mId, aVsync.mTime);
-  PostVRTask(aVsync.mTime);
+  PostCompositeTask(aVsyncTimestamp);
+  PostVRTask(aVsyncTimestamp);
   return true;
 }
 
 void CompositorVsyncScheduler::CancelCurrentCompositeTask() {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread() ||
              NS_IsMainThread());
   MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
   if (mCurrentCompositeTask) {
     mCurrentCompositeTask->Cancel();
     mCurrentCompositeTask = nullptr;
   }
 }
 
-void CompositorVsyncScheduler::Composite(VsyncId aId,
-                                         TimeStamp aVsyncTimestamp) {
+void CompositorVsyncScheduler::Composite(TimeStamp aVsyncTimestamp) {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   MOZ_ASSERT(mVsyncSchedulerOwner);
 
   {  // scope lock
     MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
     mCurrentCompositeTask = nullptr;
   }
 
@@ -217,17 +216,17 @@ void CompositorVsyncScheduler::Composite
     }
   }
 
   if (mCompositeRequestedAt || mAsapScheduling) {
     mCompositeRequestedAt = TimeStamp();
     mLastCompose = aVsyncTimestamp;
 
     // Tell the owner to do a composite
-    mVsyncSchedulerOwner->CompositeToTarget(aId, nullptr, nullptr);
+    mVsyncSchedulerOwner->CompositeToTarget(nullptr, nullptr);
 
     mVsyncNotificationsSkipped = 0;
 
     TimeDuration compositeFrameTotal = TimeStamp::Now() - aVsyncTimestamp;
     mozilla::Telemetry::Accumulate(
         mozilla::Telemetry::COMPOSITE_FRAME_ROUNDTRIP_TIME,
         compositeFrameTotal.ToMilliseconds());
   } else if (mVsyncNotificationsSkipped++ >
@@ -253,17 +252,17 @@ void CompositorVsyncScheduler::ForceComp
    * platforms, enabling/disabling vsync is not free and this oscillating
    * behavior causes a performance hit. In order to avoid this problem, we reset
    * the mVsyncNotificationsSkipped counter to keep vsync enabled.
    */
   mVsyncNotificationsSkipped = 0;
 
   mLastCompose = TimeStamp::Now();
   MOZ_ASSERT(mVsyncSchedulerOwner);
-  mVsyncSchedulerOwner->CompositeToTarget(VsyncId(), aTarget, aRect);
+  mVsyncSchedulerOwner->CompositeToTarget(aTarget, aRect);
 }
 
 bool CompositorVsyncScheduler::NeedsComposite() {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   return (bool)mCompositeRequestedAt;
 }
 
 bool CompositorVsyncScheduler::FlushPendingComposite() {
--- a/gfx/layers/ipc/CompositorVsyncScheduler.h
+++ b/gfx/layers/ipc/CompositorVsyncScheduler.h
@@ -43,17 +43,17 @@ class CompositorVsyncScheduler {
   explicit CompositorVsyncScheduler(
       CompositorVsyncSchedulerOwner* aVsyncSchedulerOwner,
       widget::CompositorWidget* aWidget);
 
   /**
    * Notify this class of a vsync. This will trigger a composite if one is
    * needed. This must be called from the vsync dispatch thread.
    */
-  bool NotifyVsync(const VsyncEvent& aVsync);
+  bool NotifyVsync(TimeStamp aVsyncTimestamp);
 
   /**
    * Do cleanup. This must be called on the compositor thread.
    */
   void Destroy();
 
   /**
    * Notify this class that a composition is needed. This will trigger a
@@ -103,35 +103,35 @@ class CompositorVsyncScheduler {
  private:
   virtual ~CompositorVsyncScheduler();
 
   // Schedule a task to run on the compositor thread.
   void ScheduleTask(already_AddRefed<CancelableRunnable>);
 
   // Post a task to run Composite() on the compositor thread, if there isn't
   // such a task already queued. Can be called from any thread.
-  void PostCompositeTask(VsyncId aId, TimeStamp aCompositeTimestamp);
+  void PostCompositeTask(TimeStamp aCompositeTimestamp);
 
   // Post a task to run DispatchVREvents() on the VR thread, if there isn't
   // such a task already queued. Can be called from any thread.
   void PostVRTask(TimeStamp aTimestamp);
 
   // This gets run at vsync time and "does" a composite (which really means
   // update internal state and call the owner to do the composite).
-  void Composite(VsyncId aId, TimeStamp aVsyncTimestamp);
+  void Composite(TimeStamp aVsyncTimestamp);
 
   void ObserveVsync();
   void UnobserveVsync();
 
   void DispatchVREvents(TimeStamp aVsyncTimestamp);
 
   class Observer final : public VsyncObserver {
    public:
     explicit Observer(CompositorVsyncScheduler* aOwner);
-    virtual bool NotifyVsync(const VsyncEvent& aVsync) override;
+    virtual bool NotifyVsync(TimeStamp aVsyncTimestamp) override;
     void Destroy();
 
    private:
     virtual ~Observer();
 
     Mutex mMutex;
     // Hold raw pointer to avoid mutual reference.
     CompositorVsyncScheduler* mOwner;
--- a/gfx/layers/ipc/CompositorVsyncSchedulerOwner.h
+++ b/gfx/layers/ipc/CompositorVsyncSchedulerOwner.h
@@ -2,31 +2,29 @@
 /* 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_layers_CompositorVsyncSchedulerOwner_h
 #define mozilla_layers_CompositorVsyncSchedulerOwner_h
 
-#include "mozilla/VsyncDispatcher.h"
-
 namespace mozilla {
 
 namespace gfx {
 class DrawTarget;
 }  // namespace gfx
 
 namespace layers {
 
 class CompositorVsyncSchedulerOwner {
  public:
   virtual bool IsPendingComposite() = 0;
   virtual void FinishPendingComposite() = 0;
-  virtual void CompositeToTarget(VsyncId aId, gfx::DrawTarget* aTarget,
+  virtual void CompositeToTarget(gfx::DrawTarget* aTarget,
                                  const gfx::IntRect* aRect = nullptr) = 0;
   virtual TimeDuration GetVsyncInterval() const = 0;
 };
 
 }  // namespace layers
 }  // namespace mozilla
 
 #endif  // mozilla_layers_CompositorVsyncSchedulerOwner_h
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -384,28 +384,32 @@ void CrossProcessCompositorBridgeParent:
         MakeUnique<ContentBuildPayload>(aInfo.transactionStart(), endTime));
   }
 #endif
   Telemetry::Accumulate(
       Telemetry::CONTENT_FULL_PAINT_TIME,
       static_cast<uint32_t>(
           (endTime - aInfo.transactionStart()).ToMilliseconds()));
 
-  aLayerTree->SetPendingTransactionId(
-      aInfo.id(), aInfo.vsyncId(), aInfo.refreshStart(),
-      aInfo.transactionStart(), aInfo.url(), aInfo.fwdTime());
+  aLayerTree->SetPendingTransactionId(aInfo.id(), aInfo.refreshStart(),
+                                      aInfo.transactionStart(), aInfo.url(),
+                                      aInfo.fwdTime());
+}
+
+void CrossProcessCompositorBridgeParent::DidComposite(
+    LayersId aId, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd) {
+  MonitorAutoLock lock(*sIndirectLayerTreesLock);
+  DidCompositeLocked(aId, aCompositeStart, aCompositeEnd);
 }
 
 void CrossProcessCompositorBridgeParent::DidCompositeLocked(
-    LayersId aId, const VsyncId& aVsyncId, TimeStamp& aCompositeStart,
-    TimeStamp& aCompositeEnd) {
+    LayersId aId, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd) {
   sIndirectLayerTreesLock->AssertCurrentThreadOwns();
   if (LayerTransactionParent* layerTree = sIndirectLayerTrees[aId].mLayerTree) {
-    TransactionId transactionId =
-        layerTree->FlushTransactionId(aVsyncId, aCompositeEnd);
+    TransactionId transactionId = layerTree->FlushTransactionId(aCompositeEnd);
     if (transactionId.IsValid()) {
       Unused << SendDidComposite(aId, transactionId, aCompositeStart,
                                  aCompositeEnd);
     }
   } else if (sIndirectLayerTrees[aId].mWrBridge) {
     MOZ_ASSERT(false);  // this should never get called for a WR compositor
   }
 }
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h
@@ -132,18 +132,20 @@ class CrossProcessCompositorBridgeParent
       LayerTransactionParent* aParent) override;
   mozilla::ipc::IPCResult RecvRemotePluginsReady() override {
     return IPC_FAIL_NO_REASON(this);
   }
 
   // Use DidCompositeLocked if you already hold a lock on
   // sIndirectLayerTreesLock; Otherwise use DidComposite, which would request
   // the lock automatically.
-  void DidCompositeLocked(LayersId aId, const VsyncId& aVsyncId,
-                          TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd);
+  void DidCompositeLocked(LayersId aId, TimeStamp& aCompositeStart,
+                          TimeStamp& aCompositeEnd);
+  void DidComposite(LayersId aId, TimeStamp& aCompositeStart,
+                    TimeStamp& aCompositeEnd) override;
 
   PTextureParent* AllocPTextureParent(
       const SurfaceDescriptor& aSharedData, const ReadLockDescriptor& aReadLock,
       const LayersBackend& aLayersBackend, const TextureFlags& aFlags,
       const LayersId& aId, const uint64_t& aSerial,
       const wr::MaybeExternalImageId& aExternalImageId) override;
 
   bool DeallocPTextureParent(PTextureParent* actor) override;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -34,18 +34,16 @@
 #include "nsMathUtils.h"      // for NS_round
 #include "nsPoint.h"          // for nsPoint
 #include "nsTArray.h"         // for nsTArray, nsTArray_Impl, etc
 #include "TreeTraversal.h"    // for ForEachNode
 #include "GeckoProfiler.h"
 #include "mozilla/layers/TextureHost.h"
 #include "mozilla/layers/AsyncCompositionManager.h"
 
-using mozilla::Telemetry::LABELS_CONTENT_FRAME_TIME_REASON;
-
 namespace mozilla {
 namespace layers {
 
 //--------------------------------------------------
 // LayerTransactionParent
 LayerTransactionParent::LayerTransactionParent(
     HostLayerManager* aManager, CompositorBridgeParentBase* aBridge,
     CompositorAnimationStorage* aAnimStorage, LayersId aId,
@@ -881,59 +879,22 @@ void LayerTransactionParent::DeallocShme
   PLayerTransactionParent::DeallocShmem(aShmem);
 }
 
 bool LayerTransactionParent::IsSameProcess() const {
   return OtherPid() == base::GetCurrentProcId();
 }
 
 TransactionId LayerTransactionParent::FlushTransactionId(
-    const VsyncId& aId, TimeStamp& aCompositeEnd) {
+    TimeStamp& aCompositeEnd) {
   if (mId.IsValid() && mPendingTransaction.IsValid() && !mVsyncRate.IsZero()) {
     double latencyMs = (aCompositeEnd - mTxnStartTime).ToMilliseconds();
     double latencyNorm = latencyMs / mVsyncRate.ToMilliseconds();
     int32_t fracLatencyNorm = lround(latencyNorm * 100.0);
     Telemetry::Accumulate(Telemetry::CONTENT_FRAME_TIME, fracLatencyNorm);
-
-    // Record CONTENT_FRAME_TIME_REASON. See
-    // WebRenderBridgeParent::FlushTransactionIdsForEpoch for more details.
-    //
-    // Note that deseralizing a layers update (RecvUpdate) can delay the receipt
-    // of the composite vsync message
-    // (CompositorBridgeParent::CompositeToTarget), since they're using the same
-    // thread. This can mean that compositing might start significantly late,
-    // but this code will still detect it as having successfully started on the
-    // right vsync (which is somewhat correct). We'd now have reduced time left
-    // in the vsync interval to finish compositing, so the chances of a missed
-    // frame increases. This is effectively including the RecvUpdate work as
-    // part of the 'compositing' phase for this metric, but it isn't included in
-    // COMPOSITE_TIME, and *is* included in CONTENT_FULL_PAINT_TIME.
-    latencyMs = (aCompositeEnd - mRefreshStartTime).ToMilliseconds();
-    latencyNorm = latencyMs / mVsyncRate.ToMilliseconds();
-    fracLatencyNorm = lround(latencyNorm * 100.0);
-    if (fracLatencyNorm < 200) {
-      // Success
-      Telemetry::AccumulateCategorical(
-          LABELS_CONTENT_FRAME_TIME_REASON::Success);
-    } else {
-      if (mTxnVsyncId == VsyncId() || aId == VsyncId() || mTxnVsyncId >= aId) {
-        // Vsync ids are nonsensical, possibly something got trigged from
-        // outside vsync?
-        Telemetry::AccumulateCategorical(
-            LABELS_CONTENT_FRAME_TIME_REASON::NoVsync);
-      } else if (aId - mTxnVsyncId > 1) {
-        // Composite started late (and maybe took too long as well)
-        Telemetry::AccumulateCategorical(
-            LABELS_CONTENT_FRAME_TIME_REASON::MissedComposite);
-      } else {
-        // Composite start on time, but must have taken too long.
-        Telemetry::AccumulateCategorical(
-            LABELS_CONTENT_FRAME_TIME_REASON::SlowComposite);
-      }
-    }
   }
 
 #if defined(ENABLE_FRAME_LATENCY_LOG)
   if (mPendingTransaction.IsValid()) {
     if (mRefreshStartTime) {
       int32_t latencyMs =
           lround((aCompositeEnd - mRefreshStartTime).ToMilliseconds());
       printf_stderr(
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -67,30 +67,28 @@ class LayerTransactionParent final : pub
   bool AllocUnsafeShmem(size_t aSize, ipc::SharedMemory::SharedMemoryType aType,
                         ipc::Shmem* aShmem) override;
 
   void DeallocShmem(ipc::Shmem& aShmem) override;
 
   bool IsSameProcess() const override;
 
   const TransactionId& GetPendingTransactionId() { return mPendingTransaction; }
-  void SetPendingTransactionId(TransactionId aId, const VsyncId& aVsyncId,
+  void SetPendingTransactionId(TransactionId aId,
                                const TimeStamp& aRefreshStartTime,
                                const TimeStamp& aTxnStartTime,
                                const nsCString& aURL,
                                const TimeStamp& aFwdTime) {
     mPendingTransaction = aId;
-    mTxnVsyncId = aVsyncId;
     mRefreshStartTime = aRefreshStartTime;
     mTxnStartTime = aTxnStartTime;
     mTxnURL = aURL;
     mFwdTime = aFwdTime;
   }
-  TransactionId FlushTransactionId(const VsyncId& aId,
-                                   TimeStamp& aCompositeEnd);
+  TransactionId FlushTransactionId(TimeStamp& aCompositeEnd);
 
   // CompositableParentManager
   void SendAsyncMessage(
       const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
 
   void SendPendingAsyncMessages() override;
 
   void SetAboutToSendAsyncMessages() override;
@@ -199,17 +197,16 @@ class LayerTransactionParent final : pub
   // mParentEpoch is the latest epoch value that we have told TabParent about
   // (via ObserveLayerUpdate).
   LayersObserverEpoch mChildEpoch;
   LayersObserverEpoch mParentEpoch;
 
   TimeDuration mVsyncRate;
 
   TransactionId mPendingTransaction;
-  VsyncId mTxnVsyncId;
   TimeStamp mRefreshStartTime;
   TimeStamp mTxnStartTime;
   TimeStamp mFwdTime;
   nsCString mTxnURL;
 
   // When the widget/frame/browser stuff in this process begins its
   // destruction process, we need to Disconnect() all the currently
   // live shadow layers, because some of them might be orphaned from
--- a/gfx/layers/ipc/LayersMessageUtils.h
+++ b/gfx/layers/ipc/LayersMessageUtils.h
@@ -19,53 +19,33 @@
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/FocusTarget.h"
 #include "mozilla/layers/GeckoContentController.h"
 #include "mozilla/layers/KeyboardMap.h"
 #include "mozilla/layers/LayerAttributes.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/layers/RefCountedShmem.h"
 #include "mozilla/layers/RepaintRequest.h"
-#include "VsyncSource.h"
 #include "mozilla/Move.h"
 
 #include <stdint.h>
 
 #ifdef _MSC_VER
 #pragma warning(disable : 4800)
 #endif
 
 namespace IPC {
 
 template <>
 struct ParamTraits<mozilla::layers::LayersId>
     : public PlainOldDataSerializer<mozilla::layers::LayersId> {};
 
-template <typename T>
-struct ParamTraits<mozilla::layers::BaseTransactionId<T>>
-    : public PlainOldDataSerializer<mozilla::layers::BaseTransactionId<T>> {};
-
 template <>
-struct ParamTraits<mozilla::VsyncId>
-    : public PlainOldDataSerializer<mozilla::VsyncId> {};
-
-template <>
-struct ParamTraits<mozilla::VsyncEvent> {
-  typedef mozilla::VsyncEvent paramType;
-
-  static void Write(Message* msg, const paramType& param) {
-    WriteParam(msg, param.mId);
-    WriteParam(msg, param.mTime);
-  }
-  static bool Read(const Message* msg, PickleIterator* iter,
-                   paramType* result) {
-    return ReadParam(msg, iter, &result->mId) &&
-           ReadParam(msg, iter, &result->mTime);
-  }
-};
+struct ParamTraits<mozilla::layers::TransactionId>
+    : public PlainOldDataSerializer<mozilla::layers::TransactionId> {};
 
 template <>
 struct ParamTraits<mozilla::layers::LayersObserverEpoch>
     : public PlainOldDataSerializer<mozilla::layers::LayersObserverEpoch> {};
 
 template <>
 struct ParamTraits<mozilla::layers::LayersBackend>
     : public ContiguousEnumSerializer<
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -47,17 +47,16 @@ using mozilla::layers::ScrollableLayerGu
 using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::LayerHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::SimpleLayerAttributes from "mozilla/layers/LayerAttributes.h";
 using mozilla::CrossProcessSemaphoreHandle from "mozilla/ipc/CrossProcessSemaphore.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::TransactionId from "mozilla/layers/LayersTypes.h";
-using mozilla::VsyncId from "mozilla/VsyncDispatcher.h";
 
 namespace mozilla {
 namespace layers {
 
 struct TargetConfig {
   IntRect naturalBounds;
   ScreenRotation rotation;
   ScreenOrientation orientation;
@@ -550,17 +549,16 @@ struct TransactionInfo
   TransactionId id;
   TargetConfig targetConfig;
   PluginWindowData[] plugins;
   bool isFirstPaint;
   FocusTarget focusTarget;
   bool scheduleComposite;
   uint32_t paintSequenceNumber;
   bool isRepeatTransaction;
-  VsyncId vsyncId;
   TimeStamp refreshStart;
   TimeStamp transactionStart;
   nsCString url;
   TimeStamp fwdTime;
 };
 
 union MaybeTransform {
   Matrix4x4;
--- a/gfx/layers/ipc/PWebRenderBridge.ipdl
+++ b/gfx/layers/ipc/PWebRenderBridge.ipdl
@@ -23,17 +23,16 @@ using mozilla::layers::CompositableHandl
 using mozilla::wr::BuiltDisplayListDescriptor from "mozilla/webrender/webrender_ffi.h";
 using mozilla::wr::IdNamespace from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::wr::MaybeIdNamespace from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::wr::ExternalImageKeyPair from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::layers::WebRenderScrollData from "mozilla/layers/WebRenderScrollData.h";
 using mozilla::layers::FocusTarget from "mozilla/layers/FocusTarget.h";
 using mozilla::layers::LayersObserverEpoch from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::TransactionId from "mozilla/layers/LayersTypes.h";
-using mozilla::VsyncId from "mozilla/VsyncDispatcher.h";
 
 namespace mozilla {
 namespace layers {
 
 sync protocol PWebRenderBridge
 {
   manager PCompositorBridge;
 
@@ -44,21 +43,21 @@ parent:
   async NewCompositable(CompositableHandle handle, TextureInfo info);
   async ReleaseCompositable(CompositableHandle compositable);
 
   async DeleteCompositorAnimations(uint64_t[] aIds);
   async SetDisplayList(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, TransactionId transactionId,
                        LayoutSize aContentSize, ByteBuf aDL, BuiltDisplayListDescriptor aDLDesc,
                        WebRenderScrollData aScrollData,
                        OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems,
-                       IdNamespace aIdNamespace, bool containsSVGGroup, VsyncId vsyncId, TimeStamp refreshStartTime, TimeStamp txnStartTime, nsCString txnURL, TimeStamp fwdTime);
+                       IdNamespace aIdNamespace, bool containsSVGGroup, TimeStamp refreshStartTime, TimeStamp txnStartTime, nsCString txnURL, TimeStamp fwdTime);
   async EmptyTransaction(FocusTarget focusTarget, ScrollUpdatesMap scrollUpdates, uint32_t aPaintSequenceNumber,
                          WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, TransactionId transactionId,
                          OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems,
-                         IdNamespace aIdNamespace, VsyncId vsyncId, TimeStamp refreshStartTime, TimeStamp txnStartTime, nsCString txnURL, TimeStamp fwdTime);
+                         IdNamespace aIdNamespace, TimeStamp refreshStartTime, TimeStamp txnStartTime, nsCString txnURL, TimeStamp fwdTime);
   async SetFocusTarget(FocusTarget focusTarget);
   async UpdateResources(OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems);
   async ParentCommands(WebRenderParentCommand[] commands);
   sync GetSnapshot(PTexture texture);
   async SetLayersObserverEpoch(LayersObserverEpoch childEpoch);
   async ClearCachedResources();
   // Schedule a composite if one isn't already scheduled.
   async ScheduleComposite();
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -523,18 +523,17 @@ void ShadowLayerForwarder::SendPaintTime
   if (!IPCOpen() || !mShadowManager->SendPaintTime(aId, aPaintTime)) {
     NS_WARNING("Could not send paint times over IPC");
   }
 }
 
 bool ShadowLayerForwarder::EndTransaction(
     const nsIntRegion& aRegionToClear, TransactionId aId,
     bool aScheduleComposite, uint32_t aPaintSequenceNumber,
-    bool aIsRepeatTransaction, const mozilla::VsyncId& aVsyncId,
-    const mozilla::TimeStamp& aRefreshStart,
+    bool aIsRepeatTransaction, const mozilla::TimeStamp& aRefreshStart,
     const mozilla::TimeStamp& aTransactionStart, const nsCString& aURL,
     bool* aSent) {
   *aSent = false;
 
   TransactionInfo info;
 
   MOZ_ASSERT(IPCOpen(), "no manager to forward to");
   if (!IPCOpen()) {
@@ -666,17 +665,16 @@ bool ShadowLayerForwarder::EndTransactio
   info.fwdTransactionId() = GetFwdTransactionId();
   info.id() = aId;
   info.plugins() = mPluginWindowData;
   info.isFirstPaint() = mIsFirstPaint;
   info.focusTarget() = mFocusTarget;
   info.scheduleComposite() = aScheduleComposite;
   info.paintSequenceNumber() = aPaintSequenceNumber;
   info.isRepeatTransaction() = aIsRepeatTransaction;
-  info.vsyncId() = aVsyncId;
   info.refreshStart() = aRefreshStart;
   info.transactionStart() = aTransactionStart;
   info.url() = aURL;
 #if defined(ENABLE_FRAME_LATENCY_LOG)
   info.fwdTime() = TimeStamp::Now();
 #endif
 
   TargetConfig targetConfig(mTxn->mTargetBounds, mTxn->mTargetRotation,
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -247,17 +247,16 @@ class ShadowLayerForwarder final : publi
   /**
    * End the current transaction and forward it to LayerManagerComposite.
    * |aReplies| are directions from the LayerManagerComposite to the
    * caller of EndTransaction().
    */
   bool EndTransaction(const nsIntRegion& aRegionToClear, TransactionId aId,
                       bool aScheduleComposite, uint32_t aPaintSequenceNumber,
                       bool aIsRepeatTransaction,
-                      const mozilla::VsyncId& aVsyncId,
                       const mozilla::TimeStamp& aRefreshStart,
                       const mozilla::TimeStamp& aTransactionStart,
                       const nsCString& aURL, bool* aSent);
 
   /**
    * Set an actor through which layer updates will be pushed.
    */
   void SetShadowManager(PLayerTransactionChild* aShadowManager);
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -100,50 +100,47 @@ void WebRenderBridgeChild::UpdateResourc
 
   this->SendUpdateResources(resourceUpdates, smallShmems, largeShmems);
 }
 
 void WebRenderBridgeChild::EndTransaction(
     const wr::LayoutSize& aContentSize, wr::BuiltDisplayList& aDL,
     wr::IpcResourceUpdateQueue& aResources, const gfx::IntSize& aSize,
     TransactionId aTransactionId, const WebRenderScrollData& aScrollData,
-    bool aContainsSVGGroup, const mozilla::VsyncId& aVsyncId,
-    const mozilla::TimeStamp& aRefreshStartTime,
+    bool aContainsSVGGroup, const mozilla::TimeStamp& aRefreshStartTime,
     const mozilla::TimeStamp& aTxnStartTime, const nsCString& aTxnURL) {
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(mIsInTransaction);
 
   ByteBuf dlData(aDL.dl.inner.data, aDL.dl.inner.length, aDL.dl.inner.capacity);
   aDL.dl.inner.capacity = 0;
   aDL.dl.inner.data = nullptr;
 
   TimeStamp fwdTime = TimeStamp::Now();
 
   nsTArray<OpUpdateResource> resourceUpdates;
   nsTArray<RefCountedShmem> smallShmems;
   nsTArray<ipc::Shmem> largeShmems;
   aResources.Flush(resourceUpdates, smallShmems, largeShmems);
 
-  this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors,
-                           GetFwdTransactionId(), aTransactionId, aContentSize,
-                           dlData, aDL.dl_desc, aScrollData, resourceUpdates,
-                           smallShmems, largeShmems, mIdNamespace,
-                           aContainsSVGGroup, aVsyncId, aRefreshStartTime,
-                           aTxnStartTime, aTxnURL, fwdTime);
+  this->SendSetDisplayList(
+      aSize, mParentCommands, mDestroyedActors, GetFwdTransactionId(),
+      aTransactionId, aContentSize, dlData, aDL.dl_desc, aScrollData,
+      resourceUpdates, smallShmems, largeShmems, mIdNamespace,
+      aContainsSVGGroup, aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime);
 
   mParentCommands.Clear();
   mDestroyedActors.Clear();
   mIsInTransaction = false;
 }
 
 void WebRenderBridgeChild::EndEmptyTransaction(
     const FocusTarget& aFocusTarget, const ScrollUpdatesMap& aUpdates,
     Maybe<wr::IpcResourceUpdateQueue>& aResources,
     uint32_t aPaintSequenceNumber, TransactionId aTransactionId,
-    const mozilla::VsyncId& aVsyncId,
     const mozilla::TimeStamp& aRefreshStartTime,
     const mozilla::TimeStamp& aTxnStartTime, const nsCString& aTxnURL) {
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(mIsInTransaction);
 
   TimeStamp fwdTime = TimeStamp::Now();
 
   nsTArray<OpUpdateResource> resourceUpdates;
@@ -152,18 +149,18 @@ void WebRenderBridgeChild::EndEmptyTrans
   if (aResources) {
     aResources->Flush(resourceUpdates, smallShmems, largeShmems);
     aResources.reset();
   }
 
   this->SendEmptyTransaction(
       aFocusTarget, aUpdates, aPaintSequenceNumber, mParentCommands,
       mDestroyedActors, GetFwdTransactionId(), aTransactionId, resourceUpdates,
-      smallShmems, largeShmems, mIdNamespace, aVsyncId, aRefreshStartTime,
-      aTxnStartTime, aTxnURL, fwdTime);
+      smallShmems, largeShmems, mIdNamespace, aRefreshStartTime, aTxnStartTime,
+      aTxnURL, fwdTime);
   mParentCommands.Clear();
   mDestroyedActors.Clear();
   mIsInTransaction = false;
 }
 
 void WebRenderBridgeChild::ProcessWebRenderParentCommands() {
   MOZ_ASSERT(!mDestroyed);
 
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -61,31 +61,27 @@ class WebRenderBridgeChild final : publi
 
  public:
   explicit WebRenderBridgeChild(const wr::PipelineId& aPipelineId);
 
   void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
 
   void UpdateResources(wr::IpcResourceUpdateQueue& aResources);
   void BeginTransaction();
-  void EndTransaction(const wr::LayoutSize& aContentSize,
-                      wr::BuiltDisplayList& dl,
-                      wr::IpcResourceUpdateQueue& aResources,
-                      const gfx::IntSize& aSize, TransactionId aTransactionId,
-                      const WebRenderScrollData& aScrollData,
-                      bool aContainsSVGroup, const mozilla::VsyncId& aVsyncId,
-                      const mozilla::TimeStamp& aRefreshStartTime,
-                      const mozilla::TimeStamp& aTxnStartTime,
-                      const nsCString& aTxtURL);
+  void EndTransaction(
+      const wr::LayoutSize& aContentSize, wr::BuiltDisplayList& dl,
+      wr::IpcResourceUpdateQueue& aResources, const gfx::IntSize& aSize,
+      TransactionId aTransactionId, const WebRenderScrollData& aScrollData,
+      bool aContainsSVGroup, const mozilla::TimeStamp& aRefreshStartTime,
+      const mozilla::TimeStamp& aTxnStartTime, const nsCString& aTxtURL);
   void EndEmptyTransaction(const FocusTarget& aFocusTarget,
                            const ScrollUpdatesMap& aUpdates,
                            Maybe<wr::IpcResourceUpdateQueue>& aResources,
                            uint32_t aPaintSequenceNumber,
                            TransactionId aTransactionId,
-                           const mozilla::VsyncId& aVsyncId,
                            const mozilla::TimeStamp& aRefreshStartTime,
                            const mozilla::TimeStamp& aTxnStartTime,
                            const nsCString& aTxtURL);
   void ProcessWebRenderParentCommands();
 
   CompositorBridgeChild* GetCompositorBridgeChild();
 
   wr::PipelineId GetPipeline() { return mPipelineId; }
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -30,18 +30,16 @@
 #include "mozilla/layers/WebRenderImageHost.h"
 #include "mozilla/layers/WebRenderTextureHost.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Unused.h"
 #include "mozilla/webrender/RenderThread.h"
 #include "mozilla/widget/CompositorWidget.h"
 
-using mozilla::Telemetry::LABELS_CONTENT_FRAME_TIME_REASON;
-
 #ifdef MOZ_GECKO_PROFILER
 #include "ProfilerMarkerPayload.h"
 #endif
 
 bool is_in_main_thread() { return NS_IsMainThread(); }
 
 bool is_in_compositor_thread() {
   return mozilla::layers::CompositorThreadHolder::IsInCompositorThread();
@@ -851,19 +849,19 @@ mozilla::ipc::IPCResult WebRenderBridgeP
     InfallibleTArray<WebRenderParentCommand>&& aCommands,
     InfallibleTArray<OpDestroy>&& aToDestroy, const uint64_t& aFwdTransactionId,
     const TransactionId& aTransactionId, const wr::LayoutSize& aContentSize,
     ipc::ByteBuf&& dl, const wr::BuiltDisplayListDescriptor& dlDesc,
     const WebRenderScrollData& aScrollData,
     nsTArray<OpUpdateResource>&& aResourceUpdates,
     nsTArray<RefCountedShmem>&& aSmallShmems,
     nsTArray<ipc::Shmem>&& aLargeShmems, const wr::IdNamespace& aIdNamespace,
-    const bool& aContainsSVGGroup, const VsyncId& aVsyncId,
-    const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
-    const nsCString& aTxnURL, const TimeStamp& aFwdTime) {
+    const bool& aContainsSVGGroup, const TimeStamp& aRefreshStartTime,
+    const TimeStamp& aTxnStartTime, const nsCString& aTxnURL,
+    const TimeStamp& aFwdTime) {
   if (mDestroyed) {
     for (const auto& op : aToDestroy) {
       DestroyActor(op);
     }
     return IPC_OK();
   }
 
   AUTO_PROFILER_TRACING("Paint", "SetDisplayList");
@@ -942,28 +940,27 @@ mozilla::ipc::IPCResult WebRenderBridgeP
 
     // We will schedule generating a frame after the scene
     // build is done, so we don't need to do it here.
   } else if (observeLayersUpdate) {
     mCompositorBridge->ObserveLayersUpdate(GetLayersId(),
                                            mChildLayersObserverEpoch, true);
   }
 
-  HoldPendingTransactionId(wrEpoch, aTransactionId, aContainsSVGGroup, aVsyncId,
+  HoldPendingTransactionId(wrEpoch, aTransactionId, aContainsSVGGroup,
                            aRefreshStartTime, aTxnStartTime, aTxnURL, aFwdTime,
                            mIsFirstPaint);
   mIsFirstPaint = false;
 
   if (!validTransaction) {
     // Pretend we composited since someone is wating for this event,
     // though DisplayList was not pushed to webrender.
     if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
       TimeStamp now = TimeStamp::Now();
-      cbp->NotifyPipelineRendered(mPipelineId, wrEpoch, VsyncId(), now, now,
-                                  now);
+      cbp->NotifyPipelineRendered(mPipelineId, wrEpoch, now, now, now);
     }
   }
 
   wr::IpcResourceUpdateQueue::ReleaseShmems(this, aSmallShmems);
   wr::IpcResourceUpdateQueue::ReleaseShmems(this, aLargeShmems);
   return IPC_OK();
 }
 
@@ -971,19 +968,18 @@ mozilla::ipc::IPCResult WebRenderBridgeP
     const FocusTarget& aFocusTarget, const ScrollUpdatesMap& aUpdates,
     const uint32_t& aPaintSequenceNumber,
     InfallibleTArray<WebRenderParentCommand>&& aCommands,
     InfallibleTArray<OpDestroy>&& aToDestroy, const uint64_t& aFwdTransactionId,
     const TransactionId& aTransactionId,
     nsTArray<OpUpdateResource>&& aResourceUpdates,
     nsTArray<RefCountedShmem>&& aSmallShmems,
     nsTArray<ipc::Shmem>&& aLargeShmems, const wr::IdNamespace& aIdNamespace,
-    const VsyncId& aVsyncId, const TimeStamp& aRefreshStartTime,
-    const TimeStamp& aTxnStartTime, const nsCString& aTxnURL,
-    const TimeStamp& aFwdTime) {
+    const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
+    const nsCString& aTxnURL, const TimeStamp& aFwdTime) {
   if (mDestroyed) {
     for (const auto& op : aToDestroy) {
       DestroyActor(op);
     }
     return IPC_OK();
   }
 
   AUTO_PROFILER_TRACING("Paint", "EmptyTransaction");
@@ -1057,35 +1053,34 @@ mozilla::ipc::IPCResult WebRenderBridgeP
     // If there are no pending transactions and we're not going to do a
     // composite, then we leave sendDidComposite as true so we just send
     // the DidComposite notification now.
     sendDidComposite = false;
   }
 
   // Only register a value for CONTENT_FRAME_TIME telemetry if we actually drew
   // something. It is for consistency with disabling WebRender.
-  HoldPendingTransactionId(mWrEpoch, aTransactionId, false, aVsyncId,
-                           aRefreshStartTime, aTxnStartTime, aTxnURL, aFwdTime,
+  HoldPendingTransactionId(mWrEpoch, aTransactionId, false, aRefreshStartTime,
+                           aTxnStartTime, aTxnURL, aFwdTime,
                            /* aIsFirstPaint */ false,
                            /* aUseForTelemetry */ scheduleComposite);
 
   if (scheduleComposite) {
     // This is actually not necessary, since ScheduleGenerateFrame() is
     // triggered via SceneBuilder thread. But if we remove it, it causes talos
     // regression. The SceneBuilder thread seems not trigger next vsync right
     // away. For now, we call ScheduleGenerateFrame() here.
     ScheduleGenerateFrame();
   } else if (sendDidComposite) {
     // The only thing in the pending transaction id queue should be the entry
     // we just added, and now we're going to pretend we rendered it
     MOZ_ASSERT(mPendingTransactionIds.size() == 1);
     if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
       TimeStamp now = TimeStamp::Now();
-      cbp->NotifyPipelineRendered(mPipelineId, mWrEpoch, VsyncId(), now, now,
-                                  now);
+      cbp->NotifyPipelineRendered(mPipelineId, mWrEpoch, now, now, now);
     }
   }
 
   wr::IpcResourceUpdateQueue::ReleaseShmems(this, aSmallShmems);
   wr::IpcResourceUpdateQueue::ReleaseShmems(this, aLargeShmems);
   return IPC_OK();
 }
 
@@ -1217,17 +1212,17 @@ void WebRenderBridgeParent::FlushFrameGe
                                               // the root WRBP
 
   // This forces a new GenerateFrame transaction to be sent to the render
   // backend thread, if one is pending. This doesn't block on any other threads.
   if (mCompositorScheduler->NeedsComposite()) {
     mCompositorScheduler->CancelCurrentCompositeTask();
     // Update timestamp of scheduler for APZ and animation.
     mCompositorScheduler->UpdateLastComposeTime();
-    MaybeGenerateFrame(VsyncId(), /* aForceGenerateFrame */ true);
+    MaybeGenerateFrame(/* aForceGenerateFrame */ true);
   }
 }
 
 void WebRenderBridgeParent::FlushFramePresentation() {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
 
   // This sends a message to the render backend thread to send a message
   // to the renderer thread, and waits for that message to be processed. So
@@ -1642,22 +1637,21 @@ bool WebRenderBridgeParent::SampleAnimat
   }
 
   return isAnimating;
 }
 
 void WebRenderBridgeParent::CompositeIfNeeded() {
   if (mSkippedComposite) {
     mSkippedComposite = false;
-    CompositeToTarget(VsyncId(), nullptr, nullptr);
+    CompositeToTarget(nullptr, nullptr);
   }
 }
 
-void WebRenderBridgeParent::CompositeToTarget(VsyncId aId,
-                                              gfx::DrawTarget* aTarget,
+void WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget,
                                               const gfx::IntRect* aRect) {
   // This function should only get called in the root WRBP
   MOZ_ASSERT(IsRootWebRenderBridgeParent());
 
   // The two arguments are part of the CompositorVsyncSchedulerOwner API but in
   // this implementation they should never be non-null.
   MOZ_ASSERT(aTarget == nullptr);
   MOZ_ASSERT(aRect == nullptr);
@@ -1678,30 +1672,29 @@ void WebRenderBridgeParent::CompositeToT
     // all pending transactions that have finished scene building.
     for (auto& id : mPendingTransactionIds) {
       if (id.mSceneBuiltTime) {
         id.mSkippedComposites++;
       }
     }
     return;
   }
-  MaybeGenerateFrame(aId, /* aForceGenerateFrame */ false);
+  MaybeGenerateFrame(/* aForceGenerateFrame */ false);
 }
 
 TimeDuration WebRenderBridgeParent::GetVsyncInterval() const {
   // This function should only get called in the root WRBP
   MOZ_ASSERT(IsRootWebRenderBridgeParent());
   if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
     return cbp->GetVsyncInterval();
   }
   return TimeDuration();
 }
 
-void WebRenderBridgeParent::MaybeGenerateFrame(VsyncId aId,
-                                               bool aForceGenerateFrame) {
+void WebRenderBridgeParent::MaybeGenerateFrame(bool aForceGenerateFrame) {
   // This function should only get called in the root WRBP
   MOZ_ASSERT(IsRootWebRenderBridgeParent());
 
   TimeStamp start = TimeStamp::Now();
   mAsyncImageManager->SetCompositionTime(start);
 
   // Ensure GenerateFrame is handled on the render backend thread rather
   // than going through the scene builder thread. That way we continue
@@ -1739,37 +1732,37 @@ void WebRenderBridgeParent::MaybeGenerat
     ScheduleGenerateFrame();
   }
   // We do this even if the arrays are empty, because it will clear out any
   // previous properties store on the WR side, which is desirable.
   fastTxn.UpdateDynamicProperties(opacityArray, transformArray);
 
   SetAPZSampleTime();
 
-  wr::RenderThread::Get()->IncPendingFrameCount(mApi->GetId(), aId, start);
+  wr::RenderThread::Get()->IncPendingFrameCount(mApi->GetId(), start);
 
 #if defined(ENABLE_FRAME_LATENCY_LOG)
   auto startTime = TimeStamp::Now();
   mApi->SetFrameStartTime(startTime);
 #endif
 
   fastTxn.GenerateFrame();
 
   mApi->SendTransaction(fastTxn);
 }
 
 void WebRenderBridgeParent::HoldPendingTransactionId(
     const wr::Epoch& aWrEpoch, TransactionId aTransactionId,
-    bool aContainsSVGGroup, const VsyncId& aVsyncId,
-    const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
-    const nsCString& aTxnURL, const TimeStamp& aFwdTime,
-    const bool aIsFirstPaint, const bool aUseForTelemetry) {
+    bool aContainsSVGGroup, const TimeStamp& aRefreshStartTime,
+    const TimeStamp& aTxnStartTime, const nsCString& aTxnURL,
+    const TimeStamp& aFwdTime, const bool aIsFirstPaint,
+    const bool aUseForTelemetry) {
   MOZ_ASSERT(aTransactionId > LastPendingTransactionId());
   mPendingTransactionIds.push_back(PendingTransactionId(
-      aWrEpoch, aTransactionId, aContainsSVGGroup, aVsyncId, aRefreshStartTime,
+      aWrEpoch, aTransactionId, aContainsSVGGroup, aRefreshStartTime,
       aTxnStartTime, aTxnURL, aFwdTime, aIsFirstPaint, aUseForTelemetry));
 }
 
 TransactionId WebRenderBridgeParent::LastPendingTransactionId() {
   TransactionId id{0};
   if (!mPendingTransactionIds.empty()) {
     id = mPendingTransactionIds.back().mId;
   }
@@ -1782,20 +1775,20 @@ void WebRenderBridgeParent::NotifySceneB
     if (id.mEpoch.mHandle == aEpoch.mHandle) {
       id.mSceneBuiltTime = aEndTime;
       break;
     }
   }
 }
 
 TransactionId WebRenderBridgeParent::FlushTransactionIdsForEpoch(
-    const wr::Epoch& aEpoch, const VsyncId& aCompositeStartId,
-    const TimeStamp& aCompositeStartTime, const TimeStamp& aRenderStartTime,
-    const TimeStamp& aEndTime, UiCompositorControllerParent* aUiController,
-    wr::RendererStats* aStats, nsTArray<FrameStats>* aOutputStats) {
+    const wr::Epoch& aEpoch, const TimeStamp& aCompositeStartTime,
+    const TimeStamp& aRenderStartTime, const TimeStamp& aEndTime,
+    UiCompositorControllerParent* aUiController, wr::RendererStats* aStats,
+    nsTArray<FrameStats>* aOutputStats) {
   TransactionId id{0};
   while (!mPendingTransactionIds.empty()) {
     const auto& transactionId = mPendingTransactionIds.front();
 
     if (aEpoch.mHandle < transactionId.mEpoch.mHandle) {
       break;
     }
 
@@ -1822,60 +1815,16 @@ TransactionId WebRenderBridgeParent::Flu
         };
         profiler_add_marker_for_thread(
             profiler_current_thread_id(), "CONTENT_FRAME_TIME",
             MakeUnique<ContentFramePayload>(transactionId.mTxnStartTime,
                                             aEndTime));
       }
 #endif
 
-      // Record CONTENT_FRAME_TIME_REASON.
-      //
-      // This uses the refresh start time (CONTENT_FRAME_TIME uses the start of
-      // display list building), since that includes layout/style time, and 200
-      // should correlate more closely with missing a vsync.
-      //
-      // Also of note is that when the root WebRenderBridgeParent decides to
-      // skip a composite (due to the Renderer being busy), that won't notify
-      // child WebRenderBridgeParents. That failure will show up as the
-      // composite starting late (since it did), but it's really a fault of a
-      // slow composite on the previous frame, not a slow
-      // CONTENT_FULL_PAINT_TIME. It would be nice to have a separate bucket for
-      // this category (scene was ready on the next vsync, but we chose not to
-      // composite), but I can't find a way to locate the right child
-      // WebRenderBridgeParents from the root. WebRender notifies us of the
-      // child pipelines contained within a render, after it finishes, but I
-      // can't see how to query what child pipeline would have been rendered,
-      // when we choose to not do it.
-      latencyMs = (aEndTime - transactionId.mRefreshStartTime).ToMilliseconds();
-      latencyNorm = latencyMs / mVsyncRate.ToMilliseconds();
-      fracLatencyNorm = lround(latencyNorm * 100.0);
-      if (fracLatencyNorm < 200) {
-        // Success
-        Telemetry::AccumulateCategorical(
-            LABELS_CONTENT_FRAME_TIME_REASON::Success);
-      } else {
-        if (transactionId.mVsyncId == VsyncId() ||
-            aCompositeStartId == VsyncId() ||
-            transactionId.mVsyncId >= aCompositeStartId) {
-          // Vsync ids are nonsensical, possibly something got trigged from
-          // outside vsync?
-          Telemetry::AccumulateCategorical(
-              LABELS_CONTENT_FRAME_TIME_REASON::NoVsync);
-        } else if (aCompositeStartId - transactionId.mVsyncId > 1) {
-          // Composite started late (and maybe took too long as well)
-          Telemetry::AccumulateCategorical(
-              LABELS_CONTENT_FRAME_TIME_REASON::MissedComposite);
-        } else {
-          // Composite start on time, but must have taken too long.
-          Telemetry::AccumulateCategorical(
-              LABELS_CONTENT_FRAME_TIME_REASON::SlowComposite);
-        }
-      }
-
       if (fracLatencyNorm > 200) {
         aOutputStats->AppendElement(FrameStats(
             transactionId.mId, aCompositeStartTime, aRenderStartTime, aEndTime,
             fracLatencyNorm,
             aStats ? (double(aStats->resource_upload_time) / 1000000.0) : 0.0,
             aStats ? (double(aStats->gpu_cache_upload_time) / 1000000.0) : 0.0,
             transactionId.mTxnStartTime, transactionId.mRefreshStartTime,
             transactionId.mFwdTime, transactionId.mSceneBuiltTime,
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -97,31 +97,30 @@ class WebRenderBridgeParent final : publ
       InfallibleTArray<OpDestroy>&& aToDestroy,
       const uint64_t& aFwdTransactionId, const TransactionId& aTransactionId,
       const wr::LayoutSize& aContentSize, ipc::ByteBuf&& dl,
       const wr::BuiltDisplayListDescriptor& dlDesc,
       const WebRenderScrollData& aScrollData,
       nsTArray<OpUpdateResource>&& aResourceUpdates,
       nsTArray<RefCountedShmem>&& aSmallShmems,
       nsTArray<ipc::Shmem>&& aLargeShmems, const wr::IdNamespace& aIdNamespace,
-      const bool& aContainsSVGGroup, const VsyncId& aVsyncId,
-      const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
-      const nsCString& aTxnURL, const TimeStamp& aFwdTime) override;
+      const bool& aContainsSVGGroup, const TimeStamp& aRefreshStartTime,
+      const TimeStamp& aTxnStartTime, const nsCString& aTxnURL,
+      const TimeStamp& aFwdTime) override;
   mozilla::ipc::IPCResult RecvEmptyTransaction(
       const FocusTarget& aFocusTarget, const ScrollUpdatesMap& aUpdates,
       const uint32_t& aPaintSequenceNumber,
       InfallibleTArray<WebRenderParentCommand>&& aCommands,
       InfallibleTArray<OpDestroy>&& aToDestroy,
       const uint64_t& aFwdTransactionId, const TransactionId& aTransactionId,
       nsTArray<OpUpdateResource>&& aResourceUpdates,
       nsTArray<RefCountedShmem>&& aSmallShmems,
       nsTArray<ipc::Shmem>&& aLargeShmems, const wr::IdNamespace& aIdNamespace,
-      const VsyncId& aVsyncId, const TimeStamp& aRefreshStartTime,
-      const TimeStamp& aTxnStartTime, const nsCString& aTxnURL,
-      const TimeStamp& aFwdTime) override;
+      const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
+      const nsCString& aTxnURL, const TimeStamp& aFwdTime) override;
   mozilla::ipc::IPCResult RecvSetFocusTarget(
       const FocusTarget& aFocusTarget) override;
   mozilla::ipc::IPCResult RecvParentCommands(
       nsTArray<WebRenderParentCommand>&& commands) override;
   mozilla::ipc::IPCResult RecvGetSnapshot(PTextureParent* aTexture) override;
 
   mozilla::ipc::IPCResult RecvSetLayersObserverEpoch(
       const LayersObserverEpoch& aChildEpoch) override;
@@ -154,41 +153,41 @@ class WebRenderBridgeParent final : publ
   void Pause();
   bool Resume();
 
   void Destroy();
 
   // CompositorVsyncSchedulerOwner
   bool IsPendingComposite() override { return false; }
   void FinishPendingComposite() override {}
-  void CompositeToTarget(VsyncId aId, gfx::DrawTarget* aTarget,
+  void CompositeToTarget(gfx::DrawTarget* aTarget,
                          const gfx::IntRect* aRect = nullptr) override;
   TimeDuration GetVsyncInterval() const override;
 
   // CompositableParentManager
   bool IsSameProcess() const override;
   base::ProcessId GetChildProcessId() override;
   void NotifyNotUsed(PTextureParent* aTexture,
                      uint64_t aTransactionId) override;
   void SendAsyncMessage(
       const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
   void SendPendingAsyncMessages() override;
   void SetAboutToSendAsyncMessages() override;
 
   void HoldPendingTransactionId(
       const wr::Epoch& aWrEpoch, TransactionId aTransactionId,
-      bool aContainsSVGGroup, const VsyncId& aVsyncId,
-      const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
-      const nsCString& aTxnURL, const TimeStamp& aFwdTime,
-      const bool aIsFirstPaint, const bool aUseForTelemetry = true);
+      bool aContainsSVGGroup, const TimeStamp& aRefreshStartTime,
+      const TimeStamp& aTxnStartTime, const nsCString& aTxnURL,
+      const TimeStamp& aFwdTime, const bool aIsFirstPaint,
+      const bool aUseForTelemetry = true);
   TransactionId LastPendingTransactionId();
   TransactionId FlushTransactionIdsForEpoch(
-      const wr::Epoch& aEpoch, const VsyncId& aCompositeStartId,
-      const TimeStamp& aCompositeStartTime, const TimeStamp& aRenderStartTime,
-      const TimeStamp& aEndTime, UiCompositorControllerParent* aUiController,
+      const wr::Epoch& aEpoch, const TimeStamp& aCompositeStartTime,
+      const TimeStamp& aRenderStartTime, const TimeStamp& aEndTime,
+      UiCompositorControllerParent* aUiController,
       wr::RendererStats* aStats = nullptr,
       nsTArray<FrameStats>* aOutputStats = nullptr);
   void NotifySceneBuiltForEpoch(const wr::Epoch& aEpoch,
                                 const TimeStamp& aEndTime);
 
   void CompositeIfNeeded();
 
   TextureFactoryIdentifier GetTextureFactoryIdentifier();
@@ -311,40 +310,38 @@ class WebRenderBridgeParent final : publ
   // In this case, ScheduleGenerateFrame is not triggered via SceneBuilder.
   // Then we want to rollback WrEpoch. See Bug 1490117.
   void RollbackWrEpoch();
 
   void FlushSceneBuilds();
   void FlushFrameGeneration();
   void FlushFramePresentation();
 
-  void MaybeGenerateFrame(VsyncId aId, bool aForceGenerateFrame);
+  void MaybeGenerateFrame(bool aForceGenerateFrame);
 
  private:
   struct PendingTransactionId {
     PendingTransactionId(const wr::Epoch& aEpoch, TransactionId aId,
-                         bool aContainsSVGGroup, const VsyncId& aVsyncId,
+                         bool aContainsSVGGroup,
                          const TimeStamp& aRefreshStartTime,
                          const TimeStamp& aTxnStartTime,
                          const nsCString& aTxnURL, const TimeStamp& aFwdTime,
                          const bool aIsFirstPaint, const bool aUseForTelemetry)
         : mEpoch(aEpoch),
           mId(aId),
-          mVsyncId(aVsyncId),
           mRefreshStartTime(aRefreshStartTime),
           mTxnStartTime(aTxnStartTime),
           mTxnURL(aTxnURL),
           mFwdTime(aFwdTime),
           mSkippedComposites(0),
           mContainsSVGGroup(aContainsSVGGroup),
           mIsFirstPaint(aIsFirstPaint),
           mUseForTelemetry(aUseForTelemetry) {}
     wr::Epoch mEpoch;
     TransactionId mId;
-    VsyncId mVsyncId;
     TimeStamp mRefreshStartTime;
     TimeStamp mTxnStartTime;
     nsCString mTxnURL;
     TimeStamp mFwdTime;
     TimeStamp mSceneBuiltTime;
     uint32_t mSkippedComposites;
     bool mContainsSVGGroup;
     bool mIsFirstPaint;
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -227,19 +227,18 @@ bool WebRenderLayerManager::EndEmptyTran
     if (WrBridge()->GetSyncObject() &&
         WrBridge()->GetSyncObject()->IsSyncObjectValid()) {
       WrBridge()->GetSyncObject()->Synchronize();
     }
   }
 
   WrBridge()->EndEmptyTransaction(mFocusTarget, mPendingScrollUpdates,
                                   mAsyncResourceUpdates, mPaintSequenceNumber,
-                                  mLatestTransactionId,
-                                  mTransactionIdAllocator->GetVsyncId(),
-                                  refreshStart, mTransactionStart, mURL);
+                                  mLatestTransactionId, refreshStart,
+                                  mTransactionStart, mURL);
   ClearPendingScrollInfoUpdate();
 
   mTransactionStart = TimeStamp();
 
   MakeSnapshotIfRequired(size);
   return true;
 }
 
@@ -359,19 +358,18 @@ void WebRenderLayerManager::EndTransacti
   wr::BuiltDisplayList dl;
   builder.Finalize(contentSize, dl);
   mLastDisplayListSize = dl.dl.inner.capacity;
 
   {
     AUTO_PROFILER_TRACING("Paint", "ForwardDPTransaction");
     WrBridge()->EndTransaction(contentSize, dl, resourceUpdates,
                                size.ToUnknownSize(), mLatestTransactionId,
-                               mScrollData, containsSVGGroup,
-                               mTransactionIdAllocator->GetVsyncId(),
-                               refreshStart, mTransactionStart, mURL);
+                               mScrollData, containsSVGGroup, refreshStart,
+                               mTransactionStart, mURL);
   }
 
   mTransactionStart = TimeStamp();
 
   MakeSnapshotIfRequired(size);
   mNeedsComposite = false;
 }
 
--- a/gfx/tests/gtest/TestVsync.cpp
+++ b/gfx/tests/gtest/TestVsync.cpp
@@ -25,17 +25,17 @@ using ::testing::_;
 // Windows 8.1 has intermittents at 50 ms. Raise limit to 5 vsync intervals.
 const int kVsyncTimeoutMS = 80;
 
 class TestVsyncObserver : public VsyncObserver {
  public:
   TestVsyncObserver()
       : mDidGetVsyncNotification(false), mVsyncMonitor("VsyncMonitor") {}
 
-  virtual bool NotifyVsync(const VsyncEvent& aVsync) override {
+  virtual bool NotifyVsync(TimeStamp aVsyncTimeStamp) override {
     MonitorAutoLock lock(mVsyncMonitor);
     mDidGetVsyncNotification = true;
     mVsyncMonitor.Notify();
     return true;
   }
 
   void WaitForVsyncNotification() {
     MOZ_ASSERT(NS_IsMainThread());
--- a/gfx/thebes/VsyncSource.cpp
+++ b/gfx/thebes/VsyncSource.cpp
@@ -50,24 +50,21 @@ VsyncSource::Display::~Display() {
   mRefreshTimerVsyncDispatcher = nullptr;
   mCompositorVsyncDispatchers.Clear();
 }
 
 void VsyncSource::Display::NotifyVsync(TimeStamp aVsyncTimestamp) {
   // Called on the vsync thread
   MutexAutoLock lock(mDispatcherLock);
 
-  mVsyncId = mVsyncId.Next();
-  VsyncEvent event(mVsyncId, aVsyncTimestamp);
-
   for (size_t i = 0; i < mCompositorVsyncDispatchers.Length(); i++) {
-    mCompositorVsyncDispatchers[i]->NotifyVsync(event);
+    mCompositorVsyncDispatchers[i]->NotifyVsync(aVsyncTimestamp);
   }
 
-  mRefreshTimerVsyncDispatcher->NotifyVsync(event);
+  mRefreshTimerVsyncDispatcher->NotifyVsync(aVsyncTimestamp);
 }
 
 TimeDuration VsyncSource::Display::GetVsyncRate() {
   // If hardware queries fail / are unsupported, we have to just guess.
   return TimeDuration::FromMilliseconds(1000.0 / 60.0);
 }
 
 void VsyncSource::Display::AddCompositorVsyncDispatcher(
--- a/gfx/thebes/VsyncSource.h
+++ b/gfx/thebes/VsyncSource.h
@@ -6,31 +6,22 @@
 #ifndef GFX_VSYNCSOURCE_H
 #define GFX_VSYNCSOURCE_H
 
 #include "nsTArray.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
 #include "nsISupportsImpl.h"
-#include "mozilla/layers/LayersTypes.h"
 
 namespace mozilla {
 class RefreshTimerVsyncDispatcher;
 class CompositorVsyncDispatcher;
 
-class VsyncIdType {};
-typedef layers::BaseTransactionId<VsyncIdType> VsyncId;
-
-namespace layout {
-class PVsyncChild;
-}
-
 namespace gfx {
-class PVsyncBridgeParent;
 
 // Controls how and when to enable/disable vsync. Lives as long as the
 // gfxPlatform does on the parent process
 class VsyncSource {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VsyncSource)
 
   typedef mozilla::RefreshTimerVsyncDispatcher RefreshTimerVsyncDispatcher;
   typedef mozilla::CompositorVsyncDispatcher CompositorVsyncDispatcher;
@@ -70,49 +61,27 @@ class VsyncSource {
 
    private:
     void UpdateVsyncStatus();
 
     Mutex mDispatcherLock;
     bool mRefreshTimerNeedsVsync;
     nsTArray<RefPtr<CompositorVsyncDispatcher>> mCompositorVsyncDispatchers;
     RefPtr<RefreshTimerVsyncDispatcher> mRefreshTimerVsyncDispatcher;
-    VsyncId mVsyncId;
   };
 
   void AddCompositorVsyncDispatcher(
       CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
   void RemoveCompositorVsyncDispatcher(
       CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
 
   RefPtr<RefreshTimerVsyncDispatcher> GetRefreshTimerVsyncDispatcher();
   virtual Display& GetGlobalDisplay() = 0;  // Works across all displays
   void Shutdown();
 
  protected:
   virtual ~VsyncSource() {}
 };
 
 }  // namespace gfx
-
-namespace recordreplay {
-namespace child {
-void NotifyVsyncObserver();
-}
-}  // namespace recordreplay
-
-struct VsyncEvent {
-  VsyncId mId;
-  TimeStamp mTime;
-
- private:
-  VsyncEvent(const VsyncId& aId, const TimeStamp& aTime)
-      : mId(aId), mTime(aTime) {}
-  VsyncEvent() {}
-  friend class gfx::VsyncSource::Display;
-  friend class gfx::PVsyncBridgeParent;
-  friend class layout::PVsyncChild;
-  friend void recordreplay::child::NotifyVsyncObserver();
-};
-
 }  // namespace mozilla
 
 #endif /* GFX_VSYNCSOURCE_H */
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -239,33 +239,30 @@ void RenderThread::HandleFrame(wr::Windo
     return;
   }
 
   if (mHandlingDeviceReset) {
     return;
   }
 
   TimeStamp startTime;
-  VsyncId startId;
 
   bool hadSlowFrame;
   {  // scope lock
     MutexAutoLock lock(mFrameCountMapLock);
     auto it = mWindowInfos.find(AsUint64(aWindowId));
     MOZ_ASSERT(it != mWindowInfos.end());
     WindowInfo* info = it->second;
     MOZ_ASSERT(info->mPendingCount > 0);
     startTime = info->mStartTimes.front();
-    startId = info->mStartIds.front();
     hadSlowFrame = info->mHadSlowFrame;
     info->mHadSlowFrame = false;
   }
 
-  UpdateAndRender(aWindowId, startId, startTime, aRender,
-                  /* aReadbackSize */ Nothing(),
+  UpdateAndRender(aWindowId, startTime, aRender, /* aReadbackSize */ Nothing(),
                   /* aReadbackBuffer */ Nothing(), hadSlowFrame);
   FrameRenderingComplete(aWindowId);
 }
 
 void RenderThread::WakeUp(wr::WindowId aWindowId) {
   if (mHasShutdown) {
     return;
   }
@@ -302,46 +299,48 @@ void RenderThread::RunEvent(wr::WindowId
   }
 
   aEvent->Run(*this, aWindowId);
   aEvent = nullptr;
 }
 
 static void NotifyDidRender(layers::CompositorBridgeParent* aBridge,
                             RefPtr<WebRenderPipelineInfo> aInfo,
-                            VsyncId aCompositeStartId,
                             TimeStamp aCompositeStart, TimeStamp aRenderStart,
                             TimeStamp aEnd, bool aRender,
                             RendererStats aStats) {
   if (aRender && aBridge->GetWrBridge()) {
     // We call this here to mimic the behavior in LayerManagerComposite, as to
     // not change what Talos measures. That is, we do not record an empty frame
     // as a frame.
     aBridge->GetWrBridge()->RecordFrame();
   }
 
   auto info = aInfo->Raw();
 
   for (uintptr_t i = 0; i < info.epochs.length; i++) {
-    aBridge->NotifyPipelineRendered(
-        info.epochs.data[i].pipeline_id, info.epochs.data[i].epoch,
-        aCompositeStartId, aCompositeStart, aRenderStart, aEnd, &aStats);
+    aBridge->NotifyPipelineRendered(info.epochs.data[i].pipeline_id,
+                                    info.epochs.data[i].epoch, aCompositeStart,
+                                    aRenderStart, aEnd, &aStats);
+  }
+
+  if (aBridge->GetWrBridge()) {
+    aBridge->GetWrBridge()->CompositeIfNeeded();
   }
 }
 
 static void NotifyDidStartRender(layers::CompositorBridgeParent* aBridge) {
   // Starting a render will change increment mRenderingCount, and potentially
   // change whether we can allow the bridge to intiate another frame.
   if (aBridge->GetWrBridge()) {
     aBridge->GetWrBridge()->CompositeIfNeeded();
   }
 }
 
 void RenderThread::UpdateAndRender(wr::WindowId aWindowId,
-                                   const VsyncId& aStartId,
                                    const TimeStamp& aStartTime, bool aRender,
                                    const Maybe<gfx::IntSize>& aReadbackSize,
                                    const Maybe<Range<uint8_t>>& aReadbackBuffer,
                                    bool aHadSlowFrame) {
   AUTO_PROFILER_TRACING("Paint", "Composite");
   MOZ_ASSERT(IsInRenderThread());
   MOZ_ASSERT(aRender || aReadbackBuffer.isNothing());
 
@@ -370,18 +369,18 @@ void RenderThread::UpdateAndRender(wr::W
   // Check graphics reset status even when rendering is skipped.
   renderer->CheckGraphicsResetStatus();
 
   TimeStamp end = TimeStamp::Now();
   auto info = renderer->FlushPipelineInfo();
 
   layers::CompositorThreadHolder::Loop()->PostTask(
       NewRunnableFunction("NotifyDidRenderRunnable", &NotifyDidRender,
-                          renderer->GetCompositorBridge(), info, aStartId,
-                          aStartTime, start, end, aRender, stats));
+                          renderer->GetCompositorBridge(), info, aStartTime,
+                          start, end, aRender, stats));
 
   if (rendered) {
     // Wait for GPU after posting NotifyDidRender, since the wait is not
     // necessary for the NotifyDidRender.
     // The wait is necessary for Textures recycling of AsyncImagePipelineManager
     // and for avoiding GPU queue is filled with too much tasks.
     // WaitForGPU's implementation is different for each platform.
     renderer->WaitForGPU();
@@ -459,27 +458,25 @@ void RenderThread::SetDestroyed(wr::Wind
   if (it == mWindowInfos.end()) {
     MOZ_ASSERT(false);
     return;
   }
   it->second->mIsDestroyed = true;
 }
 
 void RenderThread::IncPendingFrameCount(wr::WindowId aWindowId,
-                                        const VsyncId& aStartId,
                                         const TimeStamp& aStartTime) {
   MutexAutoLock lock(mFrameCountMapLock);
   auto it = mWindowInfos.find(AsUint64(aWindowId));
   if (it == mWindowInfos.end()) {
     MOZ_ASSERT(false);
     return;
   }
   it->second->mPendingCount++;
   it->second->mStartTimes.push(aStartTime);
-  it->second->mStartIds.push(aStartId);
 }
 
 void RenderThread::DecPendingFrameCount(wr::WindowId aWindowId) {
   MutexAutoLock lock(mFrameCountMapLock);
   auto it = mWindowInfos.find(AsUint64(aWindowId));
   if (it == mWindowInfos.end()) {
     MOZ_ASSERT(false);
     return;
@@ -493,17 +490,16 @@ void RenderThread::DecPendingFrameCount(
   // This function gets called for "nop frames" where nothing was rendered or
   // composited. But we count this time because the non-WR codepath equivalent
   // in CompositorBridgeParent::ComposeToTarget also counts such frames. And
   // anyway this should be relatively infrequent so it shouldn't skew the
   // numbers much.
   mozilla::Telemetry::AccumulateTimeDelta(mozilla::Telemetry::COMPOSITE_TIME,
                                           info->mStartTimes.front());
   info->mStartTimes.pop();
-  info->mStartIds.pop();
 }
 
 void RenderThread::IncRenderingFrameCount(wr::WindowId aWindowId) {
   MutexAutoLock lock(mFrameCountMapLock);
   auto it = mWindowInfos.find(AsUint64(aWindowId));
   if (it == mWindowInfos.end()) {
     MOZ_ASSERT(false);
     return;
@@ -528,17 +524,16 @@ void RenderThread::FrameRenderingComplet
   info->mRenderingCount--;
 
   // The start time is from WebRenderBridgeParent::CompositeToTarget. From that
   // point until now (when the frame is finally pushed to the screen) is
   // equivalent to the COMPOSITE_TIME metric in the non-WR codepath.
   mozilla::Telemetry::AccumulateTimeDelta(mozilla::Telemetry::COMPOSITE_TIME,
                                           info->mStartTimes.front());
   info->mStartTimes.pop();
-  info->mStartIds.pop();
 }
 
 void RenderThread::NotifySlowFrame(wr::WindowId aWindowId) {
   MutexAutoLock lock(mFrameCountMapLock);
   auto it = mWindowInfos.find(AsUint64(aWindowId));
   if (it == mWindowInfos.end()) {
     MOZ_ASSERT(false);
     return;
--- a/gfx/webrender_bindings/RenderThread.h
+++ b/gfx/webrender_bindings/RenderThread.h
@@ -16,17 +16,16 @@
 #include "mozilla/gfx/Point.h"
 #include "mozilla/MozPromise.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/webrender/webrender_ffi.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/webrender/WebRenderTypes.h"
 #include "mozilla/layers/SynchronousTask.h"
 #include "GLContext.h"
-#include "mozilla/VsyncDispatcher.h"
 
 #include <list>
 #include <queue>
 #include <unordered_map>
 
 namespace mozilla {
 namespace wr {
 
@@ -164,19 +163,18 @@ class RenderThread final {
   /// Automatically forwarded to the render thread.
   void PipelineSizeChanged(wr::WindowId aWindowId, uint64_t aPipelineId,
                            float aWidth, float aHeight);
 
   /// Automatically forwarded to the render thread.
   void RunEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aCallBack);
 
   /// Can only be called from the render thread.
-  void UpdateAndRender(wr::WindowId aWindowId, const VsyncId& aStartId,
-                       const TimeStamp& aStartTime, bool aRender,
-                       const Maybe<gfx::IntSize>& aReadbackSize,
+  void UpdateAndRender(wr::WindowId aWindowId, const TimeStamp& aStartTime,
+                       bool aRender, const Maybe<gfx::IntSize>& aReadbackSize,
                        const Maybe<Range<uint8_t>>& aReadbackBuffer,
                        bool aHadSlowFrame);
 
   void Pause(wr::WindowId aWindowId);
   bool Resume(wr::WindowId aWindowId);
 
   /// Can be called from any thread.
   void RegisterExternalImage(uint64_t aExternalImageId,
@@ -197,17 +195,17 @@ class RenderThread final {
 
   /// Can be called from any thread.
   bool IsDestroyed(wr::WindowId aWindowId);
   /// Can be called from any thread.
   void SetDestroyed(wr::WindowId aWindowId);
   /// Can be called from any thread.
   bool TooManyPendingFrames(wr::WindowId aWindowId);
   /// Can be called from any thread.
-  void IncPendingFrameCount(wr::WindowId aWindowId, const VsyncId& aStartId,
+  void IncPendingFrameCount(wr::WindowId aWindowId,
                             const TimeStamp& aStartTime);
   /// Can be called from any thread.
   void DecPendingFrameCount(wr::WindowId aWindowId);
   /// Can be called from any thread.
   void IncRenderingFrameCount(wr::WindowId aWindowId);
   /// Can be called from any thread.
   void FrameRenderingComplete(wr::WindowId aWindowId);
 
@@ -263,17 +261,16 @@ class RenderThread final {
 
   struct WindowInfo {
     bool mIsDestroyed = false;
     int64_t mPendingCount = 0;
     int64_t mRenderingCount = 0;
     // One entry in this queue for each pending frame, so the length
     // should always equal mPendingCount
     std::queue<TimeStamp> mStartTimes;
-    std::queue<VsyncId> mStartIds;
     bool mHadSlowFrame = false;
   };
 
   Mutex mFrameCountMapLock;
   std::unordered_map<uint64_t, WindowInfo*> mWindowInfos;
 
   Mutex mRenderTextureMapLock;
   std::unordered_map<uint64_t, RefPtr<RenderTextureHost>> mRenderTextures;
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -366,19 +366,18 @@ void WebRenderAPI::Readback(const TimeSt
                       gfx::IntSize aSize, const Range<uint8_t>& aBuffer)
         : mTask(aTask), mStartTime(aStartTime), mSize(aSize), mBuffer(aBuffer) {
       MOZ_COUNT_CTOR(Readback);
     }
 
     ~Readback() { MOZ_COUNT_DTOR(Readback); }
 
     virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override {
-      aRenderThread.UpdateAndRender(aWindowId, VsyncId(), mStartTime,
-                                    /* aRender */ true, Some(mSize),
-                                    Some(mBuffer), false);
+      aRenderThread.UpdateAndRender(aWindowId, mStartTime, /* aRender */ true,
+                                    Some(mSize), Some(mBuffer), false);
       layers::AutoCompleteTask complete(mTask);
     }
 
     layers::SynchronousTask* mTask;
     TimeStamp mStartTime;
     gfx::IntSize mSize;
     const Range<uint8_t>& mBuffer;
   };
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -280,56 +280,56 @@ class RefreshDriverTimer {
   }
 
   /*
    * Actually runs a tick, poking all the attached RefreshDrivers.
    * Grabs the "now" time via TimeStamp::Now().
    */
   void Tick() {
     TimeStamp now = TimeStamp::Now();
-    Tick(VsyncId(), now);
+    Tick(now);
   }
 
-  void TickRefreshDrivers(VsyncId aId, TimeStamp aNow,
+  void TickRefreshDrivers(TimeStamp aNow,
                           nsTArray<RefPtr<nsRefreshDriver>>& aDrivers) {
     if (aDrivers.IsEmpty()) {
       return;
     }
 
     nsTArray<RefPtr<nsRefreshDriver>> drivers(aDrivers);
     for (nsRefreshDriver* driver : drivers) {
       // don't poke this driver if it's in test mode
       if (driver->IsTestControllingRefreshesEnabled()) {
         continue;
       }
 
-      TickDriver(driver, aId, aNow);
+      TickDriver(driver, aNow);
     }
   }
 
   /*
    * Tick the refresh drivers based on the given timestamp.
    */
-  void Tick(VsyncId aId, TimeStamp now) {
+  void Tick(TimeStamp now) {
     ScheduleNextTick(now);
 
     mLastFireTime = now;
 
     LOG("[%p] ticking drivers...", this);
     // RD is short for RefreshDriver
     AUTO_PROFILER_TRACING("Paint", "RefreshDriverTick");
 
-    TickRefreshDrivers(aId, now, mContentRefreshDrivers);
-    TickRefreshDrivers(aId, now, mRootRefreshDrivers);
+    TickRefreshDrivers(now, mContentRefreshDrivers);
+    TickRefreshDrivers(now, mRootRefreshDrivers);
 
     LOG("[%p] done.", this);
   }
 
-  static void TickDriver(nsRefreshDriver* driver, VsyncId aId, TimeStamp now) {
-    driver->Tick(aId, now);
+  static void TickDriver(nsRefreshDriver* driver, TimeStamp now) {
+    driver->Tick(now);
   }
 
   TimeStamp mLastFireTime;
   TimeStamp mTargetTime;
 
   nsTArray<RefPtr<nsRefreshDriver>> mContentRefreshDrivers;
   nsTArray<RefPtr<nsRefreshDriver>> mRootRefreshDrivers;
 
@@ -457,98 +457,94 @@ class VsyncRefreshDriverTimer : public R
           mProcessedVsync(true) {
       MOZ_ASSERT(NS_IsMainThread());
     }
 
     class ParentProcessVsyncNotifier final : public Runnable,
                                              public nsIRunnablePriority {
      public:
       ParentProcessVsyncNotifier(RefreshDriverVsyncObserver* aObserver,
-                                 VsyncId aId, TimeStamp aVsyncTimestamp)
+                                 TimeStamp aVsyncTimestamp)
           : Runnable(
                 "VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::"
                 "ParentProcessVsyncNotifier"),
             mObserver(aObserver),
-            mId(aId),
             mVsyncTimestamp(aVsyncTimestamp) {}
 
       NS_DECL_ISUPPORTS_INHERITED
 
       NS_IMETHOD Run() override {
         MOZ_ASSERT(NS_IsMainThread());
         static bool sCacheInitialized = false;
         static bool sHighPriorityPrefValue = false;
         if (!sCacheInitialized) {
           sCacheInitialized = true;
           Preferences::AddBoolVarCache(&sHighPriorityPrefValue,
                                        "vsync.parentProcess.highPriority",
                                        mozilla::BrowserTabsRemoteAutostart());
         }
         sHighPriorityEnabled = sHighPriorityPrefValue;
 
-        mObserver->TickRefreshDriver(mId, mVsyncTimestamp);
+        mObserver->TickRefreshDriver(mVsyncTimestamp);
         return NS_OK;
       }
 
       NS_IMETHOD GetPriority(uint32_t* aPriority) override {
         *aPriority = sHighPriorityEnabled
                          ? nsIRunnablePriority::PRIORITY_HIGH
                          : nsIRunnablePriority::PRIORITY_NORMAL;
         return NS_OK;
       }
 
      private:
       ~ParentProcessVsyncNotifier() {}
       RefPtr<RefreshDriverVsyncObserver> mObserver;
-      VsyncId mId;
       TimeStamp mVsyncTimestamp;
       static mozilla::Atomic<bool> sHighPriorityEnabled;
     };
 
-    bool NotifyVsync(const VsyncEvent& aVsync) override {
+    bool NotifyVsync(TimeStamp aVsyncTimestamp) override {
       // IMPORTANT: All paths through this method MUST hold a strong ref on
       // |this| for the duration of the TickRefreshDriver callback.
 
       if (!NS_IsMainThread()) {
         MOZ_ASSERT(XRE_IsParentProcess());
         // Compress vsync notifications such that only 1 may run at a time
         // This is so that we don't flood the refresh driver with vsync messages
         // if the main thread is blocked for long periods of time
         {  // scope lock
           MonitorAutoLock lock(mRefreshTickLock);
-          mRecentVsync = aVsync.mTime;
-          mRecentVsyncId = aVsync.mId;
+          mRecentVsync = aVsyncTimestamp;
           if (!mProcessedVsync) {
             return true;
           }
           mProcessedVsync = false;
         }
 
         nsCOMPtr<nsIRunnable> vsyncEvent =
-            new ParentProcessVsyncNotifier(this, aVsync.mId, aVsync.mTime);
+            new ParentProcessVsyncNotifier(this, aVsyncTimestamp);
         NS_DispatchToMainThread(vsyncEvent);
       } else {
-        mRecentVsync = aVsync.mTime;
-        mRecentVsyncId = aVsync.mId;
-        if (!mBlockUntil.IsNull() && mBlockUntil > aVsync.mTime) {
+        mRecentVsync = aVsyncTimestamp;
+        if (!mBlockUntil.IsNull() && mBlockUntil > aVsyncTimestamp) {
           if (mProcessedVsync) {
             // Re-post vsync update as a normal priority runnable. This way
             // runnables already in normal priority queue get processed.
             mProcessedVsync = false;
             nsCOMPtr<nsIRunnable> vsyncEvent = NewRunnableMethod<>(
                 "RefreshDriverVsyncObserver::NormalPriorityNotify", this,
                 &RefreshDriverVsyncObserver::NormalPriorityNotify);
             NS_DispatchToMainThread(vsyncEvent);
           }
 
           return true;
         }
 
         RefPtr<RefreshDriverVsyncObserver> kungFuDeathGrip(this);
-        TickRefreshDriver(aVsync.mId, aVsync.mTime);
+        TickRefreshDriver(aVsyncTimestamp);
       }
 
       return true;
     }
 
     void Shutdown() {
       MOZ_ASSERT(NS_IsMainThread());
       mVsyncRefreshDriverTimer = nullptr;
@@ -560,17 +556,17 @@ class VsyncRefreshDriverTimer : public R
       }
     }
 
     void NormalPriorityNotify() {
       if (mLastProcessedTickInChildProcess.IsNull() ||
           mRecentVsync > mLastProcessedTickInChildProcess) {
         // mBlockUntil is for high priority vsync notifications only.
         mBlockUntil = TimeStamp();
-        TickRefreshDriver(mRecentVsyncId, mRecentVsync);
+        TickRefreshDriver(mRecentVsync);
       }
 
       mProcessedVsync = true;
     }
 
    private:
     ~RefreshDriverVsyncObserver() = default;
 
@@ -614,17 +610,17 @@ class VsyncRefreshDriverTimer : public R
       uint32_t duration = 1 /* ms */;
       for (size_t i = 0;
            i < mozilla::ArrayLength(sJankLevels) && duration < aJankMS;
            ++i, duration *= 2) {
         sJankLevels[i]++;
       }
     }
 
-    void TickRefreshDriver(VsyncId aId, TimeStamp aVsyncTimestamp) {
+    void TickRefreshDriver(TimeStamp aVsyncTimestamp) {
       MOZ_ASSERT(NS_IsMainThread());
 
       RecordTelemetryProbes(aVsyncTimestamp);
       if (XRE_IsParentProcess()) {
         MonitorAutoLock lock(mRefreshTickLock);
         aVsyncTimestamp = mRecentVsync;
         mProcessedVsync = true;
       } else {
@@ -638,33 +634,32 @@ class VsyncRefreshDriverTimer : public R
           (*&rightnow).UsedCanonicalNow() == aVsyncTimestamp.UsedCanonicalNow(),
           aVsyncTimestamp <= *&rightnow);
 
       // We might have a problem that we call ~VsyncRefreshDriverTimer() before
       // the scheduled TickRefreshDriver() runs. Check mVsyncRefreshDriverTimer
       // before use.
       if (mVsyncRefreshDriverTimer) {
         RefPtr<VsyncRefreshDriverTimer> timer = mVsyncRefreshDriverTimer;
-        timer->RunRefreshDrivers(aId, aVsyncTimestamp);
+        timer->RunRefreshDrivers(aVsyncTimestamp);
         // Note: mVsyncRefreshDriverTimer might be null now.
       }
 
       if (!XRE_IsParentProcess()) {
         TimeDuration tickDuration = TimeStamp::Now() - mLastChildTick;
         mBlockUntil = aVsyncTimestamp + tickDuration;
       }
     }
 
     // VsyncRefreshDriverTimer holds this RefreshDriverVsyncObserver and it will
     // be always available before Shutdown(). We can just use the raw pointer
     // here.
     VsyncRefreshDriverTimer* mVsyncRefreshDriverTimer;
     Monitor mRefreshTickLock;
     TimeStamp mRecentVsync;
-    VsyncId mRecentVsyncId;
     TimeStamp mLastChildTick;
     TimeStamp mLastProcessedTickInChildProcess;
     TimeStamp mBlockUntil;
     TimeDuration mVsyncRate;
     bool mProcessedVsync;
   };  // RefreshDriverVsyncObserver
 
   ~VsyncRefreshDriverTimer() override {
@@ -717,19 +712,17 @@ class VsyncRefreshDriverTimer : public R
     --sActiveVsyncTimers;
   }
 
   void ScheduleNextTick(TimeStamp aNowTime) override {
     // Do nothing since we just wait for the next vsync from
     // RefreshDriverVsyncObserver.
   }
 
-  void RunRefreshDrivers(VsyncId aId, TimeStamp aTimeStamp) {
-    Tick(aId, aTimeStamp);
-  }
+  void RunRefreshDrivers(TimeStamp aTimeStamp) { Tick(aTimeStamp); }
 
   RefPtr<RefreshDriverVsyncObserver> mVsyncObserver;
   // Used for parent process.
   RefPtr<RefreshTimerVsyncDispatcher> mVsyncDispatcher;
   // Used for child process.
   // The mVsyncChild will be always available before VsncChild::ActorDestroy().
   // After ActorDestroy(), StartTimer() and StopTimer() calls will be non-op.
   RefPtr<VsyncChild> mVsyncChild;
@@ -873,17 +866,17 @@ class InactiveRefreshDriverTimer final
     mLastFireTime = now;
 
     nsTArray<RefPtr<nsRefreshDriver>> drivers(mContentRefreshDrivers);
     drivers.AppendElements(mRootRefreshDrivers);
     size_t index = mNextDriverIndex;
 
     if (index < drivers.Length() &&
         !drivers[index]->IsTestControllingRefreshesEnabled()) {
-      TickDriver(drivers[index], VsyncId(), now);
+      TickDriver(drivers[index], now);
     }
 
     mNextDriverIndex++;
   }
 
   static void TimerTickOne(nsITimer* aTimer, void* aClosure) {
     RefPtr<InactiveRefreshDriverTimer> timer =
         static_cast<InactiveRefreshDriverTimer*>(aClosure);
@@ -1366,19 +1359,19 @@ nsRefreshDriver::ObserverArray& nsRefres
 
 void nsRefreshDriver::DoTick() {
   MOZ_ASSERT(!IsFrozen(), "Why are we notified while frozen?");
   MOZ_ASSERT(mPresContext, "Why are we notified after disconnection?");
   MOZ_ASSERT(!nsContentUtils::GetCurrentJSContext(),
              "Shouldn't have a JSContext on the stack");
 
   if (mTestControllingRefreshes) {
-    Tick(VsyncId(), mMostRecentRefresh);
+    Tick(mMostRecentRefresh);
   } else {
-    Tick(VsyncId(), TimeStamp::Now());
+    Tick(TimeStamp::Now());
   }
 }
 
 struct DocumentFrameCallbacks {
   explicit DocumentFrameCallbacks(nsIDocument* aDocument)
       : mDocument(aDocument) {}
 
   nsCOMPtr<nsIDocument> mDocument;
@@ -1610,17 +1603,17 @@ void nsRefreshDriver::CancelIdleRunnable
   }
 
   if (sPendingIdleRunnables->IsEmpty()) {
     delete sPendingIdleRunnables;
     sPendingIdleRunnables = nullptr;
   }
 }
 
-void nsRefreshDriver::Tick(VsyncId aId, TimeStamp aNowTime) {
+void nsRefreshDriver::Tick(TimeStamp aNowTime) {
   MOZ_ASSERT(!nsContentUtils::GetCurrentJSContext(),
              "Shouldn't have a JSContext on the stack");
 
   if (nsNPAPIPluginInstance::InPluginCallUnsafeForReentry()) {
     NS_ERROR("Refresh driver should not run during plugin call!");
     // Try to survive this by just ignoring the refresh tick.
     return;
   }
@@ -1677,17 +1670,16 @@ void nsRefreshDriver::Tick(VsyncId aId, 
 
   mResizeSuppressed = false;
 
   AutoRestore<bool> restoreInRefresh(mInRefresh);
   mInRefresh = true;
 
   AutoRestore<TimeStamp> restoreTickStart(mTickStart);
   mTickStart = TimeStamp::Now();
-  mTickVsyncId = aId;
 
   gfxPlatform::GetPlatform()->SchedulePaintIfDeviceReset();
 
   // We want to process any pending APZ metrics ahead of their positions
   // in the queue. This will prevent us from spending precious time
   // painting a stale displayport.
   if (gfxPrefs::APZPeekMessages()) {
     nsLayoutUtils::UpdateDisplayPortMarginsFromPendingMessages();
@@ -2055,18 +2047,16 @@ void nsRefreshDriver::ClearPendingTransa
 void nsRefreshDriver::ResetInitialTransactionId(
     mozilla::layers::TransactionId aTransactionId) {
   mCompletedTransaction = mOutstandingTransactionId = mNextTransactionId =
       aTransactionId;
 }
 
 mozilla::TimeStamp nsRefreshDriver::GetTransactionStart() { return mTickStart; }
 
-VsyncId nsRefreshDriver::GetVsyncId() { return mTickVsyncId; }
-
 void nsRefreshDriver::NotifyTransactionCompleted(
     mozilla::layers::TransactionId aTransactionId) {
   if (aTransactionId > mCompletedTransaction) {
     if (mOutstandingTransactionId - mCompletedTransaction > 1 &&
         mWaitingForTransaction) {
       mCompletedTransaction = aTransactionId;
       FinishedWaitingForTransaction();
     } else {
--- a/layout/base/nsRefreshDriver.h
+++ b/layout/base/nsRefreshDriver.h
@@ -20,17 +20,16 @@
 #include "nsTObserverArray.h"
 #include "nsTArray.h"
 #include "nsTHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/layers/TransactionIdAllocator.h"
-#include "mozilla/VsyncDispatcher.h"
 
 class nsPresContext;
 class nsIPresShell;
 class nsIDocument;
 class imgIRequest;
 class nsINode;
 class nsIRunnable;
 
@@ -357,17 +356,16 @@ class nsRefreshDriver final : public moz
   // mozilla::layers::TransactionIdAllocator
   TransactionId GetTransactionId(bool aThrottle) override;
   TransactionId LastTransactionId() const override;
   void NotifyTransactionCompleted(TransactionId aTransactionId) override;
   void RevokeTransactionId(TransactionId aTransactionId) override;
   void ClearPendingTransactions() override;
   void ResetInitialTransactionId(TransactionId aTransactionId) override;
   mozilla::TimeStamp GetTransactionStart() override;
-  mozilla::VsyncId GetVsyncId() override;
 
   bool IsWaitingForPaint(mozilla::TimeStamp aTime);
 
   // nsARefreshObserver
   NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override {
     return TransactionIdAllocator::AddRef();
   }
   NS_IMETHOD_(MozExternalRefCountType) Release(void) override {
@@ -411,17 +409,17 @@ class nsRefreshDriver final : public moz
     RequestTable mEntries;
   };
   typedef nsClassHashtable<nsUint32HashKey, ImageStartData> ImageStartTable;
 
   void RunFullscreenSteps();
   void DispatchAnimationEvents();
   void RunFrameRequestCallbacks(mozilla::TimeStamp aNowTime);
   void UpdateIntersectionObservations();
-  void Tick(mozilla::VsyncId aId, mozilla::TimeStamp aNowTime);
+  void Tick(mozilla::TimeStamp aNowTime);
 
   enum EnsureTimerStartedFlags {
     eNone = 0,
     eForceAdjustTimer = 1 << 0,
     eAllowTimeToGoBackwards = 1 << 1,
     eNeverAdjustTimer = 1 << 2,
   };
   void EnsureTimerStarted(EnsureTimerStartedFlags aFlags = eNone);
@@ -504,17 +502,16 @@ class nsRefreshDriver final : public moz
   bool mNotifyDOMContentFlushed;
 
   // Number of seconds that the refresh driver is blocked waiting for a
   // compositor transaction to be completed before we append a note to the gfx
   // critical log. The number is doubled every time the threshold is hit.
   uint64_t mWarningThreshold;
   mozilla::TimeStamp mMostRecentRefresh;
   mozilla::TimeStamp mTickStart;
-  mozilla::VsyncId mTickVsyncId;
   mozilla::TimeStamp mNextThrottledFrameRequestTick;
   mozilla::TimeStamp mNextRecomputeVisibilityTick;
 
   // separate arrays for each flush type we support
   ObserverArray mObservers[4];
   // These observers should NOT be included in HasObservers() since that method
   // is used to determine whether or not to stop the timer, or restore it when
   // thawing the refresh driver. On the other hand these observers are intended
--- a/layout/ipc/PVsync.ipdl
+++ b/layout/ipc/PVsync.ipdl
@@ -2,33 +2,32 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PBackground;
 include "mozilla/layers/LayersMessageUtils.h";
 
 using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
-using mozilla::VsyncEvent from "mozilla/VsyncDispatcher.h";
 
 namespace mozilla {
 namespace layout {
 
 /*
  * The PVsync is a sub-protocol in PBackground and it is used to notify
  * the vsync event from chrome to content process. It also provides the
  * interfaces for content to observe/unobserve vsync event notifications.
  */
 async protocol PVsync
 {
   manager PBackground;
 
 child:
   // Send vsync event from chrome to content process.
-  prio(high) async Notify(VsyncEvent aVsync) compress;
+  prio(high) async Notify(TimeStamp aVsyncTimestamp) compress;
 
   // Send the vsync rate to the content process.
   async VsyncRate(float aVsyncRate);
 
 parent:
   // Content process use these messages to acquire the vsync event.
   async Observe();
   async Unobserve();
--- a/layout/ipc/VsyncChild.cpp
+++ b/layout/ipc/VsyncChild.cpp
@@ -46,28 +46,29 @@ void VsyncChild::ActorDestroy(ActorDestr
   mIsShutdown = true;
   mObserver = nullptr;
 
   if (recordreplay::IsRecordingOrReplaying()) {
     recordreplay::child::SetVsyncObserver(nullptr);
   }
 }
 
-mozilla::ipc::IPCResult VsyncChild::RecvNotify(const VsyncEvent& aVsync) {
+mozilla::ipc::IPCResult VsyncChild::RecvNotify(
+    const TimeStamp& aVsyncTimestamp) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mIsShutdown);
 
   SchedulerGroup::MarkVsyncRan();
   if (mObservingVsync && mObserver) {
     if (recordreplay::IsRecordingOrReplaying() &&
         !recordreplay::child::OnVsync()) {
       return IPC_OK();
     }
 
-    mObserver->NotifyVsync(aVsync);
+    mObserver->NotifyVsync(aVsyncTimestamp);
   }
   return IPC_OK();
 }
 
 void VsyncChild::SetVsyncObserver(VsyncObserver* aVsyncObserver) {
   MOZ_ASSERT(NS_IsMainThread());
   mObserver = aVsyncObserver;
 
--- a/layout/ipc/VsyncChild.h
+++ b/layout/ipc/VsyncChild.h
@@ -47,17 +47,18 @@ class VsyncChild final : public PVsyncCh
   // TimeDuration::Forever() if mVsyncRate hasn't been set by calling
   // GetVsyncRate.
   TimeDuration VsyncRate();
 
  private:
   VsyncChild();
   virtual ~VsyncChild();
 
-  virtual mozilla::ipc::IPCResult RecvNotify(const VsyncEvent& aVsync) override;
+  virtual mozilla::ipc::IPCResult RecvNotify(
+      const TimeStamp& aVsyncTimestamp) override;
   virtual mozilla::ipc::IPCResult RecvVsyncRate(
       const float& aVsyncRate) override;
   virtual void ActorDestroy(ActorDestroyReason aActorDestroyReason) override;
 
   bool mObservingVsync;
   bool mIsShutdown;
 
   // The content side vsync observer.
--- a/layout/ipc/VsyncParent.cpp
+++ b/layout/ipc/VsyncParent.cpp
@@ -37,37 +37,37 @@ VsyncParent::VsyncParent()
   AssertIsOnBackgroundThread();
 }
 
 VsyncParent::~VsyncParent() {
   // Since we use NS_INLINE_DECL_THREADSAFE_REFCOUNTING, we can't make sure
   // VsyncParent is always released on the background thread.
 }
 
-bool VsyncParent::NotifyVsync(const VsyncEvent& aVsync) {
+bool VsyncParent::NotifyVsync(TimeStamp aTimeStamp) {
   // Called on hardware vsync thread. We should post to current ipc thread.
   MOZ_ASSERT(!IsOnBackgroundThread());
-  nsCOMPtr<nsIRunnable> vsyncEvent = NewRunnableMethod<VsyncEvent>(
+  nsCOMPtr<nsIRunnable> vsyncEvent = NewRunnableMethod<TimeStamp>(
       "layout::VsyncParent::DispatchVsyncEvent", this,
-      &VsyncParent::DispatchVsyncEvent, aVsync);
+      &VsyncParent::DispatchVsyncEvent, aTimeStamp);
   MOZ_ALWAYS_SUCCEEDS(
       mBackgroundThread->Dispatch(vsyncEvent, NS_DISPATCH_NORMAL));
   return true;
 }
 
-void VsyncParent::DispatchVsyncEvent(const VsyncEvent& aVsync) {
+void VsyncParent::DispatchVsyncEvent(TimeStamp aTimeStamp) {
   AssertIsOnBackgroundThread();
 
   // If we call NotifyVsync() when we handle ActorDestroy() message, we might
   // still call DispatchVsyncEvent().
   // Similarly, we might also receive RecvUnobserveVsync() when call
   // NotifyVsync(). We use mObservingVsync and mDestroyed flags to skip this
   // notification.
   if (mObservingVsync && !mDestroyed) {
-    Unused << SendNotify(aVsync);
+    Unused << SendNotify(aTimeStamp);
   }
 }
 
 mozilla::ipc::IPCResult VsyncParent::RecvRequestVsyncRate() {
   AssertIsOnBackgroundThread();
   TimeDuration vsyncRate = gfxPlatform::GetPlatform()
                                ->GetHardwareVsync()
                                ->GetGlobalDisplay()
--- a/layout/ipc/VsyncParent.h
+++ b/layout/ipc/VsyncParent.h
@@ -29,24 +29,24 @@ class VsyncParent final : public PVsyncP
   friend class mozilla::ipc::BackgroundParentImpl;
 
  private:
   static already_AddRefed<VsyncParent> Create();
 
   VsyncParent();
   virtual ~VsyncParent();
 
-  virtual bool NotifyVsync(const VsyncEvent& aVsync) override;
+  virtual bool NotifyVsync(TimeStamp aTimeStamp) override;
   virtual mozilla::ipc::IPCResult RecvRequestVsyncRate() override;
 
   virtual mozilla::ipc::IPCResult RecvObserve() override;
   virtual mozilla::ipc::IPCResult RecvUnobserve() override;
   virtual void ActorDestroy(ActorDestroyReason aActorDestroyReason) override;
 
-  void DispatchVsyncEvent(const VsyncEvent& aVsync);
+  void DispatchVsyncEvent(TimeStamp aTimeStamp);
 
   bool mObservingVsync;
   bool mDestroyed;
   nsCOMPtr<nsIThread> mBackgroundThread;
   RefPtr<RefreshTimerVsyncDispatcher> mVsyncDispatcher;
 };
 
 }  // namespace layout
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -13206,25 +13206,16 @@
     "alert_emails": ["gfx-telemetry-alerts@mozilla.com", "mwoodrow@mozilla.com"],
     "bug_numbers": [1503405],
     "expires_in_version": "70",
     "kind": "exponential",
     "high": 5000,
     "n_buckets": 50,
     "description": "The time, in percentage of a vsync interval, spent from beginning a paint in the content process until that frame is presented in the compositor by WebRender, excluding time spent uploading any content"
   },
-  "CONTENT_FRAME_TIME_REASON": {
-    "record_in_processes": ["main", "gpu"],
-    "alert_emails": ["gfx-telemetry-alerts@mozilla.com", "mwoodrow@mozilla.com"],
-    "bug_numbers": [1510853],
-    "expires_in_version": "73",
-    "kind": "categorical",
-    "description": "The reason that CONTENT_FRAME_TIME recorded a slow (>200) result, if any.",
-    "labels": ["Success", "NoVsync", "MissedComposite", "SlowComposite"]
-  },
   "CONTENT_LARGE_PAINT_PHASE_WEIGHT": {
     "record_in_processes": ["main", "content"],
     "alert_emails": ["gfx-telemetry-alerts@mozilla.com", "mwoodrow@mozilla.com"],
     "bug_numbers": [1309442],
     "expires_in_version": "66",
     "keyed": true,
     "keys": ["dl", "flb", "fr", "r"],
     "kind": "linear",
--- a/toolkit/recordreplay/ipc/ChildIPC.cpp
+++ b/toolkit/recordreplay/ipc/ChildIPC.cpp
@@ -409,22 +409,19 @@ void NotifyAlwaysMarkMajorCheckpoints() 
 
 static VsyncObserver* gVsyncObserver;
 
 void SetVsyncObserver(VsyncObserver* aObserver) {
   MOZ_RELEASE_ASSERT(!gVsyncObserver || !aObserver);
   gVsyncObserver = aObserver;
 }
 
-void NotifyVsyncObserver() {
+static void NotifyVsyncObserver() {
   if (gVsyncObserver) {
-    static VsyncId vsyncId;
-    vsyncId = vsyncId.Next();
-    VsyncEvent event(vsyncId, TimeStamp::Now());
-    gVsyncObserver->NotifyVsync(event);
+    gVsyncObserver->NotifyVsync(TimeStamp::Now());
   }
 }
 
 // How many paints have been started and haven't reached PaintFromMainThread
 // yet. Only accessed on the main thread.
 static int32_t gNumPendingMainThreadPaints;
 
 bool OnVsync() {
--- a/widget/VsyncDispatcher.cpp
+++ b/widget/VsyncDispatcher.cpp
@@ -22,23 +22,24 @@ CompositorVsyncDispatcher::CompositorVsy
 }
 
 CompositorVsyncDispatcher::~CompositorVsyncDispatcher() {
   MOZ_ASSERT(XRE_IsParentProcess());
   // We auto remove this vsync dispatcher from the vsync source in the
   // nsBaseWidget
 }
 
-void CompositorVsyncDispatcher::NotifyVsync(const VsyncEvent& aVsync) {
+void CompositorVsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp) {
   // In vsync thread
-  layers::CompositorBridgeParent::PostInsertVsyncProfilerMarker(aVsync.mTime);
+  layers::CompositorBridgeParent::PostInsertVsyncProfilerMarker(
+      aVsyncTimestamp);
 
   MutexAutoLock lock(mCompositorObserverLock);
   if (mCompositorVsyncObserver) {
-    mCompositorVsyncObserver->NotifyVsync(aVsync);
+    mCompositorVsyncObserver->NotifyVsync(aVsyncTimestamp);
   }
 }
 
 void CompositorVsyncDispatcher::ObserveVsync(bool aEnable) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(XRE_IsParentProcess());
   if (mDidShutdown) {
     return;
@@ -95,25 +96,25 @@ RefreshTimerVsyncDispatcher::RefreshTime
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 RefreshTimerVsyncDispatcher::~RefreshTimerVsyncDispatcher() {
   MOZ_ASSERT(XRE_IsParentProcess() || recordreplay::IsRecordingOrReplaying());
   MOZ_ASSERT(NS_IsMainThread());
 }
 
-void RefreshTimerVsyncDispatcher::NotifyVsync(const VsyncEvent& aVsync) {
+void RefreshTimerVsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp) {
   MutexAutoLock lock(mRefreshTimersLock);
 
   for (size_t i = 0; i < mChildRefreshTimers.Length(); i++) {
-    mChildRefreshTimers[i]->NotifyVsync(aVsync);
+    mChildRefreshTimers[i]->NotifyVsync(aVsyncTimestamp);
   }
 
   if (mParentRefreshTimer) {
-    mParentRefreshTimer->NotifyVsync(aVsync);
+    mParentRefreshTimer->NotifyVsync(aVsyncTimestamp);
   }
 }
 
 void RefreshTimerVsyncDispatcher::SetParentRefreshTimer(
     VsyncObserver* aVsyncObserver) {
   MOZ_ASSERT(NS_IsMainThread());
   {  // lock scope because UpdateVsyncStatus runs on main thread and will
      // deadlock
--- a/widget/VsyncDispatcher.h
+++ b/widget/VsyncDispatcher.h
@@ -6,30 +6,29 @@
 #ifndef mozilla_widget_VsyncDispatcher_h
 #define mozilla_widget_VsyncDispatcher_h
 
 #include "mozilla/Mutex.h"
 #include "mozilla/TimeStamp.h"
 #include "nsISupportsImpl.h"
 #include "nsTArray.h"
 #include "mozilla/RefPtr.h"
-#include "VsyncSource.h"
 
 namespace mozilla {
 
 class VsyncObserver {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VsyncObserver)
 
  public:
   // The method called when a vsync occurs. Return true if some work was done.
   // In general, this vsync notification will occur on the hardware vsync
   // thread from VsyncSource. But it might also be called on PVsync ipc thread
   // if this notification is cross process. Thus all observer should check the
   // thread model before handling the real task.
-  virtual bool NotifyVsync(const VsyncEvent& aVsync) = 0;
+  virtual bool NotifyVsync(TimeStamp aVsyncTimestamp) = 0;
 
  protected:
   VsyncObserver() {}
   virtual ~VsyncObserver() {}
 };  // VsyncObserver
 
 // Used to dispatch vsync events in the parent process to compositors.
 //
@@ -45,17 +44,17 @@ class VsyncObserver {
 // compositor thread in the compositor process.
 class CompositorVsyncDispatcher final {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncDispatcher)
 
  public:
   CompositorVsyncDispatcher();
 
   // Called on the vsync thread when a hardware vsync occurs
-  void NotifyVsync(const VsyncEvent& aVsync);
+  void NotifyVsync(TimeStamp aVsyncTimestamp);
 
   // Compositor vsync observers must be added/removed on the compositor thread
   void SetCompositorVsyncObserver(VsyncObserver* aVsyncObserver);
   void Shutdown();
 
  private:
   virtual ~CompositorVsyncDispatcher();
   void ObserveVsync(bool aEnable);
@@ -68,17 +67,17 @@ class CompositorVsyncDispatcher final {
 // Dispatch vsync event to ipc actor parent and chrome RefreshTimer.
 class RefreshTimerVsyncDispatcher final {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefreshTimerVsyncDispatcher)
 
  public:
   RefreshTimerVsyncDispatcher();
 
   // Please check CompositorVsyncDispatcher::NotifyVsync().
-  void NotifyVsync(const VsyncEvent& aVsync);
+  void NotifyVsync(TimeStamp aVsyncTimestamp);
 
   // Set chrome process's RefreshTimer to this dispatcher.
   // This function can be called from any thread.
   void SetParentRefreshTimer(VsyncObserver* aVsyncObserver);
 
   // Add or remove the content process' RefreshTimer to this dispatcher. This
   // will be a no-op for AddChildRefreshTimer() if the observer is already
   // registered.