diff options
Diffstat (limited to 'gfx/layers/apz/util/APZTaskRunnable.h')
-rw-r--r-- | gfx/layers/apz/util/APZTaskRunnable.h | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/gfx/layers/apz/util/APZTaskRunnable.h b/gfx/layers/apz/util/APZTaskRunnable.h new file mode 100644 index 0000000000..f5de21abd4 --- /dev/null +++ b/gfx/layers/apz/util/APZTaskRunnable.h @@ -0,0 +1,89 @@ +/* -*- 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_RepaintRequestRunnable_h +#define mozilla_layers_RepaintRequestRunnable_h + +#include <deque> +#include <unordered_set> + +#include "mozilla/layers/GeckoContentController.h" +#include "mozilla/layers/RepaintRequest.h" +#include "mozilla/layers/ScrollableLayerGuid.h" +#include "nsThreadUtils.h" + +namespace mozilla { +namespace layers { + +class GeckoContentController; + +// A runnable invoked in nsRefreshDriver::Tick as an early runnable. +class APZTaskRunnable final : public Runnable { + public: + explicit APZTaskRunnable(GeckoContentController* aController) + : Runnable("RepaintRequestRunnable"), + mController(aController), + mRegisteredPresShellId(0), + mNeedsFlushCompleteNotification(false) {} + + MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_DECL_NSIRUNNABLE + + // Queue a RepaintRequest. + // If there's already a RepaintRequest having the same scroll id, the old + // one will be discarded. + void + QueueRequest(const RepaintRequest& aRequest); + void QueueFlushCompleteNotification(); + void Revoke() { + mController = nullptr; + mRegisteredPresShellId = 0; + } + + private: + void EnsureRegisterAsEarlyRunner(); + bool IsRegisteredWithCurrentPresShell() const; + bool IsTestControllingRefreshesEnabled() const; + + // Use a GeckoContentController raw pointer here since the owner of the + // GeckoContentController instance (an APZChild instance) holds a strong + // reference of this APZTaskRunnable instance and will call Revoke() before + // the GeckoContentController gets destroyed in the dtor of the APZChild + // instance. + GeckoContentController* mController; + + struct RepaintRequestKey { + ScrollableLayerGuid::ViewID mScrollId; + RepaintRequest::ScrollOffsetUpdateType mScrollUpdateType; + bool operator==(const RepaintRequestKey& aOther) const { + return mScrollId == aOther.mScrollId && + mScrollUpdateType == aOther.mScrollUpdateType; + } + struct HashFn { + std::size_t operator()(const RepaintRequestKey& aKey) const { + return HashGeneric(aKey.mScrollId, aKey.mScrollUpdateType); + } + }; + }; + using RepaintRequests = + std::unordered_set<RepaintRequestKey, RepaintRequestKey::HashFn>; + // We have an unordered_map and a deque for pending RepaintRequests. The + // unordered_map is for quick lookup and the deque is for processing the + // pending RepaintRequests in the order we queued. + RepaintRequests mPendingRepaintRequestMap; + std::deque<RepaintRequest> mPendingRepaintRequestQueue; + // This APZTaskRunnable instance is per APZChild instance, which means its + // lifetime is tied to the APZChild instance, thus this APZTaskRunnable + // instance will be (re-)used for different pres shells so we'd need to + // have to remember the pres shell which is currently tied to the APZChild + // to deliver queued requests and notifications to the proper pres shell. + uint32_t mRegisteredPresShellId; + bool mNeedsFlushCompleteNotification; +}; + +} // namespace layers +} // namespace mozilla + +#endif // mozilla_layers_RepaintRequestRunnable_h |