Crash during drawing

  ... in the unlikely case you discovered a bug, post it here.

Crash during drawing

Postby 4ybaka » Sun Oct 30, 2011 8:40 pm

Hello.

I use prebuild jar from http://wiki.andengine.org/AndEngine_Jars and last tested jar was from 1037:42ca5fbb1d68@default.
My problem is unhandled exception with next stack:

ERROR/AndroidRuntime(437): java.lang.IndexOutOfBoundsException: Invalid location 18, size is 18
at java.util.ArrayList.get(ArrayList.java:341)
at org.anddev.andengine.entity.Entity.onManagedDrawChildren(Entity.java:1008)
at org.anddev.andengine.entity.Entity.onDrawChildren(Entity.java:1000)
at org.anddev.andengine.entity.Entity.onManagedDraw(Entity.java:993)
at org.anddev.andengine.entity.scene.Scene.onManagedDraw(Scene.java:233)
at org.anddev.andengine.entity.scene.CameraScene.onManagedDraw(CameraScene.java:99)
at org.anddev.andengine.entity.Entity.onDraw(Entity.java:875)
at org.anddev.andengine.engine.Engine.onDrawScene(Engine.java:517)
at org.anddev.andengine.engine.Engine.onDrawFrame(Engine.java:509)
at org.anddev.andengine.opengl.view.RenderSurfaceView$Renderer.onDrawFrame(RenderSurfaceView.java:154)
at org.anddev.andengine.opengl.view.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:617)
at org.anddev.andengine.opengl.view.GLSurfaceView$GLThread.run(GLSurfaceView.java:549)


I look at Entity.onManagedDrawChildren method and it seems like collection changed from another thread (but I do not know java very well so it is only my guess). It happens periodically but not regular.
PS: I have 2 scenes on one screen. Can it be related?
4ybaka
 
Posts: 1
Joined: Sun Oct 30, 2011 8:22 pm

Re: Crash during drawing

Postby Sneedd » Thu Nov 17, 2011 4:16 pm

Have the same problem, but with one scene. It seems that the container is changed somewhere.

The problem don't occur when changing the Entity::onManagedDrawChildren() Method, to this:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         public void onManagedDrawChildren(final GL10 pGL, final Camera pCamera) {
  2.                 final ArrayList<IEntity> children = this.mChildren;
  3.                 for(int i = 0; i < children.size(); i++) {
  4.                         children.get(i).onDraw(pGL, pCamera);
  5.                 }
  6.         }
  7.  
Parsed in 0.011 seconds, using GeSHi 1.0.8.4


EDIT:
Now that I played a little bit with AndEngine, I think I choosed a wrong approach. I created, attached or detached a lot of sprites in a event function. Thats why the error occured!

I also found the SpriteRemoveExample.java example file, which explained a lot:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
  2.                 /* Removing entities can only be done safely on the UpdateThread.
  3.                  * Doing it while updating/drawing can
  4.                  * cause an exception with a suddenly missing entity.
  5.                  * Alternatively, there is a possibility to run the TouchEvents on the UpdateThread by default, by doing:
  6.                  * engineOptions.getTouchOptions().setRunOnUpdateThread(true);
  7.                  * when creating the Engine in onLoadEngine(); */
  8.                 this.runOnUpdateThread(new Runnable() {
  9.                         @Override
  10.                         public void run() {
  11.                                 /* Now it is save to remove the entity! */
  12.                                 pScene.detachChild(SpriteRemoveExample.this.mFaceToRemove);
  13.                         }
  14.                 });
  15.                 return false;
  16.         }
  17.  
Parsed in 0.010 seconds, using GeSHi 1.0.8.4
Sneedd
 
Posts: 2
Joined: Thu Nov 17, 2011 4:04 pm

Re: Crash during drawing

Postby Toscal » Thu Dec 01, 2011 4:13 am

Same thing happens to me quite randomly, I managed to break the application to make intensive use of scene changes that remove and many items and is always the same error in the state, so you have every chance of being what you mention. I would like Sneedd if you would confirm that the bug has been fixed so that you are clear to all those people who feel the same. For my part I will use the option of engineoptions and try to break the application and if I fail, it informs you the solution to the problem.
Toscal
 
Posts: 15
Joined: Mon May 09, 2011 1:48 am

Re: Crash during drawing

Postby Sneedd » Thu Dec 01, 2011 1:48 pm

Actually, I would not say this is a bug. There are just two threads who aren't syncronized. The fix I have mentioned, only reduces the error, but does not resolve it. So maybe it is better to keep it the old way.

