Archived

This topic is now archived and is closed to further replies.

TrIaD

Trouble with threads and Windows Timers

Recommended Posts

Two questions: two APIs First: I wrote a Win32 application using Windows API (as opposed to MFC), and it''s using a timer to call the render function. No matter what I do (even turning all drawing off!) it runs at about 17 fps on my 400mhz PC. On a different PC (I think 133mhz or something similar) it gets 100 fps (before you get jealous, it only draws what changes, and it''s 2D... so most "frames" aren''t actually drawing anything). I''ve determined that the problem is with the timer: I have it set to fire at 10ms intervals (and I''ve tried less with the same results), but it isn''t. Putting "DoRender()" in the timer four times jacked the fps up to 90. Does anyone know why that would happen? Second: To fix the above problem, I''m trying to convert it over to multithreading, but GL has ceased rendering. I''ve clocked it (bu breaking it on the line that calculates FPS) at about 90 fps again. The code runs, but GL isn''t rendering. I''m thinking the problem is that when I switched over, I still create my RC and texture objects in the main thread. Anyone know if there''s a way to do this that doesn''t require moving everything to the render thread? What needs to be in the same thread for drawing to work properly? --Tr][aD--

Share this post


Link to post
Share on other sites
Using threads and timers calls for performance loss. When you are using the "idle processing", you use the time windows isn''t doing anything, and use set CPU usage to 100%. Have you tried this before?

    
//---------------------------------------------------------------------------

LRESULT CEngine::EnterMessageLoop()
{
// Message loop

MSG msg;
while (1)
{ while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == FALSE)
{
static float fTimeSave = 0;
float fTime = (float)GetTickCount() * 0.001f;
Animate(fTime - fTimeSave);
fTimeSave = fTime;

Draw();
}
if (GetMessage(&msg, NULL, 0, 0) != TRUE) break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//---------------------------------------------------------------------------


Share this post


Link to post
Share on other sites
actooly, no...
and I'd be impressed except for a few things...

a: I'd need that in C, not C++
b: when I tried it, my framerate dropped to a pathetic 6, and the other stuff ran very sporadically, and very slow

thing with threads, tho, is you can get better (smoother) performance if the actual game stuff runs really slow

so I'd still like an answer on what has to be done in/out of a thread to get GL to work, if anyone knows...

--Tr][aD--

Edited by - TrIaD on October 31, 2000 10:08:59 PM

Share this post


Link to post
Share on other sites
I don''t know all the details, but if I''m not mistaken, a second thread can''t draw on a seperate threads window. It needs to send the first thread a message to tell it to blit.

Using MFC & a seperate render thread caused a ~4fps loss over the balls-out win32 version. From ~29fps to ~25fps; 30,000 poly''s K6-3 450MHz, TNT. It runs too fast to time on my Athelon 600 & TNT2 (over 100fps).


And using a timer is not a good way to render, as you discovered

Share this post


Link to post
Share on other sites
(a follow-up, a day later, when it works... if anyone''s still reading, that is...)

Well, I got the stuff working today... apparently GL can only draw to a rendering context that was created in the same process... why this is, I have no clue...

I got the thread working, only to discover my 100 fps was still gone... somehow, I messed up the "only-draw-changes" code, thoguh in retrospect I don''t know how it ever worked in the first place...

A different post mentioned being in a critical section for as little time possible: this is true. The new code (which works) copies the large block of shared data with a single memcpy, then leaves the CS. I maintain two copies of the screen buffer (4880 bytes... it draws 2D tiles from an array and nothing else), and "old" and "current", and test them against each other to decide if I have to draw... then copy "current" to "old" when the draw is done.

Works great... sortof. It gets a riddiculous +2000 fps (yes, you read that right!), but eats timeslices like no tommorrow (see the post "Threads and Win32"). I fixed this with a simple sleep(5); in the render loop.

The moral: fast is good, but not too fast... don''t let a thread run away with your timeslices.

I''d also like to disagree with the alledged framerate drop using a thread. The thread gets slightly HIGHER framerates than the nonthreaded version.

--Tr][aD--

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
i am this weekend struggling with opengl, threads, and win32. i''ll tell you what i discovered.

in my case, it''s really important to have a responsive win32
user interface, no matter how slow the rendering gets. so putting the render code in the getmessage loop wasn''t an option for me. i moved all my rendering code into a new thread.

of course the opengl context needed to be made from within the new thread. but i soon discovered that this was not enough.

win98 was freezing every few minutes. i needed to cold boot every time. the opengl thread had its own context, but was sharing a window with the main thread.

i tried putting a mutex around all attempts to draw to the window, but that didn''t help.

i had to go so far as to give opengl its own window, created from inside its own thread. the main app window is the parent of the new window. soon win98 stopped freezing and everything seems to work now.

phew.

bryan

Share this post


Link to post
Share on other sites
I don''t know about having to create a window from scratch...

First off: I have no clue what a mutex is, personally, but other ppl that do say "don''t use them." Use a CRITICAL_SECTION instead.

Second: how are you using them? You don''t put CS''s around your drawing, you put them around anything accessing the same variables cross-thread (which has to happen to have a multithreaded app, duh). If you''re simultaneously reading/writing the same variable(s), this may be your problem.

I think I remember having similar problems, but I don''t any more...

--Tr][aD--

Share this post


Link to post
Share on other sites