DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (c68fe15a81fc)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
/* -*- Mode: C++; tab-width: 20; 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/. */

#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 VsyncObserver;
struct VsyncEvent;

class VsyncIdType {};
typedef layers::BaseTransactionId<VsyncIdType> VsyncId;

namespace gfx {

// 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;

 public:
  // Controls vsync unique to each display and unique on each platform
  class Display {
    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Display)
   public:
    Display();

    // Notified when this display's vsync occurs, on the vsync thread
    // The aVsyncTimestamp should normalize to the Vsync time that just occured
    // However, different platforms give different vsync notification times.
    // OSX - The vsync timestamp of the upcoming frame, in the future
    // Windows: It's messy, see gfxWindowsPlatform.
    // Android: TODO
    // All platforms should normalize to the vsync that just occured.
    // Large parts of Gecko assume TimeStamps should not be in the future such
    // as animations
    virtual void NotifyVsync(TimeStamp aVsyncTimestamp);
    void NotifyGenericObservers(VsyncEvent aEvent);

    RefPtr<RefreshTimerVsyncDispatcher> GetRefreshTimerVsyncDispatcher();

    void RegisterCompositorVsyncDispatcher(
        CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
    void DeregisterCompositorVsyncDispatcher(
        CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
    void EnableCompositorVsyncDispatcher(
        CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
    void DisableCompositorVsyncDispatcher(
        CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
    void AddGenericObserver(VsyncObserver* aObserver);
    void RemoveGenericObserver(VsyncObserver* aObserver);

    void MoveListenersToNewSource(const RefPtr<VsyncSource>& aNewSource);
    void NotifyRefreshTimerVsyncStatus(bool aEnable);
    virtual TimeDuration GetVsyncRate();

    // These should all only be called on the main thread
    virtual void EnableVsync() = 0;
    virtual void DisableVsync() = 0;
    virtual bool IsVsyncEnabled() = 0;
    virtual void Shutdown() = 0;

   protected:
    virtual ~Display();

   private:
    void UpdateVsyncStatus();

    Mutex mDispatcherLock;
    bool mRefreshTimerNeedsVsync;
    nsTArray<RefPtr<CompositorVsyncDispatcher>>
        mEnabledCompositorVsyncDispatchers;
    nsTArray<RefPtr<CompositorVsyncDispatcher>>
        mRegisteredCompositorVsyncDispatchers;
    RefPtr<RefreshTimerVsyncDispatcher> mRefreshTimerVsyncDispatcher;
    nsTArray<RefPtr<VsyncObserver>>
        mGenericObservers;  // can only be touched from the main thread
    VsyncId mVsyncId;
    VsyncId mLastVsyncIdSentToMainThread;     // hold mDispatcherLock to touch
    VsyncId mLastMainThreadProcessedVsyncId;  // hold mDispatcherLock to touch
  };

  void EnableCompositorVsyncDispatcher(
      CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
  void DisableCompositorVsyncDispatcher(
      CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
  void RegisterCompositorVsyncDispatcher(
      CompositorVsyncDispatcher* aCompositorVsyncDispatcher);
  void DeregisterCompositorVsyncDispatcher(
      CompositorVsyncDispatcher* aCompositorVsyncDispatcher);

  // Add and remove a generic observer for vsync. Note that keeping an observer
  // registered means vsync will keep firing, which may impact power usage. So
  // this is intended only for "short term" vsync observers. These methods must
  // be called on the parent process main thread, and the observer will likewise
  // be notified on the parent process main thread.
  void AddGenericObserver(VsyncObserver* aObserver);
  void RemoveGenericObserver(VsyncObserver* aObserver);

  void MoveListenersToNewSource(const RefPtr<VsyncSource>& aNewSource);

  RefPtr<RefreshTimerVsyncDispatcher> GetRefreshTimerVsyncDispatcher();
  virtual Display& GetGlobalDisplay() = 0;  // Works across all displays
  void Shutdown();

 protected:
  virtual ~VsyncSource() = default;
};

}  // namespace gfx

struct VsyncEvent {
  VsyncId mId;
  TimeStamp mTime;

  VsyncEvent(const VsyncId& aId, const TimeStamp& aTime)
      : mId(aId), mTime(aTime) {}
  VsyncEvent() = default;
};

}  // namespace mozilla

#endif /* GFX_VSYNCSOURCE_H */