Android: add command mecanism so that SDLActivity#14962
Android: add command mecanism so that SDLActivity#149621bsyl wants to merge 8 commits intolibsdl-org:mainfrom
Conversation
|
still need comment: "We still need to pump events for lifecycle activity even if there's no window or video hasn't been initialized."
|
|
I'm marking this as draft until you have a chance to test it more thoroughly in production. @AntTheAlchemist, any chance you can try this patch in a production release and provide feedback? |
|
FWIW, right now there is only one window, but conceptually the pump call would get all life cycle events and events for all windows. |
769a432 to
de582b3
Compare
|
I remember I did a while ago a patch to have multiple SDL_Window on Android, there were several SurfaceView and several Activity involved. I don't remember how it worked though.. just that it didn't provide all the functionality of SDL. maybe I could dust it out and give a try. Btw, I am trying the patch in production. I need a one or two week to have more information. |
|
MultiCraft Open Source is on the line 😀 |
|
@MoNTE48 nice, thanks for sharing. Let us know ! BTW: "the compare vs ALL Release" metric is not really relevant. because my SDL lib was a modified version. |
|
After 30K sessions, I can see that the ANR issue has been resolved. I can clearly see new ANRs with AppMetrica or the advertising library, but libSDL is no longer the cause. I didn't enable the GAMEPAD_AS_RPC build flag, but I'm not sure how many of my players use gamepads. Just one new, rare crash: |
|
Ok thanks for the info ! do you have information like how your crash rate or anr rate is now ?. I also have the ANativeWindow_setBuffersGeometry crash in SDL_CreateWindow, I have also some rare crash in: I believe it's possible that some ANR becomes Crash. or inverse. or change name. (Of course, if this is something reproducible, even with adding SDL_Delay() in code, this is has to be debugged...) |
|
looking at aosp code, setBuffersGeometry calls set_buffer_format, which doesn't check the handle validity. |
|
I'm late to the party - sorry guys. I'm now taking a proper look at this and report back with results from a production release. Currently, my gamepad heavy app stands at 0.02% crash rate and 0.18% ANR rate. Current common crashes (without this pull): Current common ANRs (without this pull): Watch this space. |
|
nice! |
|
@1bsyl what about |
36daee4 to
4359ae4
Compare
|
@MoNTE48 I adding this anyway |
So this is 3 weeks. This doesn't take into account : Android: check native_window is valid before calling ANativeWindow_setBuffersGeometry Android: add semaphores so that nativeSurface methods can wait up to going to try another test with the two previous commits |
4359ae4 to
224c331
Compare
|
So it's 1 week after starting 2nd test. that includes in addition:
Install base is the same as 1st test: ~130k users. So far, number of crash are reduced: 15
edit: as difference with 1st test, I rolled out the 2nd test directly to 100%. (whereas I waited 1 day before doing that for the 1st one). |
|
This patch doesn't work for my apps. It seems to block all input events, which only come through when the app enters background. The 2nd time I leave the app and return, I get a black screen. Am I missing something? |
|
SDL_AppEvent isn't being called for input events. Is anyone else using the SDL_App* stuff? |
|
@AntTheAlchemist I didn't try SDL_AppEvent, but now it's ok with last commit. It also takes into account block on pause (very last commit separated). but there are more changes inside: all cycle event are moved with the RPC command flow, instead of being a separate channel. this is going to be a new test in a few weeks, once the v2 finished.
NB: |
|
Thanks for that. Seems to work, but I've found a problem. After a SDL_WINDOW_RESTORED, the first frame drawn produces a black screen. This used to be fixed with a pre-emptive duplicated call to SDL_RenderPresent(), but that no longer works. My app doesn't redraw every SDL_AppIterate. It sets a redraw and refresh flag after a SDL_WINDOW_RESTORED event is recieved, then in the following SDL_AppIterate call, no draw methods are valid. No other events are sent, so the app is juts a black screen. There's no way to fix this unless my app redraws every SDL_AppIterate. |
|
@AntTheAlchemist to be clear:
diff --git a/test/testsprite.c b/test/testsprite.c
index 575be1163..010a8b49c 100644
--- a/test/testsprite.c
+++ b/test/testsprite.c
@@ -79,6 +79,7 @@ static bool LoadSprite(const char *file)
return true;
}
+static int g_draw = 0; // or can start at 1 also.
static void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite)
{
int i;
@@ -86,6 +87,10 @@ static void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite)
SDL_FRect temp;
SDL_FRect *position, *velocity;
+ if (g_draw) {
+ SDL_Log("will draw...");
+ g_draw = 0;
+ } else { return; }
/* Query the sizes */
SDL_SetRenderViewport(renderer, NULL);
SDL_GetRenderSafeArea(renderer, &viewport);
@@ -565,6 +570,10 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
if (event->type == SDL_EVENT_RENDER_DEVICE_RESET) {
LoadSprite(icon);
}
+ if (event->type == SDL_EVENT_WINDOW_RESTORED) {
+ SDL_Log("SDL_EVENT_WINDOW_RESTORED !!!");
+ g_draw = 1;
+ }
return SDLTest_CommonEventMainCallbacks(state, event);
}
here's simplified log, when going to FG |
|
Your testprite mod should fail, even without this pull. There's a known bug: #11324 |
|
@AntTheAlchemist, I am answering in the other ticket then .. |
|
Were you testing using opengles2? Vulkan wouldn't have this issue. |
|
@1bsyl is there a way I can merge this PR with the latest SDL so I can download the entire source as a ZIP? This is currently 50 commits behind. |
|
@AntTheAlchemist I am going to do a re-base |
executes no SDL code, but defers it to SDL main thread
SDLActivity hasFocus otherwise, this error may appear: DequeueBuffer: dequeueBuffer failed eglSwapBuffersWithDamageKHRImpl:1411 error 300d (EGL_BAD_SURFACE)
and Android_nativeSurface* to Android_NativeSurface*
100 ms for the C Thread to perform the corresponding action
…nt() broken after resize Call ANativeWindow_setBuffersGeometry when size changes. in addition: remove semaphores for NativeSurfaceChanged/Created/Destroyed, they were not active anyway - at start, the timeout expire because the app hasn't start. - in background. it would also expire as app is blocked-on-pause
dbdf818 to
ca98027
Compare
|
@AntTheAlchemist it should be sync'ed with latest |
|
Perhaps some of the changes could be in a separate PR, which would be reviewed and merged faster than so many changes? In any case, thank you for your work! |
|
@MoNTE48 thanks ! except for the 11324 which could be apart. (see SDL_androidwindow.c if you need it). but that not tested with Head (I am still running my tests for few days again) |




