Bug 1157066. When reading back the OMTA transfrom of a layer don't include transforms from async panning or zooming. r=kats,birtles

Containerless scrolling means that the pan zoom controller applies it's transforms (to compensate for differences between the state of layout the last time we painted and the current state as composited to the screen) to the layers that are scrolled instead of the container layer that contains the layers that scroll.

When running test_animations_omta.html there is a zoom of 1.306122 applied, and the page is scrolled down to 67 screen pixels (before the test starts, not sure why exactly). Gecko scrolls as close to 67 screen pixels as it can: 67/1.306122 = 51.29689 css pixels, which is 3077.813 appunits. Gecko scrolls to 3078 app units. When AsyncCompositionManager::TransformScrollableLayer runs we calculate the scroll position of gecko and the current scroll position that the pan zoom controller is using. Since there are no async pan or zoom operations taking place these should match. However when the gecko scroll position is calculated we get 3078/60*1.306122 = 67.0040586. So it applies a transform of 0.0040586 to the container layer for the transform that test_animations_omta.html is animating off main thread. When test_animations_omta.html reads the transform of this layer it fails because it's expecting 0 and 0.0040586 is outside of it's epsilon for considering it to be close enough.
This commit is contained in:
Timothy Nikkel 2015-04-24 19:05:52 -05:00
Родитель 65b94d7a9d
Коммит 499081808b
4 изменённых файлов: 36 добавлений и 34 удалений

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

@ -1030,7 +1030,8 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
} }
bool bool
AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame) AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
TransformsToSkip aSkip)
{ {
PROFILER_LABEL("AsyncCompositionManager", "TransformShadowTree", PROFILER_LABEL("AsyncCompositionManager", "TransformShadowTree",
js::ProfileEntry::Category::GRAPHICS); js::ProfileEntry::Category::GRAPHICS);
@ -1045,29 +1046,31 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame)
// transforms. // transforms.
bool wantNextFrame = SampleAnimations(root, aCurrentFrame); bool wantNextFrame = SampleAnimations(root, aCurrentFrame);
// FIXME/bug 775437: unify this interface with the ~native-fennec if (!(aSkip & TransformsToSkip::APZ)) {
// derived code // FIXME/bug 775437: unify this interface with the ~native-fennec
// // derived code
// Attempt to apply an async content transform to any layer that has //
// an async pan zoom controller (which means that it is rendered // Attempt to apply an async content transform to any layer that has
// async using Gecko). If this fails, fall back to transforming the // an async pan zoom controller (which means that it is rendered
// primary scrollable layer. "Failing" here means that we don't // async using Gecko). If this fails, fall back to transforming the
// find a frame that is async scrollable. Note that the fallback // primary scrollable layer. "Failing" here means that we don't
// code also includes Fennec which is rendered async. Fennec uses // find a frame that is async scrollable. Note that the fallback
// its own platform-specific async rendering that is done partially // code also includes Fennec which is rendered async. Fennec uses
// in Gecko and partially in Java. // its own platform-specific async rendering that is done partially
wantNextFrame |= SampleAPZAnimations(LayerMetricsWrapper(root), aCurrentFrame); // in Gecko and partially in Java.
if (!ApplyAsyncContentTransformToTree(root)) { wantNextFrame |= SampleAPZAnimations(LayerMetricsWrapper(root), aCurrentFrame);
nsAutoTArray<Layer*,1> scrollableLayers; if (!ApplyAsyncContentTransformToTree(root)) {
nsAutoTArray<Layer*,1> scrollableLayers;
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
mLayerManager->GetRootScrollableLayers(scrollableLayers); mLayerManager->GetRootScrollableLayers(scrollableLayers);
#else #else
mLayerManager->GetScrollableLayers(scrollableLayers); mLayerManager->GetScrollableLayers(scrollableLayers);
#endif #endif
for (uint32_t i = 0; i < scrollableLayers.Length(); i++) { for (uint32_t i = 0; i < scrollableLayers.Length(); i++) {
if (scrollableLayers[i]) { if (scrollableLayers[i]) {
TransformScrollableLayer(scrollableLayers[i]); TransformScrollableLayer(scrollableLayers[i]);
}
} }
} }
} }

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

@ -95,7 +95,9 @@ public:
// Sample transforms for layer trees. Return true to request // Sample transforms for layer trees. Return true to request
// another animation frame. // another animation frame.
bool TransformShadowTree(TimeStamp aCurrentFrame); enum class TransformsToSkip : uint8_t { NoneOfThem = 0, APZ = 1 };
bool TransformShadowTree(TimeStamp aCurrentFrame,
TransformsToSkip aSkip = TransformsToSkip::NoneOfThem);
// Calculates the correct rotation and applies the transform to // Calculates the correct rotation and applies the transform to
// our layer manager // our layer manager
@ -208,6 +210,8 @@ private:
gfx::Matrix mWorldTransform; gfx::Matrix mWorldTransform;
}; };
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(AsyncCompositionManager::TransformsToSkip)
class MOZ_STACK_CLASS AutoResolveRefLayers { class MOZ_STACK_CLASS AutoResolveRefLayers {
public: public:
explicit AutoResolveRefLayers(AsyncCompositionManager* aManager) : mManager(aManager) explicit AutoResolveRefLayers(AsyncCompositionManager* aManager) : mManager(aManager)

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

@ -1152,12 +1152,6 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
if (mPaused) { if (mPaused) {
DidComposite(); DidComposite();
} }
// When testing we synchronously update the shadow tree with the animated
// values to avoid race conditions when calling GetAnimationTransform etc.
// (since the above SetShadowProperties will remove animation effects).
if (mIsTesting) {
ApplyAsyncProperties(aLayerTree);
}
} }
mLayerManager->NotifyShadowTreeTransaction(); mLayerManager->NotifyShadowTreeTransaction();
} }
@ -1210,16 +1204,15 @@ CompositorParent::ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
// true or when called from test-only methods like // true or when called from test-only methods like
// LayerTransactionParent::RecvGetAnimationTransform. // LayerTransactionParent::RecvGetAnimationTransform.
// Synchronously update the layer tree, but only if a composite was already // Synchronously update the layer tree
// scehduled. if (aLayerTree->GetRoot()) {
if (aLayerTree->GetRoot() &&
(mCurrentCompositeTask ||
(mCompositorVsyncObserver &&
mCompositorVsyncObserver->NeedsComposite()))) {
AutoResolveRefLayers resolve(mCompositionManager); AutoResolveRefLayers resolve(mCompositionManager);
SetShadowProperties(mLayerManager->GetRoot());
TimeStamp time = mIsTesting ? mTestTime : mLastCompose; TimeStamp time = mIsTesting ? mTestTime : mLastCompose;
bool requestNextFrame = bool requestNextFrame =
mCompositionManager->TransformShadowTree(time); mCompositionManager->TransformShadowTree(time,
AsyncCompositionManager::TransformsToSkip::APZ);
if (!requestNextFrame) { if (!requestNextFrame) {
CancelCurrentCompositeTask(); CancelCurrentCompositeTask();
// Pretend we composited in case someone is waiting for this event. // Pretend we composited in case someone is waiting for this event.

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

@ -664,6 +664,8 @@ LayerTransactionParent::RecvGetOpacity(PLayerParent* aParent,
return false; return false;
} }
mShadowLayersManager->ApplyAsyncProperties(this);
*aOpacity = layer->GetLocalOpacity(); *aOpacity = layer->GetLocalOpacity();
return true; return true;
} }