Page 1 of 1

Performance problem

Posted: Wed Apr 12, 2006 10:17
by olgarry
Hello,

I'm using CEGUI 0.4.1 and OGRE 1.0.7 for my game
I use the release version for both.


My computer :

CPU : AMD Athlon 64 bit 3500+ (2GHz)
RAM : 1 Go
Graphic Cards : ATI Radeon X850XT (last drivers)
OS : Windows XP Pro SP2



And i have a problem whit the GUI of my game.
I use lots of elements in a window and sometimes i need to open a complex window within other complex window. (About 30 - 40 elements per window). So sometimes i can have 120 elements at same time on the screen.

And the FPS decrease quickly either in OpenGL or DirectX9.

When there is just 10 elements shown on the screen my FPS are about 500.
When i have 40 elements it decrease to 425 and 80 elements it decrease to 360.

And when i move cursor on some elements it decrease to 200 sometimes.

200 is very acceptable for now. But the game is not finished and it ll be more complex window and more 3D objects moving in OGRE.

I suppose i decrease under 25 FPS very quickly in my develeppoment.

Are some ways to improve the performance, like disabled any tests on windows objects ?

Thanx to people who read that and help me :)

Posted: Thu Apr 13, 2006 07:09
by gcarlton
Just looking at fps is a terrible measure of timing - alarming initial drops can correspond to very little real cost.

500fps = 2ms
360fps = 2.778ms
25fps = 40ms

So these 80 elements are taking 0.7ms to render. This is perfectly acceptable. You have 37ms left if your target is 25fps.

Posted: Thu Apr 13, 2006 09:40
by olgarry
Ok,

I was alarming because when i compile in Debug mode, i have 1 or 2 fps some time.
But i think you are right.
So i ll continue to develop and repost when i ll have very low fps on release

Posted: Sat Apr 15, 2006 10:06
by olgarry
Hello,

I've finished some more complex windows and test them in release mode.

The drop to 4 or 2 at only one moment :(.

When i select OpenGL in the OGRE setup and when the more complex window is open and the cursor move over some radiobutton (so it display their hover normal or hover selected image).

When i use DirectX9 in OGRE setup there is no problem at all and when i use OpenGL there is no problem too until i open this complex window.

I don't understand why this happen in OpenGL and not in DirectX.

Can someone try to help me ?

Posted: Wed Apr 19, 2006 07:57
by olgarry
Don't take care of my last post.

I don't know what i did but it doesn't work either with OpenGL or DirectX.

I don't know why it's so slow when i pass cursor on some radio buttons.

Help would be welcome :/

Posted: Thu Apr 20, 2006 10:16
by olgarry
Hello,

After hours of research i found that my problems was the class buttonbase.
In the UpdateInternalState function, the method getChildAtPosition() is launch on the Root Sheet. And it s launched each time the mouse move.

This is one part of the lag i have when i pass the cursor on some button of complex window containing lots of objects. Because getChildAtPosition make a test of intersection with all elements.

So i change a bit the function updateInternalState in the CEGUIButtonBase.cpp file.

I changed this :

Code: Select all

Window* sheet = System::getSingleton().getGUISheet();

      if (sheet != NULL)
      {
         // check if hovering highlight is required, which is basically ("mouse over widget" XOR "widget pushed").
         if ((this == sheet->getChildAtPosition(mouse_pos)) != d_pushed)
         {
            d_hovering = true;
         }

      }


by this :

Code: Select all

// check if hovering highlight is required, which is basically ("mouse over widget" XOR "widget pushed").
      if ((this->isHit(mouse_pos)) != d_pushed)
      {
         d_hovering = true;
      }


And it works fine. Button continue too work and there is less lag when passing cursor over buttons.
There is still some lag and i ll continue my investigation later.

Posted: Tue Apr 25, 2006 16:05
by lindquist
Thanx for the heads up. This should definitely be fixed somehow, tho the isHit approach is'nt completely "safe". isHit is not affected by overlapping windows so it might not always return the right value.

I think we can use System::getWindowContainingMouse instead, but I'll need to take a look.

thanx again.

Posted: Wed Apr 26, 2006 08:23
by olgarry
Thanx.

For now it works great for my project. But as you say i'm sure that it's not the best solution. When i have time i'll test your suggestion with System::getWindowContainingMouse.

If i find other optimisations i'll suggest them on the forum.

Thanx a lot to all CEGUI Team for their works and all people who help this project ^^

Posted: Wed May 10, 2006 15:33
by lindquist
I had a closer look at this issue last night, and it seems the solution is'nt that simple.

the isHit approach you took work pretty well, but like I expected it does'nt handle overlapping correctly.

getWindowContainingMouse is'nt an option either as it really is'nt returning the window that is containing the mouse, but rather the window that is receiving mouse event. It is affected by input capture and modal state.

In debug mode it's very clear getChildAtPosition is an expensive operation when performed on the sheet, but I'm not sure how it can be avoided as it's the only correct way of determining the picked window when zorder matters.

What I'm thinking is that this operation could be performed once in System :: injectMouseMove, and a new member could be added. Like getWindowPickedByMouse. It seems that 99% of the calls to getChildAtPosition are passed the mouse cursor position. I'll investigate more.

If I cant come up with a nice way of fixing this I'll leave it for now and address it in a later release. It may need some refactoring of the way mouse input is handled in general.

If anyone has good ideas for how to solve this efficiently, let me know.

Posted: Wed May 10, 2006 19:44
by olgarry
I'm afraid i haven't time to look for this issue :oops: . For our project isHit works and i can't spend time for this. I hope you ll find a solution and i thanx you for look at that.

After this project i ll have more time for help to CEGUI :)

Posted: Tue May 16, 2006 02:28
by lindquist
This issue has really stuck to my mind.
I'm thinking about how it can be solved, and I'm currently considering implementing a dynamic quad tree to do some "spatial partitioning" of the screen space, and the windows that occupy it.

Any thoughts are welcome...

Posted: Tue May 16, 2006 19:19
by Sneftel
It seems that a simple solution would be to cache the getChildAtPosition result at the mouse pointer. The common case is the mouse moving around in the same window, and for windows which care about hovering to be unoccluded, so it could be optimized for that: When the mouse pointer is over an unoccluded window, check it directly next frame.

Alternatively, at each level of the window hierarchy, cache the last branch taken in getChildAtPosition and check it first. That optimizes for moving around different controls in a single FrameWindow, though for large numbers a quadtree might be a good idea.