Skip to content

[Android] Crash on Scene Load: 'index out of bounds' panic when used in React Native #228

@florian-deroo

Description

@florian-deroo

Hello Spline Team,

I am currently working on integrating the Spline Android runtime into a React Native application. To achieve this, I've created a custom SimpleViewManager to bridge the native SplineView component.

Describe the bug

The application consistently crashes when I attempt to load a scene from a local res/raw resource. The crash is a fatal SIGABRT signal, originating from a panic within the native Rust runtime. The expected behavior is for the scene to load and render correctly.

Error Details

The core error message from logcat points to an "index out of bounds" panic within the material rendering code:
E SplineView: log_panics: thread '<unnamed>' panicked at 'index out of bounds: the len is 0 but the index is 0': runtime-full/src/renderer/material/renderable_material.rs:89

This seems to be preceded by errors from the Adreno graphics driver, suggesting a failure to allocate a graphic buffer, which may be the root cause of the empty list that leads to the panic.

E qdgralloc: GetGpuPixelFormat: No map for format: 0x38
E AdrenoUtils: <validate_memory_layout_input_parmas:2285>: Unknown Format 0
E GraphicBufferAllocator: Failed to allocate (4 x 4) layerCount 1 format 56 usage 300: 1

Relevant Logcat Output

Here is the full backtrace and fatal error log:

06-29 21:05:16.085 24945 25044 E SplineView: log_panics: thread '<unnamed>' panicked at 'index out of bounds: the len is 0 but the index is 0': runtime-full/src/renderer/material/renderable_material.rs:89
06-29 21:05:16.085 24945 25044 F libc      : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 25044 (DefaultDispatch), pid 24945 (com.test)
--
06-29 21:05:16.348 25073 25073 F DEBUG     : Abort message: 'index out of bounds: the len is 0 but the index is 0'
06-29 21:05:16.348 25073 25073 F DEBUG     : backtrace:
06-29 21:05:16.348 25073 25073 F DEBUG     :       #00 pc 00000000000526f4  /apex/com.android.runtime/lib64/bionic/libc.so (abort+168)
06-29 21:05:16.348 25073 25073 F DEBUG     :       #15 pc 00000000006a380c  /data/app/~~Ziy8Ll-rqfmmxo4VMN3Tdg==/com.test-wgLvl516wdhnW1EQeWsmfg==/base.apk (Java_design_spline_runtime_RustBridge_engineCreate+504)
06-29 21:05:16.348 25073 25073 F DEBUG     :       #16 pc 000000000037ef70  /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144)
06-29 21:05:16.348 25073 25073 F DEBUG     :       #21 pc 00000000002b65f0  [anon:dalvik-classes6.dex extracted in memory from /data/app/~~Ziy8Ll-rqfmmxo4VMN3Tdg==/com.test-wgLvl516wdhnW1EQeWsmfg==/base.apk] (design.spline.runtime.SplineView$loadEngineAsync$1$engine$1.invokeSuspend+0)

Environment

  • Device: ZTE (P898F01)
  • OS: Android 13 (TKQ1.221220.001)
  • ABI: arm64
  • Integration: React Native

My React Native ViewManager code

This is how I am bridging the SplineView. The setResourceName prop is called from JavaScript to load the scene.

package com.test.spline

import android.util.Log
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.SimpleViewManager
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.annotations.ReactProp
import design.spline.runtime.SplineView

@ReactModule(name = SplineViewManager.NAME)
class SplineViewManager : SimpleViewManager<SplineView>() {
    companion object {
        const val NAME = "RNSplineView"
    }

    override fun getName() = NAME

    @ReactProp(name = "resourceName")
    fun setResourceName(view: SplineView, resourceName: String?) {
        if (resourceName.isNullOrBlank()) {
          return
        }

        try {
          val context = view.context
          val resourceId = context.resources.getIdentifier(
              resourceName,
              "raw",
              context.packageName
          )

          if (resourceId != 0) {
              view.loadResource(resourceId)
          } else {
              Log.e(NAME, "Failed to find resource ID for: $resourceName")
          }
        } catch (e: Exception) {
          Log.e(NAME, "Error loading resource: $resourceName", e)
        }
    }

    override fun createViewInstance(reactContext: ThemedReactContext): SplineView {
        return SplineView(reactContext)
    }
}

Do you have any solution to implement this easily both on ios and android?

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions