зеркало из https://github.com/mozilla/gecko-dev.git
157 строки
5.5 KiB
C++
157 строки
5.5 KiB
C++
/* -*- 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
|