Strange framerate drop

Hi!
I’ve decided to give this GUI-lib a try, and my initial impression is good!
I am having an issue though, and maybe someone here can explain why (I am looking at you @t0neg0d =P).

The code I’m using is copied straight from the forum documentation topic.

The first window that appears is fine, and after the framerate stabilizes I get ~1700 fps. After clicking the button and making another window appear then the framerate drops to about ~170 fps and stays there. Adding more windows after the initial drop is cheap though.

1 window, ~1700 fps
2 windows, ~170 fps
36 windows, ~120 fps

Why that big initial fps drop?

[java]
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.math.Vector2f;
import com.jme3.system.AppSettings;
import tonegod.gui.controls.buttons.ButtonAdapter;
import tonegod.gui.controls.windows.Window;
import tonegod.gui.core.Screen;

/**

  • test
  • @author kwando
    */
    public class Main extends SimpleApplication {

public static void main(String[] args) {
Main app = new Main();
AppSettings settings = new AppSettings(true);
settings.setResolution(1280, 720);
app.setSettings(settings);
app.setShowSettings(false);
app.start();
}
public int winCount = 0;
private Screen screen;

@Override
public void simpleInitApp() {
flyCam.setDragToRotate(true);
inputManager.setCursorVisible(true);

screen = new Screen(this, "tonegod/gui/style/def/style_map.xml");
screen.initialize();
guiNode.addControl(screen);

// Add window
Window win = new Window(screen, "win", new Vector2f(15, 15));

// create button and add to window
ButtonAdapter makeWindow = new ButtonAdapter(screen, "Btn1", new Vector2f(15, 55)) {
  @Override
  public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
    createNewWindow("New Window " + winCount);
  }
};

// Add it to out initial window
win.addChild(makeWindow);

// Add window to the screen
screen.addElement(win);
//*/

}

public final void createNewWindow(String someWindowTitle) {
Window nWin = new Window(screen, “Window” + winCount, new Vector2f((screen.getWidth() / 2) - 175, (screen.getHeight() / 2) - 100));
nWin.setWindowTitle(someWindowTitle);
screen.addElement(nWin);
winCount++;
}
}
[/java]

Hum, i haven’t this problem…with the same code… i lose ~150 fps per window. at the beginning 1 window…a bit more 5600 fps…With 17 windows the fps is stable around 2900 fps…no drastic fps drop :s

“One fps” is not an absolute value. 1/1700th is much less than 1/120th @kwando :slight_smile: One frame less at 100fps is like 10 frames less at 1000 fps. Also generally the “wait times” might be due to different things, e.g. copying the material info to the GPU for the first time takes much longer than any other computation. After that the material has been copied any added windows don’t add that overhead anymore.
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless theres emotes that hint otherwise or there’s an increased use of exclamation marks and all-capital words.

@kwando
These are the results I get running the posted code: (remember, my machine is pretty crappy)

Start = 1270 fps
1 win = 1230 fps
2 win = 1170 fps
3 win = 1130 fps
4 wins = 1090 fps
5+ wins and the change gets to be minimal per window

Running an interface with 188 seperate objects + 2 OSRViewPorts + a third for cursor effects + custom cursors + audio all overlayed on top of the paging system with terrain + grass + trees and I’m still getting 500+ fps (which is amazing for this PoS)

Hmmm… let’s try looking at this a different way.

The first window + button is 3 objects (each the same mesh)… each has 16 vertices and 18 faces
There are a total of 3 textures… until you mouse over the button which would push a fourth down to the GPU.
Another for the button pressed state.

Seriously doubting this is it… so, how about hardware…

What’s your system look like?

While I wait for this… I have an idea about how to allow you to adjust the impact the GUI will have on your frame rate. If it works… this will be a very cool thing indeed.

@normen, I well aware that time is the inverse of fps…
one window 0.588 ms, 3.5% of time budget
two windows 5.88 ms, ~35& of time budget
36 windows 8.33ms ~50% of time budget
Where my time budget is (1000/60) ~ 16.7ms (60 fps)

I still think there is something fishy about those numbers… I can do considerably fancier things with the ~5.3ms between window 1 and window 2 than showing some extra quads…

@t0neg0d
I have got a macbook pro, early 2011
2,2 GHz Intel Corei7
16GB 1333MHz DDR3 RAM,
AMD Radeon HD6750M 1GB VRAM
SSD Drive

OSX 1.8.2, java 6, jME3 nightly build.

The GPU is not fanciest in the world… but I can run my deferred renderer with 255 objects + 255 lights, 2x FXAA + Bloom at around 90 fps (11ms)…

Just let me know if there is anything you want me to try =)

Its most probably the copying over the PCI bus / opengl communication. This is a common pitfall for jme developers with beefy machines or with data derived from nonrealistic test scenarios (where the bus is not occupied with other things). This is then also dependent on the lwjgl and java implementations per platform. For example mythruna performed terrible on mac in the beginning due to this.
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless theres emotes that hint otherwise or there’s an increased use of exclamation marks and all-capital words.

