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

Couldn't load shared library 'gdx-basis-universal' for target: Android #2

Closed
Peter-Warlock opened this issue Nov 6, 2023 · 26 comments

Comments

@Peter-Warlock
Copy link

Hello,

Crash on old devices with that crash stack:

g2.b0: Couldn't load shared library 'gdx-basis-universal' for target: Android
  at g2.c0.d(SourceFile:123)
  at l2.e.D(SourceFile:23)
  at l2.a.<init>(SourceFile:11)
  at l2.f.prepare(SourceFile:28)
  at o1.l.v(SourceFile:34)
  at o1.l.<init>(SourceFile:4)
  at x6.o0.<init>(SourceFile:83)
  at x6.y.k(SourceFile:312)
  at l1.l.onSurfaceChanged(SourceFile:44)
  at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1512)
  at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

Caused by: java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH in "libgdx-basis-universal.so" (built with --hash-style=gnu?)
  at java.lang.Runtime.loadLibrary(Runtime.java:364)
  at java.lang.System.loadLibrary(System.java:526)
  at g2.c0.d(SourceFile:29)
  at l2.e.D(SourceFile:23) 
  at l2.a.<init>(SourceFile:11) 
  at l2.f.prepare(SourceFile:28) 
  at o1.l.v(SourceFile:34) 
  at o1.l.<init>(SourceFile:4) 
  at x6.o0.<init>(SourceFile:83) 
  at x6.y.k(SourceFile:312) 
  at l1.l.onSurfaceChanged(SourceFile:44) 
  at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1512) 
  at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240) 

The same problem and how to fix it was described here:
google/filament#2176
(suggestion to fix here: https://stackoverflow.com/a/59649817/671393)

@metaphore
Copy link
Member

metaphore commented Nov 6, 2023

Hello, and thanks for reporting this.
Interestingly enough, I created the same issue for another native-based library a year ago and totally forgot about it.

Let me try to rebuild the Android natives with the --hash-style=both flag. Maybe it's a cure for the case.

metaphore added a commit that referenced this issue Nov 6, 2023
@metaphore
Copy link
Member

metaphore commented Nov 6, 2023

Alright, hopefully, this patch works. The new version was just published and should be available on Maven Central soon.
Please update the game and let me know if the problem persists.

Let's keep the issue open till we get a clear confirmation that it was fixed.

@Peter-Warlock
Copy link
Author

I've updated to v1.0.1.
Even compared old libgdx-basis-universal.so files with the new one. It's indeed new (has a difference) but the problem still here.
Tested on Android Emulator with API 22 and on real Android Device with API 19.
The same crash stack with the same:

Caused by: java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH in "libgdx-basis-universal.so" (built with --hash-style=gnu?)

@metaphore
Copy link
Member

I see, thank you! Seems like the flag wasn't set properly. It's good to know it can be tested on emulator, I didn't think about it.

Let me try another time and I will let you know when I make it work on the emulator 👌

@metaphore
Copy link
Member

My searches led me there android/ndk#964
Sounds like there's no easy fix for this, apart from downgrading to an old NDK, which doesn't sound all that good to me.

At this point, I'd just set the minimum required Android API to 23 and move on.

@Peter-Warlock
Copy link
Author

But why libgdx.so have no this problems? Why libgdx.so loaded without errors? Maybe it's indeed just linker setting?

@Peter-Warlock
Copy link
Author

@metaphore
Copy link
Member

metaphore commented Nov 8, 2023

Ok. It wasn't NDK issue. It was me being stupid.
A long time ago I copied the jnigen configuration from somewhere and there was a minimum Android API set to 26. As far as I know, the library doesn't have any other limitations on min API other than those that come with NDK itself. And NDK r26 minimum supported API is 21. So changing that in jnigen config finally made it spin on my API 22 arm64 emulator 🎉

There are some other issues with some of the textures that are just solid black. But it all sounds like another problem - #3 . While this one has been solved 👌
image

@metaphore
Copy link
Member

@Peter-Warlock FIY, I want to get to the bottom of that black texture issue before I make another release. In the meantime, you may want to switch to 1.0.2-SNAPSHOT from https://oss.sonatype.org/content/repositories/snapshots.
At least it fixes the problem with the natives on old Android devices. And there's a chance it could also work on your API 19 device (even though it's not officially supported by NDK).

@Peter-Warlock
Copy link
Author

Seems, like some problem with a SNAPSHOT.
After updating to 1.0.2-SNAPSHOT I got build.gradle sync error:

