Bug#930570: garbled output when using ResourcePool from multiple threads
I've noticed that occasionally in multithreaded contexts (which affects
at least Nageru on certain themes, but probably also Kdenlive, given its
heavy dependency on multiple threads), Movit will show corrupted imagery,
where textures from other threads show up at random.
I've traced this down to a bug in the multithread handling. From the upstream
commit message I wrote:
> When an EffectChain is done rendering (ie., has submitted all of the GL
> rendering commands that it needs to), it releases all of the temporary
> textures it's used back to a common freelist.
> However, if another thread needs a texture of the same size and format,
> it could be picking it off of the freelist before the GPU has actually
> completed rendering the first thread's command list, and start uploading
> into it. This is undefined behavior in OpenGL, and can create garbled
> output depending on timing and driver. (I've seen this on at least the
> classic Intel Mesa driver.)
> Fix by setting fences, so that getting a texture from the freelist
> will have an explicit ordering versus the previous work. This increases the
> size of ResourcePool::TextureFormat, but it is only ever used in a private
> std::map. std::map is node-based (it has to, since the C++ standard requires
> iterators to it to be stable), and thus, sizeof(TextureFormat) does not factor
> into sizeof(ResourcePool), and thus, there is no ABI break. Verified by
> checking on libstdc++.
The patch is small, doesn't break the ABI, and backports trivially from
upstream git. I'll be uploading through unstable, but it will probably be
stuck behind gcc-8 like Nageru was, so I assume eventually, a testing upload
will be required if the RMs accept it.