diff --git a/kivy/core/window/_window_sdl2.pyx b/kivy/core/window/_window_sdl2.pyx
index 46e15ec63..5002cd0f9 100644
--- a/kivy/core/window/_window_sdl2.pyx
+++ b/kivy/core/window/_window_sdl2.pyx
@@ -746,7 +746,13 @@ cdef class _WindowSDL2Storage:
             pass
 
     def flip(self):
-        SDL_GL_SwapWindow(self.win)
+        # On Android (and potentially other platforms), SDL_GL_SwapWindow may
+        # lock the thread waiting for a mutex from another thread to be
+        # released. Calling SDL_GL_SwapWindow with the GIL released allow the
+        # other thread to run (e.g. to process the event filter callback) and
+        # release the mutex SDL_GL_SwapWindow is waiting for.
+        with nogil:
+            SDL_GL_SwapWindow(self.win)
 
     def save_bytes_in_png(self, filename, data, int width, int height):
         cdef SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(
diff --git a/kivy/lib/sdl2.pxi b/kivy/lib/sdl2.pxi
index 6a539de6d..3a5a69d23 100644
--- a/kivy/lib/sdl2.pxi
+++ b/kivy/lib/sdl2.pxi
@@ -627,7 +627,7 @@ cdef extern from "SDL.h":
     cdef SDL_GLContext SDL_GL_GetCurrentContext()
     cdef int SDL_GL_SetSwapInterval(int interval)
     cdef int SDL_GL_GetSwapInterval()
-    cdef void SDL_GL_SwapWindow(SDL_Window * window)
+    cdef void SDL_GL_SwapWindow(SDL_Window * window) nogil
     cdef void SDL_GL_DeleteContext(SDL_GLContext context)
 
     cdef int SDL_NumJoysticks()
