Clock-Mode "Forced": Delta-Time of 0?

I’m attempting to test something in a project, I set the clock-mode to “forced” and the frame-rate to “15”–and indeed, in-game the frame-rate meter reports a frame-rate of 15.

However, when I attempt to move around, I find myself stuck in place–because, as it turns out, “[base].clock.getDt()” is returning “0”!

And indeed, this holds even if I set a higher frame-rate (such as 30 or 100).

Is this expected?

Conversely, it looks like “limited” mode produced the expected delta-time, so at the least I am able to move forward with my testing. Still, this is an unexpected result, and one that seems worth raising.

I have also observed this before, but I have not thought about it. Maybe this is due to the use of base.setSleep(), it’s just a theory that came to my mind.

If you mean on my part, then I’m pretty sure that I’ve not called that method.

Maybe this post can help you.

https://discourse.panda3d.org/t/noticeable-stutter/4646

regards

Thank you. :slight_smile:

However, based on a quick look, I’m not clear on how it applies: It doesn’t appear to be discussing the behaviour of the “forced” clock-mode.

I think the problem is not in the forced clock mode, perhaps when you do not use frame synchronization, it’s just that the OS services your applications more often and sets an increased priority. Thus, the forced clock mode is just a setting of the rendering frequency.

I think this post is about that.

Hmm… I’m not entirely confident that I follow, but as best I understand, I don’t think that it’s so.

If it were so, why would I consistently get zero delta-times out of the global clock-object? Setting rendering frequency shouldn’t affect the delta-time of the clock, I would think.

And, as noted above, using the “limited” clock-mode seems to work as expected: I get an artificially low frame-rate, with delta-times as appropriate.

The bottom line is that when your application is resting between frames, the OS steals the processor time from the application. This appoints it skips loop, hence the loss of time.

Ah, I see what you’re saying, I believe.

However, I would expect the “limited” mode to do much the same–it can also artificially reduce a program’s frame-rate, after all–and thus if that were the problem I’d expect to see the same behaviour in “limited” mode.

I suspect that we are facing this because of the use of two python and C++ threads. The right solution would be to test the minimal application entirely in C++.

I have already encountered a situation where the method of checking the mouse in the window sometimes fails. But I did not conduct an experiment on the C++ side, I think this weekend we need to test the theory.

It could be so–that I don’t know!

Fair enough! I’m not really set up for C++ testing right now, but if you want to do it then that might be useful!

This example shows how the frame time changes depending on the frequency.

from panda3d.core import (GraphicsEngine, GraphicsPipeSelection, FrameBufferProperties,
WindowProperties, ClockObject)

engine = GraphicsEngine.get_global_ptr()
pipe = GraphicsPipeSelection.get_global_ptr().make_module_pipe("pandagl")

global_clock = ClockObject.get_global_clock()
global_clock.set_mode(ClockObject.MLimited)
global_clock.set_frame_rate(60)

win_prop = WindowProperties()
win_prop.size = (800, 600)

win = engine.make_output(pipe, "window", sort = 0, fb_prop = FrameBufferProperties(), win_prop = win_prop, flags = 8)

while not win.is_closed():
        print(global_clock.dt)
        engine.render_frame()

Set the frame rate and you will see the difference.

Add: Which is generally correct, since downtime counts towards rendering time.

I note that you’re using the “limited” clock-mode there–which, as I noted, works as expected. The problem occurs when using the “forced” clock-mode.

However, in doing some testing with your program, I discovered something interesting: If I change the mode to “MForced” the program… works just as expected!

If, however, I change the program to set the clock-mode to “forced” via “loadPrcFileData”, the problem once again appears! That is, the program starts printing a value of “0.0” despite the frame-rate being set to “60”.

Here’s the modified code:

from panda3d.core import loadPrcFile, loadPrcFileData

loadPrcFileData("", "clock-mode forced") # Does not work as expected
#loadPrcFileData("", "clock-mode limited") # Works as expected
loadPrcFileData("", "clock-frame-rate 60")

from panda3d.core import (GraphicsEngine, GraphicsPipeSelection, FrameBufferProperties,
WindowProperties, ClockObject)

engine = GraphicsEngine.get_global_ptr()
pipe = GraphicsPipeSelection.get_global_ptr().make_module_pipe("pandagl")

global_clock = ClockObject.get_global_clock()

win_prop = WindowProperties()
win_prop.size = (800, 600)

win = engine.make_output(pipe, "window", sort = 0, fb_prop = FrameBufferProperties(), win_prop = win_prop, flags = 8)

while not win.is_closed():
        print(global_clock.dt)
        engine.render_frame()

So, it seems that the problem occurs specifically if one: (A) Uses the “forced” clock-mode, and (B) does so via a call to “loadPrcFileData”. (Although I haven’t tested other PRC-related approaches, such as setting the value in an actual PRC-file.)

A good investigation, under the hood of panda there are some other manipulations in the PRC. Perhaps some of this is changing in parallel.

client-sleep 0
multi-sleep 0
sync-video 0
yield-timeslice 0

But this is again a theory.

Add: I tested it in C++, the mythology of the problem from individual threads was not confirmed. This is due to the PRC.

1 Like

Fair enough! I’m going to make an issue for this on GitHub, then. Thank you for your investigations! :slight_smile:

[edit] And done!

2 Likes