When multiple SceneQuadLayer instances share the same SceneSwapchain and each calls setClip() with different UV clip regions, all layers display the same clip instead of their individually specified clip regions.
Expected behavior
Each layer should display its own unique UV clip region from the shared swapchain texture. For example, when rendering a cubemap with six layers sharing one swapchain, each layer should show a different face of the cube based on its individual clip settings.
Actual behavior
All layers display the same UV clip region, typically showing the last clip region that was set across all layers. This means:
Layer-specific clip regions are ignored
Only the most recently applied clip settings take effect globally
Multiple layers appear identical instead of showing different portions of the texture
Workaround
Consider using Meta Spatial SDK version 0.7.2 if this functionality is critical to your application.
Layer incorrectly created when using mesh-based rendering
When using ReadableMediaPanelRenderOptions with renderMode = PanelRenderMode.Mesh(), the system incorrectly creates a compositor layer instead of using only mesh-based rendering.
Expected behavior
When PanelRenderMode.Mesh() is specified, the panel should render using only a 3D mesh without creating a compositor layer.
Actual behavior
The system creates both a mesh and a compositor layer, which:
Consumes additional GPU memory and processing resources
May impact rendering performance
Goes against the intended lightweight mesh-only rendering approach
Workaround
If you’re creating ReadableMediaPanelSettings objects, you can work around the issue by applying the fix after converting to panel configuration:
val panelSettings = ReadableMediaPanelSettings(
shape = QuadShapeOptions(width = 1.0f, height = 1.0f),
display = PixelDisplayOptions(width = 1920, height = 1080),
rendering = ReadableMediaPanelRenderOptions(
renderMode = PanelRenderMode.Mesh(),
// ... other render options
),
// ... other settings
)
val panelConfig = panelSettings.toPanelConfigOptions()
panelConfig.layerConfig = null // Override the incorrect layer creation
// Use panelConfig for your panel setup
Degraded performance in debug mode
Spatial SDK applications experience significantly reduced performance when built and run in debug mode compared to release builds.
Expected behavior
Applications should perform at similar levels across build types. Debug builds should run close to release builds for basic testing.
Switch to release build variant for performance-sensitive testing:
In Android Studio, open the Build Variants tool window by navigating to View > Tool Windows > Build Variants
In the Build Variants window, locate your app module in the list
Change the build variant from debug (default) to release for the app you are testing
Note: Remember to switch back to debug mode when needed. Consider using release builds for performance profiling and user experience validation.
Audio interrupted when entering immersive mode
When an immersive application requests audio focus, background audio from other apps (such as YouTube or music players) may stop or become altered. This is caused by Android’s audio focus policies, which were designed for phone-centric use cases and do not fully account for the multi-app XR environment on Horizon OS.
Expected behavior
Background audio from non-immersive apps should continue playing uninterrupted when an immersive app is launched, as long as the immersive app does not explicitly need exclusive audio output.
Actual behavior
Entering an immersive experience can cause one or more of the following:
Background audio from other apps stops completely
Audio spatialization changes unexpectedly (for example, losing spatial positioning)
Audio does not resume after exiting the immersive experience
Workaround
There is currently no SDK-level fix for this issue. To mitigate the impact in your app:
Avoid requesting AUDIOFOCUS_GAIN unless your app absolutely requires exclusive audio. Use AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK if your app only needs temporary audio focus and can allow other audio to duck (play at reduced volume).
If your app plays background audio, handle AudioManager.OnAudioFocusChangeListener to gracefully pause and resume playback when focus is lost and regained.
Test audio behavior with other apps running in the background to verify that your app does not unintentionally disrupt their audio.
2D panel not reappearing after finishing an immersive activity
When transitioning from an immersive activity back to a 2D panel, calling finish() on the immersive activity may cause the 2D panel to not reappear. In some cases, calling finish() on an activity with panels that have enableLayer = true can cause a crash (SIGSEGV) inside libMetaSpatialSDK.so.
Note: The enableLayer parameter is deprecated. Use layerConfig: LayerConfig? instead to configure panel layer behavior.
Expected behavior
After an immersive activity completes, the previous 2D panel activity should reappear and be interactive.
Actual behavior
The 2D panel does not reappear after the immersive activity finishes.
If the activity has panels with enableLayer = true (deprecated; use layerConfig instead), calling finish() may cause a native crash due to improperly destroyed mesh, layer, and texture resources.
Workaround
Do not use finish() to close an activity that has associated panels. Instead:
Use a helper function to launch panel mode in home instead of calling finish() to transition from immersive mode back to 2D panel mode. This avoids both the crash and the missing panel issue.
// Don't do this — may crash or leave panels in a broken state
// finish()
// Do this instead — transitions back to panel mode safely
launchPanelModeInHome()
The launchPanelModeInHome() function is not an SDK method, it’s a helper pattern you implement in your app using Android intents. For a complete working example, see the HybridSample app in the Meta Spatial SDK Samples repository.
Hand UI becoming unresponsive
Hand-based UI interactions may become unresponsive in certain scenarios, particularly when using dynamically created panels or when switching between input modalities (hands and controllers).
Expected behavior
Hand interactions with UI panels should remain responsive throughout the session, including when panels are created dynamically and when switching between hand tracking and controller input.
Actual behavior
Dynamically created panels using ComposeViewPanelSettings may lose touch input responsiveness.
Scrollable views may not respond to direct hand interaction (physical touch), though distance pointer interaction may still work.
Switching between controllers and hand tracking may occasionally trigger unintended input events on UI elements.
Workaround
If you are using dynamically created panels with ComposeViewPanelSettings, update to Meta Spatial SDK v0.9.1 or later, which includes fixes for panel input corruption.
If scrollable views do not respond to direct hand touch, use distance pointer interaction (pointing from a distance and pinching) as a fallback until a fix is available.