Bug 937130 - Fix up threading and locking in APZCTreeManager. r=botond

This commit is contained in:
Kartikaya Gupta 2013-11-12 11:56:57 -05:00
Родитель 8e61693f29
Коммит 8b6ebfe49e
2 изменённых файлов: 33 добавлений и 13 удалений

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

@ -107,6 +107,8 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
bool aIsFirstPaint, uint64_t aFirstPaintLayersId,
nsTArray< nsRefPtr<AsyncPanZoomController> >* aApzcsToDestroy)
{
mTreeLock.AssertCurrentThreadOwns();
ContainerLayer* container = aLayer->AsContainerLayer();
AsyncPanZoomController* apzc = nullptr;
if (container) {
@ -315,7 +317,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent,
return result;
}
AsyncPanZoomController*
already_AddRefed<AsyncPanZoomController>
APZCTreeManager::GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent,
ScreenPoint aPoint)
{
@ -324,7 +326,7 @@ APZCTreeManager::GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent,
// Reset the cached apz transform
mCachedTransformToApzcForInputBlock = transformToApzc;
if (!apzc) {
return nullptr;
return apzc.forget();
}
for (size_t i = 1; i < aEvent.touches.Length(); i++) {
nsIntPoint point = aEvent.touches[i]->mRefPoint;
@ -341,7 +343,7 @@ APZCTreeManager::GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent,
// Cache apz transform so it can be used for future events in this block.
GetInputTransforms(apzc, mCachedTransformToApzcForInputBlock, transformToGecko);
}
return apzc.get();
return apzc.forget();
}
nsEventStatus
@ -349,6 +351,8 @@ APZCTreeManager::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
WidgetTouchEvent* aOutEvent)
{
MOZ_ASSERT(NS_IsMainThread());
nsEventStatus ret = nsEventStatus_eIgnore;
if (!aEvent.touches.Length()) {
return ret;
@ -421,6 +425,8 @@ APZCTreeManager::ProcessMouseEvent(const WidgetMouseEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
WidgetMouseEvent* aOutEvent)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y));
if (!apzc) {
return nsEventStatus_eIgnore;
@ -441,6 +447,8 @@ APZCTreeManager::ProcessEvent(const WidgetInputEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
WidgetInputEvent* aOutEvent)
{
MOZ_ASSERT(NS_IsMainThread());
// Transform the refPoint
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y));
if (!apzc) {
@ -645,6 +653,8 @@ APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint)
AsyncPanZoomController*
APZCTreeManager::FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid) {
mTreeLock.AssertCurrentThreadOwns();
// This walks the tree in depth-first, reverse order, so that it encounters
// APZCs front-to-back on the screen.
for (AsyncPanZoomController* child = aApzc->GetLastChild(); child; child = child->GetPrevSibling()) {
@ -663,6 +673,8 @@ APZCTreeManager::FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableL
AsyncPanZoomController*
APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& aHitTestPoint)
{
mTreeLock.AssertCurrentThreadOwns();
// The comments below assume there is a chain of layers L..R with L and P having APZC instances as
// explained in the comment on GetInputTransforms. This function will recurse with aApzc at L and P, and the
// comments explain what values are stored in the variables at these two levels. All the comments
@ -796,6 +808,8 @@ void
APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut,
gfx3DMatrix& aTransformToGeckoOut)
{
MonitorAutoLock 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
// below performs one iteration, where parent is at P. The comments explain what values are stored
@ -835,9 +849,12 @@ APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix&
}
}
AsyncPanZoomController*
already_AddRefed<AsyncPanZoomController>
APZCTreeManager::CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2)
{
MonitorAutoLock lock(mTreeLock);
nsRefPtr<AsyncPanZoomController> ancestor;
// If either aApzc1 or aApzc2 is null, min(depth1, depth2) will be 0 and this function
// will return null.
@ -866,7 +883,8 @@ APZCTreeManager::CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomCont
// either APZC, and return the the first common ancestor encountered.
while (true) {
if (aApzc1 == aApzc2) {
return aApzc1;
ancestor = aApzc1;
break;
}
if (depth1 <= 0) {
break;
@ -874,16 +892,18 @@ APZCTreeManager::CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomCont
aApzc1 = aApzc1->GetParent();
aApzc2 = aApzc2->GetParent();
}
return nullptr;
return ancestor.forget();
}
AsyncPanZoomController*
already_AddRefed<AsyncPanZoomController>
APZCTreeManager::RootAPZCForLayersId(AsyncPanZoomController* aApzc)
{
while (aApzc && !aApzc->IsRootForLayersId()) {
aApzc = aApzc->GetParent();
MonitorAutoLock lock(mTreeLock);
nsRefPtr<AsyncPanZoomController> apzc = aApzc;
while (apzc && !apzc->IsRootForLayersId()) {
apzc = apzc->GetParent();
}
return aApzc;
return apzc.forget();
}
}

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

@ -310,9 +310,9 @@ private:
/* Helpers */
AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid);
AsyncPanZoomController* GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& aHitTestPoint);
AsyncPanZoomController* CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2);
AsyncPanZoomController* RootAPZCForLayersId(AsyncPanZoomController* aApzc);
AsyncPanZoomController* GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent, ScreenPoint aPoint);
already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2);
already_AddRefed<AsyncPanZoomController> RootAPZCForLayersId(AsyncPanZoomController* aApzc);
already_AddRefed<AsyncPanZoomController> GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent, ScreenPoint aPoint);
nsEventStatus ProcessTouchEvent(const WidgetTouchEvent& touchEvent, ScrollableLayerGuid* aOutTargetGuid, WidgetTouchEvent* aOutEvent);
nsEventStatus ProcessMouseEvent(const WidgetMouseEvent& mouseEvent, ScrollableLayerGuid* aOutTargetGuid, WidgetMouseEvent* aOutEvent);
nsEventStatus ProcessEvent(const WidgetInputEvent& inputEvent, ScrollableLayerGuid* aOutTargetGuid, WidgetInputEvent* aOutEvent);