Skip to content

[ iOS 18 Simulator regression] Scrolling Freezes When Canvas is offscreen #3112

Open
@wcandillon

Description

@wcandillon

Description

This issue only happens on Simulator v18 and above.

We're hitting the same issue as rive-app/rive-react-native#294
When on simulator, invoking CAMetalLayer::nextDrawable can take up to 1 second if the canvas is offscreen (e.g., presenting the surface doesn't change any pixels on screen).

Doing gesture events while still having the canvas offscreen will result in having the correct framerate.

React Native Skia Version

latest

React Native Version

confirmed on 0.78 and 0.79

Using New Architecture

  • Enabled

Steps to Reproduce

use the example below

Snack, Code Example, Screenshot, or Link to Repository

import React, { useEffect } from "react";
import {
  Canvas,
  LinearGradient,
  Fill,
  // Use this function instead of interpolateColor from Reanimated
  interpolateColors,
  vec,
} from "@shopify/react-native-skia";
import {
  useDerivedValue,
  useSharedValue,
  withRepeat,
  withTiming,
} from "react-native-reanimated";
import { Text, useWindowDimensions, View } from "react-native";
import { ScrollView } from "react-native-gesture-handler";

const startColors = [
  "rgba(34, 193, 195, 0.4)",
  "rgba(34,193,195,0.4)",
  "rgba(63,94,251,1)",
  "rgba(253,29,29,0.4)",
];
const endColors = [
  "rgba(0,212,255,0.4)",
  "rgba(253,187,45,0.4)",
  "rgba(252,70,107,1)",
  "rgba(252,176,69,0.4)",
];

const AnimatedGradient = () => {
  const { width, height } = useWindowDimensions();
  const colorsIndex = useSharedValue(0);
  useEffect(() => {
    colorsIndex.value = withRepeat(
      withTiming(startColors.length - 1, {
        duration: 4000,
      }),
      -1,
      true
    );
  }, [colorsIndex]);
  const gradientColors = useDerivedValue(() => {
    return [
      interpolateColors(colorsIndex.value, [0, 1, 2, 3], startColors),
      interpolateColors(colorsIndex.value, [0, 1, 2, 3], endColors),
    ];
  });
  console.log("Rendering");
  return (
    <Canvas style={{ width: 300, height: 300, backgroundColor: "white" }}>
      <Fill>
        <LinearGradient
          start={vec(0, 0)}
          end={vec(width, height)}
          colors={gradientColors}
        />
      </Fill>
    </Canvas>
  );
};

export const Breathe = () => {
  return (
    <ScrollView contentContainerStyle={{ flexGrow: 1, gap: 20, padding: 20 }}>
      <AnimatedGradient />
      <Text>
        Start scrolling until the Animated Skia Component is off-screen
      </Text>
      <View style={{ height: 1000 }} />
    </ScrollView>
  );
};

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