@normen, so this is not an issue then? And there is nothing that can be done about it? Should I try using the GUI over a loaded scene?
I might have stumbled upon something I really do not understand about the bus communication here, but cannot see how a few streamed quads should take 5.88ms to render. =S
Do you have any keywords I can search for to learn more about this topic?

@kwando said: @normen, so this is not an issue then? And there is nothing that can be done about it? Should I try using the GUI over a loaded scene? I might have stumbled upon something I really do not understand about the bus communication here, but cannot see how a few streamed quads should take 5.88ms to render. =S Do you have any keywords I can search for to learn more about this topic?

If you want to know exactly where the time goes, theres profilers for that. If it just “disappears” in the render() method then its most probably something like what I say. Accessing and dealing with hardware is always causing interrupts and doesn’t work as fast as just doing computations on memory by the CPU, once process is magnitudes above thousands of loop iterations. In the case of hard disks this should be obvious for example :slight_smile:
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless theres emotes that hint otherwise or there’s an increased use of exclamation marks and all-capital words.

If you change the order that the windows are created does it change the order of the relative FPS drops?

Interesting… @kwando Can you try not setting the window title. The big difference between the two windows is the BitmapText.

If you notice a significant different, try running this… it will help narrow down if the problem is what I think it may be:

[java]
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.system.AppSettings;

public class TestCam extends SimpleApplication {

public static void main(String[] args) {
TestCam app = new TestCam();
AppSettings settings = new AppSettings(true);
settings.setResolution(800, 600);
app.setSettings(settings);
app.setShowSettings(false);
app.start();
}

float currentTime = 0;
float pauseTime = .25f;
float nextWidth = 5;
float widthInc = 150;
float nextHeight = 5;
float heightInc = 40;
boolean isActive = true;

@Override
public void simpleInitApp() {
flyCam.setDragToRotate(true);
inputManager.setCursorVisible(true);
}

@Override
public void simpleUpdate(float tpf) {
if (isActive) {
currentTime += tpf;
if (currentTime >= pauseTime) {
BitmapText text = new BitmapText(guiFont);
text.setLocalTranslation(nextWidth, nextHeight, .5f);
text.setText(“This is a test”);
nextHeight += heightInc;
currentTime = 0;
guiNode.attachChild(text);

            if (nextHeight >= this.getGuiViewPort().getCamera().getHeight()) {
                nextWidth += widthInc;
                nextHeight = 5;
		
                if (nextWidth >= this.getGuiViewPort().getCamera().getWidth())
                    isActive = false;
            }
        }
    }
}

}
[/java]

@all, sorry for the late answer. Was AFK the past 24 hours =)

@pspeed, there was no noticeable difference when commenting out line 59 ( //nWin.setWindowTitle(someWindowTitle); )

@t0neg0d, that test case ran as it should I guess… =S I guess BitmapText by itself could be ruled out.

Edit: typo…

@kwando said: @all, sorry for the late answer. Was AFK the past 24 hours =)

@pspeed, there was no noticeable difference when commenting out line 59 ( //nWin.setWindowTitle(someWindowTitle); )

@t0neg0d, that test case ran as it should I guess… =S I guess BitmapText by itself could be ruled out.

Edit: typo…

What happens when you don’t set the window title? Any difference? If so, then it’s the shader and I can fix that! The shader being used to render text in the library is different than the one JME uses.

@t0neg0d, Breaking News!

The problem is not the second window or the text. It is the button that is the problem! If I just hover the button, without clicking it the framerate drops. Something with the pulsating effect maybe?

@kwando
Sounds like it… I think I know how to resolve this issue for an graphic cards that might have this issue. I’ll try and get this patched up tomorrow. Sorry about this… and thank you for being so persistent!!

@t0neg0d no worries, I was was about to apologize for not finding the button issue sooner instead of blaming the second window… rookie mistake by me.

@kwando Hmmm… just had a thought. Do yo know if you have this same issue with shaders that reference g_Time? I think I may need some input from @nehon Maybe he is familiar with this issue. Either way, I’ll set up a test using sin() and g_Time and we’ll see if this is something that can be bypassed.

@t0neg0d, I cannot recall that behavior from past shader experiments I’ve done, but then I was not looking for it so I might have missed it. I can do a quick test on in when I get home.

@t0neg0d not that i recall, could you post the shader code? or point me to it?

@t0neg0d said: @kwando Hmmm... just had a thought. Do yo know if you have this same issue with shaders that reference g_Time? I think I may need some input from @nehon Maybe he is familiar with this issue. Either way, I'll set up a test using sin() and g_Time and we'll see if this is something that can be bypassed.

g_Time is essentially free. It’s just a float set like any of the other uniform bindings that are set per frame. What you do with g_Time may not be free.