Sotaro raised this question in bug 1272600. Currently for textures that don't have an internal buffer (Gralloc and DXGI) we call ReadUnlock at the end of the transaction that follows the moment they are replaced by another texture (so there is already some delay). So it looks something like Composition N-1: Texture A is used by the compositor. Txn N: Texture B replaces texture A. Composition N: Texture B is used by the compositor, Texture A is ReadUnlock()'ed. Under the hood, the driver may actually be still asynchronously rendering "composition N-1" during composition N, so technically we are releasing the texture before it is made 100% available for drawing again. This is currently Ok for drawing because we use fences on with gralloc and DXGI keyed muteces with D3D11, so if the content side tries to render into texture A just after composition N and the GPU is still reading from texture A, this extra synchronization mechanism blocks the content thread and. We could add an extra frame of delay (texture A would be ReadUnlocked in composition N+1). This would mean: * The fence and DXGI mutex would be useless when using a ReadLock. * Our copy-on-write mechanisms would block less and allocate/copy more. We could also do a mixture of both and select the strategy that works best depending on the texture type and/or compositable type if need be? I don't know what the right tradeoff is, and my initial hunch is that I am not found of the copy-on-write type of compositables triggering more copies and allocations rather than blocking for a short time. That said I know that we have had issues with keyed mutex beeing poorly implemented in some drivers, so this could let us use DXGI even in these broken configurations (if that's worth it all)... Also the fence stuff is pretty heavy-weight currently, so this (optional) extra frame could be use instead of the fences and we could probably even remove the code.
Note that video uses textures that don't have a keyed mutex (we could add them back for d3d11 if we needed, but not for d3d9). I also added code to CompositorD3D11:EndFrame that block until frame N-1 has completed entirely before it returns, so this shouldn't be a problem there. I think we could do the same for other compositors if necessary. In terms of code, it might be nice to pass the lock into the Compositor (as part of the TextureSource/Effect/DrawQuad call) and have the compositor be responsible for taking and releasing a read lock as (and when) appropriate. That way the TextureHost can immediately drop its read lock when it is removed from the Compositable, and we don't have to worry about complex timings in shared code.
(In reply to Matt Woodrow (:mattwoodrow) from comment #1) > I also added code to CompositorD3D11:EndFrame that block until frame N-1 has > completed entirely before it returns, so this shouldn't be a problem there. I would like that. > In terms of code, it might be nice to pass the lock into the Compositor (as > part of the TextureSource/Effect/DrawQuad call) and have the compositor be > responsible for taking and releasing a read lock as (and when) appropriate. Something along those lines just landed in bug 1272600: The texture can ask the compositor to unlock a TextureReadLock after the next composition. This is not totally up to the compositor because only some textures (DXGI, gralloc...) require this, so they opt into asking using the compositor for delayed unlocks. > That way the TextureHost can immediately drop its read lock when it is > removed from the Compositable, and we don't have to worry about complex > timings in shared code. This is not an issue anymore (assuming my ReadLock refactoring makes it past inbound).
You need to log in before you can comment on or make changes to this bug.