Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deciding when to rasterize with transform. #1542

Closed
glennw opened this issue Aug 2, 2017 · 9 comments
Closed

Deciding when to rasterize with transform. #1542

glennw opened this issue Aug 2, 2017 · 9 comments

Comments

@glennw
Copy link
Member

@glennw glennw commented Aug 2, 2017

When a stacking context has a complex transform (i.e. anything other then identity or translation), it can be rendered in one of two ways:

  1. Rasterize un-transformed, and then apply the transform when compositing the stacking context into the scene.
  2. Rasterize with the transform applied into a target, and then composite the transformed stacking context into the scene by drawing a screen space rectangle.

As a general rule of thumb, (1) will be faster, while (2) will be a higher quality result.

The major factor affecting quality / performance between these two options is whether glyphs need to be rasterized on the CPU that are specific to the current transform (i.e. passing the rotation / skew to Freetype or platform rasterizer). Although other display items (such as box shadows) are potentially slower to draw in (2), they are unlikely to have a major effect on the frame rate (the performance should scale roughly linearly with the resolution difference, which is not a big deal).

To determine which option to pick, we could:

(a) If the stacking context has a property binding on the matrix (for OMTA reasons) we could assume that it is either animated or likely to animate, and therefore select (1) for these stacking contexts. Anything with a specific matrix that is identity or a simple rotation would then go through (2), since we know it can't be animated without providing a new display list. This seems somewhat similar to the heuristic Gecko uses, however, it can easily go wrong (e.g. due to the dynamic nature of JS, Gecko may well decide to bind every transform to a property binding, just in case it starts animating).

(b) Add an API option to allow the client to explicitly specify which space to rasterize this stacking context in. This is certainly the easiest option for WR - however I'm not sure if that would suit all clients.

(c) Some other heuristic I haven't thought of?

My personal preference would be (b) - this is the simplest option for WR, but does push some complexity to the calling code.

Thoughts?

@glennw
Copy link
Member Author

@glennw glennw commented Aug 2, 2017

@glennw
Copy link
Member Author

@glennw glennw commented Aug 2, 2017

A mid-long term option is to always rasterize transformed, and use SDF fonts to achieve higher quality when a stacking context has a transform on it.

This means that we don't need to re-rasterize glyphs as the transform changes.

Using this (or GPU rasterized glyphs) for transformed stacking contexts, and CPU / platform rasterized glyphs for un-transformed stacking contexts is probably the ideal solution, but it'd be good to have a plan in place in the interim, until we support that.

@nical
Copy link
Collaborator

@nical nical commented Aug 2, 2017

(b) sounds good to me if it makes things easy for WR.

@mrobinson
Copy link
Member

@mrobinson mrobinson commented Aug 3, 2017

A fairly obvious and simple heuristic would be whether or not the stacking context contains glyphs at all.

@staktrace
Copy link
Contributor

@staktrace staktrace commented Aug 3, 2017

I would also prefer (b). In my experience adding an explicit API in cases like this generally works out better in the long run.

@jrmuizel
Copy link
Contributor

@jrmuizel jrmuizel commented Nov 9, 2017

@kvark, @mstange and I just had a discussion about this and also came to the conclusion that an explicit API is the way to go.

Our proposal is as that we add the following to StackingContexts:

enum Rasterization {
    Untransformed,
    Transformed{xscale: f32, yscale: f32}
}

This API should be relatively easy for Gecko to use and should give us everything we need in the short term.

@glennw
Copy link
Member Author

@glennw glennw commented Nov 9, 2017

Sounds good. This should also become relative simple to implement once the picture tree work I'm doing is complete.

@jrmuizel
Copy link
Contributor

@jrmuizel jrmuizel commented Nov 9, 2017

The enum would probably better be named:

enum Rasterization {
  SharpSlowAndSubpixeled,
  BlurryMess{xscale: f32, yscale: f32}
}

or

enum Rasterization {
  ScreenSpace,
  BufferedSpace{xscale: f32, yscale: f32}
}
@gw3583
Copy link
Collaborator

@gw3583 gw3583 commented Feb 1, 2019

We have the raster space APIs, and rasterization root support now.

@gw3583 gw3583 closed this Feb 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants
You can’t perform that action at this time.