Could not find basisu-wrapper-1.0.2-SNAPSHOT-sources.jar (com.crashinvaders.basisu:basisu-wrapper:1.0.2-SNAPSHOT:20231108.211447-2).
Searched in the following locations:
    https://oss.sonatype.org/content/repositories/snapshots/com/crashinvaders/basisu/basisu-wrapper/1.0.2-SNAPSHOT/basisu-wrapper-1.0.2-20231108.211447-2-sources.jar

I also uses HTML project and need this file. But ok. Just for test I commented this line and build.gradle sync completed with success.
But even Desktop App craches with error:
Caused by: java.lang.NoClassDefFoundError: com/crashinvaders/basisu/wrapper/BasisuWrapper
Caused by: java.lang.ClassNotFoundException: com.crashinvaders.basisu.wrapper.BasisuWrapper

Android version also crashes with that error message:

java.lang.NoClassDefFoundError: Failed resolution of: Lcom/crashinvaders/basisu/wrapper/BasisuWrapper;
at com.crashinvaders.basisu.gdx.BasisuData.<init>(BasisuData.java:43)
at com.crashinvaders.basisu.gdx.BasisuData.<init>(BasisuData.java:32)
at com.crashinvaders.basisu.gdx.BasisuTextureData.prepare(BasisuTextureData.java:137)
at com.badlogic.gdx.graphics.Texture.load(Texture.java:156)
....
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.crashinvaders.basisu.wrapper.BasisuWrapper" on path: DexPathList[...]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at com.crashinvaders.basisu.gdx.BasisuData.<init>(BasisuData.java:43) 
at com.crashinvaders.basisu.gdx.BasisuData.<init>(BasisuData.java:32) 
at com.crashinvaders.basisu.gdx.BasisuTextureData.prepare(BasisuTextureData.java:137) 
at com.badlogic.gdx.graphics.Texture.load(Texture.java:156) 

@metaphore
Copy link
Member

Yep, sorry about that. Something is wrong with the snapshot publishing routine. I investigated it a little today and it seems that all the release artifacts get uploaded to Sonatype just fine, except for the main .jar file. Don't know yet what causes the issue, but there's a similar issue with my other projects. Might be something is wrong with the configuration. I'll keep digging...

@metaphore
Copy link
Member

metaphore commented Nov 10, 2023

Ok, the snapshot should be fixed now. @Peter-Warlock please try again.
In case Gradle is stuck with the old dependencies, try this:

./gradlew --refresh-dependencies

@Peter-Warlock
Copy link
Author

Tested on the emulator API 34, 23, 22, 21 - worked well.

On the emulator API 19 it crashes with the error:

FATAL EXCEPTION: GLThread 142
Process: com.test, PID: 2921
com.badlogic.gdx.utils.SharedLibraryLoadRuntimeException: Couldn't load shared library 'gdx-basis-universal' for target: Android
	at com.badlogic.gdx.utils.SharedLibraryLoader.load(SharedLibraryLoader.java:128)
	at com.crashinvaders.basisu.gdx.BasisuNativeLibLoader.loadIfNeeded(BasisuNativeLibLoader.java:23)
	at com.crashinvaders.basisu.gdx.BasisuData.<init>(BasisuData.java:39)
	at com.crashinvaders.basisu.gdx.BasisuData.<init>(BasisuData.java:32)
	at com.crashinvaders.basisu.gdx.BasisuTextureData.prepare(BasisuTextureData.java:137)
	at com.badlogic.gdx.graphics.Texture.load(Texture.java:156)

Caused by: java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "android_set_abort_message" referenced by "libgdx-basis-universal.so"...
	at java.lang.Runtime.loadLibrary(Runtime.java:364)
	at java.lang.System.loadLibrary(System.java:526)
	at com.badlogic.gdx.utils.SharedLibraryLoader.load(SharedLibraryLoader.java:122)
	at com.crashinvaders.basisu.gdx.BasisuNativeLibLoader.loadIfNeeded(BasisuNativeLibLoader.java:23) 
	at com.crashinvaders.basisu.gdx.BasisuData.<init>(BasisuData.java:39) 
	at com.crashinvaders.basisu.gdx.BasisuData.<init>(BasisuData.java:32) 
	at com.crashinvaders.basisu.gdx.BasisuTextureData.prepare(BasisuTextureData.java:137) 

On the real device with API 19 it crashes with the same error but with different "caused by" reason:

g2.b0: Couldn't load shared library 'gdx-basis-universal' for target: Android
	at g2.c0.d(SourceFile:123)
	at l2.d.L(SourceFile:23)