To get rid of the problem I used another approach, where the entities used in my scene are more static. Entities I did not use, I made invisible.

Because Toscal wrote me a PM where he mentioned that
mEngineOptions.getTouchOptions().SetRunOnUpdateThread(true);

could solve the problem. I ran a few tests, hopefully everyone can do anything with them.

So my first action was to recreate the problem, so that the IndexOutOfBoundsException occurs. The following code should result in that error, if your computer is not too fast and you touch the emulator frequently.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public class TestActivity extends BaseGameActivity
  2. {      
  3.         private static final int CAMERA_WIDTH = 480;
  4.         private static final int CAMERA_HEIGHT = 720;
  5.         private static final int ENTITY_COUNT = 500;
  6.        
  7.         private Camera m_camera;
  8.         private Scene m_scene;
  9.         private Random m_random;
  10.  
  11.         public Engine onLoadEngine()
  12.         {      
  13.                 m_camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
  14.                 m_random = new Random();
  15.                
  16.                 EngineOptions options = new EngineOptions(
  17.                                 true,
  18.                                 ScreenOrientation.PORTRAIT,
  19.                                 new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
  20.                                 m_camera);
  21.                
  22.                 Engine engine = new Engine(options);
  23.                 return (engine);
  24.         }
  25.  
  26.         public Scene onLoadScene()
  27.         {
  28.                 this.getEngine().registerUpdateHandler(new FPSLogger());
  29.        
  30.                 m_scene = new Scene()
  31.                 {
  32.                         public boolean onSceneTouchEvent(TouchEvent pSceneTouchEvent)
  33.                         {
  34.                                 removeEntities(m_scene);
  35.                                 addEntities(m_scene);
  36.                                 return (true);
  37.                         }
  38.                 };
  39.                 this.addEntities(m_scene);
  40.                 return m_scene;
  41.         }
  42.        
  43.         public void onLoadResources()
  44.         {
  45.         }
  46.  
  47.         public void onLoadComplete()
  48.         {
  49.         }
  50.        
  51.         public void addEntities(Scene scene)
  52.         {
  53.                 for(int i = 0; i < ENTITY_COUNT; i++)
  54.                 {
  55.                         final float x1 = m_random.nextFloat() * CAMERA_WIDTH;
  56.                         final float x2 = m_random.nextFloat() * CAMERA_WIDTH;
  57.                         final float y1 = m_random.nextFloat() * CAMERA_HEIGHT;
  58.                         final float y2 = m_random.nextFloat() * CAMERA_HEIGHT;
  59.                         final float lineWidth = m_random.nextFloat() * 5;
  60.  
  61.                         final Line line = new Line(x1, y1, x2, y2, lineWidth);
  62.                         line.setColor(m_random.nextFloat(), m_random.nextFloat(), m_random.nextFloat());
  63.                         scene.attachChild(line);
  64.                 }
  65.         }
  66.        
  67.         public void removeEntities(Scene scene)
  68.         {
  69.                 try
  70.                 {
  71.                         for (int i=0; i<scene.getChildCount(); i++)
  72.                         {                              
  73.                                 Thread.sleep(10);
  74.                                 scene.detachChild(scene.getChild(i));
  75.                         }
  76.                 }
  77.                 catch (InterruptedException e)
  78.                 {
  79.                         e.printStackTrace();
  80.                 }      
  81.         }
  82. }
  83.  
Parsed in 0.013 seconds, using GeSHi 1.0.8.4


Ok, if you now use SetRunOnUpdateThread(true) by simply doing the following:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. EngineOptions options = new EngineOptions(
  2.   true,
  3.   ScreenOrientation.PORTRAIT,
  4.   new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
  5.   m_camera);
  6. options.getTouchOptions().setRunOnUpdateThread(true); // !!!!
  7.  
Parsed in 0.011 seconds, using GeSHi 1.0.8.4

The same code runs awful slow. I mean 10 or 100 times slower than without it. So I checked the documentation what this option means: TouchOptions But with no luck. Also I am not sure if the problem is solved that way.

The best solution I think is using the solution by Nicolas Gramlich seen in the SpriteRemoveExample. So if I remove the setRunOnUpdateThread(true) again and changing the removeEntities() Method this way:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         public void removeEntities()
  2.         {
  3.                 this.runOnUpdateThread(new Runnable()
  4.                 {
  5.                         public void run()
  6.                         {
  7.                                 try
  8.                                 {
  9.                                         for (int i=0; i<m_scene.getChildCount(); i++)
  10.                                         {                              
  11.                                                 Thread.sleep(10);
  12.                                                 m_scene.detachChild(m_scene.getChild(i));
  13.                                         }
  14.                                 }
  15.                                 catch (InterruptedException e)
  16.                                 {
  17.                                         e.printStackTrace();
  18.                                 }      
  19.  
  20.                         }
  21.                 });
  22.         }
  23.  
