/* -*- 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_APZSampler_h #define mozilla_layers_APZSampler_h #include #include "apz/src/APZCTreeManager.h" #include "base/platform_thread.h" // for PlatformThreadId #include "mozilla/layers/APZUtils.h" #include "mozilla/layers/SampleTime.h" #include "mozilla/StaticMutex.h" #include "mozilla/StaticPtr.h" #include "mozilla/webrender/WebRenderTypes.h" #include "Units.h" #include "VsyncSource.h" namespace mozilla { class TimeStamp; namespace wr { struct Transaction; class TransactionWrapper; struct WrWindowId; } // namespace wr namespace layers { struct ScrollbarData; /** * This interface exposes APZ methods related to "sampling" (i.e. reading the * async transforms produced by APZ). These methods should all be called on * the sampler thread. */ class APZSampler { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZSampler) public: APZSampler(const RefPtr& aApz, bool aIsUsingWebRender); // Whoever creates this sampler is responsible for calling Destroy() on it // before releasing the owning refptr. void Destroy(); 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); static void SampleForWebRender(const wr::WrWindowId& aWindowId, const uint64_t* aGeneratedFrameId, wr::Transaction* aTransaction); void SetSampleTime(const SampleTime& aSampleTime); void SampleForWebRender(const Maybe& aGeneratedFrameId, wr::TransactionWrapper& aTxn); /** * Similar to above GetCurrentAsyncTransform, but get the current transform * with LayersId and ViewID. * NOTE: This function should NOT be called on the compositor thread. */ AsyncTransform GetCurrentAsyncTransform( const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId, AsyncTransformComponents aComponents, const MutexAutoLock& aProofOfMapLock) const; /** * Returns the composition bounds of the APZC corresponding to the pair of * |aLayersId| and |aScrollId|. */ ParentLayerRect GetCompositionBounds( const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId, const MutexAutoLock& aProofOfMapLock) const; struct ScrollOffsetAndRange { CSSPoint mOffset; CSSRect mRange; }; /** * Returns the scroll offset and scroll range of the APZC corresponding to the * pair of |aLayersId| and |aScrollId| * * Note: This is called from OMTA Sampler thread, or Compositor thread for * testing. */ Maybe GetCurrentScrollOffsetAndRange( const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId, const MutexAutoLock& aProofOfMapLock) const; /** * This can be used to assert that the current thread is the * sampler thread (which samples the async transform). * This does nothing if thread assertions are disabled. */ void AssertOnSamplerThread() const; /** * Returns true if currently on the APZSampler's "sampler thread". */ bool IsSamplerThread() const; template void CallWithMapLock(Callback& aCallback) { mApz->CallWithMapLock(aCallback); } protected: virtual ~APZSampler(); static already_AddRefed GetSampler( const wr::WrWindowId& aWindowId); private: RefPtr mApz; bool mIsUsingWebRender; // Used to manage the mapping from a WR window id to APZSampler. 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>> sWindowIdMap; Maybe 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 APZSampler instance. Maybe mSamplerThreadId; Mutex mSampleTimeLock MOZ_UNANNOTATED; // Can only be accessed or modified while holding mSampleTimeLock. SampleTime mSampleTime; }; } // namespace layers } // namespace mozilla #endif // mozilla_layers_APZSampler_h