Caused by: java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "wcstoull" referenced by "libgdx-basis-universal.so"...
	at java.lang.Runtime.loadLibrary(Runtime.java:364)
	at java.lang.System.loadLibrary(System.java:526)

@Peter-Warlock
Copy link
Author

Another question about "solid black textures". Is this a result of using mipmapping or some other problem that may occur on the user's devices?

And since I mentioned mipmapping, what about mipmapping? Is there a way to use it?

@metaphore
Copy link
Member

Yep, I would expect the library to work on anything below Android API 21 as this is the min supported platform for the current NDK.

And regarding the mipmaps, they are fully supported by basis universal, it's just a question of implementation. Currently a basis/ktx2 texture gets loaded only with 0 level mipmap. It's done for simplicity sake, because for every mipmap level it would require another iteration of transcoding and I'm not sure how to handle that well. I'll look into that for the next release.

@Peter-Warlock
Copy link
Author

So, "solid black textures" from your screenshot above is a result of using mipmapping or some other problem that may occur on the user's devices?

@metaphore
Copy link
Member

I put everything that I know till this day to this issue #3
In short, it has nothing to do with mipmaps. For some reason emulators (up to Android 8) spit an OpenGL error when I try to load a ASTC texture to GPU, however OpenGL API clearly indicates that it has support for ASTC. That might be only an emulator related issue, I don't have any API 21-27 real device to test at the moment.
In the other hand, this is only related to ASTC, whereas the same basis texture transcoded to ETC2 works with no problems. So in any case an extra IF could be added to the transcoder texture type selector, to always use ETC2 over ASTC on the old Android devices. But I'd prefer to investigate further on that and find what's the actual problem is.

@Peter-Warlock
Copy link
Author

Hmm. This is interesting. Does this issue occur in both hardware and software emulation mode?

image

@metaphore
Copy link
Member

It does, I don't think it makes any difference.

@Peter-Warlock
Copy link
Author

You said: That might be only an emulator related issue, I don't have any API 21-27 real device to test at the moment.
Different emulator graphics implementations may behave differently.

I have real device with Android API 24 (Android 7.0). I can run some test if you need.

@metaphore
Copy link
Member

metaphore commented Nov 11, 2023

Well I mean API 24 real device would be perfect to see if this is only an emulator-related behavior! I'd appreciate it if you could try.

The options are:

  1. Clone the project, assemble and install the demo on an Android device locally:
./gradlew demo:android:installDebug
  1. Or you can download this zipped APK, unpack it and install manually.

@Peter-Warlock
Copy link
Author

Done. It seems to work without problems.
Sometimes, after rotating the image, some textures (upper left) lost detail and upper centered texture got some black line at bottom. I don't know if this is normal or not. So I've archived two screenshots showing this difference. It was not on every rotation. I made about 20+ screens at all and sometime it was, sometimes not. Maybe it's just result of rotation (not exact angle because of float vals).

I also archived the logs from Logcat.

Here the screen of my Logcat with API level of tested device:
image

Here your screenshot:
image

Logcat log:
bususu-demo_log.zip

2 screens showing difference:
Screenshot_2023-11-12_com.crashinvaders.basisu.demo.zip

@metaphore
Copy link
Member

Awesome, thanks!
Sounds like the issue might be not all that critical and it should be safe to move on. I'll keep the #3 open so whoever stumbles upon a similar issue may add details.

@Peter-Warlock
Copy link
Author

Just for info. For testing, I downloaded your zipped APK and run it.

@Peter-Warlock
Copy link
Author

And regarding the mipmaps, they are fully supported by basis universal, it's just a question of implementation. Currently a basis/ktx2 texture gets loaded only with 0 level mipmap. It's done for simplicity sake, because for every mipmap level it would require another iteration of transcoding and I'm not sure how to handle that well. I'll look into that for the next release.

Hi,

Another question about mipmapping. :)
As far as I can see, libgdx uses MipMapGenerator.generateMipMap() to generate all mipmaps for textures. Maybe it can be used to create mipmaps as a quick solution for Basisu\ktx2 textures without another iteration of transcoding?

Basisu\ktx2 - Looks good and I like that the texture takes up so little space, but without mipmaps some textures don't look as good.

@metaphore
Copy link
Member

metaphore commented Nov 23, 2023

Yep, after a quick googling, it sounds pretty reasonable actually, since that should be the usual way to set up mipmaps for OpenGL. I wonder why would Basis include mipmap generator if mipmaps could be simply created on the fly by a rendering API? I'll give it a spin.

PS: Next time please open a new issue if the topic is unrelated 🙏

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

No branches or pull requests

2 participants