mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1051985 - Move the APZ from ContainerLayer to Layer. r=mattwoodrow,botond
This commit is contained in:
parent
901529a459
commit
1fc3c3121f
@ -451,13 +451,13 @@ Layer::SetAnimations(const AnimationArray& aAnimations)
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayer::SetAsyncPanZoomController(AsyncPanZoomController *controller)
|
||||
Layer::SetAsyncPanZoomController(AsyncPanZoomController *controller)
|
||||
{
|
||||
mAPZC = controller;
|
||||
}
|
||||
|
||||
AsyncPanZoomController*
|
||||
ContainerLayer::GetAsyncPanZoomController() const
|
||||
Layer::GetAsyncPanZoomController() const
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (mAPZC) {
|
||||
|
@ -1471,6 +1471,12 @@ public:
|
||||
*/
|
||||
void ClearInvalidRect() { mInvalidRegion.SetEmpty(); }
|
||||
|
||||
// These functions allow attaching an AsyncPanZoomController to this layer,
|
||||
// and can be used anytime.
|
||||
// A layer has an APZC only-if GetFrameMetrics().IsScrollable()
|
||||
void SetAsyncPanZoomController(AsyncPanZoomController *controller);
|
||||
AsyncPanZoomController* GetAsyncPanZoomController() const;
|
||||
|
||||
void ApplyPendingUpdatesForThisTransaction();
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -1573,6 +1579,7 @@ protected:
|
||||
nsIntRect mClipRect;
|
||||
nsIntRect mTileSourceRect;
|
||||
nsIntRegion mInvalidRegion;
|
||||
nsRefPtr<AsyncPanZoomController> mAPZC;
|
||||
uint32_t mContentFlags;
|
||||
bool mUseClipRect;
|
||||
bool mUseTileSourceRect;
|
||||
@ -1746,12 +1753,6 @@ public:
|
||||
*/
|
||||
virtual bool RepositionChild(Layer* aChild, Layer* aAfter);
|
||||
|
||||
// These functions allow attaching an AsyncPanZoomController to this layer,
|
||||
// and can be used anytime.
|
||||
// A container layer has an APZC only-if GetFrameMetrics().IsScrollable()
|
||||
void SetAsyncPanZoomController(AsyncPanZoomController *controller);
|
||||
AsyncPanZoomController* GetAsyncPanZoomController() const;
|
||||
|
||||
void SetPreScale(float aXScale, float aYScale)
|
||||
{
|
||||
if (mPreXScale == aXScale && mPreYScale == aYScale) {
|
||||
@ -1870,7 +1871,6 @@ protected:
|
||||
|
||||
Layer* mFirstChild;
|
||||
Layer* mLastChild;
|
||||
nsRefPtr<AsyncPanZoomController> mAPZC;
|
||||
float mPreXScale;
|
||||
float mPreYScale;
|
||||
// The resolution scale inherited from the parent layer. This will already
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "Compositor.h" // for Compositor
|
||||
#include "CompositorParent.h" // for CompositorParent, etc
|
||||
#include "InputData.h" // for InputData, etc
|
||||
#include "Layers.h" // for ContainerLayer, Layer, etc
|
||||
#include "Layers.h" // for Layer, etc
|
||||
#include "mozilla/dom/Touch.h" // for Touch
|
||||
#include "mozilla/gfx/Point.h" // for Point
|
||||
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
|
||||
@ -169,154 +169,153 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
|
||||
|
||||
Matrix4x4 transform = aLayer->GetTransform();
|
||||
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
AsyncPanZoomController* apzc = nullptr;
|
||||
mApzcTreeLog << aLayer->Name() << '\t';
|
||||
if (container) {
|
||||
const FrameMetrics& metrics = aLayer->GetFrameMetrics();
|
||||
if (metrics.IsScrollable()) {
|
||||
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(aLayersId);
|
||||
if (state && state->mController.get()) {
|
||||
// If we get here, aLayer is a scrollable container layer and somebody
|
||||
// has registered a GeckoContentController for it, so we need to ensure
|
||||
// it has an APZC instance to manage its scrolling.
|
||||
|
||||
apzc = container->GetAsyncPanZoomController();
|
||||
const FrameMetrics& metrics = aLayer->GetFrameMetrics();
|
||||
if (metrics.IsScrollable()) {
|
||||
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(aLayersId);
|
||||
if (state && state->mController.get()) {
|
||||
// If we get here, aLayer is a scrollable layer and somebody
|
||||
// has registered a GeckoContentController for it, so we need to ensure
|
||||
// it has an APZC instance to manage its scrolling.
|
||||
|
||||
// If the content represented by the container layer has changed (which may
|
||||
// be possible because of DLBI heuristics) then we don't want to keep using
|
||||
// the same old APZC for the new content. Null it out so we run through the
|
||||
// code to find another one or create one.
|
||||
ScrollableLayerGuid guid(aLayersId, metrics);
|
||||
if (apzc && !apzc->Matches(guid)) {
|
||||
apzc = nullptr;
|
||||
}
|
||||
apzc = aLayer->GetAsyncPanZoomController();
|
||||
|
||||
// If the container doesn't have an APZC already, try to find one of our
|
||||
// pre-existing ones that matches. In particular, if we find an APZC whose
|
||||
// ScrollableLayerGuid is the same, then we know what happened is that the
|
||||
// layout of the page changed causing the layer tree to be rebuilt, but the
|
||||
// underlying content for which the APZC was originally created is still
|
||||
// there. So it makes sense to pick up that APZC instance again and use it here.
|
||||
if (apzc == nullptr) {
|
||||
for (size_t i = 0; i < aApzcsToDestroy->Length(); i++) {
|
||||
if (aApzcsToDestroy->ElementAt(i)->Matches(guid)) {
|
||||
apzc = aApzcsToDestroy->ElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the content represented by the scrollable layer has changed (which may
|
||||
// be possible because of DLBI heuristics) then we don't want to keep using
|
||||
// the same old APZC for the new content. Null it out so we run through the
|
||||
// code to find another one or create one.
|
||||
ScrollableLayerGuid guid(aLayersId, metrics);
|
||||
if (apzc && !apzc->Matches(guid)) {
|
||||
apzc = nullptr;
|
||||
}
|
||||
|
||||
// The APZC we get off the layer may have been destroyed previously if the layer was inactive
|
||||
// or omitted from the layer tree for whatever reason from a layers update. If it later comes
|
||||
// back it will have a reference to a destroyed APZC and so we need to throw that out and make
|
||||
// a new one.
|
||||
bool newApzc = (apzc == nullptr || apzc->IsDestroyed());
|
||||
if (newApzc) {
|
||||
apzc = new AsyncPanZoomController(aLayersId, this, state->mController,
|
||||
AsyncPanZoomController::USE_GESTURE_DETECTOR);
|
||||
apzc->SetCompositorParent(aCompositor);
|
||||
if (state->mCrossProcessParent != nullptr) {
|
||||
apzc->ShareFrameMetricsAcrossProcesses();
|
||||
}
|
||||
} else {
|
||||
// If there was already an APZC for the layer clear the tree pointers
|
||||
// so that it doesn't continue pointing to APZCs that should no longer
|
||||
// be in the tree. These pointers will get reset properly as we continue
|
||||
// building the tree. Also remove it from the set of APZCs that are going
|
||||
// to be destroyed, because it's going to remain active.
|
||||
aApzcsToDestroy->RemoveElement(apzc);
|
||||
apzc->SetPrevSibling(nullptr);
|
||||
apzc->SetLastChild(nullptr);
|
||||
}
|
||||
APZCTM_LOG("Using APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, aLayersId, metrics.GetScrollId());
|
||||
|
||||
apzc->NotifyLayersUpdated(metrics,
|
||||
aIsFirstPaint && (aLayersId == aOriginatingLayersId));
|
||||
apzc->SetScrollHandoffParentId(aLayer->GetScrollHandoffParentId());
|
||||
|
||||
// Use the composition bounds as the hit test region.
|
||||
// Optionally, the GeckoContentController can provide a touch-sensitive
|
||||
// region that constrains all frames associated with the controller.
|
||||
// In this case we intersect the composition bounds with that region.
|
||||
ParentLayerRect visible(metrics.mCompositionBounds);
|
||||
CSSRect touchSensitiveRegion;
|
||||
if (state->mController->GetTouchSensitiveRegion(&touchSensitiveRegion)) {
|
||||
// Note: we assume here that touchSensitiveRegion is in the CSS pixels
|
||||
// of our parent layer, which makes this coordinate conversion
|
||||
// correct.
|
||||
visible = visible.Intersect(touchSensitiveRegion
|
||||
* metrics.mDevPixelsPerCSSPixel
|
||||
* metrics.GetParentResolution());
|
||||
}
|
||||
|
||||
// Not sure what rounding option is the most correct here, but if we ever
|
||||
// figure it out we can change this. For now I'm rounding in to minimize
|
||||
// the chances of getting a complex region.
|
||||
ParentLayerIntRect roundedVisible = RoundedIn(visible);
|
||||
nsIntRegion unobscured;
|
||||
unobscured.Sub(nsIntRect(roundedVisible.x, roundedVisible.y,
|
||||
roundedVisible.width, roundedVisible.height),
|
||||
aObscured);
|
||||
|
||||
apzc->SetLayerHitTestData(unobscured, aTransform, transform);
|
||||
APZCTM_LOG("Setting rect(%f %f %f %f) as visible region for APZC %p\n", visible.x, visible.y,
|
||||
visible.width, visible.height,
|
||||
apzc);
|
||||
|
||||
mApzcTreeLog << "APZC " << guid
|
||||
<< "\tcb=" << visible
|
||||
<< "\tsr=" << metrics.mScrollableRect
|
||||
<< (aLayer->GetVisibleRegion().IsEmpty() ? "\tscrollinfo" : "")
|
||||
<< (apzc->HasScrollgrab() ? "\tscrollgrab" : "")
|
||||
<< "\t" << aLayer->GetContentDescription();
|
||||
|
||||
// Bind the APZC instance into the tree of APZCs
|
||||
if (aNextSibling) {
|
||||
aNextSibling->SetPrevSibling(apzc);
|
||||
} else if (aParent) {
|
||||
aParent->SetLastChild(apzc);
|
||||
} else {
|
||||
mRootApzc = apzc;
|
||||
apzc->MakeRoot();
|
||||
}
|
||||
|
||||
// For testing, log the parent scroll id of every APZC that has a
|
||||
// parent. This allows test code to reconstruct the APZC tree.
|
||||
// Note that we currently only do this for APZCs in the layer tree
|
||||
// that originated the update, because the only identifying information
|
||||
// we are logging about APZCs is the scroll id, and otherwise we could
|
||||
// confuse APZCs from different layer trees with the same scroll id.
|
||||
if (aLayersId == aOriginatingLayersId && apzc->GetParent()) {
|
||||
aPaintLogger.LogTestData(metrics.GetScrollId(), "parentScrollId",
|
||||
apzc->GetParent()->GetGuid().mScrollId);
|
||||
}
|
||||
|
||||
// Let this apzc be the parent of other controllers when we recurse downwards
|
||||
aParent = apzc;
|
||||
|
||||
if (newApzc) {
|
||||
if (apzc->IsRootForLayersId()) {
|
||||
// If we just created a new apzc that is the root for its layers ID, then
|
||||
// we need to update its zoom constraints which might have arrived before this
|
||||
// was created
|
||||
ZoomConstraints constraints;
|
||||
if (state->mController->GetRootZoomConstraints(&constraints)) {
|
||||
apzc->UpdateZoomConstraints(constraints);
|
||||
}
|
||||
} else {
|
||||
// For an apzc that is not the root for its layers ID, we give it the
|
||||
// same zoom constraints as its parent. This ensures that if e.g.
|
||||
// user-scalable=no was specified, none of the APZCs allow double-tap
|
||||
// to zoom.
|
||||
apzc->UpdateZoomConstraints(apzc->GetParent()->GetZoomConstraints());
|
||||
// If the layer doesn't have an APZC already, try to find one of our
|
||||
// pre-existing ones that matches. In particular, if we find an APZC whose
|
||||
// ScrollableLayerGuid is the same, then we know what happened is that the
|
||||
// layout of the page changed causing the layer tree to be rebuilt, but the
|
||||
// underlying content for which the APZC was originally created is still
|
||||
// there. So it makes sense to pick up that APZC instance again and use it here.
|
||||
if (apzc == nullptr) {
|
||||
for (size_t i = 0; i < aApzcsToDestroy->Length(); i++) {
|
||||
if (aApzcsToDestroy->ElementAt(i)->Matches(guid)) {
|
||||
apzc = aApzcsToDestroy->ElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
container->SetAsyncPanZoomController(apzc);
|
||||
// The APZC we get off the layer may have been destroyed previously if the layer was inactive
|
||||
// or omitted from the layer tree for whatever reason from a layers update. If it later comes
|
||||
// back it will have a reference to a destroyed APZC and so we need to throw that out and make
|
||||
// a new one.
|
||||
bool newApzc = (apzc == nullptr || apzc->IsDestroyed());
|
||||
if (newApzc) {
|
||||
apzc = new AsyncPanZoomController(aLayersId, this, state->mController,
|
||||
AsyncPanZoomController::USE_GESTURE_DETECTOR);
|
||||
apzc->SetCompositorParent(aCompositor);
|
||||
if (state->mCrossProcessParent != nullptr) {
|
||||
apzc->ShareFrameMetricsAcrossProcesses();
|
||||
}
|
||||
} else {
|
||||
// If there was already an APZC for the layer clear the tree pointers
|
||||
// so that it doesn't continue pointing to APZCs that should no longer
|
||||
// be in the tree. These pointers will get reset properly as we continue
|
||||
// building the tree. Also remove it from the set of APZCs that are going
|
||||
// to be destroyed, because it's going to remain active.
|
||||
aApzcsToDestroy->RemoveElement(apzc);
|
||||
apzc->SetPrevSibling(nullptr);
|
||||
apzc->SetLastChild(nullptr);
|
||||
}
|
||||
APZCTM_LOG("Using APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, aLayersId, metrics.GetScrollId());
|
||||
|
||||
apzc->NotifyLayersUpdated(metrics,
|
||||
aIsFirstPaint && (aLayersId == aOriginatingLayersId));
|
||||
apzc->SetScrollHandoffParentId(aLayer->GetScrollHandoffParentId());
|
||||
|
||||
// Use the composition bounds as the hit test region.
|
||||
// Optionally, the GeckoContentController can provide a touch-sensitive
|
||||
// region that constrains all frames associated with the controller.
|
||||
// In this case we intersect the composition bounds with that region.
|
||||
ParentLayerRect visible(metrics.mCompositionBounds);
|
||||
CSSRect touchSensitiveRegion;
|
||||
if (state->mController->GetTouchSensitiveRegion(&touchSensitiveRegion)) {
|
||||
// Note: we assume here that touchSensitiveRegion is in the CSS pixels
|
||||
// of our parent layer, which makes this coordinate conversion
|
||||
// correct.
|
||||
visible = visible.Intersect(touchSensitiveRegion
|
||||
* metrics.mDevPixelsPerCSSPixel
|
||||
* metrics.GetParentResolution());
|
||||
}
|
||||
|
||||
// Not sure what rounding option is the most correct here, but if we ever
|
||||
// figure it out we can change this. For now I'm rounding in to minimize
|
||||
// the chances of getting a complex region.
|
||||
ParentLayerIntRect roundedVisible = RoundedIn(visible);
|
||||
nsIntRegion unobscured;
|
||||
unobscured.Sub(nsIntRect(roundedVisible.x, roundedVisible.y,
|
||||
roundedVisible.width, roundedVisible.height),
|
||||
aObscured);
|
||||
|
||||
apzc->SetLayerHitTestData(unobscured, aTransform, transform);
|
||||
APZCTM_LOG("Setting rect(%f %f %f %f) as visible region for APZC %p\n", visible.x, visible.y,
|
||||
visible.width, visible.height,
|
||||
apzc);
|
||||
|
||||
mApzcTreeLog << "APZC " << guid
|
||||
<< "\tcb=" << visible
|
||||
<< "\tsr=" << metrics.mScrollableRect
|
||||
<< (aLayer->GetVisibleRegion().IsEmpty() ? "\tscrollinfo" : "")
|
||||
<< (apzc->HasScrollgrab() ? "\tscrollgrab" : "")
|
||||
<< "\t" << aLayer->GetContentDescription();
|
||||
|
||||
// Bind the APZC instance into the tree of APZCs
|
||||
if (aNextSibling) {
|
||||
aNextSibling->SetPrevSibling(apzc);
|
||||
} else if (aParent) {
|
||||
aParent->SetLastChild(apzc);
|
||||
} else {
|
||||
mRootApzc = apzc;
|
||||
apzc->MakeRoot();
|
||||
}
|
||||
|
||||
// For testing, log the parent scroll id of every APZC that has a
|
||||
// parent. This allows test code to reconstruct the APZC tree.
|
||||
// Note that we currently only do this for APZCs in the layer tree
|
||||
// that originated the update, because the only identifying information
|
||||
// we are logging about APZCs is the scroll id, and otherwise we could
|
||||
// confuse APZCs from different layer trees with the same scroll id.
|
||||
if (aLayersId == aOriginatingLayersId && apzc->GetParent()) {
|
||||
aPaintLogger.LogTestData(metrics.GetScrollId(), "parentScrollId",
|
||||
apzc->GetParent()->GetGuid().mScrollId);
|
||||
}
|
||||
|
||||
// Let this apzc be the parent of other controllers when we recurse downwards
|
||||
aParent = apzc;
|
||||
|
||||
if (newApzc) {
|
||||
if (apzc->IsRootForLayersId()) {
|
||||
// If we just created a new apzc that is the root for its layers ID, then
|
||||
// we need to update its zoom constraints which might have arrived before this
|
||||
// was created
|
||||
ZoomConstraints constraints;
|
||||
if (state->mController->GetRootZoomConstraints(&constraints)) {
|
||||
apzc->UpdateZoomConstraints(constraints);
|
||||
}
|
||||
} else {
|
||||
// For an apzc that is not the root for its layers ID, we give it the
|
||||
// same zoom constraints as its parent. This ensures that if e.g.
|
||||
// user-scalable=no was specified, none of the APZCs allow double-tap
|
||||
// to zoom.
|
||||
apzc->UpdateZoomConstraints(apzc->GetParent()->GetZoomConstraints());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aLayer->SetAsyncPanZoomController(apzc);
|
||||
|
||||
mApzcTreeLog << '\n';
|
||||
|
||||
// Accumulate the CSS transform between layers that have an APZC, but exclude any
|
||||
|
@ -38,7 +38,6 @@ namespace layers {
|
||||
struct ScrollableLayerGuid;
|
||||
class CompositorParent;
|
||||
class GestureEventListener;
|
||||
class ContainerLayer;
|
||||
class PCompositorParent;
|
||||
struct ViewTransform;
|
||||
class AsyncPanZoomAnimation;
|
||||
|
@ -539,12 +539,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||
ApplyAsyncContentTransformToTree(aCurrentFrame, child, aWantNextFrame);
|
||||
}
|
||||
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
if (!container) {
|
||||
return appliedTransform;
|
||||
}
|
||||
|
||||
if (AsyncPanZoomController* controller = container->GetAsyncPanZoomController()) {
|
||||
if (AsyncPanZoomController* controller = aLayer->GetAsyncPanZoomController()) {
|
||||
LayerComposite* layerComposite = aLayer->AsLayerComposite();
|
||||
Matrix4x4 oldTransform = aLayer->GetTransform();
|
||||
|
||||
@ -556,7 +551,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||
scrollOffset,
|
||||
&overscrollTransform);
|
||||
|
||||
const FrameMetrics& metrics = container->GetFrameMetrics();
|
||||
const FrameMetrics& metrics = aLayer->GetFrameMetrics();
|
||||
CSSToLayerScale paintScale = metrics.LayersPixelsPerCSSPixel();
|
||||
CSSRect displayPort(metrics.mCriticalDisplayPort.IsEmpty() ?
|
||||
metrics.mDisplayPort : metrics.mCriticalDisplayPort);
|
||||
@ -578,9 +573,11 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||
// GetTransform already takes the pre- and post-scale into account. Since we
|
||||
// will apply the pre- and post-scale again when computing the effective
|
||||
// transform, we must apply the inverses here.
|
||||
transform.Scale(1.0f/container->GetPreXScale(),
|
||||
1.0f/container->GetPreYScale(),
|
||||
1);
|
||||
if (ContainerLayer* container = aLayer->AsContainerLayer()) {
|
||||
transform.Scale(1.0f/container->GetPreXScale(),
|
||||
1.0f/container->GetPreYScale(),
|
||||
1);
|
||||
}
|
||||
transform = transform * Matrix4x4().Scale(1.0f/aLayer->GetPostXScale(),
|
||||
1.0f/aLayer->GetPostYScale(),
|
||||
1);
|
||||
@ -605,8 +602,8 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||
appliedTransform = true;
|
||||
}
|
||||
|
||||
if (container->GetScrollbarDirection() != Layer::NONE) {
|
||||
ApplyAsyncTransformToScrollbar(aCurrentFrame, container);
|
||||
if (aLayer->AsContainerLayer() && aLayer->GetScrollbarDirection() != Layer::NONE) {
|
||||
ApplyAsyncTransformToScrollbar(aCurrentFrame, aLayer->AsContainerLayer());
|
||||
}
|
||||
return appliedTransform;
|
||||
}
|
||||
@ -626,12 +623,9 @@ LayerHasNonContainerDescendants(ContainerLayer* aContainer)
|
||||
}
|
||||
|
||||
static bool
|
||||
LayerIsContainerForScrollbarTarget(Layer* aTarget, ContainerLayer* aScrollbar)
|
||||
LayerIsScrollbarTarget(Layer* aTarget, ContainerLayer* aScrollbar)
|
||||
{
|
||||
if (!aTarget->AsContainerLayer()) {
|
||||
return false;
|
||||
}
|
||||
AsyncPanZoomController* apzc = aTarget->AsContainerLayer()->GetAsyncPanZoomController();
|
||||
AsyncPanZoomController* apzc = aTarget->GetAsyncPanZoomController();
|
||||
if (!apzc) {
|
||||
return false;
|
||||
}
|
||||
@ -646,19 +640,18 @@ static void
|
||||
ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer* aScrollbar,
|
||||
Layer* aContent, bool aScrollbarIsChild)
|
||||
{
|
||||
ContainerLayer* content = aContent->AsContainerLayer();
|
||||
|
||||
// We only apply the transform if the scroll-target layer has non-container
|
||||
// children (i.e. when it has some possibly-visible content). This is to
|
||||
// avoid moving scroll-bars in the situation that only a scroll information
|
||||
// layer has been built for a scroll frame, as this would result in a
|
||||
// disparity between scrollbars and visible content.
|
||||
if (!LayerHasNonContainerDescendants(content)) {
|
||||
if (aContent->AsContainerLayer() &&
|
||||
!LayerHasNonContainerDescendants(aContent->AsContainerLayer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const FrameMetrics& metrics = content->GetFrameMetrics();
|
||||
AsyncPanZoomController* apzc = content->GetAsyncPanZoomController();
|
||||
const FrameMetrics& metrics = aContent->GetFrameMetrics();
|
||||
AsyncPanZoomController* apzc = aContent->GetAsyncPanZoomController();
|
||||
|
||||
if (aScrollbarIsChild) {
|
||||
// Because we try to apply the scrollbar transform before we apply the async transform on
|
||||
@ -730,13 +723,17 @@ ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer
|
||||
static Layer*
|
||||
FindScrolledLayerForScrollbar(ContainerLayer* aLayer, bool* aOutIsAncestor)
|
||||
{
|
||||
// XXX: once bug 967844 is implemented there might be multiple scrolled layers
|
||||
// that correspond to the scrollbar's scrollId. Verify that we deal with those
|
||||
// cases correctly.
|
||||
|
||||
// Search all siblings of aLayer and of its ancestors.
|
||||
for (Layer* ancestor = aLayer; ancestor; ancestor = ancestor->GetParent()) {
|
||||
for (Layer* scrollTarget = ancestor;
|
||||
scrollTarget;
|
||||
scrollTarget = scrollTarget->GetPrevSibling()) {
|
||||
if (scrollTarget != aLayer &&
|
||||
LayerIsContainerForScrollbarTarget(scrollTarget, aLayer)) {
|
||||
LayerIsScrollbarTarget(scrollTarget, aLayer)) {
|
||||
*aOutIsAncestor = (scrollTarget == ancestor);
|
||||
return scrollTarget;
|
||||
}
|
||||
@ -744,7 +741,7 @@ FindScrolledLayerForScrollbar(ContainerLayer* aLayer, bool* aOutIsAncestor)
|
||||
for (Layer* scrollTarget = ancestor->GetNextSibling();
|
||||
scrollTarget;
|
||||
scrollTarget = scrollTarget->GetNextSibling()) {
|
||||
if (LayerIsContainerForScrollbarTarget(scrollTarget, aLayer)) {
|
||||
if (LayerIsScrollbarTarget(scrollTarget, aLayer)) {
|
||||
*aOutIsAncestor = false;
|
||||
return scrollTarget;
|
||||
}
|
||||
|
@ -1510,7 +1510,7 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
|
||||
SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, paintSequenceNumber++);
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
|
||||
EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
EXPECT_EQ(root->GetAsyncPanZoomController(), hit.get());
|
||||
// expect hit point at LayerIntPoint(15, 15)
|
||||
EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15));
|
||||
EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15));
|
||||
@ -1518,9 +1518,9 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
|
||||
// Now we have a sub APZC with a better fit
|
||||
SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1);
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, paintSequenceNumber++);
|
||||
EXPECT_NE(root->AsContainerLayer()->GetAsyncPanZoomController(), layers[3]->AsContainerLayer()->GetAsyncPanZoomController());
|
||||
EXPECT_NE(root->GetAsyncPanZoomController(), layers[3]->GetAsyncPanZoomController());
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko);
|
||||
EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
EXPECT_EQ(layers[3]->GetAsyncPanZoomController(), hit.get());
|
||||
// expect hit point at LayerIntPoint(25, 25)
|
||||
EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25));
|
||||
EXPECT_EQ(Point(25, 25), transformToGecko * Point(25, 25));
|
||||
@ -1528,20 +1528,20 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
|
||||
// At this point, layers[4] obscures layers[3] at the point (15, 15) so
|
||||
// hitting there should hit the root APZC
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
|
||||
EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
EXPECT_EQ(root->GetAsyncPanZoomController(), hit.get());
|
||||
|
||||
// Now test hit testing when we have two scrollable layers
|
||||
SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 2);
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0, paintSequenceNumber++);
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
|
||||
EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
EXPECT_EQ(layers[4]->GetAsyncPanZoomController(), hit.get());
|
||||
// expect hit point at LayerIntPoint(15, 15)
|
||||
EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15));
|
||||
EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15));
|
||||
|
||||
// Hit test ouside the reach of layer[3,4] but inside root
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(90, 90), transformToApzc, transformToGecko);
|
||||
EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
EXPECT_EQ(root->GetAsyncPanZoomController(), hit.get());
|
||||
// expect hit point at LayerIntPoint(90, 90)
|
||||
EXPECT_EQ(Point(90, 90), transformToApzc * Point(90, 90));
|
||||
EXPECT_EQ(Point(90, 90), transformToGecko * Point(90, 90));
|
||||
@ -1593,9 +1593,9 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
|
||||
// layers[2] has content from (20,60)-(100,100). no clipping as it's not a scrollable layer
|
||||
// layers[3] has content from (20,60)-(180,140), clipped by composition bounds (20,60)-(100,100)
|
||||
|
||||
AsyncPanZoomController* apzcroot = root->AsContainerLayer()->GetAsyncPanZoomController();
|
||||
AsyncPanZoomController* apzc1 = layers[1]->AsContainerLayer()->GetAsyncPanZoomController();
|
||||
AsyncPanZoomController* apzc3 = layers[3]->AsContainerLayer()->GetAsyncPanZoomController();
|
||||
AsyncPanZoomController* apzcroot = root->GetAsyncPanZoomController();
|
||||
AsyncPanZoomController* apzc1 = layers[1]->GetAsyncPanZoomController();
|
||||
AsyncPanZoomController* apzc3 = layers[3]->GetAsyncPanZoomController();
|
||||
|
||||
// Hit an area that's clearly on the root layer but not any of the child layers.
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(75, 25), transformToApzc, transformToGecko);
|
||||
|
Loading…
Reference in New Issue
Block a user