Add some RPC commands so that SDLActivity defers most of SDL code internal execution it to the SDL main thread
see #14925
Most SDLActivity code is deferred to main SDL C thread with some command RPC.
except:
(SDL_Window *)Android_Window global variable is removed.
Android ActivityMutex is removed.
Android_LifecycleMutex, is used to lock the SDLActivity state. (Android_WaitActiveAndLockActivity()).
since it prevents the SDLActivity to add new lifecylce message, it prevents it to change state.
factorisation of EGLSurface/native_window handling. (use in surfaceChanged/Created/Destroy, and SDLCreate/DestroyWindow()
It seem to work quite nicely from my side. I tested various stuff, but not fully.
(onNativeFileDialog() was the less easy to update, and I really have to tested).
other functions are always simple. I guess, the ways it's written with named struct, prevent lot of type mistake.
Still a draft. please give a try.
I'll try it also in production maybe in a while
maybe 2 todo:
I didn't add the HID native functions .. I am not familiar with them. but then didn't rely on SDL and use no locking.
so maybe it makes not difference. (they could be added anyway afterwards).
we probably lose some event timestamp precision because event are sent from Main thread, and not SDLActivity thread. maybe it's not a big deal.
but if we need it for some command, we could add. (just enabled the timestamp, and then send it with the event).
maybe we wait to see, if this is really useful