• RuntimesBugs
  • Some Android devices cannot display animated content

When running the spine-android sample project, I found that some phones could not see the animation content, but the Debug Renderer could display the skeleton, as follows:

The devices that have been found to have this problem include:

  • Samsung Galaxy S8 Plus
  • Huawei Mate 9

Have you had similar scenes before?

Related Discussions
...

Yes, there have been similar issues reported with Spine animations not displaying correctly on certain Android devices. Here are a few potential causes and solutions based on previous discussions:

  1. Material and Shader Issues: Ensure that the materials and shaders used are compatible with the devices. Simplistic materials are recommended, and you should verify if custom materials work on other scene components.

  2. Graphics API Compatibility: Some issues have been linked to specific graphics APIs like GLES 2.0 or Vulkan. For example, there was a known bug in the material compiler for GLES 2.0 in UE4. Updating the graphics API or switching to a different one might help.

  3. Device-Specific Bugs: Certain devices may have bugs in their WebGL or graphics driver implementations. For instance, there were issues with WebGL on some Huawei and Xiaomi devices. Updating the device's software or using a different browser might resolve these issues.

  4. Spine Runtime Version: Ensure you are using the latest version of the Spine runtime. Older versions might have bugs that have been fixed in newer releases. For example, updating to the latest spine-unity runtime has resolved issues for some users.

  5. Complexity of Skeletons: Highly complex skeletons with many meshes and vertices might not render correctly on devices with less powerful GPUs. Simplifying the skeletons could help.

  6. Battery Saving Features: Some Android devices have aggressive battery-saving features that might interfere with rendering. Disabling these features for your app could be a solution.

If these suggestions do not resolve the issue, you might need to create a minimal reproducible example and share it for further investigation.

I am using spine-android 4.2

Thank you for reporting! What Android version are these phones running? We use Canvas.drawVertices() to render skeletons to a canvas. It appears that some Android versions have problems with that. This mostly affects very old phones. The phones you mentioned are from 2017 and 2016 respectively and barely match the minimum SDK requirement (Nougat). Custom ROMs also often have broken Skia (underlying tech behind Canvas) implementations.

  • Mmega ответили на это сообщение.

    Mario Samsung Galaxy S8 Plus :Android 9
    Huawei Mate 9:Android 9

    I found a similar issue on github, also android 9, which seems to be a common point:
    EsotericSoftware/spine-runtimes2591

    Correct. I managed to get a hold of an LG Nexus 5, running Android SDK level 23 (Android 6). A common "workaround" back then was to enable software rendering for a view using Canvas.drawVertices(). However, that does not work either, and at least on my device + OS combo, results in a crash inside of Skia, the library used to do all drawing of Android UIs.

    All of the APIs we use we use for rendering are actually "API level 1", which includes drawVertices(). As such, we aren't doing anything special. It appears this has been fixed in later Android versions.

    I'm afraid there's not much we can do on our end to fix this, apart from increasing the minimal SDK level we support.

    We guess it is related to the Android version. We tried devices with Android 7, 8, and 9, and they all had the same problem. Android 10 works fine.

    I suppose we have to raise the minimum supported Android version to Android 10.

    I referred to some articles on the Internet and noticed that the number of colors and vertices in its examples were consistent;
    https://stackoverflow.com/questions/14679063/canvas-drawvertices-draws-nothing

    However, when I breakpointed SpineView, I found that the number of colors was only half of the number of vertices:

    Then I tried the following on an Android 9 device: disable hardware acceleration, and then pass colors=null when canvas.drawVertices, and it played successfully! ! (Although it looked a bit jagged)

    • Изменено

    In what scenarios does the colors in RenderCommand make sense? Now its value is all -1, which actually does not work (I am currently using the spineboy resource). In addition, because the number of colors and vertices does not match, the animation playback on Android 9 is abnormal,That's the cause of the problem

    I guess it's Android 9 and below, and Native has done additional checks on the number of colors and vertices

    Yes, I figured it out. In Android 9, disable hardware acceleration, and make sure the colors passed in to canvas.drawVertices is null, or pad the size of colors to the size of vertices, and spine can play successfully!

    For Android 10, there is no need to align the sizes of colors and vertices.Because after the Android 10 update, the colors size check was corrected in the native layer

    Both the number of colors and color value of -1 are correct. Each vertex is composed of an x and y coordinate. If you have 276 vertices, the command.vertices array will have a length of 552 elements. Colors are composed of a single 32-bit integer, encoding the red, green, blue and alpha channels, each in a byte. For every vertex, there is one color, so for 276 vertices, there will be 276 colors. A color value of -1 is 0xffffffff in hex, meaning red = 255, green = 255, blue = 255, and alpha = 255.

    What seems to trip up Canvas.drawVertices() on Android < 10 is that the command.vertices and command.colors arrays may be bigger than what command.vertices.size and command.colors.size say. The reason for this is that we try not to allocate new memory if possible, but instead reuse existing arrays, if they can fit the required number of elements.

    It seems the underlying implemention of Canvas.drawVertices() on Android < 10 actually queries the arrays length instead of using the number of vertices we pass to it. That will indeed result in crashes.

    The solution for Android < 10 is not to not pass the colors array, but to temporarily allocate an array that has the exact number of elements as there are vertices, and copy over the colors from command.colors.items. This is super suboptimal, as we'll allocate a new array for each command ever frame!

    Not passing colors is not a good idea, as that means that attachment colors will not work.

    I'll modify the spine-android runtime to add this suboptimal fix for Android < 10. You can follow the issue here:
    EsotericSoftware/spine-runtimes2638

    Thank you very much. I am looking forward to the new version of spine-android runtime.

    7 дней спустя

    I've now fixed this up properly in SkeletonRenderer (pass a properly sized array to drawVertices()) and SpineView (enable software rendering). But it's borderline useless due to performance. Without hardware acceleration, animations that cover a large portion of the screen will simply be too slow.

    I've released the fix as version 4.2.7. It should be available from Maven Central in half an hour from now.

    7 дней спустя

    Performance is a real headache, but thanks anyway