Parsed in 0.010 seconds, using GeSHi 1.0.8.4

The problem with the exception does not occur, too. Also it is as slow as SetRunOnUpdateThread(true). The best ways are maybe
  • to implement a own 'Entitiy GarbageCollection', where 'removed' entities will be set invisible and removed later
or
  • using a mutex to secure the entities collection in the scene. Where someone needs to know exactly how the internals of the AndEngine work. Which I think is the best way.

Or even a AndEngine guru could give us a hint on that. Maybe there are features I did not found, yet.
Sneedd
 
Posts: 2
Joined: Thu Nov 17, 2011 4:04 pm

Re: Crash during drawing

Postby Toscal » Thu Dec 01, 2011 2:28 pm

I need some time to test and comment. I work on a Galaxy Samgung SII and have not noticed any difference in performance with the naked eye or the FPSLogger. This issue is important because in my case at least is the only application mistake and breaks it. That is not tolerable.

One idea that I had been around the head was to capture the error, omitting the repainting, but I'm not sure how to do it and may cause some kind of input lag, although in my case the error always occurs in the main menu to change scenes between screens or return the game and activated parallax background so perhaps this omission refinishing or unnoticed.

I'm thinking also send an email to Nicolas, but I will not abuse your trust to the community and may not respond to me though the forum is full of post hacienod reference to this error and none reach any solution.

What do you think?

Best Regards and sorry for my english ^^!
Toscal
 
Posts: 15
Joined: Mon May 09, 2011 1:48 am

Re: Crash during drawing

Postby Toscal » Thu Dec 01, 2011 2:34 pm

Well, coincidentally after writing the previous post I tried to exit the application which was on the menu with parallax while writing the above message and has given me the error. Therefore it is NOT the solution.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. 12-01 12:30:00.095: W/dalvikvm(16181): threadid=13: thread exiting with uncaught exception (group=0x4001e578)
  2. 12-01 12:30:00.095: E/AndroidRuntime(16181): FATAL EXCEPTION: GLThread
  3. 12-01 12:30:00.095: E/AndroidRuntime(16181): java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
  4. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
  5. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at java.util.ArrayList.get(ArrayList.java:311)
  6. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at org.anddev.andengine.entity.Entity.onManagedDrawChildren(Entity.java:1008)
  7. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at org.anddev.andengine.entity.Entity.onDrawChildren(Entity.java:1000)
  8. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at org.anddev.andengine.entity.Entity.onManagedDraw(Entity.java:993)
  9. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at org.anddev.andengine.entity.scene.Scene.onManagedDraw(Scene.java:233)
  10. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at org.anddev.andengine.entity.Entity.onDraw(Entity.java:875)
  11. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at org.anddev.andengine.engine.Engine.onDrawScene(Engine.java:517)
  12. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at org.anddev.andengine.engine.Engine.onDrawFrame(Engine.java:509)
  13. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at org.anddev.andengine.opengl.view.RenderSurfaceView$Renderer.onDrawFrame(RenderSurfaceView.java:154)
  14. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at org.anddev.andengine.opengl.view.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:617)
  15. 12-01 12:30:00.095: E/AndroidRuntime(16181):    at org.anddev.andengine.opengl.view.GLSurfaceView$GLThread.run(GLSurfaceView.java:549)
  16.  
Parsed in 0.012 seconds, using GeSHi 1.0.8.4


Indeed, the same error as always, it is random as try to break the application yesterday and I could not and now performs an action and the application falls.

mmm :evil:
Toscal
 
Posts: 15
Joined: Mon May 09, 2011 1:48 am

Re: Crash during drawing

Postby simplydt » Tue Feb 19, 2013 12:54 pm

Hi Toscal,

You probably already solved this but for anyone who stumbles on this with Google, I used the following thread to fix this same problem:

gles1/unloading-resources-t5843.html?hilit=unloading%20resources#p26026

Also, I had to delete all other things (not only sprites), such used Arrays, Timers, etc... Basically remove everything you created, and then the problem should go away. It did for me, yay! :D
simplydt
 
Posts: 3
Joined: Tue Feb 19, 2013 12:51 pm


Return to Bugs

Who is online

Users browsing this forum: No registered users and 3 guests