Skip to content

Conversation

@liyuqian
Copy link
Contributor

@liyuqian liyuqian commented Sep 9, 2018

For retained rendering, we don't want to push the offset down to each leaf layer. Otherwise, changing an offset layer on the very high level could cascade the change to too many leaves, which means that we can't retain them.

To not push the offset downwards, we simply push a TransformLayer when there's an offset. Skia has a fast path for concatenating scale/translation-only matrix so this operation should be fast (no performance regression is measured on Moto G4).

This also makes our compositor much cleaner as we don't have to pass layerOffset all over the places in XXXLayer::addToScene.

We can also remove the offset_ field and its related operations from flow::PictureLayer, flow::TextureLayer, flow::ChildSceneLayer in flutter/engine once this change landed.

This is our first step towards #21756

@yjbanov
Copy link
Contributor

yjbanov commented Sep 11, 2018

Have you considered using Layer.owner as a marker for retaining layers? I have a working prototype of this if you want to see it.

@liyuqian
Copy link
Contributor Author

@yjbanov Sure, I'll have a look. Can you point me to your prototype?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a breaking change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll preserve the old API. It will disallow me to remove some code that I think would be beneficial to our code health and tech debt in the long run. But we can always change the API and make the decision of whether to remove such code or not later in a separate PR.

@Hixie
Copy link
Contributor

Hixie commented Sep 25, 2018

I think we should continue to support the old API, even if we change the default implementation of OffsetLayer to use transforms and pass through zero instead of passing through the offset.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd prefer a dedicated pushOffset method on SceneBuilder that matches the API of OffsetLayer:

@override
void addToScene(ui.SceneBuilder builder) {
  builder.pushOffset(offset.dx, offset.dy);
}

The dx and dy can be easily (and more efficiently) converted to a transform matrix by the engine. Knowing the difference between a transform and an offset I can use it to collapse a series of offsets into a single offset as an optimization that reduces the total number of layers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me. flutter/engine#6349 is uploaded to handle this. Once that landed, I can change this (either in this PR, or in the next PR).

liyuqian added a commit to liyuqian/engine that referenced this pull request Sep 26, 2018
@liyuqian
Copy link
Contributor Author

@Hixie Added [Offset layerOffset = Offset.zero] back so it won't break the API but will encourage to not use layerOffset.

liyuqian added a commit to flutter/engine that referenced this pull request Sep 27, 2018
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this is fixing an old bug, can you add a test for this?

@Hixie
Copy link
Contributor

Hixie commented Sep 27, 2018

LGTM.

I'm surprised by the premise of this PR, though. why would we need to send anything to the engine but the new offsets on the leaves?

@yjbanov
Copy link
Contributor

yjbanov commented Sep 27, 2018

@Hixie here's an example:

Frame 1:

offset(0, 0)
  opacity()
    offset(10, 10)
      picture()
    pop()
  pop()
pop()

Frame 2:

offset(10, 10)
  opacity()
    offset(10, 10)
      picture()
    pop()
  pop()
pop()

Today, this is submitted to the Engine as:

Frame 1:

opacity()
  picture() with offset(10, 10)
pop()

Frame 2:

opacity()
  picture() with offset(20, 20)
pop()

Note that we mutated the tree under the "opacity" node.

After this change, we will submit the layers to the engine unchanged, i.e. the sub-tree rooted at "opacity" is not mutated from frame 1 to frame 2, which tells the engine "nothing's changed under opacity and it is safe to cache it".

@liyuqian liyuqian merged commit 783c028 into flutter:master Sep 28, 2018
GaryQian pushed a commit to GaryQian/engine that referenced this pull request Oct 2, 2018
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants