100% load with RenderScene

Hi all,
we are using Opengles2.0 in graphics_SDK_4_04_00_02 which uses PVR shell as an abstraction layer. In which most of the trainingcourses / demos giving me 100 percent load when we are using the frame work of PVRshell . We understand RenderScene ( ) will be holding the data which we need to render onto the screen. Even though we made it as dummy we are getting a full load on the ARM core .
In Most of the cases glSwapbuffer may be doing a tight loop check for V sync detection may overloads the CPU. so we disabled it using PVRShellSet (prefNoShellSwapBuffer, true); so it will not enter onto glSwapbuffers use case( if it works we can make a sleep before the swap-buffers use case so that the tight loop can be removed ). But its of no use . It insists me to put a sleep in my RenderScene function on my application ,But Common guys its of no use for my use-case to achieve the required frame-rate . Can anybody point out who cause this overloading eventhough we makes RenderScene as a dummy function. Am i missing something, is there anything do i need to taken care of ? Is it like whenever a Vsync comes, the PVRshell framework will call the RenderScene function and at the backend ( on PVR shell ) the glSwapbuffers gets called . So may i know any tight loop condition happens on the Vsync check from PVRshell. Please Reply ASAP and help me to sort out this problem . All suggestions are appreciated.

Hi,

Firstly could I ask what device you are running your application on?
Also could I suggest that you try using the latest SDK (16.2) which can be found here: https://www.imgcommunity.local/developers/powervr/installers/
Have you run any other 3D applications on your device which does not use the framework - if so what are the results (CPU usage etc.)?
And finally could you attach the source code for the example you are trying to run.

Kind Regards,
Shaun

Hi shaun,

[i][b]Thanks for the quick response and joining me to sort out this problem . My responses to your queries are given below.[/b][/i]

[size size="{size}"][size size="{size}"]
>> Firstly could I ask what device you are running your application on?[/size][/size]
We are working in a solution from TI’s TMS320DM8168 which has SGX530 based 3D graphics engine . In which we used the graphical SDK of version 4_04_00_02 and PVRSDK_VERSION “2.05.25.0804”

[size size="{size}"][size size="{size}"]
>> Could I suggest that you try using the latest SDK (16.2) which can be found here ?[/size][/size]
Our development is done with this SDK where nobody have mentioned this as a bug . Or no errata find related to this . So I need to understand is there something wrong or do i done something wrong, any way i will keep it as a last hope.

>>[size size="{size}"][size size="{size}"] Have you run any other 3D applications on your device which does not use the framework – if so what are the results (CPU usage etc.)?[/size][/size]
Can you suggest some other framworks if you know . I dont have much idea about the other available frameworks.

>> [size size="{size}"][size size="{size}"]could you attach the source code for the example you are trying to run.?[/size][/size]
This is a sample training example which introduces PVRSHell and its framework. i just commented out all lines from the RenderScene to analyse this issue but its showing 100% CPU load. this source code can be found out in the graphical SDK at graphics_SDK_4_04_00_02/GFX_Linux_SDK/OGLES2/SDKPackage/TrainingCourse/03_IntroducingPVRShell/OGLES2/OGLES2IntroducingPVRShell.cpp. Any way attaching the source code
[attachment file=55286] and its behaviour on the target ( load using top command [attachment file=55285] ).

Hi,

Could you try adding the function setSwapInterval(1); to the initApplication function.
This should force V-Sync to be enabled, which may solve your high CPU usage.

Kind Regards,
Shaun

Hi Shaun,

You meant to say in the InitApplication API of my sample application. i fear it can't access there as it is a private member to PVRShell class.  so i made a temporary fix like make the same function as public and tried ti access over my application but no success. One thing to note as per my understanding setSwapInterval(1); is for fraame updation after the successful completion of a single frame ,which means i get a fps of 60 . now if we set setSwapInterval(2); it will update on every second frame so it will reduce the fps to 30. but i am not seeing any progress in this area. load remains the same .

Hi

Maybe you misunderstood me please add the function like so to your sample application:

[scode lang="{language}"]
//This is in your sample application
bool OGLESIntroducingPVRShell::InitApplication()
{
setSwapInterval(1); //Add me here
return true;
}[/scode]

There should be no need to edit the Shell class as the function is public and is accessible by application.
Just to clarify the setSwapInterval function enables or disables v-sync, a value of 0 means there is no interval (no vsync). A value of 1 enables v-sync.

Kind Regards,
Shaun

Hi Shaun,

Attaching the PVRShell.h file. you can see the member is private

[attachment file=55296].

