Samsung / GearVRf

The GearVR framework(GearVRf) is an Open Source VR rendering library for application development on VR-supported Android devices.
http://www.gearvrf.org
Apache License 2.0
407 stars 217 forks source link

"Surface was already locked" exception #1976

Closed Nathipha closed 6 years ago

Nathipha commented 6 years ago

I'm randomly experiencing this exception when I load my options menu:

09-04 16:22:45.634: W/System.err(28570): java.lang.IllegalArgumentException
09-04 16:22:45.634: W/System.err(28570):    at android.view.Surface.nativeLockCanvas(Native Method)
09-04 16:22:45.634: W/System.err(28570):    at android.view.Surface.lockCanvas(Surface.java:330)
09-04 16:22:45.634: W/System.err(28570):    at org.gearvrf.scene_objects.GVRTextViewSceneObject.refresh(GVRTextViewSceneObject.java:399)
09-04 16:22:45.634: W/System.err(28570):    at org.gearvrf.scene_objects.GVRTextViewSceneObject.access$5(GVRTextViewSceneObject.java:397)
09-04 16:22:45.634: W/System.err(28570):    at org.gearvrf.scene_objects.GVRTextViewSceneObject$GVRDrawFrameListenerImpl.onDrawFrame(GVRTextViewSceneObject.java:377)
09-04 16:22:45.634: W/System.err(28570):    at org.gearvrf.GVRViewManager.doMemoryManagementAndPerFrameCallbacks(GVRViewManager.java:850)
09-04 16:22:45.635: W/System.err(28570):    at org.gearvrf.GVRViewManager.access$5(GVRViewManager.java:828)
09-04 16:22:45.635: W/System.err(28570):    at org.gearvrf.GVRViewManager$3.beforeDrawEyes(GVRViewManager.java:776)
09-04 16:22:45.635: W/System.err(28570):    at org.gearvrf.GVRViewManager.beforeDrawEyes(GVRViewManager.java:342)
09-04 16:22:45.635: W/System.err(28570):    at org.gearvrf.GVRActivity$1.onBeforeDrawEyes(GVRActivity.java:575)
09-04 16:22:45.635: W/System.err(28570):    at org.gearvrf.VrapiActivityHandler$5.onDrawFrame(VrapiActivityHandler.java:416)
09-04 16:22:45.635: W/System.err(28570):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1571)
09-04 16:22:45.635: W/System.err(28570):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)
09-04 16:22:45.650: E/BufferQueueProducer(28570): [SurfaceTexture-671-28570-608] dequeueBuffer: attempting to exceed the max dequeued buffer count (1)
09-04 16:22:45.650: E/Surface(28570): dequeueBuffer failed (Function not implemented)
09-04 16:22:45.650: E/GVRViewManager(28570): DrawFrameListener org.gearvrf.scene_objects.GVRTextViewSceneObject$GVRDrawFrameListenerImpl@a8c2347 threw java.lang.IllegalArgumentException

This exception is then thrown over and over again and only a couple of the GVRTextViewSceneObjects load. When I go back to the normal game (which is still displaying just fine), then load the options menu again it continues throwing this exception and only displays a black screen.

Sometimes it doesn't happen for an hour, then I happens twice within 10 minutes.

To load the options menu I'm doing the following:

I'm still using version 3.0.1 of the framework and I'm aware that you won't be able to fix the problem yourself but I'm wondering if anyone has come across anything similar and has a suggestion what I could try to fix it - maybe it's even been fixed in a later version and I can simply change it in my version of the framework too.

Nathipha commented 6 years ago

There are two more types of "Surface was already locked" errors:

This one I've seen maybe once or twice so far:

09-05 15:53:11.733: E/GraphicBufferAllocator(1109): Failed to allocate (128 x 64) layerCount 1 format 1 usage 133: 5
09-05 15:53:11.734: E/BufferQueueProducer(1109): [SurfaceTexture-432-1109-406] dequeueBuffer: createGraphicBuffer failed
09-05 15:53:11.734: E/Surface(1109): dequeueBuffer failed (Out of memory)
09-05 15:53:11.734: E/GVRTextViewObject(1109): lockCanvas failed

This is the most common one:

09-05 15:38:22.908: E/GVRViewManager(29841): DrawFrameListener org.gearvrf.scene_objects.GVRTextViewSceneObject$GVRDrawFrameListenerImpl@8e5905c threw java.lang.NullPointerException: Attempt to invoke virtual method 'int android.text.Layout.getHeight()' on a null object reference
09-05 15:38:22.932: E/GVRViewManager(29841): DrawFrameListener org.gearvrf.scene_objects.GVRTextViewSceneObject$GVRDrawFrameListenerImpl@8e5905c threw java.lang.IllegalArgumentException: Surface was already locked

I thought that it's maybe related to the GVRPicker but even with that disabled I get the exception. There are 7 rows of GVRTextViewSceneObjects in my options menu (the last one isn't "clickable", so no GVRMeshCollider) and I've noticed that the exception always gets thrown somewhere between row 4 and 6, which is always one of the rows I'm directly looking at when the options menu is loaded. I can't seem to pinpoint when exactly it's happening though, if it's while I'm setting the text size,... changing the background or attaching the GVRMeshCollider - sometimes it's happening sooner, sometimes later.

liaxim commented 6 years ago

Do you create new TextViewSOs every time you go to your options menu?

Nathipha commented 6 years ago

Yes, I am.

Thanks for the hint! I changed it, so they only generate once at the very beginning, then just move and rotate them every time the options menu is opened and it hasn't thrown another exception since then, even after opening/closing the menu about 40 times. I also noticed that the buttons are now displayed properly every time - no more black background with weirdly large text that changes back to normal once I look at it (because of the picker/mesh collider). Let's hope that this is indeed fixed now and I didn't just get lucky. Thanks!

Is that what causes the surface to not unlock properly and then throw an exception: Creating too many GVRTextViewSceneObjects in a too short amount of time and eventually it just gets "stuck"?

liaxim commented 6 years ago

It is very likely there are resource and memory leaks. This is not a real fix but a mere workaround. There is no such problem to my knowledge in the latest version.

Can we close the issue?