Bug 1286957 - Because combining touch-action areas into the event regions is fraught with peril, dump them into the dispatch-to-content region. r=tnikkel

MozReview-Commit-ID: FOyCEFP3Hw6
This commit is contained in:
Kartikaya Gupta 2016-07-20 19:02:09 -04:00
Родитель 3bba9b339e
Коммит 879f91bb9c
3 изменённых файлов: 73 добавлений и 14 удалений

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

@ -465,6 +465,11 @@ public:
LayerState aLayerState);
AnimatedGeometryRoot* GetAnimatedGeometryRoot() { return mAnimatedGeometryRoot; }
/**
* A region including the horizontal pan, vertical pan, and no action regions.
*/
nsRegion CombinedTouchActionRegion();
/**
* Add the given hit regions to the hit regions to the hit retions for this
* PaintedLayer.
@ -3243,6 +3248,12 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
&containingPaintedLayerData->mHitRegion,
&containingPaintedLayerData->mMaybeHitRegion,
&matrixCache);
// See the comment in nsDisplayList::AddFrame, where the touch action regions
// are handled. The same thing applies here.
bool alreadyHadRegions =
!containingPaintedLayerData->mNoActionRegion.IsEmpty() ||
!containingPaintedLayerData->mHorizontalPanRegion.IsEmpty() ||
!containingPaintedLayerData->mVerticalPanRegion.IsEmpty();
nsLayoutUtils::TransformToAncestorAndCombineRegions(
data->mNoActionRegion,
mContainerReferenceFrame,
@ -3264,7 +3275,10 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
&containingPaintedLayerData->mVerticalPanRegion,
&containingPaintedLayerData->mDispatchToContentHitRegion,
&matrixCache);
if (alreadyHadRegions) {
containingPaintedLayerData->mDispatchToContentHitRegion.OrWith(
containingPaintedLayerData->CombinedTouchActionRegion());
}
} else {
EventRegions regions;
regions.mHitRegion = ScaleRegionToOutsidePixels(data->mHitRegion);
@ -3461,17 +3475,35 @@ PaintedLayerData::Accumulate(ContainerState* aState,
}
}
nsRegion
PaintedLayerData::CombinedTouchActionRegion()
{
nsRegion result;
result.Or(mHorizontalPanRegion, mVerticalPanRegion);
result.OrWith(mNoActionRegion);
return result;
}
void
PaintedLayerData::AccumulateEventRegions(ContainerState* aState, nsDisplayLayerEventRegions* aEventRegions)
{
FLB_LOG_PAINTED_LAYER_DECISION(this, "Accumulating event regions %p against pld=%p\n", aEventRegions, this);
mHitRegion.Or(mHitRegion, aEventRegions->HitRegion());
mMaybeHitRegion.Or(mMaybeHitRegion, aEventRegions->MaybeHitRegion());
mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, aEventRegions->DispatchToContentHitRegion());
mNoActionRegion.Or(mNoActionRegion, aEventRegions->NoActionRegion());
mHorizontalPanRegion.Or(mHorizontalPanRegion, aEventRegions->HorizontalPanRegion());
mVerticalPanRegion.Or(mVerticalPanRegion, aEventRegions->VerticalPanRegion());
mHitRegion.OrWith(aEventRegions->HitRegion());
mMaybeHitRegion.OrWith(aEventRegions->MaybeHitRegion());
mDispatchToContentHitRegion.OrWith(aEventRegions->DispatchToContentHitRegion());
// See the comment in nsDisplayList::AddFrame, where the touch action regions
// are handled. The same thing applies here.
bool alreadyHadRegions = !mNoActionRegion.IsEmpty() ||
!mHorizontalPanRegion.IsEmpty() ||
!mVerticalPanRegion.IsEmpty();
mNoActionRegion.OrWith(aEventRegions->NoActionRegion());
mHorizontalPanRegion.OrWith(aEventRegions->HorizontalPanRegion());
mVerticalPanRegion.OrWith(aEventRegions->VerticalPanRegion());
if (alreadyHadRegions) {
mDispatchToContentHitRegion.OrWith(CombinedTouchActionRegion());
}
// Calculate scaled versions of the bounds of mHitRegion and mMaybeHitRegion
// for quick access in FindPaintedLayerFor().

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

@ -3676,14 +3676,31 @@ nsDisplayLayerEventRegions::AddFrame(nsDisplayListBuilder* aBuilder,
// Touch action region
uint32_t touchAction = nsLayoutUtils::GetTouchActionFromFrame(aFrame);
if (touchAction & NS_STYLE_TOUCH_ACTION_NONE) {
mNoActionRegion.Or(mNoActionRegion, borderBox);
} else {
if ((touchAction & NS_STYLE_TOUCH_ACTION_PAN_X)) {
mHorizontalPanRegion.Or(mHorizontalPanRegion, borderBox);
if (touchAction != NS_STYLE_TOUCH_ACTION_AUTO) {
// If this frame has touch-action areas, and there were already
// touch-action areas from some other element on this same event regions,
// then all we know is that there are multiple elements with touch-action
// properties. In particular, we don't know what the relationship is
// between those elements in terms of DOM ancestry, and so we don't know
// how to combine the regions properly. Instead, we just add all the areas
// to the dispatch-to-content region, so that the APZ knows to check with
// the main thread. XXX we need to come up with a better way to do this,
// see bug 1287829.
bool alreadyHadRegions = !mNoActionRegion.IsEmpty() ||
!mHorizontalPanRegion.IsEmpty() ||
!mVerticalPanRegion.IsEmpty();
if (touchAction & NS_STYLE_TOUCH_ACTION_NONE) {
mNoActionRegion.OrWith(borderBox);
} else {
if ((touchAction & NS_STYLE_TOUCH_ACTION_PAN_X)) {
mHorizontalPanRegion.OrWith(borderBox);
}
if ((touchAction & NS_STYLE_TOUCH_ACTION_PAN_Y)) {
mVerticalPanRegion.OrWith(borderBox);
}
}
if ((touchAction & NS_STYLE_TOUCH_ACTION_PAN_Y)) {
mVerticalPanRegion.Or(mVerticalPanRegion, borderBox);
if (alreadyHadRegions) {
mDispatchToContentHitRegion.OrWith(CombinedTouchActionRegion());
}
}
}
@ -3710,6 +3727,15 @@ nsDisplayLayerEventRegions::IsEmpty() const
return false;
}
nsRegion
nsDisplayLayerEventRegions::CombinedTouchActionRegion()
{
nsRegion result;
result.Or(mHorizontalPanRegion, mVerticalPanRegion);
result.OrWith(mNoActionRegion);
return result;
}
int32_t
nsDisplayLayerEventRegions::ZIndex() const
{

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

@ -3164,6 +3164,7 @@ public:
const nsRegion& NoActionRegion() { return mNoActionRegion; }
const nsRegion& HorizontalPanRegion() { return mHorizontalPanRegion; }
const nsRegion& VerticalPanRegion() { return mVerticalPanRegion; }
nsRegion CombinedTouchActionRegion();
virtual void WriteDebugInfo(std::stringstream& aStream) override;