Closed Bug 1429305 Opened 6 years ago Closed 5 years ago

[motion-1] Support compositor animations for motion path

Categories

(Core :: CSS Transitions and Animations, enhancement, P3)

enhancement

Tracking

()

RESOLVED FIXED
mozilla72
Tracking Status
firefox72 --- fixed

People

(Reporter: boris, Assigned: boris)

References

(Blocks 3 open bugs)

Details

Attachments

(8 files, 1 obsolete file)

Motion path is a kind of transformation, and we could animate an element along a path. Bug 1429303 makes offset-distance and offset-rotate animatable, but only on the main thread. In order to get the better performance, we should run motion-path animation on the compositor thread.
P5 because we don't have concrete plans to implement CSS motion at this time.
Priority: -- → P5
This should be easier done once bug 1479173 landed.
Depends on: 1479173

OK, this bug is necessary for example like this: https://codepen.io/BorisChiou/pen/xpLbov

Priority: P5 → P3
Component: DOM: Animation → CSS Transitions and Animations
Summary: Support compositor animations for motion path → [motion-1] Support compositor animations for motion path
See Also: → 1569795
Assignee: nobody → boris.chiou
Status: NEW → ASSIGNED
Blocks: 1582554

Bug 1586096 may have an impact on this because we set the anchor point to transform-origin if offset-anchor is auto. In other words, transform-origin animation may affect motion-path if offset-anchor is auto.

See Also: → 1586096

Hi Matt,

I have a question about getting the DrawTarget on the compositor thread for web-renderer. Actually, what I want is to build a gfx::Path in AnimationHelper::SampleAnimations(). Here is my original code for building the gfx::Path on main thread, and the compositor thread on non-wr:

  RefPtr<gfx::DrawTarget> drawTarget;
      gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
  RefPtr<gfx::PathBuilder> builder =
      drawTarget->CreatePathBuilder(gfx::FillRule::FILL_WINDING);
  return SVGPathData::BuildPath(..., builder, ...);

However, it seems we cannot use gfxPlatform()::GetPlatform() for web-renderer on the compsitor thread (which is in GPU process?). I hit the assertion in gfxPlatform::Init() [1]. So how do I get the draw target on the compositor thread for web-renderer? I may use it in AnimationHelper::SampleAnimations() [2]. Thank you.

[1] Assertion failure: !XRE_IsGPUProcess() (GFX: Not allowed in GPU process.), at https://searchfox.org/mozilla-central/rev/171109434c6f2fe086af3b2322839b346a112a99/gfx/thebes/gfxPlatform.cpp#857
[2] https://searchfox.org/mozilla-central/rev/171109434c6f2fe086af3b2322839b346a112a99/gfx/layers/AnimationHelper.cpp#552

Flags: needinfo?(matt.woodrow)

Or nical may know this:

Hi Nicolas, I'm trying to build a gfx::Path in web-renderer (e.g. WebRenderBridgeParent::AdvanceAnimations()). The caller is in GPU process I guess, so I cannot use gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget() to get the DrawTarget on the compositor thread, right? (Because gfxPlatform cannot be initialized in GPU process) Do you have any suggestion to get DrawTarget in WebRenderBridgeParent::AdvanceAnimations()? Or Any way to get the PathBuilder if there is not DrawTarget in wr. Thanks.

Flags: needinfo?(nical.bugzilla)

I can see DrawTarget* is an argument of WebRenderBridgeParent::CompositeToTarget, we can probably use it. (the function ends up calling SampleAnimations). But I am not sure when SampleAnimations is called via nsIDOMWindowUtils.getOMTAStyle.

Yes, but unfortunately, it is always nullptr in web-renderer (i.e. we check MOZ_ASSERT(aTarget == nullptr); in this function).

I suspect I have to write a lightweight version of path builder which converts Span<const StylePathCommand> into FlattenedPath, so I don't have to care about DrawTarget because what we need is to call ComputePointAtLength and ComputeLenght in css pixel unit. This can be used by main thread and compositor thread (in layer and wr system).

Can you just create a DrawTargetSkia and use that to get a PathBuilder?

We have separate implementations of path builders, so that the backend can efficiently use the path you create, and so that any calculations done on the path match what will be rendered.

It sounds like you don't render the path itself (since you'd need a DrawTarget!), so neither of those matter. Skia's builder should be fine.

Flags: needinfo?(matt.woodrow)

(In reply to Matt Woodrow (:mattwoodrow) from comment #10)

Can you just create a DrawTargetSkia and use that to get a PathBuilder?

We have separate implementations of path builders, so that the backend can efficiently use the path you create, and so that any calculations done on the path match what will be rendered.

It sounds like you don't render the path itself (since you'd need a DrawTarget!), so neither of those matter. Skia's builder should be fine.

Cool. yes we don't have to render the path. I will try to create DrawTargetSkia for this, just for calculation the angle and position. Thanks a lot.

Flags: needinfo?(nical.bugzilla)

I'd like to add some new data type for motion path, so it'd be great to
put all of them in an independent file.

The current implementation uses nsIFrame to get everything. However, we
want to reuse ResolveMotionPath() on the compositor thread (in the parent
process), so we need to refactor this function to avoid using nsIframe
everywhere.

On the compositor thread in GPU process (i.e. web-renderer), gfxPlatform() is
not initialized, so we don't have the DrawTarget information.
Fortunately, all we need is to calculate the motion point and direction
vector, so we don't have to care about which backend we use.

Therefore, make PathBuilder as a parameter, so we can just pass a valid
PathBuilder on the compositor thread. For main thread (i.e. content
process), using the original way is fine.

This also includes the implementation of SetAnimatable, FromAnimatable,
and merge the final matrix with motion path.

Besides, we always use PathBuilderSkia for calculating the gfx::Path for
web-renderer.

We cache the path in AnimationInfo for layers, and in
CompsoitorAnimationStorage for web-renderer.

Blocks: 1591629

We need to pass these two types into the compositor, so we need a better
way to serialize these rust types. We use serde and serde_json to
serialize/deserialize them. It's ok to use other Serializer, but it
seems we includes serde_json already, and it serizlize the type into a
string, so we can easily reuse it.

Comment on attachment 9103144 [details]
Bug 1429305 - No need to send non-animating offset-* if no effective motion path.

Revision D50012 was moved to bug 1592787. Setting attachment 9103144 [details] to obsolete.

Attachment #9103144 - Attachment is obsolete: true
Blocks: 1592822
Blocks: 1593106
Blocks: 1592787
Pushed by bchiou@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/fc105e53c1cd
Move motion path utils into a separate file. r=hiro
https://hg.mozilla.org/integration/autoland/rev/6b0c544e7744
Refactor for ResolveMotionPath. r=hiro
https://hg.mozilla.org/integration/autoland/rev/a3d6aab91bd4
Make PathBuilder as a parameter. r=hiro
https://hg.mozilla.org/integration/autoland/rev/7e71a2643d86
Use serde to serialize LengthPercentage and StyleRayFunction. r=emilio
https://hg.mozilla.org/integration/autoland/rev/0a68f6ee4e49
Add new layer messages for passing motion path info. r=hiro,mattwoodrow
https://hg.mozilla.org/integration/autoland/rev/5159301a8446
Cache gfx path. r=hiro
https://hg.mozilla.org/integration/autoland/rev/b0d2fc650478
Extend compositor properties for motion. r=hiro
https://hg.mozilla.org/integration/autoland/rev/012c857ee208
Enable OMTA for motion path and add some tests for it. r=hiro
Regressions: 1594960
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: