ogl main loop displaying linked list but without threads?

Started by
8 comments, last by Toji 17 years, 4 months ago
Ok, so i understood the hard way that ogl doesn't support threads with ogl commands in them. That sucks. The thing is, i need to display a lot messages on screen, and if do that in the main rendering loop, it slows down my fps to much because the linked list is to big. So i decided to fire of a thread instead. I did some research, and i came to my above conclusion (ogl doesn't support threads (well no threads with ogl in them anyway). So how do i fix something like that? Doesn't seem possible to me. I need to walk the list somewhere!
Advertisement
Well, we'd need more info about the program to know for sure what's really going on, but I would hazard guess that simply "walking the list" is not where your slowdown is coming from. You say you're displaying a bunch of messages on-screen? I would first look at optimizing your text rendering routines.

If you're using one of the built-in font generation techniques (ie: wglUseFontBitmaps) that could be slowing you down. Consider Texture Mapped Fonts instead. Other than that, there's some inefficiency in how you're making the render calls themselves. Are you using glBegin/glEnd? If so look into Display lists or VBOs. Finally, from the sounds of it you are probably trying to implement a console of some sort, yes? If so, you probably don't need to redraw the entire thing every frame, because it will only change when new messages are added. Maybe you could try rendering to a texture whenever the text changes and then simply rendering that texture the the screen every time after till the text changes again.

I realize that some of those suggestions simply won't apply to your situation, but as I said: We can't help much more till we know more about what you are doing.
// The user formerly known as Tojiro67445, formerly known as Toji [smile]
I'm using GLUT on MacosX. Glut has some bitmap functions, i use this one:
void renderbitmapfont(GLfloat x, GLfloat y, GLfloat z,GLchar *format,...){	va_list args;	GLchar buffer[200], *p;	va_start(args, format);	vsprintf(buffer, format, args);	va_end(args);		glRasterPos3f(x, y,z);	for (p = buffer; *p; p++)    glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *p); <- GLUT SPECIFIC}


I call this from the main rendering loop:

GLint display_events(GLvoid){	events *tmp=e_head;	GLint x=LINE_INDENT;	GLint y=LINE_SPACING;		set_ortho(width,LINE_INDENT);	while(tmp!=NULL) {	glColor4f(tmp->r,tmp->g,tmp->b,tmp->a);	renderbitmapfont(x,y-=15,0,tmp->event,tmp->timestamp);	tmp=tmp->next;	}	unset_ortho();			}


As you can see, i can't use this stuff in a thread. You're comment about only displaying the stuff that not already has been rendered, although sensible, i don't think that will work because i think my rendering loop will overwrite it, that's why it's actually a bonus for me that it calls the font function so often and so fast. Or maybe i'm just wrong about that assumption (probably). In any case, for every event that i generate, fps is dropping by +- 10. The *tmp pointer is a pointer to the event database.

Thank you for your comments. And yes, it is a console type thingie.
As I recall glutBitmapCharacter() is relatively slow, but it certainly IS easier to use than some methods. Just out of curiosity, though, you said you're dropping ~10 frames? Out of how many? If you're dropping to from, say 40 to 30 then this is probably something to worry about However, if you're dropping from 200 to 190 then it's probably much less of a concern than you would think.

Thanks for posting the code! It helps! I'll see if I can give more in-depth advice after work today...
// The user formerly known as Tojiro67445, formerly known as Toji [smile]
I agree. I know they are slow, but haven't had the need to implement other fonts. Stroke fonts just seem even more slower. About the fps, well, i have about 180-190 fps. When i have the app fullscreen and a screen full off events (on top of the stuff to be drawn ofcourse) it's about 20 fps :-)

Other then that, i try to be sparse about the usage about my frames, because i know i still need them later on (when i start applying textures and stuff). I also tried implementing display list for my app, but it seemed it was 'fill-limited' as i believe they call it (i make the app bigger, it gets slower, i minimize the app a bit, it goes faster). So i wouldn't benefit from that a lot.

Thanks a lot for your comments!
Quote:Original post by 3dnewbie
Ok, so i understood the hard way that ogl doesn't support threads with ogl commands in them. That sucks.


You misunderstood. Opengl does not allow one rendering context to be owned by more than one thread at once. You can change which thread that is during the lifetime of the context.

In any case, it would be nonsensical for more than one thread to use the same OGL context, because they'd need to do a great deal of synchronisation to prevent problems as GL is extremely stateful.

Quote:
The thing is, i need to display a lot messages on screen, and if do that in the main rendering loop, it slows down my fps to much because the linked list is to big.


In which case, you have other problems. Using threads won't help if it's GPU blocked, or if it's CPU-blocked if you only have one CPU.

Moreover, if your linked list "is too big", then probably a redesign is in order.

Relying on specific behaviour of preemptive multitasking is basically a no-no, especially on a PC platform which could in fact be anything.

