When investigating https://bugzilla.mozilla.org/show_bug.cgi?id=1452979 with the help of @mstange, we concluded that the issue is produced within WR. When using canvas elements that have a CSS image-rendering property, Gecko creates the texture as a native D3D11Texture and initialises it using linear filtering. Neither Gecko nor WR change this filtering ever after creating the texture, thus resulting in a filtering that is always the same as on creation, see https://searchfox.org/mozilla-central/rev/55da592d85c2baf8d8818010c41d9738c97013d2/gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp#111.
Right now, the ImageRendering property of an image is correctly applied when it's placed in the correct texture cache, excluding any textures that are not cached. WR should be able to apply filtering to external images, e.g. when showing the same video twice with different filtering settings. Looking at https://searchfox.org/mozilla-central/rev/55da592d85c2baf8d8818010c41d9738c97013d2/gfx/webrender/src/batch.rs#1635, the ImageRequest objects already holds the correct ImageRendering property. Therefore, it should be possible to apply this filtering property.
I would like to work on this, if possible :) My proposal is to extend the DeferredResolve struct with an ImageRendering item (see https://searchfox.org/mozilla-central/rev/55da592d85c2baf8d8818010c41d9738c97013d2/gfx/webrender_api/src/display_item.rs#578) and add it to the deferred_resolves list. The lock call at https://searchfox.org/mozilla-central/rev/55da592d85c2baf8d8818010c41d9738c97013d2/gfx/webrender/src/renderer.rs#3456 could then use this ImageRendering item to provide the correct filter at https://searchfox.org/mozilla-central/rev/55da592d85c2baf8d8818010c41d9738c97013d2/gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp#111 or https://searchfox.org/mozilla-central/rev/55da592d85c2baf8d8818010c41d9738c97013d2/gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp#133
I think this sounds like it should work fine, go for it!
@gw3583 we could also apply the proper filtering to external images internally in WR (based on provided ImageRendering) if we use GL sampler objects. This would also technically allow us to use the same texture cache for nearest/linear filters, by just using different parts of it with different sampler objects. So we'd still be breaking the batches but potentially doing less work on those breaks: since we leave the actual texture untouched, the driver can go a faster route seeing only the sampler being changed. Likewise, I'd expect Angle to also not bother rebinding the actual texture SRV.
@kvark GL sampler objects aren't available in GL3 though, right?
glGenSampler is available on GLES 3.0 and GL 3.3
Our lowest / agreed target is GL3.1 (although we haven't discussed if that still makes sense as a target for a long time).
Right. As an option, we could require GL3.1 + ARB_sampler_objects (see gpuinfo support).
I have a working solution based on my proposal. It passes all reftests mentioned in https://bugzilla.mozilla.org/show_bug.cgi?id=1452979#c1, as well as video tests and changing the filter on-the-fly during video playback via JS. @mstange will push the patch to a try server to test it.