Bug 1451469 - Implement the guts of the WR sampler thread registration. r=botond

This lets the APZSampler know which thread is the actual sampler thread.
This is only really used for the thread assertions, but might be useful
for debugging and such as well.

Note that since this behaviour is not dependent on any prefs (unlike the
updater thread, which is only the scene builder thread when the async
scene building pref is enabled), we don't hook it up to the rust code
just yet; that will happen in the last patch.

MozReview-Commit-ID: DrrJOyFA65D

--HG--
extra : rebase_source : 61e8e75ae16f95fe5ce95fa42a3dff501979ab9e
This commit is contained in:
Kartikaya Gupta 2018-04-16 17:39:14 -04:00
parent ee76c6b413
commit 6186818885
2 changed files with 56 additions and 0 deletions

View File

@ -9,6 +9,7 @@
#include <unordered_map>
#include "base/platform_thread.h" // for PlatformThreadId
#include "mozilla/layers/AsyncCompositionManager.h" // for AsyncTransform
#include "mozilla/StaticMutex.h"
#include "nsTArray.h"
@ -43,6 +44,14 @@ public:
void SetWebRenderWindowId(const wr::WindowId& aWindowId);
/**
* This function is invoked from rust on the render backend thread when it
* is created. It effectively tells the APZSampler "the current thread is
* the sampler thread for this window id" and allows APZSampler to remember
* which thread it is.
*/
static void SetSamplerThread(const wr::WrWindowId& aWindowId);
bool PushStateToWR(wr::TransactionBuilder& aTxn,
const TimeStamp& aSampleTime);
@ -90,6 +99,7 @@ public:
protected:
virtual ~APZSampler();
bool UsingWebRenderSamplerThread() const;
static already_AddRefed<APZSampler> GetSampler(const wr::WrWindowId& aWindowId);
private:
@ -102,6 +112,19 @@ private:
static std::unordered_map<uint64_t, APZSampler*> sWindowIdMap;
Maybe<wr::WrWindowId> mWindowId;
// 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 APZSampler instance.
// This is written to once during init and never cleared, and so reading it
// from multiple threads during normal operation (after initialization)
// without locking should be fine.
Maybe<PlatformThreadId> mSamplerThreadId;
#ifdef DEBUG
// This flag is used to ensure that we don't ever try to do sampler-thread
// stuff before the updater thread has been properly initialized.
mutable bool mSamplerThreadQueried;
#endif
};
} // namespace layers

View File

@ -23,6 +23,9 @@ std::unordered_map<uint64_t, APZSampler*> APZSampler::sWindowIdMap;
APZSampler::APZSampler(const RefPtr<APZCTreeManager>& aApz)
: mApz(aApz)
#ifdef DEBUG
, mSamplerThreadQueried(false)
#endif
{
MOZ_ASSERT(aApz);
mApz->SetSampler(this);
@ -47,6 +50,16 @@ APZSampler::SetWebRenderWindowId(const wr::WindowId& aWindowId)
sWindowIdMap[wr::AsUint64(aWindowId)] = this;
}
/*static*/ void
APZSampler::SetSamplerThread(const wr::WrWindowId& aWindowId)
{
if (RefPtr<APZSampler> sampler = GetSampler(aWindowId)) {
// Ensure nobody tried to use the updater thread before this point.
MOZ_ASSERT(!sampler->mSamplerThreadQueried);
sampler->mSamplerThreadId = Some(PlatformThread::CurrentId());
}
}
bool
APZSampler::PushStateToWR(wr::TransactionBuilder& aTxn,
const TimeStamp& aSampleTime)
@ -173,9 +186,29 @@ APZSampler::AssertOnSamplerThread() const
bool
APZSampler::IsSamplerThread() const
{
if (UsingWebRenderSamplerThread()) {
return PlatformThread::CurrentId() == *mSamplerThreadId;
}
return CompositorThreadHolder::IsInCompositorThread();
}
bool
APZSampler::UsingWebRenderSamplerThread() const
{
// If mSamplerThreadId is not set at the point that this is called, then
// that means that either (a) WebRender is not enabled for the compositor
// to which this APZSampler is attached or (b) we are attempting to do
// something sampler-related before WebRender is up and running. In case
// (a) falling back to the compositor thread is correct, and in case (b)
// we should stop doing the sampler-related thing so early. We catch this
// case by setting the mSamplerThreadQueried flag and asserting on WR
// initialization.
#ifdef DEBUG
mSamplerThreadQueried = true;
#endif
return mSamplerThreadId.isSome();
}
/*static*/ already_AddRefed<APZSampler>
APZSampler::GetSampler(const wr::WrWindowId& aWindowId)
{