Twinkletoes
Posts: 210
Joined: Fri May 25, 2012 9:44 pm

Multiple GLES contexts

Thu Aug 16, 2012 11:27 pm

Does anyone have any code to create a second GLES context?
I'm looking to run two threads sharing texture and shader resources.
I'm basing my demo on hello_triangle 2.


void CreateSecondaryOpenGLContext()
{
static const EGLint context_attributes[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};

EGLContext context = eglCreateContext(GlobalOpenGlState->display,
GlobalOpenGlState->config,
GlobalOpenGlState->context,
context_attributes);

// release surface so that second thread can render
eglMakeCurrent(GlobalOpenGlState->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

// connect the context to the surface
int result = eglMakeCurrent(GlobalOpenGlState->display, GlobalOpenGlState->surface, GlobalOpenGlState->surface, context);
assert(EGL_FALSE != result);
check();
}

The assertion fails. Any thoughts?

User avatar
jackokring
Posts: 818
Joined: Tue Jul 31, 2012 8:27 am
Location: London, UK
Contact: ICQ

Re: Multiple GLES contexts

Thu Aug 16, 2012 11:45 pm

Is this to display something like a rear view mirror view? Is it possible to set a Texture2D in the fragment shader? Is it possible to run two different vertex shaders (transformed views) by if/else?

Cheers Jacko
Pi[NFA]=B256R0USB CL4SD8GB Raspbian Stock.
Pi[Work]=A+256 CL4SD8GB Raspbian Stock.
My favourite constant 1.65056745028

User avatar
jackokring
Posts: 818
Joined: Tue Jul 31, 2012 8:27 am
Location: London, UK
Contact: ICQ

Re: Multiple GLES contexts

Fri Aug 17, 2012 2:09 am

Something like the following untested fragment shader outline. The vertex shader also needs to if/else on mainRender.

Code: Select all

vec4 otherRender[size];

if(mainRender == 1) {
  mainColor = (mirrorIn) ? mirrorRender[[gl_FragCoord.x*scaleX + gl_FragCoord.y * width*scaleY] : mainCalcColor;
  gl_FragColor = mainColor;
  otherRender[gl_FragCoord.x + gl_FragCoord.y * width] = mainColor;
} else /* mirror render */ {
  gl_FragColor = otherRender[gl_FragCoord.x + gl_FragCoord.y * width];
  mirrorRender[gl_FragCoord.x + gl_FragCoord.y * width] = mirrorColor;
}
Cheers Jacko
Pi[NFA]=B256R0USB CL4SD8GB Raspbian Stock.
Pi[Work]=A+256 CL4SD8GB Raspbian Stock.
My favourite constant 1.65056745028

blu
Posts: 55
Joined: Tue Jul 17, 2012 9:57 pm

Re: Multiple GLES contexts

Fri Aug 17, 2012 7:38 am

Hi Twinkletoes. As it is not exactly clear from your post: are you trying to create a second context for a second thread to use _concurrently_ with an original context? If so, then I don't know whether that could work (read: most likely not). What might work, though, (and I haven't done anything multi-context on the Pi, so citing from memory here) should work like this:

You have one context. To make it usable in another thread, you unbind the context from the original creator thread, by eglMakeCurrent(NO_SURFACE, NO_SURFACE, NO_CONTEXT), then you bind the same context in the second thread, where you do your 2nd-thread work. Once finished, you unbind again from the second thread, so you can bind it back again in the first one. Basically, there's no concurrency, as you notice. Such a use-pattern is mainly useful when you have an asset-feeder thread, which might occasionally 'grab' the context, load some assets, then yield it back to the original rendering thread.

Here's also a khronos.org thread you might find useful: http://www.khronos.org/message_boards/v ... f=4&t=1328

Twinkletoes
Posts: 210
Joined: Fri May 25, 2012 9:44 pm

Re: Multiple GLES contexts

Fri Aug 17, 2012 8:06 am

Yes I want concurrency. My textures are large (8-16MB), so I want one thread to load them without stalling the render context. Once they're loaded then they'll be used by the second thread, which has carried on rendering with the old textures in the mean time.

Can't see the point of sharing a single context between threads - if one can only use it when the other is blocked, why have multiple threads?

blu
Posts: 55
Joined: Tue Jul 17, 2012 9:57 pm

Re: Multiple GLES contexts

Fri Aug 17, 2012 8:23 am

Twinkletoes wrote:Yes I want concurrency. My textures are large (8-16MB), so I want one thread to load them without stalling the render context. Once they're loaded then they'll be used by the second thread, which has carried on rendering with the old textures in the mean time.

Can't see the point of sharing a single context between threads - if one can only use it when the other is blocked, why have multiple threads?
Your use-case is exactly what I meant with the one-context scenario above. Behold:

Render thread:
1. grabs context
2. sets state
3. emits draw calls & flushes
4. yields context

Asset thread:
1. loads/generates/processes raw assets
2. grabs context
3. uploads assets to context
4. yields context

Now, assuming the main workload for Render thread is in steps 2 and 3 (after which the actual GPU work starts), while the main workload for Asset thread is in step 1, voila - you get concurrency with one context.

User avatar
jackokring
Posts: 818
Joined: Tue Jul 31, 2012 8:27 am
Location: London, UK
Contact: ICQ

Re: Multiple GLES contexts

Fri Aug 17, 2012 8:44 am

blu wrote:
Twinkletoes wrote:Yes I want concurrency. My textures are large (8-16MB), so I want one thread to load them without stalling the render context. Once they're loaded then they'll be used by the second thread, which has carried on rendering with the old textures in the mean time.

Can't see the point of sharing a single context between threads - if one can only use it when the other is blocked, why have multiple threads?
Your use-case is exactly what I meant with the one-context scenario above. Behold:
Render thread:
1. grabs context
1a. check que and pass in object if one queued
2. sets state
3. emits draw calls & flushes
4. loop to 1a

Asset thread:
1. loads/generates/processes raw assets
2. nothing to do here
3. que asset for render
4. loop to 2

Is also possible.
Pi[NFA]=B256R0USB CL4SD8GB Raspbian Stock.
Pi[Work]=A+256 CL4SD8GB Raspbian Stock.
My favourite constant 1.65056745028

Return to “OpenGLES”