APZTaskRunnable.h (3915B)
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_RepaintRequestRunnable_h 8 #define mozilla_layers_RepaintRequestRunnable_h 9 10 #include <deque> 11 #include <unordered_set> 12 13 #include "mozilla/layers/GeckoContentController.h" 14 #include "mozilla/layers/GeckoContentControllerTypes.h" 15 #include "mozilla/layers/RepaintRequest.h" 16 #include "mozilla/layers/ScrollableLayerGuid.h" 17 #include "nsThreadUtils.h" 18 19 namespace mozilla { 20 namespace layers { 21 22 class GeckoContentController; 23 24 // A runnable invoked in nsRefreshDriver::Tick as an early runnable. 25 class APZTaskRunnable final : public Runnable { 26 using APZStateChange = GeckoContentController_APZStateChange; 27 28 public: 29 explicit APZTaskRunnable(GeckoContentController* aController) 30 : Runnable("RepaintRequestRunnable"), 31 mController(aController), 32 mRegisteredPresShellId(0), 33 mNeedsFlushCompleteNotification(false) {} 34 35 MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_DECL_NSIRUNNABLE 36 37 // Queue a RepaintRequest. 38 // If there's already a RepaintRequest having the same scroll id, the old 39 // one will be discarded. 40 void 41 QueueRequest(const RepaintRequest& aRequest); 42 void QueueAPZStateChange(const ScrollableLayerGuid& aGuid, 43 const APZStateChange& aChange, const int& aArg, 44 Maybe<uint64_t> aInputBlockId); 45 void QueueFlushCompleteNotification(); 46 void Revoke() { 47 mController = nullptr; 48 mRegisteredPresShellId = 0; 49 } 50 51 private: 52 void EnsureRegisterAsEarlyRunner(); 53 bool IsRegisteredWithCurrentPresShell() const; 54 bool IsTestControllingRefreshesEnabled() const; 55 56 // Use a GeckoContentController raw pointer here since the owner of the 57 // GeckoContentController instance (an APZChild instance) holds a strong 58 // reference of this APZTaskRunnable instance and will call Revoke() before 59 // the GeckoContentController gets destroyed in the dtor of the APZChild 60 // instance. 61 GeckoContentController* mController; 62 63 struct RepaintRequestKey { 64 ScrollableLayerGuid::ViewID mScrollId; 65 RepaintRequest::ScrollOffsetUpdateType mScrollUpdateType; 66 bool operator==(const RepaintRequestKey& aOther) const { 67 return mScrollId == aOther.mScrollId && 68 mScrollUpdateType == aOther.mScrollUpdateType; 69 } 70 struct HashFn { 71 std::size_t operator()(const RepaintRequestKey& aKey) const { 72 return HashGeneric(aKey.mScrollId, aKey.mScrollUpdateType); 73 } 74 }; 75 }; 76 struct APZStateChangeRequest { 77 ScrollableLayerGuid mGuid; 78 APZStateChange mChange; 79 int mArg; 80 Maybe<uint64_t> mInputBlockId; 81 }; 82 using Request = mozilla::Variant<RepaintRequest, APZStateChangeRequest>; 83 using RepaintRequests = 84 std::unordered_set<RepaintRequestKey, RepaintRequestKey::HashFn>; 85 // We have an unordered_map and a deque for pending RepaintRequests. The 86 // unordered_map is for quick lookup and the deque is for processing the 87 // pending RepaintRequests in the order we queued. 88 RepaintRequests mPendingRepaintRequestMap; 89 std::deque<Request> mPendingRequestQueue; 90 // This APZTaskRunnable instance is per APZChild instance, which means its 91 // lifetime is tied to the APZChild instance, thus this APZTaskRunnable 92 // instance will be (re-)used for different pres shells so we'd need to 93 // have to remember the pres shell which is currently tied to the APZChild 94 // to deliver queued requests and notifications to the proper pres shell. 95 uint32_t mRegisteredPresShellId; 96 bool mNeedsFlushCompleteNotification; 97 }; 98 99 } // namespace layers 100 } // namespace mozilla 101 102 #endif // mozilla_layers_RepaintRequestRunnable_h