feat: Allow build without Skia or Frame Processors (#1710)

* feat: Make Frame Processors optional in JS

* Allow Android build without Frame Processors

* fix: Fix `EncoderProfiles.width` null-error

* Update gradle.properties

* Update gradle.properties

* fix: Use `#ifdef` instead of `#if`

* Update JVisionCameraProxy.cpp

* fix: Fix definitions

* Revert "fix: Use `#ifdef` instead of `#if`"

This reverts commit b19f32e5ce7df558cadcc8c4b5006c9cdf2cbe66.

* fix: Fix build

* chore: Codestyle

* Update JFrameProcessor.cpp
This commit is contained in:
Marc Rousavy
2023-08-23 12:42:38 +02:00
committed by GitHub
parent 617c5607d4
commit 862e05b64f
21 changed files with 266 additions and 147 deletions

View File

@@ -1,9 +1,11 @@
import type { Frame, FrameInternal } from './Frame';
import type { FrameProcessor } from './CameraProps';
import { Camera } from './Camera';
import { Worklets } from 'react-native-worklets-core';
import { CameraRuntimeError } from './CameraError';
// only import typescript types
import type TWorklets from 'react-native-worklets-core';
type BasicParameterType = string | number | boolean | undefined;
type ParameterType = BasicParameterType | BasicParameterType[] | Record<string, BasicParameterType | undefined>;
@@ -28,17 +30,48 @@ interface TVisionCameraProxy {
isSkiaEnabled: boolean;
}
Camera.installFrameProcessorBindings();
let isAsyncContextBusy = { value: false };
let runOnAsyncContext = (_frame: Frame, _func: () => void): void => {
throw new CameraRuntimeError(
'system/frame-processors-unavailable',
'Frame Processors are not available, react-native-worklets-core is not installed!',
);
};
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { Worklets } = require('react-native-worklets-core') as typeof TWorklets;
// Install native Frame Processor Runtime Manager
Camera.installFrameProcessorBindings();
// @ts-expect-error global is untyped, it's a C++ host-object
if (global.VisionCameraProxy == null) {
throw new CameraRuntimeError(
'system/frame-processors-unavailable',
'Failed to install VisionCameraProxy. Are Frame Processors properly enabled?',
);
}
isAsyncContextBusy = Worklets.createSharedValue(false);
const asyncContext = Worklets.createContext('VisionCamera.async');
runOnAsyncContext = Worklets.createRunInContextFn((frame: Frame, func: () => void) => {
'worklet';
try {
// Call long-running function
func();
} finally {
// Potentially delete Frame if we were the last ref
(frame as FrameInternal).decrementRefCount();
isAsyncContextBusy.value = false;
}
}, asyncContext);
} catch (e) {
// Worklets are not installed, so Frame Processors are disabled.
}
// @ts-expect-error global is untyped, it's a C++ host-object
export const VisionCameraProxy = global.VisionCameraProxy as TVisionCameraProxy;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (VisionCameraProxy == null) {
throw new CameraRuntimeError(
'system/frame-processors-unavailable',
'Failed to install VisionCameraProxy. Are Frame Processors properly enabled?',
);
}
declare global {
// eslint-disable-next-line no-var
@@ -96,21 +129,6 @@ export function runAtTargetFps<T>(fps: number, func: () => T): T | undefined {
return undefined;
}
const isAsyncContextBusy = Worklets.createSharedValue(false);
const asyncContext = Worklets.createContext('VisionCamera.async');
const runOnAsyncContext = Worklets.createRunInContextFn((frame: Frame, func: () => void) => {
'worklet';
try {
// Call long-running function
func();
} finally {
// Potentially delete Frame if we were the last ref
(frame as FrameInternal).decrementRefCount();
isAsyncContextBusy.value = false;
}
}, asyncContext);
/**
* Runs the given function asynchronously, while keeping a strong reference to the Frame.
*

View File

@@ -1,11 +1,11 @@
import { ConfigPlugin, withGradleProperties } from '@expo/config-plugins';
/**
* Set the `disableFrameProcessors` value in the static `gradle.properties` file.
* Set the `VisionCamera_disableFrameProcessors` value in the static `gradle.properties` file.
* This is used to disable frame processors if you don't need it for android.
*/
export const withDisableFrameProcessorsAndroid: ConfigPlugin = (c) => {
const disableFrameProcessorsKey = 'disableFrameProcessors';
const disableFrameProcessorsKey = 'VisionCamera_disableFrameProcessors';
return withGradleProperties(c, (config) => {
config.modResults = config.modResults.filter((item) => {
if (item.type === 'property' && item.key === disableFrameProcessorsKey) return false;

View File

@@ -1,8 +1,6 @@
import { DependencyList, useMemo } from 'react';
import type { DrawableFrame, Frame, FrameInternal } from '../Frame';
import { FrameProcessor } from '../CameraProps';
// Install RN Worklets by importing it
import 'react-native-worklets-core';
export function createFrameProcessor(frameProcessor: FrameProcessor['frameProcessor'], type: FrameProcessor['type']): FrameProcessor {
return {