Bug 1464568 - Set the shadow base transform value for the case where opacity animations' calculation was skipped. r=kats

And make DOMWindowUtils.getOMTCTransform work for opacity animations' layer.

MozReview-Commit-ID: 7P99WjYqPr0
This commit is contained in:
Hiroyuki Ikezoe
2018-06-05 12:50:39 +09:00
parent 8ed64a7809
commit 19c81c05d0
6 changed files with 81 additions and 5 deletions

View File

@@ -3769,9 +3769,13 @@ nsDOMWindowUtils::GetOMTCTransform(Element* aElement,
return NS_OK;
}
Layer* layer =
FrameLayerBuilder::GetDedicatedLayer(frame,
DisplayItemType::TYPE_TRANSFORM);
DisplayItemType itemType = DisplayItemType::TYPE_TRANSFORM;
if (nsLayoutUtils::HasEffectiveAnimation(frame, eCSSProperty_opacity) &&
!frame->IsTransformed()) {
itemType = DisplayItemType::TYPE_OPACITY;
}
Layer* layer = FrameLayerBuilder::GetDedicatedLayer(frame, itemType);
if (!layer) {
return NS_OK;
}

View File

@@ -1701,7 +1701,8 @@ interface nsIDOMWindowUtils : nsISupports {
* Returns the value of the transform value on the compositor thread.
* Unlike the above getOMTAStyle, the transform value returned by this
* includes both of animating and APZ values.
* Note: This function doesn't work on WebRender at all.
* Note: This function doesn't work on WebRender at all. Also this function
* does work only for transform layer and opacity layer with animations.
*/
AString getOMTCTransform(in Element aElement,
[optional] in AString aPseudoElement);

View File

@@ -0,0 +1,60 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test that opacity animation is correctly placed during asynchronous scrolling</title>
<script src="apz_test_utils.js"></script>
<script src="/tests/SimpleTest/paint_listener.js"></script>
<meta name="viewport" content="width=device-width"/>
<style>
#anim {
background: green;
width: 100px;
height: 100px;
animation: anim 100s step-start;
}
@keyframes anim {
from { opacity: 0; }
to { opacity: 1; }
}
</style>
</head>
<body>
<!--
This height should be smaller than window height, otherwise the animation
followed by this element will be out of view, thus the animation doesn't run
on the compositor.
-->
<div style="height: 500px"></div>
<div id="anim"></div>
</body>
<script>
'use strict';
const utils = SpecialPowers.getDOMWindowUtils(window);
async function test_opacity() {
utils.setDisplayPortForElement(0, 0, 300, 1000, document.documentElement, 1);
await promiseAllPaintsDone();
let transform = utils.getOMTCTransform(anim);
is(transform, "matrix(1, 0, 0, 1, 0, 0)",
"The element shouldn't be moved before scrolling");
utils.setAsyncScrollOffset(document.documentElement, 0, 300);
await new Promise(resolve => waitForApzFlushedRepaints(resolve));
transform = utils.getOMTCTransform(anim);
is(transform, "matrix(1, 0, 0, 1, 0, -300)",
"Element should have been moved by the offset");
}
if (utils.layerManagerType == 'WebRender') {
ok(true, "This test doesn't need to run on WebRender");
subtestDone();
} else {
waitUntilApzStable().then(test_opacity).then(subtestDone);
}
</script>
</html>

View File

@@ -15,6 +15,7 @@
helper_bug1346632.html
helper_bug1414336.html
helper_bug1464568_transform.html
helper_bug1464568_opacity.html
helper_click.html
helper_div_pan.html
helper_drag_click.html

View File

@@ -12,6 +12,8 @@
const subtests = [
{ file: 'helper_bug1464568_transform.html',
prefs: [["apz.test.logging_enabled", true]] },
{ file: 'helper_bug1464568_opacity.html',
prefs: [["apz.test.logging_enabled", true]] },
];
// Run the actual test in its own window, because it requires that the
// root APZC be scrollable. Mochitest pages themselves often run

View File

@@ -710,7 +710,7 @@ SampleAnimations(Layer* aLayer,
}
case AnimationHelper::SampleResult::Skipped:
switch (animations[0].property()) {
case eCSSProperty_opacity:
case eCSSProperty_opacity: {
MOZ_ASSERT(
layer->AsHostLayer()->GetShadowOpacitySetByAnimation());
#ifdef DEBUG
@@ -720,7 +720,15 @@ SampleAnimations(Layer* aLayer,
// Servo_AnimationValue_GetOpacity(animationValue),
// *(aStorage->GetAnimationOpacity(layer->GetCompositorAnimationsId()))));
#endif
// Even if opacity animation value has unchanged, we have to set
// the shadow base transform value here since the value might
// have been changed by APZC.
HostLayer* layerCompositor = layer->AsHostLayer();
layerCompositor->SetShadowBaseTransform(
layer->GetBaseTransform());
layerCompositor->SetShadowTransformSetByAnimation(false);
break;
}
case eCSSProperty_transform: {
MOZ_ASSERT(
layer->AsHostLayer()->GetShadowTransformSetByAnimation());