diff --git a/pythonforandroid/bootstraps/sdl2/build/src/main/java/org/kivy/android/PythonActivity.java b/pythonforandroid/bootstraps/sdl2/build/src/main/java/org/kivy/android/PythonActivity.java index f1fd943a34..ded381f161 100644 --- a/pythonforandroid/bootstraps/sdl2/build/src/main/java/org/kivy/android/PythonActivity.java +++ b/pythonforandroid/bootstraps/sdl2/build/src/main/java/org/kivy/android/PythonActivity.java @@ -199,7 +199,7 @@ protected void onPostExecute(String result) { ))) { // Because sometimes the app will get stuck here and never // actually run, ensure that it gets launched if we're active: - mActivity.onResume(); + mActivity.resumeNativeThread(); } } diff --git a/pythonforandroid/bootstraps/sdl2/build/src/patches/SDLActivity.java.patch b/pythonforandroid/bootstraps/sdl2/build/src/patches/SDLActivity.java.patch index 4c24e458b6..c7aa4bf666 100644 --- a/pythonforandroid/bootstraps/sdl2/build/src/patches/SDLActivity.java.patch +++ b/pythonforandroid/bootstraps/sdl2/build/src/patches/SDLActivity.java.patch @@ -1,18 +1,18 @@ --- a/src/main/java/org/libsdl/app/SDLActivity.java +++ b/src/main/java/org/libsdl/app/SDLActivity.java -@@ -94,6 +94,8 @@ +@@ -225,6 +225,8 @@ // This is what SDL runs in. It invokes SDL_main(), eventually protected static Thread mSDLThread; - + + public static int keyboardInputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD; + protected static SDLGenericMotionListener_API12 getMotionListener() { if (mMotionListener == null) { if (Build.VERSION.SDK_INT >= 26) { -@@ -196,6 +198,15 @@ +@@ -323,6 +325,15 @@ Log.v(TAG, "onCreate()"); super.onCreate(savedInstanceState); - + + SDLActivity.initialize(); + // So we can call stuff from static callbacks + mSingleton = this; @@ -22,70 +22,54 @@ + // and we can't run setup tasks until that thread completes. + protected void finishLoad() { + - // Load shared libraries - String errorMsgBrokenLib = ""; try { -@@ -639,7 +650,7 @@ + Thread.currentThread().setName("SDLActivity"); + } catch (Exception e) { +@@ -824,7 +835,7 @@ Handler commandHandler = new SDLCommandHandler(); - + // Send a message from the SDLMain thread - boolean sendCommand(int command, Object data) { + protected boolean sendCommand(int command, Object data) { Message msg = commandHandler.obtainMessage(); msg.arg1 = command; msg.obj = data; -@@ -1051,6 +1062,21 @@ - return Arrays.copyOf(filtered, used); +@@ -1302,6 +1313,20 @@ + return SDLActivity.mSurface.getNativeSurface(); } - -+ /** -+ * Calls turnActive() on singleton to keep loading screen active -+ */ -+ public static void triggerAppConfirmedActive() { -+ mSingleton.appConfirmedActive(); -+ } -+ -+ /** -+ * Trick needed for loading screen, overridden by PythonActivity -+ * to keep loading screen active -+ */ -+ public void appConfirmedActive() { -+ } -+ + ++ /** ++ * Calls turnActive() on singleton to keep loading screen active ++ */ ++ public static void triggerAppConfirmedActive() { ++ mSingleton.appConfirmedActive(); ++ } ++ ++ /** ++ * Trick needed for loading screen, overridden by PythonActivity ++ * to keep loading screen active ++ */ ++ public void appConfirmedActive() { ++ } + - // APK expansion files support - - /** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */ -@@ -1341,14 +1367,13 @@ - }; - - public void onSystemUiVisibilityChange(int visibility) { -- if (SDLActivity.mFullscreenModeActive && (visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 || (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) { -- -+ // SDL2 BUGFIX (see sdl bug #4424 ) - REMOVE WHEN FIXED IN UPSTREAM !! -+ if (SDLActivity.mFullscreenModeActive && ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 || (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)) { - Handler handler = getWindow().getDecorView().getHandler(); - if (handler != null) { - handler.removeCallbacks(rehideSystemUi); // Prevent a hide loop. - handler.postDelayed(rehideSystemUi, 2000); - } -- + // Input + + /** +@@ -1795,7 +1820,7 @@ } - } - -@@ -1475,6 +1500,7 @@ - String[] arguments = SDLActivity.mSingleton.getArguments(); - + Log.v("SDL", "Running main function " + function + " from library " + library); +- + SDLActivity.mSingleton.appConfirmedActive(); SDLActivity.nativeRunMain(library, function, arguments); - + Log.v("SDL", "Finished main function"); -@@ -2002,7 +2028,7 @@ +@@ -2316,7 +2341,7 @@ public InputConnection onCreateInputConnection(EditorInfo outAttrs) { ic = new SDLInputConnection(this, true); - -- outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD; + +- outAttrs.inputType = InputType.TYPE_CLASS_TEXT; + outAttrs.inputType = SDLActivity.keyboardInputType; outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_FLAG_NO_FULLSCREEN /* API 11 */; + diff --git a/pythonforandroid/recipes/kivy/__init__.py b/pythonforandroid/recipes/kivy/__init__.py index 82e22dfda4..bece49ee6f 100644 --- a/pythonforandroid/recipes/kivy/__init__.py +++ b/pythonforandroid/recipes/kivy/__init__.py @@ -1,11 +1,26 @@ import glob from os.path import basename, exists, join +import sys +import packaging.version import sh from pythonforandroid.recipe import CythonRecipe from pythonforandroid.toolchain import current_directory, shprint +def is_kivy_affected_by_deadlock_issue(recipe=None, arch=None): + with current_directory(join(recipe.get_build_dir(arch.arch), "kivy")): + kivy_version = shprint( + sh.Command(sys.executable), + "-c", + "import _version; print(_version.__version__)", + ) + + return packaging.version.parse( + str(kivy_version) + ) < packaging.version.Version("2.2.0.dev0") + + class KivyRecipe(CythonRecipe): version = '2.1.0' url = 'https://github.com/kivy/kivy/archive/{version}.zip' @@ -14,6 +29,11 @@ class KivyRecipe(CythonRecipe): depends = ['sdl2', 'pyjnius', 'setuptools'] python_depends = ['certifi'] + # sdl-gl-swapwindow-nogil.patch is needed to avoid a deadlock. + # See: https://github.com/kivy/kivy/pull/8025 + # WARNING: Remove this patch when a new Kivy version is released. + patches = [("sdl-gl-swapwindow-nogil.patch", is_kivy_affected_by_deadlock_issue)] + def cythonize_build(self, env, build_dir='.'): super().cythonize_build(env, build_dir=build_dir) @@ -48,7 +68,7 @@ def get_recipe_env(self, arch): env['KIVY_SDL2_PATH'] = ':'.join([ join(self.ctx.bootstrap.build_dir, 'jni', 'SDL', 'include'), join(self.ctx.bootstrap.build_dir, 'jni', 'SDL2_image'), - join(self.ctx.bootstrap.build_dir, 'jni', 'SDL2_mixer'), + join(self.ctx.bootstrap.build_dir, 'jni', 'SDL2_mixer', 'include'), join(self.ctx.bootstrap.build_dir, 'jni', 'SDL2_ttf'), ]) diff --git a/pythonforandroid/recipes/kivy/sdl-gl-swapwindow-nogil.patch b/pythonforandroid/recipes/kivy/sdl-gl-swapwindow-nogil.patch new file mode 100644 index 0000000000..8a7c33a8be --- /dev/null +++ b/pythonforandroid/recipes/kivy/sdl-gl-swapwindow-nogil.patch @@ -0,0 +1,32 @@ +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() diff --git a/pythonforandroid/recipes/sdl2/__init__.py b/pythonforandroid/recipes/sdl2/__init__.py index 114a9ea8d4..d1929d06d8 100644 --- a/pythonforandroid/recipes/sdl2/__init__.py +++ b/pythonforandroid/recipes/sdl2/__init__.py @@ -6,9 +6,9 @@ class LibSDL2Recipe(BootstrapNDKRecipe): - version = "2.0.9" - url = "https://www.libsdl.org/release/SDL2-{version}.tar.gz" - md5sum = 'f2ecfba915c54f7200f504d8b48a5dfe' + version = "2.24.0" + url = "https://github.com/libsdl-org/SDL/releases/download/release-{version}/SDL2-{version}.tar.gz" + md5sum = 'cf539ffe9e0dd6f943ac9de75fd2e56e' dir_name = 'SDL' @@ -22,7 +22,7 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True, with_python=True): def should_build(self, arch): libdir = join(self.get_build_dir(arch.arch), "../..", "libs", arch.arch) - libs = ['libhidapi.so', 'libmain.so', 'libSDL2.so', 'libSDL2_image.so', 'libSDL2_mixer.so', 'libSDL2_ttf.so'] + libs = ['libmain.so', 'libSDL2.so', 'libSDL2_image.so', 'libSDL2_mixer.so', 'libSDL2_ttf.so'] return not all(exists(join(libdir, x)) for x in libs) def build_arch(self, arch): diff --git a/pythonforandroid/recipes/sdl2_image/__init__.py b/pythonforandroid/recipes/sdl2_image/__init__.py index 920b3ae648..a91c6f1bc2 100644 --- a/pythonforandroid/recipes/sdl2_image/__init__.py +++ b/pythonforandroid/recipes/sdl2_image/__init__.py @@ -1,14 +1,25 @@ +import os +import sh +from pythonforandroid.logger import shprint from pythonforandroid.recipe import BootstrapNDKRecipe +from pythonforandroid.util import current_directory class LibSDL2Image(BootstrapNDKRecipe): - version = '2.0.4' - url = 'https://www.libsdl.org/projects/SDL_image/release/SDL2_image-{version}.tar.gz' + version = '2.6.2' + url = 'https://github.com/libsdl-org/SDL_image/releases/download/release-{version}/SDL2_image-{version}.tar.gz' dir_name = 'SDL2_image' - patches = ['toggle_jpg_png_webp.patch', - 'extra_cflags.patch', - ] + patches = ['enable-webp.patch'] + + def prebuild_arch(self, arch): + # We do not have a folder for each arch on BootstrapNDKRecipe, so we + # need to skip the external deps download if we already have done it. + external_deps_dir = os.path.join(self.get_build_dir(arch.arch), "external") + if not os.path.exists(os.path.join(external_deps_dir, "libwebp")): + with current_directory(external_deps_dir): + shprint(sh.Command("./download.sh")) + super().prebuild_arch(arch) recipe = LibSDL2Image() diff --git a/pythonforandroid/recipes/sdl2_image/add_ndk_platform_include_dir.patch b/pythonforandroid/recipes/sdl2_image/add_ndk_platform_include_dir.patch deleted file mode 100644 index 123e5c573a..0000000000 --- a/pythonforandroid/recipes/sdl2_image/add_ndk_platform_include_dir.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/Android.mk b/Android.mk -index d48111b..3108b2c 100644 ---- a/Android.mk -+++ b/Android.mk -@@ -22,7 +22,7 @@ SUPPORT_WEBP := false - WEBP_LIBRARY_PATH := external/libwebp-0.3.0 - - --LOCAL_C_INCLUDES := $(LOCAL_PATH) -+LOCAL_C_INCLUDES := $(LOCAL_PATH) $(NDK_PLATFORM_INCLUDE_DIR) - LOCAL_CFLAGS := -DLOAD_BMP -DLOAD_GIF -DLOAD_LBM -DLOAD_PCX -DLOAD_PNM \ - -DLOAD_TGA -DLOAD_XCF -DLOAD_XPM -DLOAD_XV - LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays $(EXTRA_CFLAGS) diff --git a/pythonforandroid/recipes/sdl2_image/enable-webp.patch b/pythonforandroid/recipes/sdl2_image/enable-webp.patch new file mode 100644 index 0000000000..98d72f2017 --- /dev/null +++ b/pythonforandroid/recipes/sdl2_image/enable-webp.patch @@ -0,0 +1,12 @@ +diff -Naur SDL2_image.orig/Android.mk SDL2_image/Android.mk +--- SDL2_image.orig/Android.mk 2022-10-03 20:51:52.000000000 +0200 ++++ SDL2_image/Android.mk 2022-10-03 20:52:48.000000000 +0200 +@@ -32,7 +32,7 @@ + + # Enable this if you want to support loading WebP images + # The library path should be a relative path to this directory. +-SUPPORT_WEBP ?= false ++SUPPORT_WEBP := true + WEBP_LIBRARY_PATH := external/libwebp + + diff --git a/pythonforandroid/recipes/sdl2_image/extra_cflags.patch b/pythonforandroid/recipes/sdl2_image/extra_cflags.patch deleted file mode 100644 index c2b875bbe4..0000000000 --- a/pythonforandroid/recipes/sdl2_image/extra_cflags.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- SDL2_image-2.0.4/Android.mk.orig 2018-10-31 15:58:52.000000000 +0100 -+++ SDL2_image-2.0.4/Android.mk 2019-02-07 21:57:29.552365123 +0100 -@@ -61,6 +61,8 @@ LOCAL_SRC_FILES := \ - - LOCAL_CFLAGS := -DLOAD_BMP -DLOAD_GIF -DLOAD_LBM -DLOAD_PCX -DLOAD_PNM \ - -DLOAD_SVG -DLOAD_TGA -DLOAD_XCF -DLOAD_XPM -DLOAD_XV -+LOCAL_CFLAGS += $(EXTRA_CFLAGS) -+ - LOCAL_LDLIBS := - LOCAL_STATIC_LIBRARIES := - LOCAL_SHARED_LIBRARIES := SDL2 diff --git a/pythonforandroid/recipes/sdl2_image/toggle_jpg_png_webp.patch b/pythonforandroid/recipes/sdl2_image/toggle_jpg_png_webp.patch deleted file mode 100644 index f7dce8ac62..0000000000 --- a/pythonforandroid/recipes/sdl2_image/toggle_jpg_png_webp.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- SDL2_image-2.0.4/Android.mk.orig 2018-10-31 15:58:52.000000000 +0100 -+++ SDL2_image-2.0.4/Android.mk 2019-02-07 23:51:51.740299680 +0100 -@@ -3,18 +3,18 @@ SDL_IMAGE_LOCAL_PATH := $(call my-dir) - - # Enable this if you want to support loading JPEG images - # The library path should be a relative path to this directory. --SUPPORT_JPG ?= true -+SUPPORT_JPG := true - JPG_LIBRARY_PATH := external/jpeg-9b - - # Enable this if you want to support loading PNG images - # The library path should be a relative path to this directory. --SUPPORT_PNG ?= true -+SUPPORT_PNG := true - PNG_LIBRARY_PATH := external/libpng-1.6.32 - - # Enable this if you want to support loading WebP images - # The library path should be a relative path to this directory. --SUPPORT_WEBP ?= true --WEBP_LIBRARY_PATH := external/libwebp-0.6.0 -+SUPPORT_WEBP := true -+WEBP_LIBRARY_PATH := external/libwebp-1.0.0 - - - # Build the library diff --git a/pythonforandroid/recipes/sdl2_mixer/__init__.py b/pythonforandroid/recipes/sdl2_mixer/__init__.py index 32369f21ef..733ef21148 100644 --- a/pythonforandroid/recipes/sdl2_mixer/__init__.py +++ b/pythonforandroid/recipes/sdl2_mixer/__init__.py @@ -2,11 +2,9 @@ class LibSDL2Mixer(BootstrapNDKRecipe): - version = '2.0.4' - url = 'https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-{version}.tar.gz' + version = '2.6.2' + url = 'https://github.com/libsdl-org/SDL_mixer/releases/download/release-{version}/SDL2_mixer-{version}.tar.gz' dir_name = 'SDL2_mixer' - patches = ['toggle_modplug_mikmod_smpeg_ogg.patch'] - recipe = LibSDL2Mixer() diff --git a/pythonforandroid/recipes/sdl2_mixer/toggle_modplug_mikmod_smpeg_ogg.patch b/pythonforandroid/recipes/sdl2_mixer/toggle_modplug_mikmod_smpeg_ogg.patch deleted file mode 100644 index 9c3c9e52f4..0000000000 --- a/pythonforandroid/recipes/sdl2_mixer/toggle_modplug_mikmod_smpeg_ogg.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- orig/Android.mk 2018-10-31 15:58:59.000000000 +0100 -+++ patched/Android.mk 2019-03-08 12:11:35.271258500 +0100 -@@ -3,7 +3,7 @@ - - - # Enable this if you want to support loading FLAC music with libFLAC --SUPPORT_FLAC ?= true -+SUPPORT_FLAC := false - FLAC_LIBRARY_PATH := external/flac-1.3.2 - - # Enable this if you want to support loading OGG Vorbis music via Tremor -@@ -12,11 +12,11 @@ - VORBIS_LIBRARY_PATH := external/libvorbisidec-1.2.1 - - # Enable this if you want to support loading MP3 music via MPG123 --SUPPORT_MP3_MPG123 ?= true -+SUPPORT_MP3_MPG123 := false - MPG123_LIBRARY_PATH := external/mpg123-1.25.6 - - # Enable this if you want to support loading MOD music via modplug --SUPPORT_MOD_MODPLUG ?= true -+SUPPORT_MOD_MODPLUG := false - MODPLUG_LIBRARY_PATH := external/libmodplug-0.8.9.0 - - # Enable this if you want to support TiMidity diff --git a/pythonforandroid/recipes/sdl2_ttf/__init__.py b/pythonforandroid/recipes/sdl2_ttf/__init__.py index bbebaac6a1..4934bd4a67 100644 --- a/pythonforandroid/recipes/sdl2_ttf/__init__.py +++ b/pythonforandroid/recipes/sdl2_ttf/__init__.py @@ -2,8 +2,8 @@ class LibSDL2TTF(BootstrapNDKRecipe): - version = '2.0.15' - url = 'https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-{version}.tar.gz' + version = '2.20.1' + url = 'https://github.com/libsdl-org/SDL_ttf/releases/download/release-{version}/SDL2_ttf-{version}.tar.gz' dir_name = 'SDL2_ttf' diff --git a/setup.py b/setup.py index eaaad56883..1f61113818 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ install_reqs = [ 'appdirs', 'colorama>=0.3.3', 'jinja2', 'sh>=1.10; sys_platform!="nt"', - 'pep517', 'toml', + 'pep517', 'toml', 'packaging', ] # (pep517 and toml are used by pythonpackage.py)