0

I am new to Direct2D and recently I've found a wierd problem. When external power supply is plugged, my program runs at a steady FPS of 60, which I know may be a result of VSync; but after unplugging the external power supply for a while, my program drops to a steady FPS of 30 (I outputed the time interval between every two renderings and it shows 32ms).

And even if I plugged the power supply again, it still remains at 30 FPS until I reboot the computer.

Is it because my laptop shut down something when powered by battery which cuts the FPS to its half? If true, what can I do for it?

My laptop's OS is Windows 8.1.

Here are some code that may be helpful.

HRESULT hr = S_OK;

if (!m_pRenderTarget)
{
    RECT rc;
    GetClientRect(m_hwnd, &rc);

    D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);

    D2D1_HWND_RENDER_TARGET_PROPERTIES render_target_properties = D2D1::HwndRenderTargetProperties(m_hwnd, size);

    //render_target_properties.presentOptions = D2D1_PRESENT_OPTIONS_IMMEDIATELY;
    //↑ Tried this and it doesn't work, don't know why

    // Create a Direct2D render target.
    hr = m_pDirect2dFactory->CreateHwndRenderTarget(
        D2D1::RenderTargetProperties(),
        render_target_properties,
        &m_pRenderTarget
        );

}

return hr;

The mainloop looks like this:

while(msg.message!=WM_QUIT)
{
    if(PeekMessage(&msg,0,0,0,PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    now_time = timeGetTime();
    if(now_time - last_time >= 1000/MAX_FPS)
    {
        OutputDebugPrintf("%lf\n", now_time - last_time);
        application->Update(now_time - last_time);
        application->OnRender();
        last_time = now_time;

    }
}

I'm sure it takes little time in Update() and it can run at a steady frame rate of 60, so there seems to be no problem in OnRender().

Thank you!

DarkZero
  • 2,259
  • 3
  • 25
  • 36

2 Answers2

0

I wasn't aware of this myself but you already guessed right: many (all?) laptops drop their refresh rate when running on battery. See google. And if vsync runs slower, so will your loop. There appear to be solutions to disable this, depending on your hardware (e.g. for Intel).

Mike Versteeg
  • 1,615
  • 14
  • 28
  • Thank you for your response, but isn't 32ms too long a refresh interval? I did not see my screen flashes when on battery, though my application flashed obviously. I have no idea about this phenomenon. – DarkZero Apr 15 '15 at 04:14
  • I tried running another game(`Osu!`) and it shows that it can run at 120FPS with vsync off under the same condition, so I think to disable vsync may be a solution. I tried using `render_target_properties.presentOptions = D2D1_PRESENT_OPTIONS_IMMEDIATELY;` but it doesn't work. Do you have any idea with this? Thank you! – DarkZero Apr 15 '15 at 08:00
  • PAL tv refreshes every 40 ms (20 per frame, but let's not get into that discussion), so no, it is not too long. And it makes no sense to compute 120 fps if your display won't display them. – Mike Versteeg Apr 16 '15 at 07:48
0

Bit late but your problem has nothing the do with the code i think. Many laptops with an nvidia video card have a system called "Battery Boost". When enabled, your can drag a slider to an fps count. When charging the battery games get vsynced to 60 fps. When not charging games get vsynced to the fps indicated by the slider: enter image description here

With the top-right toggle you can disable this feature. This menu can be found in the nvidia experience program -> settings -> games.

ocdy1001
  • 33
  • 6
  • Thank you for your answer, hope this can be a reference for those who have met the same problem. I no longer work on this game though... – DarkZero Feb 12 '17 at 07:25