diff --git a/direct/src/dist/FreezeTool.py b/direct/src/dist/FreezeTool.py
index 678f8c0888..aad6dc4b24 100644
--- a/direct/src/dist/FreezeTool.py
+++ b/direct/src/dist/FreezeTool.py
@@ -925,7 +925,22 @@ class Freezer:
if sys.version_info < (3, 8):
abi_flags += 'm'
- if 'linux' in self.platform:
+ if 'android' in self.platform:
+ arch = self.platform.split('_', 1)[1]
+ if arch in ('arm64', 'aarch64'):
+ suffixes.append(('.cpython-{0}{1}-aarch64-linux-android.so'.format(abi_version, abi_flags), 'rb', 3))
+ elif arch in ('arm', 'armv7l'):
+ suffixes.append(('.cpython-{0}{1}-arm-linux-androideabi.so'.format(abi_version, abi_flags), 'rb', 3))
+ elif arch in ('x86_64', 'amd64'):
+ suffixes.append(('.cpython-{0}{1}-x86_64-linux-android.so'.format(abi_version, abi_flags), 'rb', 3))
+ elif arch in ('i386', 'i686'):
+ suffixes.append(('.cpython-{0}{1}-i686-linux-android.so'.format(abi_version, abi_flags), 'rb', 3))
+
+ suffixes += [
+ ('.abi{0}.so'.format(sys.version_info[0]), 'rb', 3),
+ ('.so', 'rb', 3),
+ ]
+ elif 'linux' in self.platform:
suffixes += [
('.cpython-{0}{1}-x86_64-linux-gnu.so'.format(abi_version, abi_flags), 'rb', 3),
('.cpython-{0}{1}-i686-linux-gnu.so'.format(abi_version, abi_flags), 'rb', 3),
@@ -1150,6 +1165,9 @@ class Freezer:
self.modules['_frozen_importlib'] = self.ModuleDef('importlib._bootstrap', implicit = True)
self.modules['_frozen_importlib_external'] = self.ModuleDef('importlib._bootstrap_external', implicit = True)
+ if self.platform.startswith('android'):
+ self.modules['_android_support'] = self.ModuleDef('_android_support', implicit = True)
+
for moduleName in startupModules:
if moduleName not in self.modules:
self.addModule(moduleName, implicit = True)
diff --git a/direct/src/dist/_android.py b/direct/src/dist/_android.py
index ac6a8c85b9..bebb7bf9df 100644
--- a/direct/src/dist/_android.py
+++ b/direct/src/dist/_android.py
@@ -50,7 +50,7 @@ def flag_resource(id, **values):
bitmask = 0
flags = attrib.value.split('|')
for flag in flags:
- bitmask = values[flag]
+ bitmask |= values[flag]
attrib.compiled_item.prim.int_hexadecimal_value = bitmask
return compile
@@ -168,10 +168,11 @@ ANDROID_ATTRIBUTES = {
'allowSingleTap': bool_resource(0x1010259),
'allowTaskReparenting': bool_resource(0x1010204),
'alwaysRetainTaskState': bool_resource(0x1010203),
+ 'appCategory': enum_resource(0x01010545, "game", "audio", "video", "image", "social", "news", "maps", "productivity", "accessibility"),
'clearTaskOnLaunch': bool_resource(0x1010015),
+ 'configChanges': flag_resource(0x0101001f, mcc=0x0001, mnc=0x0002, locale=0x0004, touchscreen=0x0008, keyboard=0x0010, keyboardHidden=0x0020, navigation=0x0040, orientation=0x0080, screenLayout=0x0100, uiMode=0x0200, screenSize=0x0400, smallestScreenSize=0x0800, layoutDirection=0x2000, colorMode=0x4000, grammaticalGender=0x8000, fontScale=0x40000000, fontWeightAdjustment=0x10000000),
'debuggable': bool_resource(0x0101000f),
'documentLaunchMode': enum_resource(0x1010445, "none", "intoExisting", "always", "never"),
- 'configChanges': flag_resource(0x0101001f, mcc=0x0001, mnc=0x0002, locale=0x0004, touchscreen=0x0008, keyboard=0x0010, keyboardHidden=0x0020, navigation=0x0040, orientation=0x0080, screenLayout=0x0100, uiMode=0x0200, screenSize=0x0400, smallestScreenSize=0x0800, layoutDirection=0x2000, fontScale=0x40000000),
'enabled': bool_resource(0x101000e),
'excludeFromRecents': bool_resource(0x1010017),
'exported': bool_resource(0x1010010),
@@ -179,6 +180,7 @@ ANDROID_ATTRIBUTES = {
'finishOnTaskLaunch': bool_resource(0x1010014),
'fullBackupContent': bool_resource(0x10104eb),
'glEsVersion': int_resource(0x1010281),
+ 'hardwareAccelerated': bool_resource(0x10102d3),
'hasCode': bool_resource(0x101000c),
'host': str_resource(0x1010028),
'icon': ref_resource(0x1010002),
@@ -194,8 +196,9 @@ ANDROID_ATTRIBUTES = {
'name': str_resource(0x1010003),
'noHistory': bool_resource(0x101022d),
'pathPattern': str_resource(0x101002c),
- 'resizeableActivity': bool_resource(0x10104f6),
+ 'preferMinimalPostProcessing': bool_resource(0x101060c),
'required': bool_resource(0x101028e),
+ 'resizeableActivity': bool_resource(0x10104f6),
'scheme': str_resource(0x1010027),
'screenOrientation': enum_resource(0x101001e, 'landscape', 'portrait', 'user', 'behind', 'sensor', 'nosensor', 'sensorLandscape', 'sensorPortrait', 'reverseLandscape', 'reversePortrait', 'fullSensor', 'userLandscape', 'userPortrait', 'fullUser', 'locked'),
'stateNotNeeded': bool_resource(0x1010016),
diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py
index 5f12b7fe4b..cfddcd89af 100644
--- a/direct/src/dist/commands.py
+++ b/direct/src/dist/commands.py
@@ -188,11 +188,26 @@ FrozenImporter.get_data = get_data
"""
SITE_PY_ANDROID = """
+# Define this first, before we import anything that might import an extension
+# module.
import sys, os
+from importlib import _bootstrap, _bootstrap_external
+
+class AndroidExtensionFinder:
+ @classmethod
+ def find_spec(cls, fullname, path=None, target=None):
+ soname = 'libpy.' + fullname + '.so'
+ path = os.path.join(sys.platlibdir, soname)
+
+ if os.path.exists(path):
+ loader = _bootstrap_external.ExtensionFileLoader(fullname, path)
+ return _bootstrap.ModuleSpec(fullname, loader, origin=path)
+
+
+sys.meta_path.append(AndroidExtensionFinder)
+
+
from _frozen_importlib import _imp, FrozenImporter
-from importlib import _bootstrap_external
-from importlib.abc import Loader, MetaPathFinder
-from importlib.machinery import ModuleSpec
from io import RawIOBase, TextIOWrapper
from android_log import write as android_log_write
@@ -242,8 +257,9 @@ class AndroidLogStream:
def writable(self):
return True
-sys.stdout = AndroidLogStream(2, 'Python')
-sys.stderr = AndroidLogStream(3, 'Python')
+if sys.version_info < (3, 13):
+ sys.stdout = AndroidLogStream(4, 'python.stdout')
+ sys.stderr = AndroidLogStream(5, 'python.stderr')
# Alter FrozenImporter to give a __file__ property to frozen modules.
@@ -262,20 +278,6 @@ def get_data(path):
FrozenImporter.find_spec = find_spec
FrozenImporter.get_data = get_data
-
-
-class AndroidExtensionFinder(MetaPathFinder):
- @classmethod
- def find_spec(cls, fullname, path=None, target=None):
- soname = 'libpy.' + fullname + '.so'
- path = os.path.join(os.path.dirname(sys.executable), soname)
-
- if os.path.exists(path):
- loader = _bootstrap_external.ExtensionFileLoader(fullname, path)
- return ModuleSpec(fullname, loader, origin=path)
-
-
-sys.meta_path.append(AndroidExtensionFinder)
"""
@@ -294,6 +296,7 @@ class build_apps(setuptools.Command):
self.application_id = None
self.android_abis = None
self.android_debuggable = False
+ self.android_app_category = None
self.android_version_code = 1
self.android_min_sdk_version = 21
self.android_max_sdk_version = None
@@ -516,6 +519,18 @@ class build_apps(setuptools.Command):
tmp.update(self.package_data_dirs)
self.package_data_dirs = tmp
+ if 'android' in self.platforms:
+ assert self.application_id, \
+ 'Must have a valid application_id when targeting Android!'
+
+ parts = self.application_id.split('.')
+ assert len(parts) >= 2, \
+ 'application_id must contain at least one \'.\' separator!'
+
+ for part in parts:
+ assert part.isidentifier(), \
+ 'Each part of application_id must be a valid identifier!'
+
# Default to all supported ABIs (for the given Android version).
if self.android_max_sdk_version and self.android_max_sdk_version < 21:
assert self.android_max_sdk_version >= 19, \
@@ -782,10 +797,29 @@ class build_apps(setuptools.Command):
version = self.distribution.get_version()
classifiers = self.distribution.get_classifiers()
- is_game = False
- for classifier in classifiers:
- if classifier == 'Topic :: Games/Entertainment' or classifier.startswith('Topic :: Games/Entertainment ::'):
- is_game = True
+ # If we have no app category, determine it based on the classifiers.
+ category = self.android_app_category
+ if not category:
+ for classifier in classifiers:
+ classifier = tuple(classifier.split(' :: '))
+ if len(classifier) < 2 or classifier[0] != 'Topic':
+ continue
+
+ if classifier[:2] == ('Topic', 'Games/Entertainment'):
+ category = 'game'
+ break
+ elif classifier[:3] == ('Topic', 'Multimedia', 'Audio'):
+ category = 'audio'
+ elif classifier[:4] == ('Topic', 'Multimedia', 'Graphics', 'Editors'):
+ category = 'image'
+ elif classifier[:2] == ('Topic', 'Communications', 'Usenet News'):
+ category = 'news'
+ elif classifier[:2] == ('Topic', 'Office/Business'):
+ category = 'productivity'
+ elif classifier[:3] == ('Topic', 'Communications', 'Chat'):
+ category = 'social'
+ elif classifier[:3] == ('Topic', 'Multimedia', 'Video'):
+ category = 'video'
manifest = ET.Element('manifest')
manifest.set('xmlns:android', 'http://schemas.android.com/apk/res/android')
@@ -816,9 +850,13 @@ class build_apps(setuptools.Command):
application = ET.SubElement(manifest, 'application')
application.set('android:label', name)
- application.set('android:isGame', ('false', 'true')[is_game])
+ if category == 'game':
+ application.set('android:isGame', 'true')
+ if category:
+ application.set('android:appCategory', category)
application.set('android:debuggable', ('false', 'true')[self.android_debuggable])
application.set('android:extractNativeLibs', 'true')
+ application.set('android:hardwareAccelerated', 'true')
app_icon = self.icon_objects.get('*', self.icon_objects.get(self.macos_main_app))
if app_icon:
@@ -828,9 +866,11 @@ class build_apps(setuptools.Command):
activity = ET.SubElement(application, 'activity')
activity.set('android:name', 'org.panda3d.android.PythonActivity')
activity.set('android:label', appname)
- activity.set('android:theme', '@android:style/Theme.NoTitleBar')
- activity.set('android:configChanges', 'orientation|keyboardHidden')
+ activity.set('android:theme', '@android:style/Theme.NoTitleBar.Fullscreen')
+ activity.set('android:alwaysRetainTaskState', 'true')
+ activity.set('android:configChanges', 'layoutDirection|locale|grammaticalGender|fontScale|fontWeightAdjustment|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation')
activity.set('android:launchMode', 'singleInstance')
+ activity.set('android:preferMinimalPostProcessing', 'true')
act_icon = self.icon_objects.get(appname)
if act_icon and act_icon is not app_icon:
diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py
index 71ed125746..0ffbc6fba8 100644
--- a/direct/src/showbase/ShowBase.py
+++ b/direct/src/showbase/ShowBase.py
@@ -679,7 +679,7 @@ class ShowBase(DirectObject.DirectObject):
complete.
"""
- if Thread.getCurrentThread() != Thread.getMainThread():
+ if sys.platform != "android" and Thread.getCurrentThread() != Thread.getMainThread():
task = taskMgr.add(self.destroy, extraArgs=[])
task.wait()
return
@@ -3439,7 +3439,7 @@ class ShowBase(DirectObject.DirectObject):
This method must be called from the main thread, otherwise an error is
thrown.
"""
- if Thread.getCurrentThread() != Thread.getMainThread():
+ if Thread.getCurrentThread() != Thread.getMainThread() and sys.platform != "android":
self.notify.error("run() must be called from the main thread.")
return
diff --git a/dtool/src/prc/notify.cxx b/dtool/src/prc/notify.cxx
index 009c6ab818..ce7df151c6 100644
--- a/dtool/src/prc/notify.cxx
+++ b/dtool/src/prc/notify.cxx
@@ -467,12 +467,12 @@ config_initialized() {
Notify *ptr = Notify::ptr();
- for (int i = 0; i <= NS_fatal; ++i) {
+ for (int severity = 0; severity <= NS_fatal; ++severity) {
int priority = ANDROID_LOG_UNKNOWN;
if (severity != NS_unspecified) {
- priority = i + 1;
+ priority = severity + 1;
}
- ptr->_log_streams[i] = new AndroidLogStream(priority);
+ ptr->_log_streams[severity] = new AndroidLogStream(priority);
}
#elif defined(__EMSCRIPTEN__)
diff --git a/makepanda/makepackage.py b/makepanda/makepackage.py
index 26447c9b6d..a46684d7d0 100755
--- a/makepanda/makepackage.py
+++ b/makepanda/makepackage.py
@@ -866,7 +866,7 @@ def MakeInstallerAndroid(version, **kwargs):
shutil.copy(source, target)
# Walk through the library dependencies.
- handle = subprocess.Popen(['readelf', '--dynamic', target], stdout=subprocess.PIPE)
+ handle = subprocess.Popen(['llvm-readelf', '--dynamic', target], stdout=subprocess.PIPE)
for line in handle.communicate()[0].splitlines():
# The line will look something like:
# 0x0000000000000001 (NEEDED) Shared library: [libpanda.so]
diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py
index 15d14cb04b..3d3ae9e6f1 100755
--- a/makepanda/makepanda.py
+++ b/makepanda/makepanda.py
@@ -2077,13 +2077,23 @@ def CompileJava(target, src, opts):
if GetHost() == 'android':
cmd = "ecj "
else:
- cmd = "javac -bootclasspath " + BracketNameWithQuotes(SDK["ANDROID_JAR"]) + " "
+ cmd = "javac "
+ home = os.environ.get('JAVA_HOME')
+ if home:
+ javac_path = os.path.join(home, 'bin', 'javac')
+ if GetHost() == 'windows':
+ javac_path += '.exe'
+ if os.path.isfile(javac_path):
+ cmd = BracketNameWithQuotes(javac_path) + " "
+
+ cmd += "-Xlint:deprecation "
optlevel = GetOptimizeOption(opts)
if optlevel >= 4:
cmd += "-debug:none "
- cmd += "-cp " + GetOutputDir() + "/classes "
+ classpath = BracketNameWithQuotes(SDK["ANDROID_JAR"] + ":" + GetOutputDir() + "/classes")
+ cmd += "-cp " + classpath + " "
cmd += "-d " + GetOutputDir() + "/classes "
cmd += BracketNameWithQuotes(src)
oscmd(cmd)
@@ -4945,11 +4955,13 @@ if GetTarget() == 'android':
TargetAdd('org/panda3d/android/NativeIStream.class', opts=OPTS, input='NativeIStream.java')
TargetAdd('org/panda3d/android/NativeOStream.class', opts=OPTS, input='NativeOStream.java')
TargetAdd('org/panda3d/android/PandaActivity.class', opts=OPTS, input='PandaActivity.java')
+ TargetAdd('org/panda3d/android/PandaActivity$1.class', opts=OPTS+['DEPENDENCYONLY'], input='PandaActivity.java')
TargetAdd('org/panda3d/android/PythonActivity.class', opts=OPTS, input='PythonActivity.java')
TargetAdd('classes.dex', input='org/panda3d/android/NativeIStream.class')
TargetAdd('classes.dex', input='org/panda3d/android/NativeOStream.class')
TargetAdd('classes.dex', input='org/panda3d/android/PandaActivity.class')
+ TargetAdd('classes.dex', input='org/panda3d/android/PandaActivity$1.class')
TargetAdd('classes.dex', input='org/panda3d/android/PythonActivity.class')
TargetAdd('p3android_composite1.obj', opts=OPTS, input='p3android_composite1.cxx')
diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py
index 3a4feb5b57..f34b847dec 100644
--- a/makepanda/makepandacore.py
+++ b/makepanda/makepandacore.py
@@ -1846,7 +1846,7 @@ def SmartPkgEnable(pkg, pkgconfig = None, libs = None, incs = None, defs = None,
DefSymbol(target_pkg, d, v)
return
- elif not custom_loc and GetHost() == "darwin" and framework is not None:
+ elif not custom_loc and GetHost() == "darwin" and GetTarget() == "darwin" and framework is not None:
prefix = SDK["MACOSX"]
if (os.path.isdir(prefix + "/Library/Frameworks/%s.framework" % framework) or
os.path.isdir(prefix + "/System/Library/Frameworks/%s.framework" % framework) or
@@ -2622,6 +2622,8 @@ def SdkLocateAndroid():
# We need to redistribute the C++ standard library.
stdlibc = os.path.join(ndk_root, 'sources', 'cxx-stl', 'llvm-libc++')
stl_lib = os.path.join(stdlibc, 'libs', abi, 'libc++_shared.so')
+ if not os.path.isfile(stl_lib):
+ stl_lib = os.path.join(prebuilt_dir, 'sysroot', 'usr', 'lib', ANDROID_TRIPLE.rstrip('0123456789'), 'libc++_shared.so')
CopyFile(os.path.join(GetOutputDir(), 'lib', 'libc++_shared.so'), stl_lib)
# The Android support library polyfills C++ features not available in the
diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py
index bafda55f3f..1ccbc618b0 100644
--- a/makepanda/makewheel.py
+++ b/makepanda/makewheel.py
@@ -677,6 +677,7 @@ def makewheel(version, output_dir, platform=None):
or platform.startswith('win_') \
or platform.startswith('cygwin_')
is_macosx = platform.startswith('macosx_')
+ is_android = platform.startswith('android_')
# Global filepaths
panda3d_dir = join(output_dir, "panda3d")
@@ -747,6 +748,9 @@ def makewheel(version, output_dir, platform=None):
elif is_macosx:
pylib_name = 'libpython{0}.{1}{2}.dylib'.format(sys.version_info[0], sys.version_info[1], suffix)
pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name)
+ elif is_android and CrossCompiling():
+ pylib_name = 'libpython{0}.{1}{2}.so'.format(sys.version_info[0], sys.version_info[1], suffix)
+ pylib_path = os.path.join(GetThirdpartyDir(), 'python', 'lib', pylib_name)
else:
pylib_name = get_config_var('LDLIBRARY')
pylib_arch = get_config_var('MULTIARCH')
diff --git a/panda/src/android/android_main.cxx b/panda/src/android/android_main.cxx
index 13895d99f6..55355533c3 100644
--- a/panda/src/android/android_main.cxx
+++ b/panda/src/android/android_main.cxx
@@ -75,6 +75,7 @@ void android_main(struct android_app* app) {
<< "New native activity started on " << *current_thread << "\n";
// Were we given an optional location to write the stdout/stderr streams?
+ bool owns_stdout = false;
methodID = env->GetMethodID(activity_class, "getIntentOutputUri", "()Ljava/lang/String;");
jstring joutput_uri = (jstring) env->CallObjectMethod(activity->clazz, methodID);
if (joutput_uri != nullptr) {
@@ -92,6 +93,7 @@ void android_main(struct android_app* app) {
dup2(fd, 1);
dup2(fd, 2);
+ owns_stdout = true;
} else {
android_cat.error()
<< "Failed to open output path " << path << "\n";
@@ -109,6 +111,7 @@ void android_main(struct android_app* app) {
<< spec.get_server_and_port() << "\n";
dup2(fd, 1);
dup2(fd, 2);
+ owns_stdout = true;
} else {
android_cat.error()
<< "Failed to open output socket "
@@ -267,11 +270,10 @@ void android_main(struct android_app* app) {
// We still need to keep an event loop going until Android gives us leave
// to end the process.
- int looper_id;
- int events;
- struct android_poll_source *source;
- while ((looper_id = ALooper_pollAll(-1, nullptr, &events, (void**)&source)) >= 0) {
- // Process this event, but intercept application command events.
+ while (!app->destroyRequested) {
+ int looper_id;
+ struct android_poll_source *source;
+ auto result = ALooper_pollOnce(-1, &looper_id, nullptr, (void **)&source);
if (looper_id == LOOPER_ID_MAIN) {
int8_t cmd = android_app_read_cmd(app);
android_app_pre_exec_cmd(app, cmd);
@@ -300,8 +302,10 @@ void android_main(struct android_app* app) {
env->ReleaseStringUTFChars(filename, filename_str);
}
- close(1);
- close(2);
+ if (owns_stdout) {
+ close(1);
+ close(2);
+ }
// Detach the thread before exiting.
activity->vm->DetachCurrentThread();
diff --git a/panda/src/android/pview_manifest.xml b/panda/src/android/pview_manifest.xml
index b462e4018a..e68dce5584 100644
--- a/panda/src/android/pview_manifest.xml
+++ b/panda/src/android/pview_manifest.xml
@@ -8,7 +8,7 @@
-
+
diff --git a/panda/src/androiddisplay/androidGraphicsWindow.cxx b/panda/src/androiddisplay/androidGraphicsWindow.cxx
index b3a8ae425d..1cc59d8298 100644
--- a/panda/src/androiddisplay/androidGraphicsWindow.cxx
+++ b/panda/src/androiddisplay/androidGraphicsWindow.cxx
@@ -181,16 +181,14 @@ process_events() {
GraphicsWindow::process_events();
// Read all pending events.
- int looper_id;
- int events;
- struct android_poll_source* source;
+ struct android_poll_source *source;
- // Loop until all events are read.
- while ((looper_id = ALooper_pollAll(0, nullptr, &events, (void**)&source)) >= 0) {
- // Process this event.
- if (source != nullptr) {
- source->process(_app, source);
- }
+ auto result = ALooper_pollOnce(0, nullptr, nullptr, (void **)&source);
+ nassertv(result != ALOOPER_POLL_ERROR);
+
+ // Process this event.
+ if (source != nullptr) {
+ source->process(_app, source);
}
}
@@ -437,14 +435,15 @@ ns_handle_command(int32_t command) {
case APP_CMD_WINDOW_RESIZED:
properties.set_size(ANativeWindow_getWidth(_app->window),
ANativeWindow_getHeight(_app->window));
+ system_changed_properties(properties);
break;
case APP_CMD_WINDOW_REDRAW_NEEDED:
break;
case APP_CMD_CONTENT_RECT_CHANGED:
- properties.set_origin(_app->contentRect.left, _app->contentRect.top);
+ /*properties.set_origin(_app->contentRect.left, _app->contentRect.top);
properties.set_size(_app->contentRect.right - _app->contentRect.left,
_app->contentRect.bottom - _app->contentRect.top);
- system_changed_properties(properties);
+ system_changed_properties(properties);*/
break;
case APP_CMD_GAINED_FOCUS:
properties.set_foreground(true);
diff --git a/panda/src/framework/pandaFramework.cxx b/panda/src/framework/pandaFramework.cxx
index 6d249cdc56..32de3dda76 100644
--- a/panda/src/framework/pandaFramework.cxx
+++ b/panda/src/framework/pandaFramework.cxx
@@ -204,6 +204,8 @@ close_framework() {
_event_handler.remove_all_hooks();
+ _task_mgr.cleanup();
+
_is_open = false;
_made_default_pipe = false;
_default_pipe.clear();
diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx
index eca73217b6..fc4ac4e7ad 100644
--- a/panda/src/gobj/shader.cxx
+++ b/panda/src/gobj/shader.cxx
@@ -1653,11 +1653,11 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
(!cp_errchk_parameter_uniform(p))) {
return false;
}
- bool k_prefix = false;
+ //bool k_prefix = false;
// solve backward compatibility issue
if (pieces[0] == "k") {
- k_prefix = true;
+ //k_prefix = true;
basename = basename.substr(2);
}
diff --git a/panda/src/pipeline/threadPosixImpl.I b/panda/src/pipeline/threadPosixImpl.I
index 308dc3ede0..326868ab61 100644
--- a/panda/src/pipeline/threadPosixImpl.I
+++ b/panda/src/pipeline/threadPosixImpl.I
@@ -19,7 +19,7 @@ ThreadPosixImpl(Thread *parent_obj) :
_parent_obj(parent_obj)
{
_joinable = false;
- _detached = false;
+ _detached = true;
_status = S_new;
#ifdef ANDROID
_jni_env = nullptr;
diff --git a/panda/src/text/textAssembler.cxx b/panda/src/text/textAssembler.cxx
index a98abb68b3..7e18b07d03 100644
--- a/panda/src/text/textAssembler.cxx
+++ b/panda/src/text/textAssembler.cxx
@@ -1479,7 +1479,7 @@ assemble_row(TextAssembler::TextRow &row,
PN_stdfloat underscore_start = 0.0f;
const TextProperties *underscore_properties = nullptr;
-#ifdef HAVE_HARFBUZZ
+#if defined(HAVE_HARFBUZZ) && defined(HAVE_FREETYPE)
const ComputedProperties *prev_cprops = nullptr;
hb_buffer_t *harfbuff = nullptr;
#endif
@@ -1525,7 +1525,7 @@ assemble_row(TextAssembler::TextRow &row,
line_height = max(line_height, font->get_line_height() * properties->get_glyph_scale() * properties->get_text_scale());
}
-#ifdef HAVE_HARFBUZZ
+#if defined(HAVE_HARFBUZZ) && defined(HAVE_FREETYPE)
if (tch._cprops != prev_cprops || graphic != nullptr) {
if (harfbuff != nullptr && hb_buffer_get_length(harfbuff) > 0) {
// Shape the buffer accumulated so far.
@@ -1760,7 +1760,7 @@ assemble_row(TextAssembler::TextRow &row,
}
}
-#ifdef HAVE_HARFBUZZ
+#if defined(HAVE_HARFBUZZ) && defined(HAVE_FREETYPE)
if (harfbuff != nullptr && hb_buffer_get_length(harfbuff) > 0) {
shape_buffer(harfbuff, placed_glyphs, xpos, prev_cprops->_properties);
}
@@ -1797,7 +1797,7 @@ void TextAssembler::
shape_buffer(hb_buffer_t *buf, PlacedGlyphs &placed_glyphs, PN_stdfloat &xpos,
const TextProperties &properties) {
-#ifdef HAVE_HARFBUZZ
+#if defined(HAVE_HARFBUZZ) && defined(HAVE_FREETYPE)
// If we did not specify a text direction, harfbuzz will guess it based on
// the script we are using.
hb_direction_t direction = HB_DIRECTION_INVALID;
diff --git a/pandatool/src/deploy-stub/android_main.cxx b/pandatool/src/deploy-stub/android_main.cxx
index 5aa24b53d2..d1e140c5f3 100644
--- a/pandatool/src/deploy-stub/android_main.cxx
+++ b/pandatool/src/deploy-stub/android_main.cxx
@@ -161,8 +161,6 @@ void android_main(struct android_app *app) {
std::string dtool_name = std::string(libdir) + "/libp3dtool.so";
ExecutionEnvironment::set_dtool_name(dtool_name);
android_cat.info() << "Path to dtool: " << dtool_name << "\n";
-
- env->ReleaseStringUTFChars(libdir_jstr, libdir);
}
// Get the path to the APK.
@@ -184,6 +182,7 @@ void android_main(struct android_app *app) {
// Map the blob to memory
void *blob = map_blob(lib_path, (off_t)blobinfo.blob_offset, (size_t)blobinfo.blob_size);
+ env->ReleaseStringUTFChars(lib_path_jstr, lib_path);
assert(blob != NULL);
assert(blobinfo.num_pointers <= MAX_NUM_POINTERS);
@@ -242,14 +241,16 @@ void android_main(struct android_app *app) {
preconfig.utf8_mode = 1;
PyStatus status = Py_PreInitialize(&preconfig);
if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- return;
+ env->ReleaseStringUTFChars(libdir_jstr, libdir);
+ Py_ExitStatusException(status);
+ return;
}
// Register the android_log module.
if (PyImport_AppendInittab("android_log", &PyInit_android_log) < 0) {
android_cat.error()
<< "Failed to register android_log module.\n";
+ env->ReleaseStringUTFChars(libdir_jstr, libdir);
return;
}
@@ -259,8 +260,8 @@ void android_main(struct android_app *app) {
config.buffered_stdio = 0;
config.configure_c_stdio = 0;
config.write_bytecode = 0;
- PyConfig_SetBytesString(&config, &config.executable, lib_path);
- env->ReleaseStringUTFChars(lib_path_jstr, lib_path);
+ PyConfig_SetBytesString(&config, &config.platlibdir, libdir);
+ env->ReleaseStringUTFChars(libdir_jstr, libdir);
status = Py_InitializeFromConfig(&config);
PyConfig_Clear(&config);
@@ -297,11 +298,10 @@ void android_main(struct android_app *app) {
// We still need to keep an event loop going until Android gives us leave
// to end the process.
- int looper_id;
- int events;
- struct android_poll_source *source;
- while ((looper_id = ALooper_pollAll(-1, nullptr, &events, (void**)&source)) >= 0) {
- // Process this event, but intercept application command events.
+ while (!app->destroyRequested) {
+ int looper_id;
+ struct android_poll_source *source;
+ auto result = ALooper_pollOnce(-1, &looper_id, nullptr, (void **)&source);
if (looper_id == LOOPER_ID_MAIN) {
int8_t cmd = android_app_read_cmd(app);
android_app_pre_exec_cmd(app, cmd);
@@ -332,4 +332,6 @@ void android_main(struct android_app *app) {
// Detach the thread before exiting.
activity->vm->DetachCurrentThread();
+
+ _exit(0);
}