APZSampler.h (5209B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_layers_APZSampler_h 8 #define mozilla_layers_APZSampler_h 9 10 #include <unordered_map> 11 12 #include "apz/src/APZCTreeManager.h" 13 #include "base/platform_thread.h" // for PlatformThreadId 14 #include "mozilla/layers/APZUtils.h" 15 #include "mozilla/layers/SampleTime.h" 16 #include "mozilla/StaticMutex.h" 17 #include "mozilla/StaticPtr.h" 18 #include "mozilla/webrender/WebRenderTypes.h" 19 #include "Units.h" 20 #include "VsyncSource.h" 21 22 namespace mozilla { 23 24 class TimeStamp; 25 26 namespace wr { 27 struct Transaction; 28 class TransactionWrapper; 29 struct WrWindowId; 30 } // namespace wr 31 32 namespace layers { 33 34 struct ScrollbarData; 35 36 /** 37 * This interface exposes APZ methods related to "sampling" (i.e. reading the 38 * async transforms produced by APZ). These methods should all be called on 39 * the sampler thread. 40 */ 41 class APZSampler { 42 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZSampler) 43 44 public: 45 APZSampler(const RefPtr<APZCTreeManager>& aApz, bool aIsUsingWebRender); 46 47 // Whoever creates this sampler is responsible for calling Destroy() on it 48 // before releasing the owning refptr. 49 void Destroy(); 50 51 void SetWebRenderWindowId(const wr::WindowId& aWindowId); 52 53 /** 54 * This function is invoked from rust on the render backend thread when it 55 * is created. It effectively tells the APZSampler "the current thread is 56 * the sampler thread for this window id" and allows APZSampler to remember 57 * which thread it is. 58 */ 59 static void SetSamplerThread(const wr::WrWindowId& aWindowId); 60 static void SampleForWebRender(const wr::WrWindowId& aWindowId, 61 const uint64_t* aGeneratedFrameId, 62 wr::Transaction* aTransaction); 63 64 void SetSampleTime(const SampleTime& aSampleTime); 65 void SampleForWebRender(const Maybe<VsyncId>& aGeneratedFrameId, 66 wr::TransactionWrapper& aTxn); 67 68 /** 69 * Similar to above GetCurrentAsyncTransform, but get the current transform 70 * with LayersId and ViewID. 71 * NOTE: This function should NOT be called on the compositor thread. 72 */ 73 AsyncTransform GetCurrentAsyncTransform( 74 const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId, 75 AsyncTransformComponents aComponents, 76 const MutexAutoLock& aProofOfMapLock) const; 77 78 /** 79 * Returns the composition bounds of the APZC corresponding to the pair of 80 * |aLayersId| and |aScrollId|. 81 */ 82 ParentLayerRect GetCompositionBounds( 83 const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId, 84 const MutexAutoLock& aProofOfMapLock) const; 85 86 struct ScrollOffsetAndRange { 87 CSSPoint mOffset; 88 CSSRect mRange; 89 }; 90 /** 91 * Returns the scroll offset and scroll range of the APZC corresponding to the 92 * pair of |aLayersId| and |aScrollId| 93 * 94 * Note: This is called from OMTA Sampler thread, or Compositor thread for 95 * testing. 96 */ 97 Maybe<ScrollOffsetAndRange> GetCurrentScrollOffsetAndRange( 98 const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId, 99 const MutexAutoLock& aProofOfMapLock) const; 100 101 /** 102 * This can be used to assert that the current thread is the 103 * sampler thread (which samples the async transform). 104 * This does nothing if thread assertions are disabled. 105 */ 106 void AssertOnSamplerThread() const; 107 108 /** 109 * Returns true if currently on the APZSampler's "sampler thread". 110 */ 111 bool IsSamplerThread() const; 112 113 template <typename Callback> 114 void CallWithMapLock(Callback& aCallback) { 115 mApz->CallWithMapLock(aCallback); 116 } 117 118 protected: 119 virtual ~APZSampler(); 120 121 static already_AddRefed<APZSampler> GetSampler( 122 const wr::WrWindowId& aWindowId); 123 124 private: 125 RefPtr<APZCTreeManager> mApz; 126 bool mIsUsingWebRender; 127 128 // Used to manage the mapping from a WR window id to APZSampler. These are 129 // only used if WebRender is enabled. Both sWindowIdMap and mWindowId should 130 // only be used while holding the sWindowIdLock. Note that we use a 131 // StaticAutoPtr wrapper on sWindowIdMap to avoid a static initializer for the 132 // unordered_map. This also avoids the initializer/memory allocation in cases 133 // where we're not using WebRender. 134 static StaticMutex sWindowIdLock MOZ_UNANNOTATED; 135 static StaticAutoPtr<std::unordered_map<uint64_t, RefPtr<APZSampler>>> 136 sWindowIdMap; 137 Maybe<wr::WrWindowId> mWindowId; 138 139 // Lock used to protected mSamplerThreadId 140 mutable Mutex mThreadIdLock MOZ_UNANNOTATED; 141 // If WebRender is enabled, this holds the thread id of the render backend 142 // thread (which is the sampler thread) for the compositor associated with 143 // this APZSampler instance. 144 Maybe<PlatformThreadId> mSamplerThreadId; 145 146 Mutex mSampleTimeLock MOZ_UNANNOTATED; 147 // Can only be accessed or modified while holding mSampleTimeLock. 148 SampleTime mSampleTime; 149 }; 150 151 } // namespace layers 152 } // namespace mozilla 153 154 #endif // mozilla_layers_APZSampler_h