Bug 1433579 - Allow recursively holding the APZ tree lock. r=botond

MozReview-Commit-ID: DzLgqb2wMN9

--HG--
extra : rebase_source : 6d7ba7bf5d574fefdd9e17a2c54ff2a48671701f
This commit is contained in:
Kartikaya Gupta 2018-01-31 12:00:19 -05:00
Родитель 6991ad1d07
Коммит bb553f0d58
2 изменённых файлов: 30 добавлений и 31 удалений

Просмотреть файл

@ -158,7 +158,7 @@ APZCTreeManager::CheckerboardFlushObserver::Observe(nsISupports* aSubject,
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mTreeManager.get());
MutexAutoLock lock(mTreeManager->mTreeLock);
RecursiveMutexAutoLock lock(mTreeManager->mTreeLock);
if (mTreeManager->mRootNode) {
ForEachNode<ReverseIterator>(mTreeManager->mRootNode.get(),
[](HitTestingTreeNode* aNode)
@ -294,7 +294,7 @@ APZCTreeManager::UpdateHitTestingTreeImpl(uint64_t aRootLayerTreeId,
{
APZThreadUtils::AssertOnCompositorThread();
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
// For testing purposes, we log some data to the APZTestData associated with
// the layers id that originated this update.
@ -344,7 +344,7 @@ APZCTreeManager::UpdateHitTestingTreeImpl(uint64_t aRootLayerTreeId,
state.mLayersIdsToDestroy.erase(aRootLayerTreeId);
mApzcTreeLog << "[start]\n";
mTreeLock.AssertCurrentThreadOwns();
mTreeLock.AssertCurrentThreadIn();
ForEachNode<ReverseIterator>(aRoot,
[&](ScrollNode aLayerMetrics)
@ -502,7 +502,7 @@ APZCTreeManager::PushStateToWR(wr::TransactionBuilder& aTxn,
{
APZThreadUtils::AssertOnCompositorThread();
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
// During the first pass through the tree, we build a cache of guid->HTTN so
// that we can find the relevant APZC instances quickly in subsequent passes,
@ -778,7 +778,7 @@ APZCTreeManager::PrepareNodeForLayer(const ScrollNode& aLayer,
HitTestingTreeNode* aNextSibling,
TreeBuildingState& aState)
{
mTreeLock.AssertCurrentThreadOwns();
mTreeLock.AssertCurrentThreadIn();
bool needsApzc = true;
if (!aMetrics.IsScrollable()) {
@ -1074,7 +1074,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
MOZ_ASSERT(mToolbarAnimator);
ScreenPoint scrollOffset;
{
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
RefPtr<AsyncPanZoomController> apzc = FindRootContentOrRootApzc();
if (apzc) {
scrollOffset = ViewAs<ScreenPixel>(apzc->GetCurrentAsyncScrollOffset(AsyncPanZoomController::eForHitTesting),
@ -1124,7 +1124,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
// When the mouse is outside the window we still want to handle dragging
// but we won't find an APZC. Fallback to root APZC then.
{ // scope lock
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
if (!apzc && mRootNode) {
apzc = mRootNode->GetApzc();
}
@ -1739,7 +1739,7 @@ APZCTreeManager::SetupScrollbarDrag(MouseInput& aMouseInput,
// due to async scrolling, so look that up and apply it.
LayerToParentLayerMatrix4x4 thumbTransform;
{
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
thumbTransform = ComputeTransformForNode(aScrollThumbNode);
}
// Only consider the translation, since we do not support both
@ -1903,7 +1903,7 @@ void
APZCTreeManager::UpdateZoomConstraints(const ScrollableLayerGuid& aGuid,
const Maybe<ZoomConstraints>& aConstraints)
{
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
RefPtr<HitTestingTreeNode> node = GetTargetNode(aGuid, nullptr);
MOZ_ASSERT(!node || node->GetApzc()); // any node returned must have an APZC
@ -1962,8 +1962,7 @@ APZCTreeManager::FlushRepaintsToClearScreenToGeckoTransform()
// matched APZCs is the same. It is simplest to ensure that by flushing the
// pending repaint requests, which makes all of the untransforms empty (and
// therefore equal).
MutexAutoLock lock(mTreeLock);
mTreeLock.AssertCurrentThreadOwns();
RecursiveMutexAutoLock lock(mTreeLock);
ForEachNode<ReverseIterator>(mRootNode.get(),
[](HitTestingTreeNode* aNode)
@ -1987,7 +1986,7 @@ APZCTreeManager::CancelAnimation(const ScrollableLayerGuid &aGuid)
void
APZCTreeManager::AdjustScrollForSurfaceShift(const ScreenPoint& aShift)
{
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
RefPtr<AsyncPanZoomController> apzc = FindRootContentOrRootApzc();
if (apzc) {
apzc->AdjustScrollForSurfaceShift(aShift);
@ -2003,7 +2002,7 @@ APZCTreeManager::ClearTree()
APZThreadUtils::RunOnControllerThread(NewRunnableMethod(
"layers::InputQueue::Clear", mInputQueue, &InputQueue::Clear));
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
// Collect the nodes into a list, and then destroy each one.
// We can't destroy them as we collect them, because ForEachNode()
@ -2032,7 +2031,7 @@ APZCTreeManager::ClearTree()
RefPtr<HitTestingTreeNode>
APZCTreeManager::GetRootNode() const
{
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
return mRootNode;
}
@ -2235,7 +2234,7 @@ APZCTreeManager::HitTestAPZC(const ScreenIntPoint& aPoint)
already_AddRefed<AsyncPanZoomController>
APZCTreeManager::GetTargetAPZC(const ScrollableLayerGuid& aGuid)
{
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
RefPtr<HitTestingTreeNode> node = GetTargetNode(aGuid, nullptr);
MOZ_ASSERT(!node || node->GetApzc()); // any node returned must have an APZC
RefPtr<AsyncPanZoomController> apzc = node ? node->GetApzc() : nullptr;
@ -2253,7 +2252,7 @@ already_AddRefed<AsyncPanZoomController>
APZCTreeManager::GetTargetAPZC(const uint64_t& aLayersId,
const FrameMetrics::ViewID& aScrollId)
{
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
ScrollableLayerGuid guid(aLayersId, 0, aScrollId);
RefPtr<HitTestingTreeNode> node = GetTargetNode(guid, &GuidComparatorIgnoringPresShell);
MOZ_ASSERT(!node || node->GetApzc()); // any node returned must have an APZC
@ -2265,7 +2264,7 @@ already_AddRefed<HitTestingTreeNode>
APZCTreeManager::GetTargetNode(const ScrollableLayerGuid& aGuid,
GuidComparator aComparator) const
{
mTreeLock.AssertCurrentThreadOwns();
mTreeLock.AssertCurrentThreadIn();
RefPtr<HitTestingTreeNode> target = DepthFirstSearchPostOrder<ReverseIterator>(mRootNode.get(),
[&aGuid, &aComparator](HitTestingTreeNode* node)
{
@ -2288,7 +2287,7 @@ APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint,
CompositorHitTestInfo* aOutHitResult,
RefPtr<HitTestingTreeNode>* aOutScrollbarNode)
{
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
CompositorHitTestInfo hitResult = CompositorHitTestInfo::eInvisibleToHitTest;
HitTestingTreeNode* scrollbarNode = nullptr;
@ -2385,7 +2384,7 @@ APZCTreeManager::BuildOverscrollHandoffChain(const RefPtr<AsyncPanZoomController
// order in which scroll will be handed off to them.
// Grab tree lock since we'll be walking the APZC tree.
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
// Build the chain. If there is a scroll parent link, we use that. This is
// needed to deal with scroll info layers, because they participate in handoff
@ -2459,7 +2458,7 @@ APZCTreeManager::SetLongTapEnabled(bool aLongTapEnabled)
RefPtr<HitTestingTreeNode>
APZCTreeManager::FindScrollThumbNode(const AsyncDragMetrics& aDragMetrics)
{
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
return DepthFirstSearch<ReverseIterator>(mRootNode.get(),
[&aDragMetrics](HitTestingTreeNode* aNode) {
@ -2493,7 +2492,7 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
CompositorHitTestInfo* aOutHitResult,
HitTestingTreeNode** aOutScrollbarNode)
{
mTreeLock.AssertCurrentThreadOwns();
mTreeLock.AssertCurrentThreadIn();
// This walks the tree in depth-first, reverse order, so that it encounters
// APZCs front-to-back on the screen.
@ -2586,7 +2585,7 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
AsyncPanZoomController*
APZCTreeManager::FindRootApzcForLayersId(uint64_t aLayersId) const
{
mTreeLock.AssertCurrentThreadOwns();
mTreeLock.AssertCurrentThreadIn();
HitTestingTreeNode* resultNode = BreadthFirstSearch<ReverseIterator>(mRootNode.get(),
[aLayersId](HitTestingTreeNode* aNode) {
@ -2601,7 +2600,7 @@ APZCTreeManager::FindRootApzcForLayersId(uint64_t aLayersId) const
AsyncPanZoomController*
APZCTreeManager::FindRootContentApzcForLayersId(uint64_t aLayersId) const
{
mTreeLock.AssertCurrentThreadOwns();
mTreeLock.AssertCurrentThreadIn();
HitTestingTreeNode* resultNode = BreadthFirstSearch<ReverseIterator>(mRootNode.get(),
[aLayersId](HitTestingTreeNode* aNode) {
@ -2616,7 +2615,7 @@ APZCTreeManager::FindRootContentApzcForLayersId(uint64_t aLayersId) const
AsyncPanZoomController*
APZCTreeManager::FindRootContentOrRootApzc() const
{
mTreeLock.AssertCurrentThreadOwns();
mTreeLock.AssertCurrentThreadIn();
// Note: this is intended to find the same "root" that would be found
// by AsyncCompositionManager::ApplyAsyncContentTransformToTree inside
@ -2738,7 +2737,7 @@ ScreenToParentLayerMatrix4x4
APZCTreeManager::GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const
{
Matrix4x4 result;
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
// The comments below assume there is a chain of layers L..R with L and P having APZC instances as
// explained in the comment above. This function is called with aApzc at L, and the loop
@ -2779,7 +2778,7 @@ ParentLayerToScreenMatrix4x4
APZCTreeManager::GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const
{
Matrix4x4 result;
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
// The comments below assume there is a chain of layers L..R with L and P having APZC instances as
// explained in the comment above. This function is called with aApzc at L, and the loop
@ -2814,7 +2813,7 @@ APZCTreeManager::GetCurrentMousePosition() const
already_AddRefed<AsyncPanZoomController>
APZCTreeManager::GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const
{
MutexAutoLock lock(mTreeLock);
RecursiveMutexAutoLock lock(mTreeLock);
RefPtr<AsyncPanZoomController> apzc;
// For now, we only ever want to do pinching on the root-content APZC for
// a given layers id.
@ -2838,7 +2837,7 @@ APZCTreeManager::GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoo
already_AddRefed<AsyncPanZoomController>
APZCTreeManager::CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const
{
mTreeLock.AssertCurrentThreadOwns();
mTreeLock.AssertCurrentThreadIn();
RefPtr<AsyncPanZoomController> ancestor;
// If either aApzc1 or aApzc2 is null, min(depth1, depth2) will be 0 and this function
@ -2884,7 +2883,7 @@ APZCTreeManager::CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomCont
LayerToParentLayerMatrix4x4
APZCTreeManager::ComputeTransformForNode(const HitTestingTreeNode* aNode) const
{
mTreeLock.AssertCurrentThreadOwns();
mTreeLock.AssertCurrentThreadIn();
if (AsyncPanZoomController* apzc = aNode->GetApzc()) {
// If the node represents scrollable content, apply the async transform
// from its APZC.

Просмотреть файл

@ -18,7 +18,7 @@
#include "mozilla/layers/IAPZCTreeManager.h" // for IAPZCTreeManager
#include "mozilla/layers/KeyboardMap.h" // for KeyboardMap
#include "mozilla/layers/FocusState.h" // for FocusState
#include "mozilla/Mutex.h" // for Mutex
#include "mozilla/RecursiveMutex.h" // for RecursiveMutex
#include "mozilla/RefPtr.h" // for RefPtr
#include "mozilla/TimeStamp.h" // for mozilla::TimeStamp
#include "nsCOMPtr.h" // for already_AddRefed
@ -649,7 +649,7 @@ private:
* is considered part of the APZC tree management state.
* Finally, the lock needs to be held when accessing mZoomConstraints.
* IMPORTANT: See the note about lock ordering at the top of this file. */
mutable mozilla::Mutex mTreeLock;
mutable mozilla::RecursiveMutex mTreeLock;
RefPtr<HitTestingTreeNode> mRootNode;
/* Holds the zoom constraints for scrollable layers, as determined by the
* the main-thread gecko code. */