webrender/core/doc/swizzling.md
It'd be great to have some (in-tree) docs describing the process you've worked through here, the overall motivation, how it works on different GPUs / platforms etc. Perhaps as a follow up?
The goal is to avoid the CPU conversion of data done by the driver on texture data uploads. It's slow and always done synchronously, hurting our "Renderer" thread CPU utilization.
Gecko produces all of the image data in BGRA. Switching "imagelib" to RGBA is possible, but modifying Skia to follow is less trivial.
OpenGL support for BGRA8 as an internal texture format is a complex story: it's officially supported in Angle and a fair share of Android devices, but it's not available on the desktop GL (and until recently wasn't available in the Android emulator). Unofficially, when textures are initialized with glTexImage (as opposed to glTexStorage) with RGBA internal format, the desktop GL drivers often prefer to store the data in BGRA8 format, actually.
The only way to avoid the CPU conversion is to provide the data in exactly the same format that the driver is using internally for a texture. In this case, the driver does a straght memcpy into its CPU-visible memory, which is the best we can hope for with OpenGL API.
https://phabricator.services.mozilla.com/D21965 is providing the solution to this problem. The main principles are:
glTexStorage whenever it's available. Doing so gives us full control of the internal format, also allows to avoid allocating memory for mipmaps that we don't use.Swizzle. That swizzle configuration changes the way shaders sample from a texture, adjusting for the fact the data was provided in a different format.Swizzle and thus would produce incorrect results. To address this, the change enhances cs_copy shader to be used in place of blitting from the texture cache, where needed.Windows/Angle and Android:
glTexStorage with BGRA8 internal format, no swizzling is needed in general case.Windows (non-Angle), Mac, Linux:
glTexStorage is available, we use it with RGBA8 internal format, swizzling everything on texture sampling.gTexImage and expect the data to come in BGRA format, no swizzling is involved.