setAnimationInterval does nothing on Android


#1

Hi All,
I have a problem with reducing my fps count, as I don’t need 60 (I’m creating an interactive book for children). The problem is, when I set
pDirector->setAnimationInterval(1.0f / 30.0f);
it works on iOS devices but doesn’t on Android (Nexus 7, myTab10, LG P760 Optimus L9).
The method
pDirector->getAnimationInterval();
reports correct interval of 1/30 of a second (0.03333333…).

I even tried modifiying the Cocos2dxRendereer.java - I tried hardcodeing the fps, I tried uncommenting parts about fps controll in “onDrawFrame” in this class, but nothing seems to work :confused:

I’m using cocos2d-2.1beta3-x-2.1.1

Any kind of help or hint as to how to make it work would be greatly appreciated!


#2

Guys, could anyone at least confirm if this is doable?

/* Bump */


#3

Pawel Lopusinski wrote:

Guys, could anyone at least confirm if this is doable?
>
/* Bump */

Same here, i can confirm it.

Director’s animation interval is used nowhere, so it can’t have effect on drawing.


#4

Well, I’ve managed to do it :slight_smile: I don’t know why, but when I uncommented the fps control part in Cocos2dxRenderer.java it didn’t work, but when I wrote it myself it does. The snippet below shows how it’s done, and the magic value of “40” gives about 35fps. Anyway it would be fairly easy to rig it to react to setAnimationInterval();

Don’t forget to rebuild cocos before testing!

public void onDrawFrame(final GL10 gl) {

         // FPS controlling algorithm is not accurate, and it will slow down FPS
         // on some devices. So comment FPS controlling code.

        loopStart = System.currentTimeMillis();

        try {
            if (loopRuntime < 40) {
                Log.wtf("RENDERER", "Sleeping for == " + (40 - loopRuntime));
                Thread.sleep(40 - loopRuntime);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //final long nowInNanoSeconds = System.nanoTime();
        //final long interval = nowInNanoSeconds - this.mLastTickInNanoSeconds;


        // should render a frame when onDrawFrame() is called or there is a
        // "ghost"
        Cocos2dxRenderer.nativeRender();

        loopEnd = System.currentTimeMillis();
        loopRuntime = (loopEnd - loopStart);

        Log.wtf("RENDERER", "loopRunTime == " + loopRuntime);

        // fps controlling
        /*if (interval < Cocos2dxRenderer.sAnimationInterval) {
            try {
                // because we render it before, so we should sleep twice time interval
                Thread.sleep((Cocos2dxRenderer.sAnimationInterval - interval) / Cocos2dxRenderer.NANOSECONDSPERMICROSECOND);
            } catch (final Exception e) {
            }
        }*/

        //this.mLastTickInNanoSeconds = nowInNanoSeconds;
}

#5

I was looking for FPS control on Android.
Appreciate your code, Pawel.

I have modified your code a little for more accurate result.
The ‘loopStart’ time should be gotten right before Cocos2dxRenderer.nativeRender(), not before Thread.sleep() because the thread’s sleep time should not be included in rendering time.

private long renderingElapsedTime;

@Override
public void onDrawFrame(final GL10 gl) {
    /*
     * FPS controlling algorithm is not accurate, and it will slow down FPS
     * on some devices. So comment FPS controlling code.
     */

    try {
        if (renderingElapsedTime * NANOSECONDSPERMICROSECOND < Cocos2dxRenderer.sAnimationInterval) {
            Thread.sleep((Cocos2dxRenderer.sAnimationInterval - renderingElapsedTime * NANOSECONDSPERMICROSECOND) / NANOSECONDSPERMICROSECOND);
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    /*
    final long nowInNanoSeconds = System.nanoTime();
    final long interval = nowInNanoSeconds - this.mLastTickInNanoSeconds;
    */

    // Get the timestamp when rendering started
    long renderingStartedTimestamp = System.currentTimeMillis();

    // should render a frame when onDrawFrame() is called or there is a
    // "ghost"
    Cocos2dxRenderer.nativeRender();

    // Calculate the elapsed time during rendering
    renderingElapsedTime = (System.currentTimeMillis() - renderingStartedTimestamp);

    /*
    // fps controlling
    if (interval < Cocos2dxRenderer.sAnimationInterval) {
        try {
            // because we render it before, so we should sleep twice time interval
            Thread.sleep((Cocos2dxRenderer.sAnimationInterval - interval) / Cocos2dxRenderer.NANOSECONDSPERMICROSECOND);
        } catch (final Exception e) {
        }
    }

    this.mLastTickInNanoSeconds = nowInNanoSeconds;
    */
}

#6

Thanks you guys for the work. I faced the same problem so I need this solution too :slight_smile: Thanks!


#7

thanks Pawel & Neo.


#8

I am having a similar issue running on blackberry z10 I am using momentics ide but I made the changes and still there is no difference. I am a blackberry noob so would this work at all on it?


#9

because on android as i remember you don’t have any FPS controll your FPS will be as fast as GPU allow or CPU :slight_smile:

You can check this in
cocos2dx/platform/android/java/src/org/cocos2dx/lib/Cocos2dxRenderer.java

in onDrawFrame my looks like

    protected long startTime;

    @Override
    public void onDrawFrame(final GL10 gl) {

        long lastTime = System.currentTimeMillis();
        lastTime = System.currentTimeMillis() - startTime;
        if (lastTime < Cocos2dxRenderer.sAnimationInterval) {
            try {
                Thread.sleep(Cocos2dxRenderer.sAnimationInterval - lastTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        startTime = System.currentTimeMillis();
        Cocos2dxRenderer.nativeRender();
    }

But it isn’t perfect :slight_smile: