Imagination PowerVR SDK Blog

Best practice: Context sharing vs. PBO



I’m optimizing an engine where the texture uploads are done in the main render thread which brings performance penalties as the textures are quite large. I have two variants on the table on how to solve this:

  • Shared OpenGL context which is used by a secondary thread to create and upload textures which are then shared with the main render thread context.

  • Staying with one context and using PBOs with non-blocking upload calls.

I have doubts about context sharing as they are traditionally known to be performance heavy and are not implemented well on many drivers.

Given your experience with PowerVR platforms, what do you think is the better method and why?




in our experience shared contexts just lead to trouble. Their effectiveness highly depends on the driver. I’d advise to just stick to using PBOs with non-blocking calls in accordance with our PowerVR Performance Recommendations. (




thanks for your answer. Can you name me an example where creating a texture the traditional way on a shared context and using it in the main render context can lead to trouble and why? I read the performance documents here

and it lists shared contextes as an option for buffer uploads in section 6.6.1 but I can’t find info on how they perform compared to mapped memory.



it can lead to trouble mainly because drivers are usually not good at handling multiple contexts/threads.
Using PBOs avoids this, that’s why I’m recommending it.
I don’t have any metrics on their performance, I’m afraid you’ll need to benchmark them.




another angle for the problem: What about mipmaps?
I can move texture upload to a different thread via glMapBuffer but mipmap generation would still be in the main thread (via glGenerateMipmap ). Is there a way to move it to another thread too? Or should I assume it is just fast enough?


Hi Desperado,

don’t assume anything, I think the best thing would be to do a test. Implement PBO texture buffer and generate mips with glGenerateMipmap. It should run async (and shouldn’t block on the CPU side) on the 2D pipeline of the GPU. You can verify this using PVRTune.

Let me know if it worked.