Problem with eglSwapBuffers and heap corruption
I've got a bit of a problem with the use of eglSwapBuffers in my Series 60 code, I'm using 2nd edition SDK under the WINS emulator.
I was running my app full screen which seemed to automatically make it use the direct screen access code.
When I displayed the menu I was hitting memory corruption errors. I tracked this down to the menu display causing loss of direct screen access, which freed the bitmap being used for this but OpenGL still had a pointer to this now dead bitmap and in the call to glClear it corrupted the heap trying to write to this dead pointer.
I debugged into the sample apps to see how they avoided this problem and discovered that apps like Example3D and GlExample were calling eglSwapBuffers at the start of their draw cycles, this call sorted out the dead pointer problem and stopped the heap corruption.
This solution also fixed my problem but it doesn't seem to be right thing to do, surely eglSwapBuffers should be called straight after the drawing code to copy it to the display ASAP. The method used in those sample apps is postponing the screen update until the next animation cycle causing an unwanted lag in updating the display.
I've just had a look through some of the other sample apps and believe they are surviving this problem by luck, the ones that run in full screen but don't call eglSwapBuffers until after their draw cycle are actually drawing to freed memory but getting away with it because writing to freed heap space doesn't actually corrupt anything unless some other code tries to use that heap.
I've confirmed this by making the following change in the \OpenGlExamples\3Dexamples\openglex\rain sample.
TInt CRainContainer::DrawCallBack( TAny* aInstance )
CRainContainer* instance = (CRainContainer*) aInstance;
if ( instance->iRain->GetState() == CRain::ERunning )
/* Call the main OpenGL ES Symbian rendering 'loop' */
// Added following alloc and heap checks to churn and test the heap
instance->iRain->AppCycle( instance->iFrame );
In the call after AppCycle() to User::Heap().Check() the code paniced with User-49 when the menu was displayed, what has happened is the alloc of 100 bytes has gone into the space freed by deleting the direct screen buffer, the opengl draw code has then trashed the free cell pointer at the end of this new alloc cell, which was picked up by the heap check afterwards.
At the moment I can't see any solution other than calling eglSwapBuffers before my draw code, and having to put up with the lag in updating the display.
But I suggest this whole situation needs to be looked at carefully to prevent other people hitting this same problem I did with heap corruption, it was very very hard to track down, involved writing a heap dump function to analyse what was corrupting my heap, lots of memory watch break points to track back step by step who was responsible for the corruption, then watching the same memory watch points in the sample apps to work out why they didn't hit the same problem as me.
At the very least all the sample apps need to be changed so they aren't writing to freed memory.
Great Ape Software Ltd
Re: Problem with eglSwapBuffers and heap corruption
[QUOTE=greatape]...but it doesn't seem to be right thing to do, surely eglSwapBuffers should be called straight after the drawing code to copy it to the display ASAP. The method used in those sample apps is postponing the screen update until the next animation cycle causing an unwanted lag in updating the display.[/QUOTE]
In the simulation world this is often considered the 'correct' method. I'm not exactly sure why this is, but I guess it's because a constant latency is better for the user than a variable one.