Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upMove the pending scene data structure to the SceneBuilder thread #2998
Conversation
|
I am so sorry for this wall of code. Most of it is moving things around. I think that the code is quite a bit easier to understand after this change than before but the diff view doesn't do it justice. You can ignore the first 5 commits which are from #2992. |
| use time::precise_time_ns; | ||
|
|
||
| /// Represents the work associated to a transaction before scene building. | ||
| pub struct Transaction { |
This comment has been minimized.
This comment has been minimized.
nical
Aug 30, 2018
Author
Collaborator
Whether splitting the data in Transaction into a lot of vectors the best is up for debate, here is a bit of context:
I realize that having a bunch of small vectors means a bunch of small allocations, however:
- This representation made it easy to do a few of things in this PR such as knowing whether the transaction needs triggers a scene build and whether it can skip the scene builder by simply looking at which vectors are empty.
- It will simplify the problem of merging transaction whenever we get to implementing that. Right now if scene building takes a long time, requests can accumulate faster than they are processed which leads to growing delay between user input and rendering which is awful. I want to be able to take several transactions and merge them into one that accumulates the important states while discarding redundant or out of date changes. This is a easier to do if things are organized this way than with a single vector.
With this change the render backend only sees the state of the scene that it can use for frame building and the scene builder thread manages its own scene. This will allow us to perform low priority scene building and rasterization asynchronously without having to involve the render backend thread.
All documents currently always have the same config.
From now on, generate frame means having the frame builder generate a frame (but not necessarily render it), and render means asking the renderer to render a frame.
|
I added a commit that simplifies the terminology around generating frames and rendering (and fixes a bug I caused because of the associated confusion) Before this PR:
After this PR:
|
|
try push looks good so far: https://treeherder.mozilla.org/#/jobs?repo=try&revision=e606386b9e899fcde16d8344fdc8c5ddaaf9e6e3 The push has all of the commits since the last WR update so I can't take credit for the unexpected passes. There are also a few failures with rendering differences within fuzzing range and I don't think these can be the result of this PR. |
webrender/src/render_backend.rs, line 332 at r3 (raw file):
I'd marginally prefer us to be consistent with the rest of the internal code and call this webrender/src/render_backend.rs, line 333 at r3 (raw file):
uuh, so we have an old flag with an entirely new semantics now webrender/src/render_backend.rs, line 529 at r3 (raw file):
I am slightly confused here at a high level: we receive a scene message for updating the document, but then some of the updates affect webrender/src/render_backend.rs, line 594 at r3 (raw file):
why are we taking out the blob rasterizer? webrender/src/render_backend.rs, line 828 at r3 (raw file):
why are we boxing the transaction? webrender/src/render_backend.rs, line 940 at r3 (raw file):
we might need a separate flag for hit tester info update, given that it shouldn't need the full frame build webrender/src/scene.rs, line 193 at r3 (raw file):
nit: this could look cleaner without a webrender/src/scene_builder.rs, line 22 at r2 (raw file): Previously, nical (Nicolas Silva) wrote…
Does gecko has facilities implemented/planned for accelerating those heap allocations? We have accumulated quite a big technical debt in performance, partly because of those allocations, and I want to see the light at the end of this tunnel. |
webrender/src/render_backend.rs, line 332 at r3 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Sounds good to me. I'd like to avoid touching the public API in this PR but I'll rename some of the places now. webrender/src/render_backend.rs, line 333 at r3 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
I like webrender/src/render_backend.rs, line 529 at r3 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
The transaction itself is just info about updating documents. Because of how these things are pipelined document updates that are not applied right away upon receiving the transaction go in this transaction object. webrender/src/render_backend.rs, line 594 at r3 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Oops, that's a mistake. webrender/src/render_backend.rs, line 828 at r3 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Large structures that move around a lot like this one tend to generate atrocious code behind the scenes, I think that it's a healthy habit to box them when they are not created often (once per transaction isn't often). webrender/src/render_backend.rs, line 940 at r3 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Agreed. it'll be easy to add the flag when we implement watever's needed to generate only the hit testing info. webrender/src/scene_builder.rs, line 22 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
I don't think there is anything specific in Gecko for this. I believe that our biggest problem with allocations right now in webrender is reallocating/growing large vectors, so these small vectors śhould be anecdotal in comparison. More generally, I don't have a very strong attachment to the way the |
webrender/src/render_backend.rs, line 333 at r3 (raw file): Previously, nical (Nicolas Silva) wrote…
I'm ok with ending up with webrender/src/render_backend.rs, line 529 at r3 (raw file): Previously, nical (Nicolas Silva) wrote…
so on the high level - why not make all mutation of the document to go through a transaction? webrender/src/render_backend.rs, line 594 at r3 (raw file): Previously, nical (Nicolas Silva) wrote…
heads up - still not addressed? webrender/src/render_backend.rs, line 828 at r3 (raw file): Previously, nical (Nicolas Silva) wrote…
How large of a structure are we talking about? Would be great to make this more systematic and document in guidelines, e.g. structures larger than 128 bytes should be boxed. webrender/src/scene_builder.rs, line 22 at r2 (raw file): Previously, nical (Nicolas Silva) wrote…
That's an interesting observation. |
The way I picture things in my mind, they all do. There are 3 structs that represent the transaction at different stages of the pipeline TransactionMsg -> Transaction -> BuiltTransaction Some things get applied between TransactionMsg and Transaction (that's the ones you are referring to in this comment), others between Transaction and BuiltTransaction (scene building, blob rasterization), others after BuiltTransaction (scrolling, frame building for example).
Sorry I got mixed up, it was actually not a mistake. It's correct to move the blob rasterizer out of the transaction here because we want to move it into the render backend (it is uniquely owned). Using |
|
|
@bors-servo r+ |
|
|
Move the pending scene data structure to the SceneBuilder thread This PR reorganizes the code in the render backend and scene builder such that: - The render backend now only manages a single scene per document: the one it can use for frame building. - The scene builder now manages a scene per document and uses it to generate the `FrameBuilder`. - The render backend sends to the scene builder thread the events it needs to keep the Scene data structure up to date. - Transactions have been consolidated around 3 structs: `TransactionMsg` is what the API sends to the render backend, `Transaction` is what the render backend creates and sends to the scene builder thread(s), and `BuiltTransaction` is what the scene builder sends back to the render backend after scene building. These three structs represent the same thing but at different stages of the pipeline. - A *lot* of code was simplified (for example no more calling `update_document` twice with different parameters before and after scene building to have it do different things) This change is needed in order to get the low priority scene building in #2989 to work without requiring extra handshakes between the scene builder and the render backend threads. This is rebased on top of #2992. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/2998) <!-- Reviewable:end -->
|
|
|
This seemed to cause regressions of Bug 1489471 and Bug 1489189. |
nical commentedAug 30, 2018
•
edited by larsbergstrom
This PR reorganizes the code in the render backend and scene builder such that:
FrameBuilder.TransactionMsgis what the API sends to the render backend,Transactionis what the render backend creates and sends to the scene builder thread(s), andBuiltTransactionis what the scene builder sends back to the render backend after scene building. These three structs represent the same thing but at different stages of the pipeline.update_documenttwice with different parameters before and after scene building to have it do different things)This change is needed in order to get the low priority scene building in #2989 to work without requiring extra handshakes between the scene builder and the render backend threads.
This is rebased on top of #2992.
This change is