Bug 1279071 - Change GetOpacity to GetAnimationOpacity to return opacity value applied by animation. r?birtles,mstange
MozReview-Commit-ID: 6rMUlnppOeK
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3632,23 +3632,28 @@ nsDOMWindowUtils::GetOMTAStyle(nsIDOMEle
}
}
if (frame && nsLayoutUtils::AreAsyncAnimationsEnabled()) {
if (aProperty.EqualsLiteral("opacity")) {
Layer* layer =
FrameLayerBuilder::GetDedicatedLayer(frame,
nsDisplayItem::TYPE_OPACITY);
if (layer) {
- float value;
ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
if (forwarder && forwarder->HasShadowManager()) {
- forwarder->GetShadowManager()->SendGetOpacity(
- layer->AsShadowableLayer()->GetShadow(), &value);
- cssValue = new nsROCSSPrimitiveValue;
- cssValue->SetNumber(value);
+ float value;
+ bool hadAnimatedOpacity;
+ forwarder->GetShadowManager()->SendGetAnimationOpacity(
+ layer->AsShadowableLayer()->GetShadow(),
+ &value, &hadAnimatedOpacity);
+
+ if (hadAnimatedOpacity) {
+ cssValue = new nsROCSSPrimitiveValue;
+ cssValue->SetNumber(value);
+ }
}
}
} else if (aProperty.EqualsLiteral("transform")) {
Layer* layer =
FrameLayerBuilder::GetDedicatedLayer(frame,
nsDisplayItem::TYPE_TRANSFORM);
if (layer) {
ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -680,16 +680,17 @@ SampleAnimations(Layer* aLayer, TimeStam
Animatable interpolatedValue;
SampleValue(portion, animation, animData.mStartValues[segmentIndex],
animData.mEndValues[segmentIndex], &interpolatedValue, layer);
LayerComposite* layerComposite = layer->AsLayerComposite();
switch (animation.property()) {
case eCSSProperty_opacity:
{
layerComposite->SetShadowOpacity(interpolatedValue.get_float());
+ layerComposite->SetShadowOpacitySetByAnimation(true);
break;
}
case eCSSProperty_transform:
{
Matrix4x4 matrix = interpolatedValue.get_ArrayOfTransformFunction()[0].get_TransformMatrix().value();
if (ContainerLayer* c = layer->AsContainerLayer()) {
matrix.PostScale(c->GetInheritedXScale(), c->GetInheritedYScale(), 1);
}
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -1328,16 +1328,17 @@ LayerManagerComposite::ChangeCompositor(
mTwoPassTmpTarget = nullptr;
}
LayerComposite::LayerComposite(LayerManagerComposite *aManager)
: mCompositeManager(aManager)
, mCompositor(aManager->GetCompositor())
, mShadowOpacity(1.0)
, mShadowTransformSetByAnimation(false)
+ , mShadowOpacitySetByAnimation(false)
, mDestroyed(false)
, mLayerComposited(false)
{ }
LayerComposite::~LayerComposite()
{
}
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -501,16 +501,20 @@ public:
{
mShadowVisibleRegion = aRegion;
}
void SetShadowOpacity(float aOpacity)
{
mShadowOpacity = aOpacity;
}
+ void SetShadowOpacitySetByAnimation(bool aSetByAnimation)
+ {
+ mShadowOpacitySetByAnimation = aSetByAnimation;
+ }
void SetShadowClipRect(const Maybe<ParentLayerIntRect>& aRect)
{
mShadowClipRect = aRect;
}
void SetShadowBaseTransform(const gfx::Matrix4x4& aMatrix)
{
@@ -533,16 +537,17 @@ public:
// These getters can be used anytime.
float GetShadowOpacity() { return mShadowOpacity; }
const Maybe<ParentLayerIntRect>& GetShadowClipRect() { return mShadowClipRect; }
const LayerIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
const gfx::Matrix4x4& GetShadowBaseTransform() { return mShadowTransform; }
gfx::Matrix4x4 GetShadowTransform();
bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; }
+ bool GetShadowOpacitySetByAnimation() { return mShadowOpacitySetByAnimation; }
bool HasLayerBeenComposited() { return mLayerComposited; }
gfx::IntRect GetClearRect() { return mClearRect; }
// Returns false if the layer is attached to an older compositor.
bool HasStaleCompositor() const;
/**
* Return the part of the visible region that has been fully rendered.
@@ -560,16 +565,17 @@ public:
protected:
gfx::Matrix4x4 mShadowTransform;
LayerIntRegion mShadowVisibleRegion;
Maybe<ParentLayerIntRect> mShadowClipRect;
LayerManagerComposite* mCompositeManager;
RefPtr<Compositor> mCompositor;
float mShadowOpacity;
bool mShadowTransformSetByAnimation;
+ bool mShadowOpacitySetByAnimation;
bool mDestroyed;
bool mLayerComposited;
gfx::IntRect mClearRect;
};
// Render aLayer using aCompositor and apply all mask layers of aLayer: The
// layer's own mask layer (aLayer->GetMaskLayer()), and any ancestor mask
// layers.
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1155,16 +1155,17 @@ CompositorBridgeParent::SetShadowPropert
// FIXME: Bug 717688 -- Do these updates in LayerTransactionParent::RecvUpdate.
LayerComposite* layerComposite = layer->AsLayerComposite();
// Set the layerComposite's base transform to the layer's base transform.
layerComposite->SetShadowBaseTransform(layer->GetBaseTransform());
layerComposite->SetShadowTransformSetByAnimation(false);
layerComposite->SetShadowVisibleRegion(layer->GetVisibleRegion());
layerComposite->SetShadowClipRect(layer->GetClipRect());
layerComposite->SetShadowOpacity(layer->GetOpacity());
+ layerComposite->SetShadowOpacitySetByAnimation(false);
}
);
}
void
CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
{
profiler_tracing("Paint", "Composite", TRACING_INTERVAL_START);
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -720,31 +720,38 @@ LayerTransactionParent::RecvSetTestSampl
bool
LayerTransactionParent::RecvLeaveTestMode()
{
mShadowLayersManager->LeaveTestMode(this);
return true;
}
bool
-LayerTransactionParent::RecvGetOpacity(PLayerParent* aParent,
- float* aOpacity)
+LayerTransactionParent::RecvGetAnimationOpacity(PLayerParent* aParent,
+ float* aOpacity,
+ bool* aHasAnimationOpacity)
{
+ *aHasAnimationOpacity = false;
if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
return false;
}
Layer* layer = cast(aParent)->AsLayer();
if (!layer) {
return false;
}
mShadowLayersManager->ApplyAsyncProperties(this);
+ if (!layer->AsLayerComposite()->GetShadowOpacitySetByAnimation()) {
+ return true;
+ }
+
*aOpacity = layer->GetLocalOpacity();
+ *aHasAnimationOpacity = true;
return true;
}
bool
LayerTransactionParent::RecvGetAnimationTransform(PLayerParent* aParent,
MaybeTransform* aTransform)
{
if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -138,18 +138,19 @@ protected:
const bool& isRepeatTransaction,
const mozilla::TimeStamp& aTransactionStart,
const int32_t& aPaintSyncId) override;
virtual bool RecvClearCachedResources() override;
virtual bool RecvForceComposite() override;
virtual bool RecvSetTestSampleTime(const TimeStamp& aTime) override;
virtual bool RecvLeaveTestMode() override;
- virtual bool RecvGetOpacity(PLayerParent* aParent,
- float* aOpacity) override;
+ virtual bool RecvGetAnimationOpacity(PLayerParent* aParent,
+ float* aOpacity,
+ bool* aHasAnimationOpacity) override;
virtual bool RecvGetAnimationTransform(PLayerParent* aParent,
MaybeTransform* aTransform)
override;
virtual bool RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aId,
const float& aX, const float& aY) override;
virtual bool RecvSetAsyncZoom(const FrameMetrics::ViewID& aId,
const float& aValue) override;
virtual bool RecvFlushApzRepaints() override;
--- a/gfx/layers/ipc/PLayerTransaction.ipdl
+++ b/gfx/layers/ipc/PLayerTransaction.ipdl
@@ -73,17 +73,21 @@ parent:
// Testing APIs
// Enter test mode, set the sample time to sampleTime, and resample
// animations. sampleTime must not be null.
sync SetTestSampleTime(TimeStamp sampleTime);
// Leave test mode and resume normal compositing
sync LeaveTestMode();
- sync GetOpacity(PLayer layer) returns (float opacity);
+ // Returns the value of the opacity applied to the layer by animation.
+ // |hasAnimationOpacity| is true if the layer has an opacity value
+ // specified by animation. If it's false, |opacity| value is indefinite.
+ sync GetAnimationOpacity(PLayer layer) returns (float opacity,
+ bool hasAnimationOpacity);
// Returns the value of the transform applied to the layer by animation after
// factoring out translation components introduced to account for the offset
// of the corresponding frame and transform origin and after converting to CSS
// pixels. If the layer is not transformed by animation, the return value will
// be void_t.
sync GetAnimationTransform(PLayer layer) returns (MaybeTransform transform);
--- a/layout/style/test/test_animations_omta.html
+++ b/layout/style/test/test_animations_omta.html
@@ -1200,44 +1200,44 @@ addAsyncAnimTest(function *() {
omta_is("transform", { ty: 0 }, RunningOn.Compositor,
"animation-play-state test 3, at 0s");
advance_clock(250);
gDiv.style.animationPlayState = "paused, running"; // pause 1
yield waitForPaintsFlushed();
// As noted with the tests for animation-iteration-count, for opacity
// animations we don't strictly check the finished animation is being animated
// on the main thread, but simply that it is producing the correct result.
- omta_is_approx("opacity", gTF.ease_out(0.25), 0.01, RunningOn.Either,
- "animation-play-state test 2 at 250ms");
+ omta_is_approx("opacity", gTF.ease_out(0.25), 0.01, RunningOn.MainThread,
+ "animation-play-state test 2 at 250ms"); // paused
omta_is_approx("transform", { ty: 100 * gTF.ease_in(0.125) }, 0.01,
RunningOn.Compositor,
"animation-play-state test 3 at 250ms");
advance_clock(250);
- omta_is_approx("opacity", gTF.ease_out(0.25), 0.01, RunningOn.Either,
- "animation-play-state test 2 at 500ms");
+ omta_is_approx("opacity", gTF.ease_out(0.25), 0.01, RunningOn.MainThread,
+ "animation-play-state test 2 at 500ms"); // paused
omta_is_approx("transform", { ty: 100 * gTF.ease_in(0.25) }, 0.01,
RunningOn.Compositor,
"animation-play-state test 3 at 500ms");
advance_clock(250);
gDiv.style.animationPlayState = "running, paused"; // unpause 1, pause 2
yield waitForPaintsFlushed();
advance_clock(250);
omta_is_approx("opacity", gTF.ease_out(0.5), 0.01, RunningOn.Compositor,
"animation-play-state test 2 at 1000ms");
omta_is_approx("transform", { ty: 100 * gTF.ease_in(0.375) }, 0.01,
RunningOn.MainThread,
- "animation-play-state test 3 at 1000ms");
+ "animation-play-state test 3 at 1000ms"); // paused
gDiv.style.animationPlayState = "paused"; // pause all
yield waitForPaintsFlushed();
advance_clock(3000);
- omta_is_approx("opacity", gTF.ease_out(0.5), 0.01, RunningOn.Either,
- "animation-play-state test 2 at 4000ms");
+ omta_is_approx("opacity", gTF.ease_out(0.5), 0.01, RunningOn.MainThread,
+ "animation-play-state test 2 at 4000ms"); // paused
omta_is_approx("transform", { ty: 100 * gTF.ease_in(0.375) }, 0.01,
RunningOn.MainThread,
- "animation-play-state test 3 at 4000ms");
+ "animation-play-state test 3 at 4000ms"); // paused
gDiv.style.animationPlayState = "running, paused"; // pause 2
yield waitForPaintsFlushed();
advance_clock(850);
omta_is_approx("opacity", gTF.ease_out(0.65), 0.01, RunningOn.Compositor,
"animation-play-state test 2 at 4850ms");
omta_is_approx("transform", { ty: 100 * gTF.ease_in(0.375) }, 0.01,
RunningOn.MainThread,
"animation-play-state test 3 at 4850ms");
@@ -1357,20 +1357,20 @@ addAsyncAnimTest(function *() {
omta_is("opacity", 1, RunningOn.Either,
"delay and play-state delay test at 0ms");
advance_clock(400);
omta_is("opacity", 1, RunningOn.Either,
"delay and play-state delay test at 400ms");
gDiv.style.animationPlayState = "paused";
yield waitForPaintsFlushed();
advance_clock(100);
- omta_is("opacity", 1, RunningOn.Either,
+ omta_is("opacity", 1, RunningOn.MainThread, // paused
"delay and play-state delay test at 500ms");
advance_clock(500);
- omta_is("opacity", 1, RunningOn.Either,
+ omta_is("opacity", 1, RunningOn.MainThread, // paused
"delay and play-state delay test at 1000ms");
gDiv.style.animationPlayState = "running";
yield waitForPaintsFlushed();
advance_clock(100);
yield waitForPaints();
omta_is("opacity", 0, RunningOn.Compositor,
"delay and play-state delay test at 1100ms");
advance_clock(100);
--- a/layout/style/test/test_animations_omta_start.html
+++ b/layout/style/test/test_animations_omta_start.html
@@ -151,16 +151,22 @@ function testTransitionTakingOver() {
waitForAllPaints(function() {
child.style.opacity = "1.0";
var opacity = gUtils.getOMTAStyle(child, "opacity");
// FIXME Bug 1039799 (or lower priority followup): Animations
// inherited from an animating parent element don't get shipped to
// the compositor thread.
todo_is(opacity, "0.4",
"transition that interrupted animation is correct");
+
+ // Trigger to start the transition, without this the transition will
+ // be pending in advanceTimeAndRefresh(0) so the transition will not
+ // be sent to the compositor until we call advanceTimeAndRefresh with
+ // a positive time value.
+ getComputedStyle(child).opacity;
gUtils.advanceTimeAndRefresh(0);
waitForAllPaints(function() {
var opacity = gUtils.getOMTAStyle(child, "opacity");
is(opacity, "0.4",
"transition that interrupted animation is correct");
gUtils.advanceTimeAndRefresh(5000);
waitForAllPaints(function() {
opacity = gUtils.getOMTAStyle(child, "opacity");