tor-browser

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

CompositorVsyncScheduler.h (5999B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_layers_CompositorVsyncScheduler_h
      8 #define mozilla_layers_CompositorVsyncScheduler_h
      9 
     10 #include <stdint.h>  // for uint64_t
     11 
     12 #include "mozilla/Monitor.h"    // for Monitor
     13 #include "mozilla/RefPtr.h"     // for RefPtr
     14 #include "mozilla/TimeStamp.h"  // for TimeStamp
     15 #include "mozilla/gfx/Point.h"  // for IntSize
     16 #include "mozilla/layers/SampleTime.h"
     17 #include "mozilla/webrender/webrender_ffi.h"
     18 #include "mozilla/VsyncDispatcher.h"
     19 #include "mozilla/widget/CompositorWidget.h"
     20 #include "nsISupportsImpl.h"
     21 
     22 namespace mozilla {
     23 
     24 class CancelableRunnable;
     25 class Runnable;
     26 
     27 namespace gfx {
     28 class DrawTarget;
     29 }  // namespace gfx
     30 
     31 namespace layers {
     32 
     33 class CompositorVsyncSchedulerOwner;
     34 
     35 /**
     36 * Manages the vsync (de)registration and tracking on behalf of the
     37 * compositor when it need to paint.
     38 * Turns vsync notifications into scheduled composites.
     39 **/
     40 class CompositorVsyncScheduler {
     41  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncScheduler)
     42 
     43 public:
     44  CompositorVsyncScheduler(CompositorVsyncSchedulerOwner* aVsyncSchedulerOwner,
     45                           widget::CompositorWidget* aWidget);
     46 
     47  /**
     48   * Notify this class of a vsync. This will trigger a composite if one is
     49   * needed. This must be called from the vsync dispatch thread.
     50   */
     51  void NotifyVsync(const VsyncEvent& aVsync);
     52 
     53  /**
     54   * Do cleanup. This must be called on the compositor thread.
     55   */
     56  void Destroy();
     57 
     58  /**
     59   * Notify this class that a composition is needed. This will trigger a
     60   * composition soon (likely at the next vsync). This must be called on the
     61   * compositor thread.
     62   */
     63  void ScheduleComposition(wr::RenderReasons aReasons);
     64 
     65  /**
     66   * Cancel any composite task that has been scheduled but hasn't run yet.
     67   *
     68   * Returns the render reasons of the canceled task if any.
     69   */
     70  wr::RenderReasons CancelCurrentCompositeTask();
     71 
     72  /**
     73   * Check if a composite is pending. This is generally true between a call
     74   * to ScheduleComposition() and the time the composite happens.
     75   */
     76  bool NeedsComposite();
     77 
     78  /**
     79   * Force a composite to happen right away, without waiting for the next vsync.
     80   * This must be called on the compositor thread.
     81   */
     82  void ForceComposeToTarget(wr::RenderReasons aReasons,
     83                            gfx::DrawTarget* aTarget,
     84                            const gfx::IntRect* aRect);
     85 
     86  /**
     87   * If a composite is pending, force it to trigger right away. This must be
     88   * called on the compositor thread. Returns true if there was a composite
     89   * flushed.
     90   */
     91  bool FlushPendingComposite();
     92 
     93  /**
     94   * Return the vsync timestamp of the last or ongoing composite. Must be called
     95   * on the compositor thread.
     96   */
     97  const SampleTime& GetLastComposeTime() const;
     98 
     99  /**
    100   * Return the vsync timestamp and id of the most recently received
    101   * vsync event. Must be called on the compositor thread.
    102   */
    103  const TimeStamp& GetLastVsyncTime() const;
    104  const TimeStamp& GetLastVsyncOutputTime() const;
    105  const VsyncId& GetLastVsyncId() const;
    106 
    107  /**
    108   * Update LastCompose TimeStamp to current timestamp.
    109   * The function is typically used when composition is handled outside the
    110   * CompositorVsyncScheduler.
    111   */
    112  void UpdateLastComposeTime();
    113 
    114 private:
    115  virtual ~CompositorVsyncScheduler();
    116 
    117  // Post a task to run Composite() on the compositor thread, if there isn't
    118  // such a task already queued. Can be called from any thread.
    119  void PostCompositeTask(const VsyncEvent& aVsyncEvent,
    120                         wr::RenderReasons aReasons);
    121 
    122  // Post a task to run DispatchVREvents() on the VR thread, if there isn't
    123  // such a task already queued. Can be called from any thread.
    124  void PostVRTask(TimeStamp aTimestamp);
    125 
    126  /**
    127   * Cancel any VR task that has been scheduled but hasn't run yet.
    128   */
    129  void CancelCurrentVRTask();
    130 
    131  // This gets run at vsync time and "does" a composite (which really means
    132  // update internal state and call the owner to do the composite).
    133  void Composite(const VsyncEvent& aVsyncEvent, wr::RenderReasons aReasons);
    134 
    135  void ObserveVsync();
    136  void UnobserveVsync();
    137 
    138  void DispatchVREvents(TimeStamp aVsyncTimestamp);
    139 
    140  class Observer final : public VsyncObserver {
    141    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncScheduler::Observer,
    142                                          override)
    143 
    144   public:
    145    explicit Observer(CompositorVsyncScheduler* aOwner);
    146    void NotifyVsync(const VsyncEvent& aVsync) override;
    147    void Destroy();
    148 
    149   private:
    150    virtual ~Observer();
    151 
    152    Mutex mMutex;
    153    // Hold raw pointer to avoid mutual reference.
    154    CompositorVsyncScheduler* mOwner;
    155  };
    156 
    157  CompositorVsyncSchedulerOwner* mVsyncSchedulerOwner;
    158  SampleTime mLastComposeTime;
    159  TimeStamp mLastVsyncTime;
    160  TimeStamp mLastVsyncOutputTime;
    161  VsyncId mLastVsyncId;
    162 
    163  bool mAsapScheduling;
    164  bool mIsObservingVsync;
    165  // Accessed on the compositor thread.
    166  wr::RenderReasons mRendersDelayedByVsyncReasons;
    167  TimeStamp mCompositeRequestedAt;
    168  int32_t mVsyncNotificationsSkipped;
    169  widget::CompositorWidget* mWidget;
    170  RefPtr<CompositorVsyncScheduler::Observer> mVsyncObserver;
    171 
    172  mozilla::Monitor mCurrentCompositeTaskMonitor;
    173  RefPtr<CancelableRunnable> mCurrentCompositeTask
    174      MOZ_GUARDED_BY(mCurrentCompositeTaskMonitor);
    175  // Accessed on multiple threads, guarded by mCurrentCompositeTaskMonitor.
    176  wr::RenderReasons mCurrentCompositeTaskReasons
    177      MOZ_GUARDED_BY(mCurrentCompositeTaskMonitor);
    178 
    179  mozilla::Monitor mCurrentVRTaskMonitor;
    180  RefPtr<CancelableRunnable> mCurrentVRTask
    181      MOZ_GUARDED_BY(mCurrentVRTaskMonitor);
    182 };
    183 }  // namespace layers
    184 }  // namespace mozilla
    185 
    186 #endif  // mozilla_layers_CompositorVsyncScheduler_h