Quote:
So i decided to fire of a thread instead. I did some research, and i came to my above conclusion (ogl doesn't support threads (well no threads with ogl in them anyway).

So how do i fix something like that? Doesn't seem possible to me. I need to walk the list somewhere!


You need to refactor your code. OpenGL's restriction on one thread per context is perfectly reasonable, and even if it was removed, it wouldn't help you at all, because your threads would have to be effectively serialised so as to not trash each others' state.

Mark
Quote:You misunderstood. Opengl does not allow one rendering context to be owned by more than one thread at once. You can change which thread that is during the lifetime of the context.


Ok. So 'thread' here is basically meaning: The rendering context must be used exclusively by only one calling function.
In any case, i'm still screwed. (_if_ i'm not allowed to make 1 thread (current program excluded, i don't count that as a thread anyway) that is)

Quote:
In any case, it would be nonsensical for more than one thread to use the same OGL context, because they'd need to do a great deal of synchronisation to prevent problems as GL is extremely stateful.


More then one, yes. I'm just firing off a thread so that the main rendering loop does not suffer any slowdowns upon drawing its frames. Nothing wrong with that no? Actually, seems like the only way to get something done without negative impact on the rendering loop.

Quote:In which case, you have other problems. Using threads won't help if it's GPU blocked, or if it's CPU-blocked if you only have one CPU.


Could you explain that please? I'm not sure how i can tell the difference.

Quote:Moreover, if your linked list "is too big", then probably a redesign is in order.

It's not to big, i just said that because it's adversely affecting my fps. That's why i want to offload it by just firing off 1 thread, like a fork, just with all the benefits :-)

Quote:
Relying on specific behaviour of preemptive multitasking is basically a no-no, especially on a PC platform which could in fact be anything.


I don't know what that means. I'm on powerpc btw. I thought intel architectures were pretty much the same (per series)?

Thanks
Quote:
Quote:In which case, you have other problems. Using threads won't help if it's GPU blocked, or if it's CPU-blocked if you only have one CPU.


Could you explain that please? I'm not sure how i can tell the difference.

Quote:Moreover, if your linked list "is too big", then probably a redesign is in order.

It's not to big, i just said that because it's adversely affecting my fps. That's why i want to offload it by just firing off 1 thread, like a fork, just with all the benefits :-)


What he means is that if your bottleneck is on the GPU (fillrate, vertex processing, etc.) then multithreading your app will make no difference. (Actually, it could easily hurt preformance if you're not careful.) Also, you mentioned earlier that your app seems to slow down as you increase the resolution, therefore it's almost certain that your app is currently fillrate limited (on your PC, in any case), and your CPU is likely just spinning it's wheels in the background. All of this is effectivly saying that looping through your linked list is most likely NOT your problem.

Here's a simple test: in your print loop comment out the line that actually does the rendering (renderbitmapfont) leaving the linked list iteration in place. If the application speeds up when you do this then your bottleneck lies in the rendering of your fonts, which is then the first thing you should optimize.

Oh, and to address a previous question: Yes, your text will get overwritten when you redraw your scene, which is why I suggested rendering your text out to a texture first, then redrawing the texture every time, only updating it when the text changes. You'll still be drawing one big quad every frame, but at least it won't have as much impact on the overall speed.

// The user formerly known as Tojiro67445, formerly known as Toji [smile]
Quote:Original post by 3dnewbie
Ok. So 'thread' here is basically meaning: The rendering context must be used exclusively by only one calling function.
In any case, i'm still screwed. (_if_ i'm not allowed to make 1 thread (current program excluded, i don't count that as a thread anyway) that is)


You can create as many threads as you like but only one must make gl calls at once. This makes sense, as it would screw up *anyway* if more than one did.

Every program has one thread; some create more. If you create one extra thread, you now have two (including the original thread which will continue to run after the new one has been created, possibly at the same time if conditions permit).

Quote:More then one, yes. I'm just firing off a thread so that the main rendering loop does not suffer any slowdowns upon drawing its frames. Nothing wrong with that no? Actually, seems like the only way to get something done without negative impact on the rendering loop.


If the rendering loop suffers slowdowns, it's probably because it's doing too much rendering. Unless you're doing heaps of physics calculations inside the rendering loop (which is bad practice), creating extra threads won't help. Reduce the amount of rendering.

Quote:
Quote:
Relying on specific behaviour of preemptive multitasking is basically a no-no, especially on a PC platform which could in fact be anything.


I don't know what that means. I'm on powerpc btw. I thought intel architectures were pretty much the same (per series)?


I meant PC vs console, i.e. any platform which has non-fixed hardware. In this sense, Mac is the same as PC.

Mark
One other thing I just thought of: Since your GPU, for all intents and purpouses, is essentially a special-case CPU any render calls that you make with OGL/DirectX ARE running in a separate thread. So you've already got the multi-threaded functionality you're looking for!
// The user formerly known as Tojiro67445, formerly known as Toji [smile]

This topic is closed to new replies.

Advertisement