Is it possible to render from another thread without OpenGLES

Started by
5 comments, last by LoneDwarf 10 years, 1 month ago

Okay, so here is what I'm trying to accomplish:

I want to render a loading screen using textures directly to the back buffer without going through OpenGL, this way the context thread can be spent actually loading the context resources.

Ideally it would be something that I can run in a thread parallel to the context thread and render at regular intervals without delaying the loading thread too much.

I understand that you can do shared contexts in some cases, but I also understand that support for such a thing is sketchy at best, even among 3.0+ devices.

I could render an image, swap and then load my resources, but the display would be stale. If possible I'd like to avoid that.

Is it possible to reliably and portably render from another thread? Do I just need to bite the bullet and litter my code with updates to a loading screen? That seems non-optimal.

Perception is when one imagination clashes with another
Advertisement

It depends on how you implemented things.

Remember that even if you do use multiple threads in your application, there is only one video card. (or chip. or processor. or whatever you call it on a SoC device. I'll just go with "card".)

If you have one thread issuing instructions to the card for the loading screen, and another thread issuing instructions to the card for the game content, it can be very easy for the hardware to do something you didn't want. Both sets of instruction streams are going into the graphics card at the same time.

Is it possible to do it? Yes, some have done it before.

Probably the best solution is only available when rendering is decoupled from other systems and you have classes with a single responsibility of mapping resources on the GPU, you can assign your renderer to display the loading screen information while the other resource managers (icky word) are busy streaming in the other content. If your system is designed this way it is just a matter of switching a state in your renderer and the next frame will switch from the loading screen to the game.

Another option if you don't have decopuled systems is to just not draw while one thread is using the card. The data-loading thread that is transferring stuff to the GPU with data can stop occasionally and notify the 'loading screen' thread to do its job. The loading screen draws a frame, then notifies the data-loading thread resumes work.

That's what I was worried about. Currently the tech I'm using has the resources tightly coupled to the graphics initialization. And I'm out of time to change such an expansive architecture.It seems like anything I do will be a hack and will not be reliable. It alright there are other, less robust ways of showing a loading screen. Thanks!

Perception is when one imagination clashes with another

If contexts with shared objects don't work for some reason, you can still try to reduce the impact on resource loading. OpenGLES 3.0 core and OpenGLES 2.0 w/ appropriate extension provide PBOs for asynchronous texture updates. Create a texture object, create a PBO, map the PBO, and let the background thread fill in the PBO. Then unmap the PBO and let the rendering thread pass a TexSubImage command. You perhaps need to set a fence, too.

PBOs have some scattered support from my initial research, and isn't reliable.

Perception is when one imagination clashes with another

I use a three tiered system.

I always render on the main thread and load on a background thread.

If shared context is supported, I use that and all is hunky dory

If not I look for surfaceless contexts. They allow you to load graphics on a seperate thread than the drawing thread

If not I fall back to an emergency mode. In the emergency mode I create a whole bunch of contexts on the main thread and store them in an array.

When the background thread wants to start a load it does a cross thread call to a function on the main thread which gives it one of these pre-prepared contexts.

If no contexts are available, it sleeps for a while and tries again.

All three techniques work, but you never know which one is running on a device so it can be a nightmare when a bug turns up.

Just incase, some platforms have an image you can supply that is show for you by the OS (iOS and BB10 do for sure).

Other than that, what I do is load the splash screen texture, render the quad and swap. Now don't swap the buffer again until you have finished loading.

This topic is closed to new replies.

Advertisement