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 upRefactor and improve the texture cache, implement new allocator. #1572
Conversation
Simplify render targets (always array textures). Remove resize_texture which is now unused. Support uploading all texture types via PBO. Remove support for texture upload without PBO.
* The texture cache now acts more like a traditional cache, where the cache is a fixed size, and can evict items as required. * The allocator is switched to a slab style allocator, allowing deterministic behavior when allocating and freeing. * The slab allocator does not suffer from fragmentation like the previous allocator, and has no coalesce requirements. * The eviction policy is a lot smarter than the previous implementation. Items are evicted from the cache as required, and not before. * Since the shared cache is a fixed / bounded size, any allocations that are too large for the cache are created as standalone textures. * In the rare / edge case of the fixed sized cache being full, and the cache not being able to evict items, these items also fallback to the standalone texture allocator. * All textures using the sColor* samplers are now array textures. This will allow us to simplify the large image tiling code in the future. * All texture updates are performed via PBO, to eliminate CPU driver stalls when updating textures.
|
r? @kvark I'm so sorry for the size of this patch. It really snowballed. Let me know if you want to discuss details on IRC / Vidyo etc. I'm happy with the end result though :) I've done a fair amount of manual testing in both Servo and Gecko. It also passes the Gecko sanity reftests, the Servo WPT/CSS tests and the Wrench reftests. |
|
@staktrace @sotaroikeda @JerryShih I've run the gecko sanity tests locally with this, and they pass. It doesn't change any external interfaces, but it does expect that external textures which use the normal texture2D sampler switch over to place them into the texture2DArray sampler. It doesn't affect anything that goes via the TextureRect or TextureExternal image types. Do you foresee any issues with this? I'll ping you later during the week with some questions I have on running a try build with this change. |
|
@kvark PS: The |
|
To get a feel for how the cache works, the image below may help. This is what the cache looks like after browsing a heap of wikipedia and mozilla pages in Servo. You can see that within each layer of a texture array, there are number of "regions". Each region acts as a slab allocator with a fixed size, that allows fast and deterministic allocating and freeing. We'll probably want to tweak the slab sizes, but the initial implementation seems to work well on all the pages I've tried so far. |
|
Overall, I think moving to slab allocation is a great step forward! The amount of code is making it rather difficult to get a full picture even when using Reviewable, but I got a general idea, and I like it (despite the fact I was cleaning up the coalescing not so long ago) ;)
Hmm, not sure about this one. I feel like we should not be hard-coding the texture cache size. If there is a workload that needs a little more than we have, we'll see consistent drop in performance there, where optimally I'd like our performance curve to be smooth. So, instead of allocating a standalone texture, can we just allocate a new texture page to be added to the cache (and reused later on)?
I love those, thank you! Although, perhaps it would be visually more appealing to render them Y-flipped, so that all the textures look exactly as they are on screen. Reviewed 32 of 34 files at r1, 2 of 2 files at r2. webrender/res/debug_font.fs.glsl, line 10 at r2 (raw file):
is that check intended for removal? webrender/src/device.rs, line 1644 at r2 (raw file):
is this path intended for removal as well? webrender/src/freelist.rs, line 94 at r2 (raw file):
please add a comment explaining what webrender/src/glyph_cache.rs, line 14 at r2 (raw file):
should it use webrender/src/glyph_rasterizer.rs, line 161 at r2 (raw file):
nit: probably easier to have webrender/src/glyph_rasterizer.rs, line 273 at r2 (raw file):
shouldn't we check for the webrender/src/glyph_rasterizer.rs, line 274 at r2 (raw file):
is update always following webrender/src/internal_types.rs, line 100 at r2 (raw file):
I feel like we'll eventually (not now!) need to have a separate webrender/src/renderer.rs, line 2417 at r2 (raw file):
shouldn't this be webrender/src/resource_cache.rs, line 108 at r2 (raw file):
is there any point in this struct now as oppose to just typedeffing to webrender/src/resource_cache.rs, line 144 at r2 (raw file):
I think it can be easily done on the caller site now that we have Rust-1.19 (used by Gecko) and all those pretty retain methods in libstd webrender/src/texture_cache.rs, line 82 at r2 (raw file):
nice struct! webrender/src/texture_cache.rs, line 231 at r2 (raw file):
do we have any detection of a forgotten webrender/src/texture_cache.rs, line 404 at r2 (raw file):
I think this procedure can be done simpler and a bit faster without temporary arrays:
Although, this doesn't seem to be a performance critical place here, so we can look into it later. The current code is correct. webrender/src/texture_cache.rs, line 477 at r2 (raw file):
can we use webrender/src/texture_cache.rs, line 870 at r2 (raw file):
I thought that webrender/src/texture_cache.rs, line 906 at r2 (raw file):
nit: could be Comments from Reviewable |
|
Review status: 29 of 34 files reviewed at latest revision, 17 unresolved discussions. webrender/res/debug_font.fs.glsl, line 10 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yep, not needed now that we require es3. webrender/src/device.rs, line 1644 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yep - es3 supports alpha texture format natively. webrender/src/freelist.rs, line 94 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. webrender/src/glyph_cache.rs, line 14 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. webrender/src/glyph_rasterizer.rs, line 161 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. webrender/src/glyph_rasterizer.rs, line 273 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
In this case (a newly rasterized glyph), we know that we will definitely want to update. webrender/src/glyph_rasterizer.rs, line 274 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Only if request returns true, or the caller knows it wants to update the image data. webrender/src/internal_types.rs, line 100 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Sounds good. webrender/src/renderer.rs, line 2417 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. webrender/src/resource_cache.rs, line 108 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Probably not - we could perhaps do as a follow up though? webrender/src/resource_cache.rs, line 144 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yup, we could do that as a follow up when we remove the resource class cache struct. webrender/src/texture_cache.rs, line 231 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Yes, get() asserts that the last_frame matches the current frame. webrender/src/texture_cache.rs, line 404 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Sounds good! webrender/src/texture_cache.rs, line 477 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. webrender/src/texture_cache.rs, line 870 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. webrender/src/texture_cache.rs, line 906 at r2 (raw file): Previously, kvark (Dzmitry Malyshau) wrote…
Done. Comments from Reviewable |
|
@kvark Thanks for the review. I think all comments / questions addressed - I still haven't run on the gecko try build yet. I agree with you about the resizing - in the case where we evict everything not used on this frame and still can't fit in the cache, we could resize and add more layers. Are you happy for this to be done as a follow up? |
|
Yes, I'm happy with it. I assume you are going to test Gecko before merging? Review status: 29 of 34 files reviewed at latest revision, 1 unresolved discussion. Comments from Reviewable |
|
Yup, I'll test against Gecko today. Thanks! |
I think there is no problem if we try to use texture2DArray for texture2D sampler with your fix. |
|
OK, gecko test run results here - https://treeherder.mozilla.org/#/jobs?repo=try&revision=727e26960bc131783b36d0fe4cd6dc143af414b3 I think that's all done correctly and tested OK - but I'll get @staktrace to confirm since I haven't tried this before. If that's all OK, and with the sign-off from @JerryShih above, this should be good to merge. |
|
@staktrace The required changes in gecko are:
|
|
@glennw The try push looks good, thanks! And also thanks for listing the changes required in gecko, that's perfect! |
|
Ok, sounds like a fairy tale, |
|
|
Refactor and improve the texture cache, implement new allocator. Refactor and improve the texture cache implementation. * All textures using the sColor* samplers are now array textures. This will allow us to simplify the large image tiling code in the future. * All texture updates are performed via PBO, to eliminate CPU driver stalls when updating textures. * The texture cache now acts more like a traditional cache, where the cache is a fixed size, and can evict items as required. * The allocator is switched to a slab style allocator, allowing deterministic behavior when allocating and freeing. * The slab allocator does not suffer from fragmentation like the previous allocator, and has no coalesce requirements. * The eviction policy is a lot smarter than the previous implementation. Items are evicted from the cache as required. * Since the shared cache is a fixed / bounded size, any allocations that are too large for the cache are created as standalone textures. * In the rare / edge case of the fixed sized cache being full, and the cache not being able to evict items, these items also fallback to the standalone texture allocator. * Add support for array textures that don't have FBOs. * Simplify render targets (always array textures). * Remove resize_texture which is now unused. * Remove support for texture upload without PBO. * Add support for weak handles to freelist. * Update gleam to 0.4.8 (allows upload of array textures via PBO). <!-- 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/1572) <!-- Reviewable:end -->
|
|

glennw commentedAug 14, 2017
•
edited by larsbergstrom
Refactor and improve the texture cache implementation.
All textures using the sColor* samplers are now array textures. This will allow us to simplify the large image tiling code in the future.
All texture updates are performed via PBO, to eliminate CPU driver stalls when updating textures.
The texture cache now acts more like a traditional cache, where the cache is a fixed size, and can evict items as required.
The allocator is switched to a slab style allocator, allowing deterministic behavior when allocating and freeing.
The slab allocator does not suffer from fragmentation like the previous allocator, and has no coalesce requirements.
The eviction policy is a lot smarter than the previous implementation. Items are evicted from the cache as required.
Since the shared cache is a fixed / bounded size, any allocations that are too large for the cache are created as standalone textures.
In the rare / edge case of the fixed sized cache being full, and the cache not being able to evict items, these items also fallback to the standalone texture allocator.
Add support for array textures that don't have FBOs.
Simplify render targets (always array textures).
Remove resize_texture which is now unused.
Remove support for texture upload without PBO.
Add support for weak handles to freelist.
Update gleam to 0.4.8 (allows upload of array textures via PBO).
This change is