In MediaTextureResource.cpp, the rendering thread calls UpdateDeferredResource, from the
FMediaTextureResource class.
The function looks like this:
uint8* TextureBuffer = (uint8*)RHILockTexture2D(Texture2D, 0, RLM_WriteOnly, Stride, false);
FMemory::Memcpy(TextureBuffer, CurrentFrame->GetData(), CurrentFrame->Num());
RHIUnlockTexture2D(Texture2D, 0, false);
It’s slow. I’m benchmarking 3ms for a HD texture size (1920x1080). My goal is to playback a 4k movie, at 60 fps smoothly. No hickup, no skip frame.
My first optimization was to replace the Lock-Memcpy-Unlock with RHIUpdateTexture2D. It’s cutting the time by approximately a factor of 3, which is not bad. What this function ultimately calls is
Direct3DDeviceIMContext->UpdateSubresource.
Now, there’s this presentation form NVidia:
Slide 14, it says:
Avoid UpdateSubresource() for textures! Especially bad with larger textures!
Instead, NVidia suggets to use ring buffers of staging texture, update and upload the data in the main thread, and calls map-CopyResource in the rendering thread.
I guess the right way to do it is uploading the frames as fast as they arrive in the main thread, and bind the resource in the game thread to data already on the device.
Is that something you are looking at?
Is there something in the engine that I can use to quickly try it?
Or maybe there’s an alternate solution that we have’nt figure out yet?
Thanks,
Bryan