summaryrefslogtreecommitdiffstats
path: root/gfx/layers/wr/OMTASampler.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/wr/OMTASampler.h')
-rw-r--r--gfx/layers/wr/OMTASampler.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/gfx/layers/wr/OMTASampler.h b/gfx/layers/wr/OMTASampler.h
new file mode 100644
index 0000000000..513c905fa1
--- /dev/null
+++ b/gfx/layers/wr/OMTASampler.h
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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_OMTASampler_h
+#define mozilla_layers_OMTASampler_h
+
+#include <unordered_map>
+#include <queue>
+
+#include "base/platform_thread.h" // for PlatformThreadId
+#include "mozilla/layers/OMTAController.h" // for OMTAController
+#include "mozilla/Atomics.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/StaticMutex.h"
+#include "mozilla/StaticPtr.h"
+#include "mozilla/webrender/WebRenderTypes.h" // For WrWindowId, WrEpoch, etc.
+
+namespace mozilla {
+
+class TimeStamp;
+
+namespace wr {
+struct Transaction;
+class TransactionWrapper;
+} // namespace wr
+
+namespace layers {
+class Animation;
+class CompositorAnimationStorage;
+class OMTAValue;
+struct CompositorAnimationIdsForEpoch;
+struct LayersId;
+struct WrAnimations;
+
+/**
+ * This interface exposes OMTA methods related to "sampling" (i.e. calculating
+ * animating values) and "". All sampling methods should be called on the
+ * sampler thread, all some of them should be called on the compositor thread.
+ */
+class OMTASampler final {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OMTASampler)
+
+ public:
+ OMTASampler(const RefPtr<CompositorAnimationStorage>& aAnimStorage,
+ LayersId aRootLayersId);
+
+ // Whoever creates this sampler is responsible for calling Destroy() on it
+ // before releasing the owning refptr.
+ void Destroy();
+
+ void SetWebRenderWindowId(const wr::WrWindowId& aWindowId);
+
+ /**
+ * This function is invoked from rust on the render backend thread when it
+ * is created. It effectively tells the OMTASampler "the current thread is
+ * the sampler thread for this window id" and allows OMTASampler to remember
+ * which thread it is.
+ */
+ static void SetSamplerThread(const wr::WrWindowId& aWindowId);
+
+ static void Sample(const wr::WrWindowId& aWindowId, wr::Transaction* aTxn);
+
+ /**
+ * Sample all animations, called on the sampler thread.
+ */
+ void Sample(wr::TransactionWrapper& aTxn);
+
+ /**
+ * These funtions get called on the the compositor thread.
+ */
+ void SetSampleTime(const TimeStamp& aSampleTime);
+ void ResetPreviousSampleTime();
+ void SetAnimations(uint64_t aId, const LayersId& aLayersId,
+ const nsTArray<layers::Animation>& aAnimations);
+ bool HasAnimations() const;
+
+ /**
+ * Clear AnimatedValues and Animations data, called on the compositor
+ * thread.
+ */
+ void ClearActiveAnimations(
+ std::unordered_map<uint64_t, wr::Epoch>& aActiveAnimations);
+ void RemoveEpochDataPriorTo(
+ std::queue<CompositorAnimationIdsForEpoch>& aCompositorAnimationsToDelete,
+ std::unordered_map<uint64_t, wr::Epoch>& aActiveAnimations,
+ const wr::Epoch& aRenderedEpoch);
+
+ // Those two methods are for testing called on the compositor thread.
+ OMTAValue GetOMTAValue(const uint64_t& aId) const;
+ /**
+ * There are two possibilities when this function gets called, either 1) in
+ * testing refesh driver mode or 2) in normal refresh driver mode. In the case
+ * of 2) |aTestingSampleTime| should be Nothing() so that we can use
+ * |mPreviousSampleTime| and |mSampleTime| for sampling animations.
+ */
+ void SampleForTesting(const Maybe<TimeStamp>& aTestingSampleTime);
+
+ /**
+ * Returns true if currently on the "sampler thread".
+ */
+ bool IsSamplerThread() const;
+
+ void EnterTestMode() { mIsInTestMode = true; }
+ void LeaveTestMode() { mIsInTestMode = false; }
+
+ protected:
+ ~OMTASampler() = default;
+
+ static already_AddRefed<OMTASampler> GetSampler(
+ const wr::WrWindowId& aWindowId);
+
+ private:
+ WrAnimations SampleAnimations(const TimeStamp& aPreviousSampleTime,
+ const TimeStamp& aSampleTime);
+
+ RefPtr<OMTAController> mController;
+ // Can only be accessed or modified while holding mStorageLock.
+ RefPtr<CompositorAnimationStorage> mAnimStorage;
+ mutable Mutex mStorageLock MOZ_UNANNOTATED;
+
+ // Used to manage the mapping from a WR window id to OMTASampler. These are
+ // only used if WebRender is enabled. Both sWindowIdMap and mWindowId should
+ // only be used while holding the sWindowIdLock. Note that we use a
+ // StaticAutoPtr wrapper on sWindowIdMap to avoid a static initializer for the
+ // unordered_map. This also avoids the initializer/memory allocation in cases
+ // where we're not using WebRender.
+ static StaticMutex sWindowIdLock MOZ_UNANNOTATED;
+ static StaticAutoPtr<std::unordered_map<uint64_t, RefPtr<OMTASampler>>>
+ sWindowIdMap;
+ Maybe<wr::WrWindowId> mWindowId;
+
+ // Lock used to protected mSamplerThreadId
+ mutable Mutex mThreadIdLock MOZ_UNANNOTATED;
+ // If WebRender is enabled, this holds the thread id of the render backend
+ // thread (which is the sampler thread) for the compositor associated with
+ // this OMTASampler instance.
+ Maybe<PlatformThreadId> mSamplerThreadId;
+
+ Mutex mSampleTimeLock MOZ_UNANNOTATED;
+ // Can only be accessed or modified while holding mSampleTimeLock.
+ TimeStamp mSampleTime;
+ // Same as |mSampleTime|, can only be accessed or modified while holding
+ // mSampleTimeLock.
+ // We basically use this time stamp instead of |mSampleTime| to make
+ // animations more in sync with other animations on the main thread.
+ TimeStamp mPreviousSampleTime;
+ Atomic<bool> mIsInTestMode;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_OMTASampler_h