0

I've a Problem with my Rendering Loop. During moving object's I see a Little stutter that Looks like eglSwapBuffers swap's same buffer twice. My FPS is constantly between 59 - 60 FPS. The movement takes deltaTime into account at calculate new Position.

What could that be ??? Could double buffering solve this Problem ???

Here is a small Video ( hopefully you'll see what I mean ). http://youtu.be/bQYiqHUzPuI

Here is my Rendering Loop

BOOL CEngine::OnStep()
{
    BOOL    bResult = TRUE;
    UINT32  u32CurrFrameStartTime = GetTime();
    FLOAT32 f32DeltaTime;

    f32DeltaTime = ( u32CurrFrameStartTime - m_u32LastFrameStartTime ) / 1000000000.0f;
    m_u32LastFrameStartTime = u32CurrFrameStartTime;

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    GLERROR();

    if ( m_pScreenBase == NULL )
    {
        if ( eglSwapBuffers( m_pDisplay, m_pSurface ) == EGL_FALSE )
        {
            LogError( "eglSwapBuffers function failed." );
        }

        if ( ( m_pScreenBase = new CStartScreen() ) == NULL )
            LogError( "Can't allocate memory for CStartScreen." );

        m_pScreenBase->Initialize();
    }

    m_pScreenBase->Update( f32DeltaTime );
    m_pScreenBase->Render();

    if ( eglSwapBuffers( m_pDisplay, m_pSurface ) == EGL_FALSE )
    {
        LogError( "eglSwapBuffers function failed." );
    }

    m_i32FramesPerSecond += 1;

    if ( GetTime() - m_u32FPSResetTimer >= 1000000000 )
    {
        LogFPS( "%d", m_i32FramesPerSecond );
        m_i32FramesPerSecond = 0;
        m_u32FPSResetTimer = GetTime();
    }

    // return false when app should be exit
    return bResult;
}

Here is the update function

void CStartScreen::Update( FLOAT32  f32DeltaTime )
{
    for ( INT32 i = 0; i < MAX_SQUARES; i++ )
    {
        m_pSquare[ i ]->IncPosX( ( 400.0f * f32DeltaTime ) );

        if ( m_pSquare[ i ]->GetPosX() >= 800.0f )
        {
            m_pSquare[ i ]->IncPosX( -( 800.0f + m_pSquare[ i ]->GetWidth() ) );
        }
    }
}

If it's needed, I can post my EGL and OpenGL Setup too.

UPDATE 1 :

UINT32 is defined as

typedef unsigned int UINT32;

inline UINT32 GetTime()
{
    timespec    sTime;
    UINT32      u32Return = 0;

    clock_gettime( CLOCK_MONOTONIC, &sTime );
    u32Return = ( sTime.tv_sec * 1000000000LL ) + sTime.tv_nsec;

    return u32Return;
}

And here is the delta time for 1 second

f32DeltaTime : 0.012029
f32DeltaTime : 0.016487
f32DeltaTime : 0.016548
f32DeltaTime : 0.023608
f32DeltaTime : 0.017631
f32DeltaTime : 0.023363
f32DeltaTime : 0.012963
f32DeltaTime : 0.026373
f32DeltaTime : 0.016470
f32DeltaTime : 0.012811
f32DeltaTime : 0.016439
f32DeltaTime : 0.016852
f32DeltaTime : 0.025931
f32DeltaTime : 0.012679
f32DeltaTime : 0.013243
f32DeltaTime : 0.014694
f32DeltaTime : 0.016561
f32DeltaTime : 0.016589
f32DeltaTime : 0.020299
f32DeltaTime : 0.014101
f32DeltaTime : 0.016626
f32DeltaTime : 0.016892
f32DeltaTime : 0.016347
f32DeltaTime : 0.018130
f32DeltaTime : 0.019623
f32DeltaTime : 0.012288
f32DeltaTime : 0.016677
f32DeltaTime : 0.016895
f32DeltaTime : 0.016405
f32DeltaTime : 0.018474
f32DeltaTime : 0.017564
f32DeltaTime : 0.014213
f32DeltaTime : 0.016659
f32DeltaTime : 0.016830
f32DeltaTime : 0.016486
f32DeltaTime : 0.018657
f32DeltaTime : 0.026178
**f32DeltaTime : 0.006349**
f32DeltaTime : 0.014091
f32DeltaTime : 0.016504
f32DeltaTime : 0.016617
f32DeltaTime : 0.024325
f32DeltaTime : 0.013866
f32DeltaTime : 0.015417
f32DeltaTime : 0.014500
f32DeltaTime : 0.016950
f32DeltaTime : 0.016418
f32DeltaTime : 0.018194
f32DeltaTime : 0.016803
f32DeltaTime : 0.017097
f32DeltaTime : 0.013594
f32DeltaTime : 0.016732
f32DeltaTime : 0.016599
f32DeltaTime : 0.017600
f32DeltaTime : 0.021286
f32DeltaTime : 0.012039
f32DeltaTime : 0.016735
f32DeltaTime : 0.017146
f32DeltaTime : 0.020083

Not sure but i think the line " f32DeltaTime : 0.006349 " could be the problem... But why f32DeltaTime is so small in some Frames ??? Does eglSwapBuffers does nothing at this Frame ??? But why ??? Question over question :)

  • Are you sure nothing is resetting `m_pScreenBase` to NULL? – fadden Jun 23 '13 at 16:13
  • Hi, I'm sure, nothing is reseting m_pScreenBase. I'm getting crazy :( What could cause this problem ??? – Hasan Caliskan Jun 23 '13 at 18:22
  • I think the small delta might be expected, coming on the heels of a larger delta. It should average out to .0167 at 60fps; 0.026178 + .006349 == .032527, averaging .0163. – fadden Jun 23 '13 at 23:54
  • Hello Fadden, could that be a VSYNC Problem ??? Did you have an example Native-Activity with EGL and OpenGL. I have no more ideas :(.... – Hasan Caliskan Jun 24 '13 at 21:49
  • You're not running off vsync, exactly. You're running off `eglSwapBuffers()`, which finishes some time after vsync arrives. (vsync wakes surfaceflinger, surfaceflinger acquires the next buffer, eglSwapBuffers returns). So long as eglSwapBuffers finishes before the point where the surface compositor latches the next frame, you're fine; and even if you drop a frame occasionally, your delta-time-based update function should make it appear smooth. Something else to try: set f32DeltaTime = 0.0167 and see how it looks (i.e. take time completely out of the equation). – fadden Jun 24 '13 at 22:24
  • Hi, as you mention I've tried to set f32DeltaTime to a fix value before, but stuttering is still exist. Is there a way to synch eglSwapBuffers with vsync ? That could not be so complicate to move an object smoothly :( – Hasan Caliskan Jun 24 '13 at 23:12

1 Answers1

0

It looks like your time base is in nanoseconds but held in a 32-bit integer. If you're pulling values out of clock_gettime() in your GetTime() function, you'll need both seconds and nanoseconds, and should be holding it in a 64-bit integer. Otherwise time will occasionally leap backward when you compute a delta.

For example, if you're only using tv_nsec:

  • previous frame start time is 0s 900000ns
  • current frame start time is 1s 100000ns

If you just subtract the nanoseconds, you'll get a backward leap of 800000ns, instead of a forward step of 200000ns.

You can check this by logging the f32DeltaTime values to see if they're consistent.

fadden
  • 51,356
  • 5
  • 116
  • 166