Also We can use PVRShellSet( arg,val) API to set the swapinterval . you can use PVRShellSet( prefSwapInterval,xx) to set the swap interval.

Adding the implementation of setSwapInterval from Shell/API/KEGL/PVRShellAPI.cpp

bool PVRShell::setSwapInterval(const int i32Value)
{
#ifdef EGL_VERSION_1_1
m_pShellData->nSwapInterval = i32Value;
return true;
#else
return false;
#endif
}

as our OpenGL version is 2.0 is there anything to do with it ?

Hi Vishnu,

It seems like we have been confusing ourselves, I have been looking at SDK 4.0 code because in your first post you said you were using “SDK_4_04_00_02”; however saying that we don’t actually have a version which corresponds to this - our versions are 16.2, 16.1, 4.2, 4.1, 4.0, 3.5 etc. The code you sent me actually looks like it is from SDK 3.5 which is why you are seeing a completely different implementation (3.5 -> 4.0 was a very big update for our SDK).

So could you confirm the SDK version you are using please.

If you are using a version of our SDK prior to 4.0 then you should use the PVRShellSet function and forget about the setSwapInterval function.

Kind Regards,
Shaun

Hi shahun,

 Sorry for the trouble , we are using this SDK which was given by TI ( graphics_SDK_4.04.00.02). have you made any release with this ODM.  i have used PVRShellSet function also but its of no use, as the value is not reflecting any change.   

from the code,

bool PVRShell::setSwapInterval(const int i32Value)
{
#ifdef EGL_VERSION_1_1
m_pShellData->nSwapInterval = i32Value;
return true;
#else
return false;
#endif
}

If i am using OGLES_2.0 is this variable helps ? also can you tell me where i can find the version number attaching the Release note from the SDK if its of any use.

Hi Vishnu,

No problem, I am not familiar with that version number, however from the code it looks like a version prior to 4.0, if you could check the documentation you may be able to find the exact version number, you can find the SDK documentation at the path <install dir>\Documentation\SDKBrowser and then open the Release Notes file you should see “PowerVR Tools and SDK v[xx]” at the top of the document.

