Advertisement

[win32] Slow callback rutines

Started by June 20, 2001 08:21 AM
1 comment, last by ZubZorro 23 years, 7 months ago
Hey. i''ve been trying to setup my windows callback function in a class, and i have some problems with it. It seems to work fine, but it is awfully slow.. i mean, so slow, that you can be sure there is some error in the code somewhere... and I''ve been trying to locate the error without any luck.. hoping there is someone who can point it out for me. i have a class Engine, in which i want to encapsulate the callback function. I have done it the easy way, by making an intermediary global function. also, i have only one Engine object that is global too:

Engine* engine

//intermediary rutine to handle windows callback
LRESULT CALLBACK wndCallback( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ){
	return engine->callback( hWnd, uMsg, wParam, lParam );
}
 
Now, i have tried to kind''s of message loop, first i tried the non-locking which nehe talks about, where we redraw if there is no new message. I figured this could be the cause of my slow-down, but when i tried it the other way around( with GetMessage ), performace was just as awful. Here is both of my callback functions, with all but the loops themself cut out: PeekMessage:

	while( !done ){
		if( PeekMessage( &msg, hWnd, 0, 0, PM_REMOVE ) ){
			if( msg.message == WM_QUIT )
				done = true;
			else{
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
		}else{
			QueryPerformanceCounter( &now );
			delta = ( (float)now.QuadPart / ticksPerSec );			
			prev = now;
			
			//ENGINE STUFF START
			renderer->render();
			//ENGINE STUFF END

			SwapBuffers( hDC );
		}

	}

 
GetMessage version:

	while( GetMessage( &msg, hWnd, 0, 0) ){
		if( msg.message == WM_QUIT ){
			return 0;
		}
		QueryPerformanceCounter( &now );
		delta = ( (float)now.QuadPart / ticksPerSec );			
		prev = now;
		TranslateMessage( &msg );
		DispatchMessage( &msg );

		renderer->render();
		SwapBuffers( hDC );
	}
 
And finally the callback inside my Engine class


LRESULT Engine::callback( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ){
	switch( uMsg ){
	case WM_CLOSE:							
		PostQuitMessage(0);				
		return 0;
	}
	return DefWindowProc( hWnd, uMsg, wParam, lParam );

}
 
Jonas Meyer Rasmussen meyer@diku.dk
Jonas Meyer Rasmussenmeyer@diku.dk
Hi!
Always use PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) and GetMessage(&msg, NULL, 0, 0) instead of PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE) and GetMessage(&msg, hWnd, 0, 0). When you pass the hWnd parameter you tell the function only to retrieve messages posted to the window''s message queue. That way you will not get the WM_QUIT message because that message is posted in the current threads message queue and not the current window''s message queue. When you pass NULL instead of hWnd you tell the function that you want to retrieve messages from both the window''s and the threads message queue.
I dont know which part of you code makes the application run so slow but try to use the profiler to see what function is the slow one.

- René

Real programmers don't document, if it was hard to write it should be hard to understand

Advertisement
Just a guess - check if you handle WM_PAINT. In your WNDPROC you should have something like:
  case WM_PAINT:    ::ValidateRect(hWnd, NULL);    return 0;  

Or you can call Begin/EndPaint, but ValidateRect is faster. If you don''t validate the window on WM_PAINT Windows will keep sending it to you effectively using up all the CPU time.

Another note: GetMessage blocks, i.e. it will not return until it can retrieve a message from the message queue. So, if your message queue is empty - you game is not running, it''s just sitting inside GetMessage and waiting. This might help:
  // the game loopMSG msg;for(;;){    // check if there are any messages on the queue    while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))    {        // get it from the queue        if(0 == ::GetMessage(&msg, NULL, 0, 0))            return msg.wParam;        ::TranslateMessage(&msg);        ::DispatchMessage(&msg);    }    // actual game code here}  

This topic is closed to new replies.

Advertisement