tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

VsyncParent.cpp (3034B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "VsyncParent.h"
      8 
      9 #include "nsIThread.h"
     10 #include "nsThreadUtils.h"
     11 
     12 namespace mozilla::dom {
     13 
     14 VsyncParent::VsyncParent()
     15    : mObservingVsync(false),
     16      mDestroyed(false),
     17      mInitialThread(NS_GetCurrentThread()) {}
     18 
     19 void VsyncParent::UpdateVsyncDispatcher(
     20    const RefPtr<VsyncDispatcher>& aVsyncDispatcher) {
     21  if (aVsyncDispatcher == mVsyncDispatcher) {
     22    return;
     23  }
     24 
     25  if (mObservingVsync && mVsyncDispatcher) {
     26    mVsyncDispatcher->RemoveVsyncObserver(this);
     27  }
     28  mVsyncDispatcher = aVsyncDispatcher;
     29  if (mObservingVsync) {
     30    mVsyncDispatcher->AddVsyncObserver(this);
     31  }
     32 }
     33 
     34 void VsyncParent::NotifyVsync(const VsyncEvent& aVsync) {
     35  if (IsOnInitialThread()) {
     36    DispatchVsyncEvent(aVsync);
     37    return;
     38  }
     39 
     40  // Called on hardware vsync thread. We should post to current ipc thread.
     41  nsCOMPtr<nsIRunnable> vsyncEvent = NewRunnableMethod<VsyncEvent>(
     42      "dom::VsyncParent::DispatchVsyncEvent", this,
     43      &VsyncParent::DispatchVsyncEvent, aVsync);
     44  MOZ_ALWAYS_SUCCEEDS(NS_DispatchToThreadQueue(
     45      vsyncEvent.forget(), mInitialThread, EventQueuePriority::Vsync));
     46 }
     47 
     48 void VsyncParent::DispatchVsyncEvent(const VsyncEvent& aVsync) {
     49  AssertIsOnInitialThread();
     50 
     51  // If we call NotifyVsync() when we handle ActorDestroy() message, we might
     52  // still call DispatchVsyncEvent().
     53  // Similarly, we might also receive RecvUnobserveVsync() when call
     54  // NotifyVsync(). We use mObservingVsync and mDestroyed flags to skip this
     55  // notification.
     56  if (mObservingVsync && !mDestroyed) {
     57    TimeDuration vsyncRate = mVsyncDispatcher->GetVsyncRate();
     58    (void)SendNotify(aVsync, vsyncRate.ToMilliseconds());
     59  }
     60 }
     61 
     62 mozilla::ipc::IPCResult VsyncParent::RecvObserve() {
     63  AssertIsOnInitialThread();
     64  if (!mObservingVsync) {
     65    if (mVsyncDispatcher) {
     66      mVsyncDispatcher->AddVsyncObserver(this);
     67    }
     68    mObservingVsync = true;
     69    return IPC_OK();
     70  }
     71  return IPC_FAIL_NO_REASON(this);
     72 }
     73 
     74 mozilla::ipc::IPCResult VsyncParent::RecvUnobserve() {
     75  AssertIsOnInitialThread();
     76  if (mObservingVsync) {
     77    if (mVsyncDispatcher) {
     78      mVsyncDispatcher->RemoveVsyncObserver(this);
     79    }
     80    mObservingVsync = false;
     81    return IPC_OK();
     82  }
     83  return IPC_FAIL_NO_REASON(this);
     84 }
     85 
     86 void VsyncParent::ActorDestroy(ActorDestroyReason aActorDestroyReason) {
     87  MOZ_ASSERT(!mDestroyed);
     88  AssertIsOnInitialThread();
     89  if (mObservingVsync && mVsyncDispatcher) {
     90    mVsyncDispatcher->RemoveVsyncObserver(this);
     91  }
     92  mVsyncDispatcher = nullptr;
     93  mDestroyed = true;
     94 }
     95 
     96 bool VsyncParent::IsOnInitialThread() {
     97  return NS_GetCurrentThread() == mInitialThread;
     98 }
     99 
    100 void VsyncParent::AssertIsOnInitialThread() { MOZ_ASSERT(IsOnInitialThread()); }
    101 
    102 }  // namespace mozilla::dom