Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android: Ensure cleanup of all subobjects in the OpenSL audio driver #85955

Conversation

PierceLBrooks
Copy link
Contributor

@PierceLBrooks PierceLBrooks commented Dec 9, 2023

Depending on different Android devices, without these changes, a crash or a hang may occur when the Godot engine instance is being torn down as the OpenSL audio playback subsystem gets closed. The most easily expressible side effect of such an occurrence appears as follows ( taken from ADB LogCat ):

12-04 20:08:28.161 11819 11862 E libOpenSLES: Object::Destroy(0xb40000752d630930) for engine ignored; 2 total active objects
12-04 20:08:28.161 11819 11862 E libOpenSLES: Object::Destroy(0xb40000752d630930) for engine ignored; active object ID 2 at 0xb40000752d62fc50
12-04 20:08:28.161 11819 11862 E libOpenSLES: Object::Destroy(0xb40000752d630930) for engine ignored; active object ID 3 at 0xb40000755d61c230

Bugsquad edit:

@PierceLBrooks PierceLBrooks requested review from a team as code owners December 9, 2023 08:06
@AThousandShips
Copy link
Member

Can you please open an issue report for this, or link to one if one exists, to help track the issue (so it doesn't get lost if this PR is closed for some reason, or a different solution is required)

@@ -48,6 +48,7 @@ class OS_Unix : public OS {

public:
OS_Unix();
virtual ~OS_Unix();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed? OS already has a virtual destructor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps not, though I recall that when I was breakpointing through this, the stack traces looked a bit different - and clearer in my opinion - when I explicitly declared this intermediately inherited virtual destructor.

}

void AudioDriverOpenSL::set_pause(bool p_pause) {
pause = p_pause;

if (active) {
if (active && playItf) {
Copy link
Member

@AThousandShips AThousandShips Dec 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other contexts where the different pointers are used without a check, should they not have them as well?

Also active is not set to true until after it has initialized this pointer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this check primarily to ward against possible data race conditions of accessing the playItf while the driver is being cleaned up more than out of any concern for the state of a partial initialization success/failure where some members are populated before the active flag is toggled on. My familiarity with the extent of set_pause's usage is limited, but if there is some notion of a guarantee that it won't be called in parallel with driver destruction, then I can take this out as redundant. Otherwise, I can instead add extra checks elsewhere to the cases you described.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went ahead and added a bit of extra carefulness here...
11ff925

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this check primarily to ward against possible data race conditions of accessing the playItf while the driver is being cleaned up.

There can still be a rare data race condition when this line executes between these lines:

(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
playItf = nullptr;

Because of that playItf is not nullptr here:
if (active && playItf) {

But will be nullptr here:
(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PAUSED);

IMO doesn't have to be addressed in this PR

@AThousandShips
Copy link
Member

See also:

@Alex2782

This comment was marked as outdated.

@PierceLBrooks
Copy link
Contributor Author

@Alex2782 the callback nullification seems redundant since I do not believe those function pointers will be invoked inside the underlying OpenSL engine whenever the corresponding interface reference's state is "*_STOPPED", but it certainly wouldn't hurt, and I definitely agree that the buffers should probably be freed as well.

@PierceLBrooks
Copy link
Contributor Author

@AThousandShips
I have just filed an issue for this here...
#85979
Thanks for reviewing!

@PierceLBrooks
Copy link
Contributor Author

@Alex2782 After some testing, I have found that the buffer array deletion and buffer interface callback nullification causes a crash upon app closure:

12-09 17:01:03.153 24211 24426 D tProjectManage: PlayerBase::stop() from IPlayer
12-09 17:01:03.153 24211 24426 D AudioTrack: stop(707): called with 732942 frames delivered
12-09 17:01:03.208 24211 24426 I GodotBenchmark: BENCHMARK:
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 	- [Startup]
12-09 17:01:03.208 24211 24426 I GodotBenchmark:  		- Godot::onCreate: 4.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Core: 64.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Setup: 1102.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- GodotFragment::onCreate: 180.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Initialize Early Settings: 38.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Servers: 411.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Setup Window and Boot: 18.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Translations and Remaps: 1.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Text Server: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Scene: 355.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Platforms: 1.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Finalize Setup: 43.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Project Manager: 1982.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Total: 3406.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 	- [Core]
12-09 17:01:03.208 24211 24426 I GodotBenchmark:  		- Register Types: 39.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Register Extensions: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Register Singletons: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Unregister Extensions: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Unregister Types: 43.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 	- [Servers]
12-09 17:01:03.208 24211 24426 I GodotBenchmark:  		- Register Extensions: 52.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Modules and Extensions: 6.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Input: 47.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Display: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Tablet Driver: 1.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Rendering: 245.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Audio: 51.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- XR: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Register Singletons: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Unregister Extensions: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 	- [Scene]
12-09 17:01:03.208 24211 24426 I GodotBenchmark:  		- Register Types: 210.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Register Singletons: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Modules and Extensions: 144.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Unregister Types: 1.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 	- [Editor]
12-09 17:01:03.208 24211 24426 I GodotBenchmark:  		- Register Types: 7.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Modules and Extensions: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Unregister Types: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 	- [EditorTheme]
12-09 17:01:03.208 24211 24426 I GodotBenchmark:  		- Generate Icons (All): 936.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Generate Icons (Only Thumbs): 16.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Register Fonts: 28.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Create Editor Theme: 1543.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 		- Create Custom Theme: 0.0 msec.
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 
12-09 17:01:03.208 24211 24426 I GodotBenchmark: 	- [Shutdown]
12-09 17:01:03.208 24211 24426 I GodotBenchmark:  		- Total: 64.0 msec.
12-09 17:01:03.210 24211 24426 I scudo   : Scudo ERROR: invalid chunk state when deallocating address 0x2000073e8f14ae0
12-09 17:01:03.210 24211 24426 F libc    : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 24426 (GLThread 92), pid 24211 (tProjectManager)
Screenshot 2023-12-09 at 4 59 24 PM Screenshot 2023-12-09 at 5 02 56 PM

@Alex2782
Copy link
Contributor

Alex2782 commented Dec 9, 2023

ok I'll try it tomorrow too: official audio demos


I didn't notice any crashes in my test project. I just found it strange that something was active even though I wasn't playing any sound.

@Alex2782
Copy link
Contributor

Tested with spectrum demo. No crashes or OpenSL error messages. 👍


BACK button, with print_line outputs in functions finish, end, ~AudioDriverOpenSL
(Destructor would not be absolutely necessary here)

2023-12-10 19:22:25.617 15220-15220 ViewRootIm...[GodotApp] com.godot.game                       I  ViewPostIme key 0
2023-12-10 19:22:25.632 15220-15312 godot                   com.godot.game                       I  finish
2023-12-10 19:22:25.632 15220-15312 godot                   com.godot.game                       I  end
2023-12-10 19:22:25.632 15220-15312 com.godot.game          com.godot.game                       D  PlayerBase::stop() from IPlayer
2023-12-10 19:22:25.632 15220-15312 AudioTrack              com.godot.game                       D  stop(171): called with 370440 frames delivered
2023-12-10 19:22:25.668 15220-15312 godot                   com.godot.game                       I  ~AudioDriverOpenSL
2023-12-10 19:22:25.668 15220-15312 godot                   com.godot.game                       I  end
2023-12-10 19:22:25.668 15220-15220 GodotActivity           com.godot.game                       V  Force quitting Godot instance
2023-12-10 19:22:25.669 15220-15220 Process                 com.godot.game                       I  Sending signal. PID: 15220 SIG: 9
---------------------------- PROCESS ENDED (15220) for package com.godot.game ----------------------------

APP-LIST button + wipe away (remove) the app

At first everything is paused, stopped and only the OpenGL Surface is destroyed. After 5 seconds I removed the app, at the end only the message Destroying Godot app... appears. I hope that the resources will be fully released by the system.

Logcat
2023-12-10 19:49:04.762 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  MSG_WINDOW_FOCUS_CHANGED 0 0
2023-12-10 19:49:04.815 16980-16994 ViewRootIm...[GodotApp] com.godot.game                       I  Resizing android.view.ViewRootImpl@84c60fb: frame = [0,0][2560,1600] reportDraw = false forceLayout = false syncSeqId = 0
2023-12-10 19:49:04.817 16980-16980 InsetsController        com.godot.game                       D  onStateChanged: InsetsState: {mDisplayFrame=Rect(0, 0 - 2560, 1600), mDisplayCutout=DisplayCutout{insets=Rect(0, 0 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]} cutoutPathParserInfo={CutoutPathParserInfo{displayWidth=0 displayHeight=0 physicalDisplayWidth=0 physicalDisplayHeight=0 density={0.0} cutoutSpec={} rotation={0} scale={0.0} physicalPixelDisplaySizeRatio={0.0}}}}, mRoundedCorners=RoundedCorners{[RoundedCorner{position=TopLeft, radius=28, center=Point(28, 28)}, RoundedCorner{position=TopRight, radius=28, center=Point(2532, 28)}, RoundedCorner{position=BottomRight, radius=28, center=Point(2532, 1572)}, RoundedCorner{position=BottomLeft, radius=28, center=Point(28, 1572)}]}  mRoundedCornerFrame=Rect(0, 0 - 2560, 1600), mPrivacyIndicatorBounds=PrivacyIndicatorBounds {static bounds=Rect(2466, 0 - 2560, 51) rotation=1}, mSources= { InsetsSource: {mType=ITYPE_STATUS_BAR, mFrame=[0,0][2560,51], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_LEFT_GESTURES, mFrame=[0,0][0,1600], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_RIGHT_GESTURES, mFrame=[2560,0][2560,1600], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_TOP_MANDATORY_GESTURES, mFrame=[0,0][2560,51], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_BOTTOM_MANDATORY_GESTURES, mFrame=[0,1498][2560,1600], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_TOP_TAPPABLE_ELEMENT, mFrame=[0,0][2560,51], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_BOTTOM_TAPPABLE_ELEMENT, mFrame=[0,1498][2560,1600], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_IME, mFrame=[0,0][0,0], mVisibleFrame=[0,843][2560,1600], mVisible=false, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_EXTRA_NAVIGATION_BAR, mFrame=[0,1498][2560,1600], mVisible=true, mInsetsRoundedCornerFrame=false} } host=com.godot.game/com.godot.game.GodotApp from=android.view.ViewRootImpl$ViewRootHandler.handleMessageImpl:6805
2023-12-10 19:49:04.818 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  handleResized, msg = 4 frames=ClientWindowFrames{frame=[0,0][2560,1600] display=[0,0][2560,1600] parentFrame=[0,0][0,0] parentClippedByDisplayCutout=false} forceNextWindowRelayout=false displayId=0 resizeMode=-1 frameChanged=false displayFrameChanged=false configChanged=false displayChanged=false
2023-12-10 19:49:05.248 16980-17015 com.godot.game          com.godot.game                       D  PlayerBase::pause() from IPlayer
2023-12-10 19:49:05.272 16980-16980 SensorManager           com.godot.game                       D  unregisterListener
2023-12-10 19:49:05.278 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  handleAppVisibility mAppVisible = true visible = false
2023-12-10 19:49:05.281 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  stopped(true) old = false
2023-12-10 19:49:05.282 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  WindowStopped on com.godot.game/com.godot.game.GodotApp set to true
2023-12-10 19:49:05.283 16980-17004 SurfaceView@63828d0     com.godot.game                       D  windowPositionLost, frameNr = 0
2023-12-10 19:49:05.284 16980-17004 SurfaceView@63828d0     com.godot.game                       I  aOrMT: ViewRootImpl@fc8ec7e[GodotApp] t = android.view.SurfaceControl$Transaction@623a8d5 fN = 0 android.view.SurfaceView.-$$Nest$mapplyOrMergeTransaction:0 android.view.SurfaceView$SurfaceViewPositionUpdateListener.positionLost:1579 android.graphics.RenderNode$CompositePositionUpdateListener.positionLost:380 
2023-12-10 19:49:05.285 16980-16980 SurfaceView@63828d0     com.godot.game                       I  windowStopped(true) false org.godotengine.godot.GodotGLRenderView{63828d0 VFE...... .F...... 0,0-2560,1447 aid=1073741825} of ViewRootImpl@fc8ec7e[GodotApp]
2023-12-10 19:49:05.286 16980-16980 SurfaceView@63828d0     com.godot.game                       I  Changes: creating=false format=false size=false visible=true alpha=false hint=false mUseAlpha=false visible=true left=false top=false
2023-12-10 19:49:05.286 16980-16980 SurfaceView@63828d0     com.godot.game                       I  104343760 Cur surface: Surface(name=null)/@0x69ad448
2023-12-10 19:49:05.287 16980-16980 SurfaceView@63828d0     com.godot.game                       I  applyTransactionOnVriDraw: vri = ViewRootImpl@fc8ec7e[GodotApp] fRS = false t = 0xb40000775ee96000 android.view.SurfaceView.performSurfaceTransaction:970 android.view.SurfaceView.updateSurface:1116 android.view.SurfaceView.setWindowStopped:346 
2023-12-10 19:49:05.288 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  applyTransactionOnDraw: mRemoved = false isHardwareEnabled = true t = 0xb40000775ee96000android.view.SurfaceView.applyTransactionOnVriDraw:2059 android.view.SurfaceView.performSurfaceTransaction:970 android.view.SurfaceView.updateSurface:1116 android.view.SurfaceView.setWindowStopped:346 android.view.SurfaceView.surfaceDestroyed:1874 
2023-12-10 19:49:05.288 16980-16980 SurfaceView@63828d0     com.godot.game                       I  surfaceDestroyed
2023-12-10 19:49:05.289 16980-16980 SurfaceView@63828d0     com.godot.game                       I  surfaceDestroyed callback.size 1 #1 org.godotengine.godot.GodotGLRenderView{63828d0 VFE...... .F...... 0,0-2560,1447 aid=1073741825}
2023-12-10 19:49:05.289 16980-16980 SurfaceView@63828d0     com.godot.game                       I  updateSurface: mVisible = false mSurface.isValid() = true
2023-12-10 19:49:05.290 16980-16980 SurfaceView@63828d0     com.godot.game                       I  releaseSurfaces: viewRoot = ViewRootImpl@fc8ec7e[GodotApp]
2023-12-10 19:49:05.291 16980-16980 SurfaceView@63828d0     com.godot.game                       I  applyTransactionOnVriDraw: vri = ViewRootImpl@fc8ec7e[GodotApp] fRS = true t = 0xb4000076ceaf4700 android.view.SurfaceView.releaseSurfaces:869 android.view.SurfaceView.updateSurface:1183 android.view.SurfaceView.setWindowStopped:346 
2023-12-10 19:49:05.291 16980-16980 SurfaceView@63828d0     com.godot.game                       I  applyTransactionOnVriDraw: viewRoot.applyTransactionOnDrawFromReleaseSurfaces
2023-12-10 19:49:05.291 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  from releaseSurfaces t.apply t = 0xb4000076ceaf4700
2023-12-10 19:49:05.292 16980-16980 SurfaceView@63828d0     com.godot.game                       V  Layout: x=0 y=51 w=2560 h=1447, frame=Rect(0, 0 - 2560, 1447)
2023-12-10 19:49:05.303 16980-16980 MSHandlerLifeCycle      com.godot.game                       I  check: return. Multi-window not supported pkg=com.godot.game
2023-12-10 19:49:05.303 16980-16980 MSHandlerLifeCycle      com.godot.game                       I  removeMultiSplitHandler: no exist. decor=DecorView@d42bb7a[GodotApp]
2023-12-10 19:49:05.306 16980-16980 InputTransport          com.godot.game                       D  Input channel destroyed: 'ClientS', fd=122
2023-12-10 19:49:05.311 16980-16980 SurfaceView@63828d0     com.godot.game                       I  onWindowVisibilityChanged(8) false org.godotengine.godot.GodotGLRenderView{63828d0 VFE...... .F...... 0,0-2560,1447 aid=1073741825} of ViewRootImpl@fc8ec7e[GodotApp]
2023-12-10 19:49:05.311 16980-16980 SurfaceView@63828d0     com.godot.game                       D  updateSurface: surface is not valid
2023-12-10 19:49:05.311 16980-16980 SurfaceView@63828d0     com.godot.game                       I  releaseSurfaces: viewRoot = ViewRootImpl@fc8ec7e[GodotApp]
2023-12-10 19:49:05.312 16980-16980 SurfaceView@63828d0     com.godot.game                       I  applyTransactionOnVriDraw: vri = ViewRootImpl@fc8ec7e[GodotApp] fRS = true t = 0xb40000775eeba500 android.view.SurfaceView.releaseSurfaces:869 android.view.SurfaceView.updateSurface:1009 android.view.SurfaceView.onWindowVisibilityChanged:382 
2023-12-10 19:49:05.312 16980-16980 SurfaceView@63828d0     com.godot.game                       I  applyTransactionOnVriDraw: viewRoot.applyTransactionOnDrawFromReleaseSurfaces
2023-12-10 19:49:05.312 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  from releaseSurfaces t.apply t = 0xb40000775eeba500
2023-12-10 19:49:05.313 16980-17004 OpenGLRenderer          com.godot.game                       D  setSurface called with nullptr
2023-12-10 19:49:05.313 16980-17004 OpenGLRenderer          com.godot.game                       D  setSurface() destroyed EGLSurface
2023-12-10 19:49:05.313 16980-17004 OpenGLRenderer          com.godot.game                       D  destroyEglSurface
2023-12-10 19:49:05.315 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  performTraversals mFirst=false windowShouldResize=false viewVisibilityChanged=true mForceNextWindowRelayout=false params=null
2023-12-10 19:49:05.327 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  Relayout returned: old=(0,0,2560,1600) new=(0,0,2560,1600) req=(2560,1600)8 dur=11 res=0x2 s={false 0x0} ch=false seqId=0
2023-12-10 19:49:05.329 16980-16980 SurfaceView@63828d0     com.godot.game                       D  updateSurface: surface is not valid
2023-12-10 19:49:05.330 16980-16980 SurfaceView@63828d0     com.godot.game                       I  releaseSurfaces: viewRoot = ViewRootImpl@fc8ec7e[GodotApp]
2023-12-10 19:49:05.331 16980-16980 SurfaceView@63828d0     com.godot.game                       I  applyTransactionOnVriDraw: vri = ViewRootImpl@fc8ec7e[GodotApp] fRS = true t = 0xb40000775ef30700 android.view.SurfaceView.releaseSurfaces:869 android.view.SurfaceView.updateSurface:1009 android.view.SurfaceView.lambda$new$0$android-view-SurfaceView:201 
2023-12-10 19:49:05.331 16980-16980 SurfaceView@63828d0     com.godot.game                       I  applyTransactionOnVriDraw: viewRoot.applyTransactionOnDrawFromReleaseSurfaces
2023-12-10 19:49:05.331 16980-16980 ViewRootIm...[GodotApp] com.godot.game                       I  from releaseSurfaces t.apply t = 0xb40000775ef30700
2023-12-10 19:49:05.341  1459-3165  WindowManager           pid-1459                             E  win=Window{19d60d2 u0 com.godot.game/com.godot.game.GodotApp} destroySurfaces: appStopped=true cleanupOnResume=false win.mWindowRemovalAllowed=false win.mRemoveOnExit=false win.mViewVisibility=8 caller=com.android.server.wm.ActivityRecord.destroySurfaces:6776 com.android.server.wm.ActivityRecord.destroySurfaces:6757 com.android.server.wm.ActivityRecord.notifyAppStopped:6821 com.android.server.wm.ActivityRecord.activityStopped:7427 com.android.server.wm.ActivityClientController.activityStopped:263 android.app.IActivityClientController$Stub.onTransact:621 com.android.server.wm.ActivityClientController.onTransact:141 
2023-12-10 19:49:10.908 16980-16980 GodotActivity           com.godot.game                       V  Destroying Godot app...
---------------------------- PROCESS ENDED (16980) for package com.godot.game ----------------------------

Copy link
Contributor

@m4gr3d m4gr3d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good!

Can you address the comments from @AThousandShips and squash your commits once the PR is ready.

@PierceLBrooks
Copy link
Contributor Author

@m4gr3d I believe that I have already addressed the comments by @AThousandShips thus far to date, and I will handle the commit squash shortly here.

@PierceLBrooks PierceLBrooks force-pushed the plb/fix-opensl-audio-driver-closure branch from 71f3566 to c197418 Compare December 21, 2023 03:29
@m4gr3d m4gr3d modified the milestones: 4.x, 4.3 Dec 21, 2023
drivers/unix/os_unix.cpp Outdated Show resolved Hide resolved
@@ -330,3 +365,7 @@ void AudioDriverOpenSL::set_pause(bool p_pause) {

AudioDriverOpenSL::AudioDriverOpenSL() {
}

AudioDriverOpenSL::~AudioDriverOpenSL() {
end();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unnecessary, don't think the destructor of AudioDriverOpenSL can be called without finish if everything initialized properly. Here is the order of calls as far as I'm aware: _terminate() -> Main::cleanup() -> Main::cleanup() (copied to include another link) -> audio_server->finish() -> AudioServer::finish() -> AudioDriver::finish() -> delete os_android -> ~OS_Android() -> ~AudioDriverOpenSL(). If it crashes, no destructors are called. If AudioServer was not created, AudioDriverOpenSL::init, AudioDriverOpenSL::start and AudioDriverOpenSL::input_start can't be called

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any harm in leaving this here since if end() has already been called, the second call will be a no-op.

Copy link
Contributor

@kus04e4ek kus04e4ek Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no harm, but it's not needed too. It also creates inconsistency with other AudioDrivers as no other AudioDriver defines a destructor, there's already a function finish for this. It's more of a style change than anything

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a quick test and the fix still works as expected with the destructor removed so it can be removed for consistency.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed an updated removing that destructor.

I also removed the explicit ~OS_Unix destructor and virtual qualifier for ~OS_Android which were discussed above. They're not wrong, but also don't seem needed for that fix, and would introduce an inconsistency between OS_Android and other OS implementations.

If we want to make sure all classes that inherit one with a virtual destructor also make it explicit in their declaration, that should likely be a separate style fix (as I understand it it shouldn't impact the behavior: https://stackoverflow.com/questions/71249522/virtual-destructor-needed-for-class-which-is-both-derived-and-base).

Still would be worth testing the latest commit again to make sure.

Copy link
Contributor

@kus04e4ek kus04e4ek Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked the latest push and libOpenSLES: Object::Destroy errors are still gone

@akien-mga akien-mga modified the milestones: 4.3, 4.4 Jul 7, 2024
@m4gr3d
Copy link
Contributor

m4gr3d commented Jul 29, 2024

@akien-mga #85979 is more visible after #94661 (the Android OS thinks the app has crashed even though it's still running) so we should include this PR in 4.3.

I had approved this PR a while ago, so it's good to go from my point of view.

@m4gr3d m4gr3d modified the milestones: 4.4, 4.3 Jul 29, 2024
@akien-mga akien-mga changed the title Ensure a total cleanup of all relevant subobjects within the OpenSL audio driver for Android Android: Ensure cleanup of all subobjects in the OpenSL audio driver Jul 30, 2024
@akien-mga akien-mga force-pushed the plb/fix-opensl-audio-driver-closure branch from c197418 to 7b99033 Compare July 30, 2024 15:17
@akien-mga akien-mga force-pushed the plb/fix-opensl-audio-driver-closure branch from 7b99033 to e3482a9 Compare July 30, 2024 15:20
@akien-mga akien-mga merged commit f763962 into godotengine:master Jul 31, 2024
18 checks passed
@akien-mga
Copy link
Member

Thanks! And congrats for your first merged Godot contribution 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Android's OpenSL audio driver complains about members that remain open after app closure
7 participants