# Frame limiting

**URL:** <https://discourse.glfw.org/t/frame-limiting/70>\
**Category:** support\
**Created:** [June 10, 2014, 10:23pm UTC](https://discourse.glfw.org/t/frame-limiting/70 "2014-06-10T22:23:14Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/glfw/original/1X/b8cdefe6b61b8d5aee6c43b2c56e9cf5eabecfe4.svg) [@system](https://discourse.glfw.org/u/system)\
**Post date:** [June 10, 2014, 10:23pm UTC](https://discourse.glfw.org/t/frame-limiting/70/1 "2014-06-10T22:23:14Z")

</div>

**[iamwhosiam](https://sourceforge.net/u/iamwhosiam/)** wrote on [Tuesday, June 10, 2014](https://sourceforge.net/p/glfw/discussion/247562/thread/c397f144/#b5f4):

i don’t know where else to go with this question, but this following code successfully locked the frame rate in sdl.

when i ported it to glfw it no longer works. the frame rate it locks too is seemingly random. could someone pretty please take a look at this snippet and help me out?

```
double wait_time = 1.0 / (targetFrameRate);

if(glfwGetTime() - frame_start < wait_time)
{
    double dur = (wait_time - (glfwGetTime() - frame_start));
    Sleep((DWORD)(dur * 1000.0 + 0.5));
}

frame_start = glfwGetTime();

```

any help is much appreciated 🙂

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/glfw/original/1X/b8cdefe6b61b8d5aee6c43b2c56e9cf5eabecfe4.svg) [@system](https://discourse.glfw.org/u/system)\
**Post date:** [June 11, 2014, 3:05pm UTC](https://discourse.glfw.org/t/frame-limiting/70/2 "2014-06-11T15:05:21Z")

</div>

**[dougbinks](https://sourceforge.net/u/dougbinks/)** wrote on [Wednesday, June 11, 2014](https://sourceforge.net/p/glfw/discussion/247562/thread/c397f144/#abaa):

Where are you calling glfwSwapBuffers()? You should do this before you measure the frame\_start time, otherwise you’re not taking into account the actual rendering time.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/glfw/original/1X/b8cdefe6b61b8d5aee6c43b2c56e9cf5eabecfe4.svg) [@system](https://discourse.glfw.org/u/system)\
**Post date:** [June 11, 2014, 6:09pm UTC](https://discourse.glfw.org/t/frame-limiting/70/3 "2014-06-11T18:09:25Z")

</div>

**[arampl](https://sourceforge.net/u/arampl/)** wrote on [Wednesday, June 11, 2014](https://sourceforge.net/p/glfw/discussion/247562/thread/c397f144/#9510):

i’m not using sleep function:

```auto
void renderfps(int framerate) 
{ 
	currentTime = glfwGetTime(); 

	if(currentTime - lastTime >= 1.0 / framerate) 
	{
		lastTime = currentTime;
		render(); 
	}
}

```

currentTime, lastTime - doubles  
render() is my rendering function with glfwSwapBuffers()

renderfps(60) - 60 fps, called in the main loop

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/glfw/original/1X/b8cdefe6b61b8d5aee6c43b2c56e9cf5eabecfe4.svg) [@system](https://discourse.glfw.org/u/system)\
**Post date:** [June 18, 2014, 1:05am UTC](https://discourse.glfw.org/t/frame-limiting/70/4 "2014-06-18T01:05:58Z")

</div>

**[iamwhosiam](https://sourceforge.net/u/iamwhosiam/)** wrote on [Wednesday, June 18, 2014](https://sourceforge.net/p/glfw/discussion/247562/thread/c397f144/#2060):

arampl: i tried this technique and it worked but since the process never sleeps it takes up too much cpu and i dont want my game to be a hog 😉

doug binks: here’s my main loop, i took out the non-relevant bits and i think the functions are pretty self explanatory.

while( !glfwWindowShouldClose(window) )  
{  
tw\_time\_frame\_start(); // get the start time  
handle\_events();  
update\_func();

```
setup_2d_proj();

draw_func();

glfwSwapBuffers(window);

tw_time_update(); // actual sleep code is in here
tw_input_update();

```

}

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/glfw/original/1X/b8cdefe6b61b8d5aee6c43b2c56e9cf5eabecfe4.svg) [@system](https://discourse.glfw.org/u/system)\
**Post date:** [June 18, 2014, 11:26am UTC](https://discourse.glfw.org/t/frame-limiting/70/5 "2014-06-18T11:26:07Z")

</div>

**[dougbinks](https://sourceforge.net/u/dougbinks/)** wrote on [Wednesday, June 18, 2014](https://sourceforge.net/p/glfw/discussion/247562/thread/c397f144/#f3df):

@iamwhosiam: At brief glance the code seems reasonable, but this is hard to tell without all the code. I’d advise trying to create a small test app, and if that has problems you could share it with me and I could help debug it.

I would try a few changes.

Make sure you time the entire loop, so the start time should be measured after the tw\_time\_update(). This way if you have any time being taken up inside tw\_input\_update this is being accounted for.

Write your code for easy debugging, and make sure you don’t pass 0 to Sleep. Example below:

```auto
double wait_time = 1.0 / (targetFrameRate);
double curr_frame_time = glfwGetTime() - frame_start;
double dur = 1000.0 * ( wait_time - curr_frame_time ) + 0.5;
DWORD durDW = (DWORD)dur;
if( durDW > 0 ) // ensures that we don't have a dur > 0.0 which converts to a durDW of 0.
{
    Sleep( durDW );
}

double frame_end = glfwGetTime();
// here you could print to file or OutputDebugStream curr_frame_time, frame_end - frame_start and dur.
frame_start = frame_end;

```

Note that there is no guarantee that Sleep will return exactly on the time you require. It’s possible your odd frame times were due to passing in a 0 value to Sleep, which causes the thread to give up it’s time slice.

```auto

```

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/glfw/original/1X/b8cdefe6b61b8d5aee6c43b2c56e9cf5eabecfe4.svg) [@system](https://discourse.glfw.org/u/system)\
**Post date:** [June 18, 2014, 11:31am UTC](https://discourse.glfw.org/t/frame-limiting/70/6 "2014-06-18T11:31:50Z")

</div>

**[dougbinks](https://sourceforge.net/u/dougbinks/)** wrote on [Wednesday, June 18, 2014](https://sourceforge.net/p/glfw/discussion/247562/thread/c397f144/#7610):

Oops - forgot DWORD is unsigned. Make sure to use a signed integer type when converting from double as it’s undefined as to what happens for negative values on cast to unsigned int.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/glfw/original/1X/b8cdefe6b61b8d5aee6c43b2c56e9cf5eabecfe4.svg) [@system](https://discourse.glfw.org/u/system)\
**Post date:** [June 20, 2014, 6:05am UTC](https://discourse.glfw.org/t/frame-limiting/70/7 "2014-06-20T06:05:44Z")

</div>

**[iamwhosiam](https://sourceforge.net/u/iamwhosiam/)** wrote on [Friday, June 20, 2014](https://sourceforge.net/p/glfw/discussion/247562/thread/c397f144/#98ea):

ok i made a test app that just creates a window then just calculates frame rate and sleeps and it’s still doing it.

ive uploaded it to [http://pastebin.com/E1kGThRn](http://pastebin.com/E1kGThRn)

one question i have, is should i be setting the swap interval to zero or maybe one? or just leave it default? having vsync on would be cool but im not sure if it would mess with the frame rate. also some peoples computers might just force it off anyway so, just leave it default and make em both work?

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/glfw/original/1X/b8cdefe6b61b8d5aee6c43b2c56e9cf5eabecfe4.svg) [@system](https://discourse.glfw.org/u/system)\
**Post date:** [June 20, 2014, 10:32am UTC](https://discourse.glfw.org/t/frame-limiting/70/8 "2014-06-20T10:32:59Z")

</div>

**[dougbinks](https://sourceforge.net/u/dougbinks/)** wrote on [Friday, June 20, 2014](https://sourceforge.net/p/glfw/discussion/247562/thread/c397f144/#a5c9):

This code works for - I can change the target\_frame\_rate and never get more, though can get less obviously.

Note that glfwSetWindowTitle can be expensive, so I moved this into calc\_frame\_rate inside the if(elapsed\>1) so as to change the title only once per second.

Preferably you should use something like FRAPS or gDEBugger to check frame rate, and this shows a nice solid flat FPS graph for me.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/glfw/original/1X/b8cdefe6b61b8d5aee6c43b2c56e9cf5eabecfe4.svg) [@system](https://discourse.glfw.org/u/system)\
**Post date:** [June 20, 2014, 11:21am UTC](https://discourse.glfw.org/t/frame-limiting/70/9 "2014-06-20T11:21:15Z")

</div>

**[iamwhosiam](https://sourceforge.net/u/iamwhosiam/)** wrote on [Friday, June 20, 2014](https://sourceforge.net/p/glfw/discussion/247562/thread/c397f144/#1acf):

ok, thank u very much for your time 🙂

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/glfw/original/1X/b8cdefe6b61b8d5aee6c43b2c56e9cf5eabecfe4.svg) [@system](https://discourse.glfw.org/u/system)\
**Post date:** [June 20, 2014, 12:10pm UTC](https://discourse.glfw.org/t/frame-limiting/70/10 "2014-06-20T12:10:35Z")

</div>

**[dougbinks](https://sourceforge.net/u/dougbinks/)** wrote on [Friday, June 20, 2014](https://sourceforge.net/p/glfw/discussion/247562/thread/c397f144/#524f):

On the question of vsync, I would make that user configurable. I prefer having it on, but some don’t. Also note the documentation on glfwSwapInterval and negative swap intervals which can work well.

Note on Windows the \_GLFW\_USE\_DWM\_SWAP\_INTERVAL definition (requires a recompile of glfw) controls whether to ignore swap interval settings when the DWM compositing is on, and as you say many drivers can override the application settings.