With regards to your question about EGL, this is a separate library which handles communication between OpenGL ES and the native platform (https://www.khronos.org/egl).

Edit: I have just noticed that you can pass an argument at command line to set vsync, so when you execute your program add -vsync 1 after the executable.

Kind Regards,
Shaun

Hi Shaun,

  I will follow up the same in khronos/EGL forum. Meanwhile can you give me some points / conclusions where i need to look into. also this binary can be profiled . such that i can check for any while condition is happening at back end or not. 

from the following piece of code can you tell me when this RenderScene gets called.

this is from the PVRShell.cpp file

[size size="{size}"][size size="{size}"][b]bool PVRShellInit::Run()
{
static unsigned long StartTime = 0;

    switch(m_eState)
    {
    case ePVRShellInitApp:
            if(!m_pShell-&gt;InitApplication())
            {
                    m_eState = ePVRShellExit;
                    return true;
            }

    case ePVRShellInitInstance:
            {
                    m_CommandLine.Apply(*m_pShell);

                    // Output non-api specific data if required
                    OutputInfo();

                    // Perform OS initialisation
            if(!OsInitOS())
                    {
                            m_pShell-&gt;PVRShellOutputDebug("InitOS failed!\n");
                            m_eState = ePVRShellQuitApp;
                            return true;
                    }

                    // Initialize the 3D API
                    if(!OsDoInitAPI())
                    {
                            m_pShell-&gt;PVRShellOutputDebug("InitAPI failed!\n");
                            m_eState = ePVRShellReleaseOS;
                            gShellDone = true;
                            return true;
                    }

                    // Output api specific data if required
                    OutputAPIInfo();

                    // Initialise the app
                    if(!m_pShell-&gt;InitView())
                    {
                            m_pShell-&gt;PVRShellOutputDebug("InitView failed!\n");
                            m_eState = ePVRShellReleaseAPI;
                            gShellDone = true;
                            return true;
                    }

                    if(StartTime==0)
                    {
                            StartTime = OsGetTime();
                    }

                    m_eState = ePVRShellRender;
                    return true;
            }
    case ePVRShellRender:
            {
                    // Main message loop:
                    if(!m_pShell-&gt;RenderScene())
                            break;

                    ApiRenderComplete();
                    OsRenderComplete();

#ifdef PVRSHELL_FPS_OUTPUT
if(m_pShell->m_pShellData->bOutputFPS)
FpsUpdate();
#endif
int nCurrentFrame = m_pShell->m_pShellData->nShellCurFrameNum;

                    if(DoIsKeyPressed(PVRShellKeyNameScreenshot) || (nCurrentFrame &gt;= m_pShell-&gt;m_pShellData-&gt;nCaptureFrameStart &amp;&amp; nCurrentFrame &lt;= m_pShell-&gt;m_pShellData-&gt;nCaptureFrameStop))
                    {
                            unsigned char *pBuf;
                            if(m_pShell-&gt;PVRShellScreenCaptureBuffer(m_pShell-&gt;PVRShellGet(prefWidth), m_pShell-&gt;PVRShellGet(prefHeight), &amp;pBuf))
                            {
                                    if(m_pShell-&gt;PVRShellScreenSave(PVRSHELL_SCREENSHOT_NAME, pBuf) != 0)
                                    {
                                            m_pShell-&gt;PVRShellSet(prefExitMessage, "Screen-shot save failed.\n");
                                    }
                            }
                            else
                            {
                                    m_pShell-&gt;PVRShellSet(prefExitMessage, "Screen capture failed.\n");
                            }
                            FREE(pBuf);
                    }

                    if(DoIsKeyPressed(PVRShellKeyNameQUIT))
                            gShellDone = true;

                    if(gShellDone)
                            break;

                    /* Quit if maximum number of allowed frames is reached */
                    if((m_pShell-&gt;m_pShellData-&gt;nDieAfterFrames&gt;=0) &amp;&amp; (nCurrentFrame &gt;= m_pShell-&gt;m_pShellData-&gt;nDieAfterFrames))
                            break;

                    /* Quit if maximum time is reached */
                    if((m_pShell-&gt;m_pShellData-&gt;fDieAfterTime&gt;=0.0f) &amp;&amp; (((OsGetTime()-StartTime)*0.001f) &gt;= m_pShell-&gt;m_pShellData-&gt;fDieAfterTime))
                            break;

                    m_pShell-&gt;m_pShellData-&gt;nShellCurFrameNum++;
                    return true;
            }

    case ePVRShellReleaseView:
            m_pShell-&gt;ReleaseView();

    case ePVRShellReleaseAPI:
            OsDoReleaseAPI();

    case ePVRShellReleaseOS:
            OsReleaseOS();

            if(!gShellDone &amp;&amp; m_pShell-&gt;m_pShellData-&gt;nInitRepeats)
            {
                    --m_pShell-&gt;m_pShellData-&gt;nInitRepeats;
                    m_eState = ePVRShellInitInstance;
                    return true;
            }

    case ePVRShellQuitApp:
            // Final app tidy-up
            m_pShell-&gt;QuitApplication();

    case ePVRShellExit:
            OsExit();
            StringCopy(m_pShell-&gt;m_pShellData-&gt;pszAppName, 0);
            StringCopy(m_pShell-&gt;m_pShellData-&gt;pszExitMessage, 0);
            return false;
    }

    m_eState = (EPVRShellState)(m_eState + 1);
    return true;

}[/b]
[/size][/size]

Hi Vishnu,

From the code snippet that you have posted the main render loop is here:
[scode lang="{language}"]//…

// Main message loop:
if(!m_pShell->RenderScene())
break;

ApiRenderComplete();
OsRenderComplete();

//…[/scode]

RenderScene will execute the (overridden) function in the example application which is where your OGL calls are executed.
ApiRenderComplete will execute swap buffers and OsRenderComplete checks if the application should close.

If you want to profile your application you can use PVRTrace and PVRTune (which should be included in your SDK), the setup for both of these applications should be in the included documentation.

Edit: Just a follow up to the EGL question, I don’t know what version of EGL is available on your platform but if you wanted to check whether the code gets executed you could simply add a printf statement inside the if def.

Regards,
Shaun

Hi Shaun,

getting support from EGL needs a registration from company side . as i am getting this error during the sign up

": Your company must already be a member of the Khronos Group for you to gain access to the members area of this site. If your company is a member and you are visiting for the first time, apply to receive login information. (note: all information will kept confidential to the Khronos Group). " . As its not a reliable solution for resolving only this bug.

Hi vishnu,

My apologies I did not realise, I was sending you that link mainly so that you knew what EGL was, if you are simply looking to find out the available version of EGL you can take a look at the egl.h file which is located at [install directory]/Builds/Include/EGL/egl.h

At the top (around line 50) of the file you should see something like this:
[scode lang="{language}"]/* EGL Versioning */
#define EGL_VERSION_1_0 1
#define EGL_VERSION_1_1 1
#define EGL_VERSION_1_2 1
#define EGL_VERSION_1_3 1
#define EGL_VERSION_1_4 1[/scode]

Hope this helps,
Shaun