expo-gl 12.4.0 → 12.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,16 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 12.5.0 — 2023-05-08
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - Fixed leaking GL context. ([#21247](https://github.com/expo/expo/pull/21247) by [@wkozyra95](https://github.com/wkozyra95))
18
+
19
+ ### 💡 Others
20
+
21
+ - Remove legacy code for old Expo Go. ([#21247](https://github.com/expo/expo/pull/21247) by [@wkozyra95](https://github.com/wkozyra95))
22
+
13
23
  ## 12.4.0 — 2023-02-14
14
24
 
15
25
  ### 🎉 New features
package/README.md CHANGED
@@ -16,7 +16,7 @@ Provides GLView that acts as OpenGL ES render target and gives GL context object
16
16
 
17
17
  # Installation in managed Expo projects
18
18
 
19
- For [managed](https://docs.expo.dev/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/gl-view/).
19
+ For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/gl-view/).
20
20
 
21
21
  # Installation in bare React Native projects
22
22
 
@@ -25,25 +25,25 @@ For bare React Native projects, you must ensure that you have [installed and con
25
25
  ### Add the package to your npm dependencies
26
26
 
27
27
  ```
28
- expo install expo-gl
28
+ npx expo install expo-gl
29
29
  ```
30
30
 
31
31
  ### Compatibility
32
32
 
33
33
  To use version `11.2.0` or newer of `expo-gl` you will need to use at least version `0.68.0` of React Native.
34
34
 
35
- | expo-gl | react-native |
36
- | ------------------ | -------------------- |
37
- | <=8.x.x | \* |
38
- | >=9.0.0 && <11.2.0 | >=0.63.1 && <0.65.0 |
39
- | >=11.2.0 | >=0.68.0 |
35
+ | expo-gl | react-native |
36
+ | ------------------ | ------------------- |
37
+ | <=8.x.x | \* |
38
+ | >=9.0.0 && <11.2.0 | >=0.63.1 && <0.65.0 |
39
+ | >=11.2.0 | >=0.68.0 |
40
40
 
41
41
  To use reanimated worklets you will need compatible version of `react-native-reanimated`.
42
42
 
43
- | expo-gl | react-native-reanimated |
44
- | ------------------ | ----------------------- |
45
- | <11.3.0 | <=2.8.0 |
46
- | >=11.3.0 | >2.8.0 |
43
+ | expo-gl | react-native-reanimated |
44
+ | -------- | ----------------------- |
45
+ | <11.3.0 | <=2.8.0 |
46
+ | >=11.3.0 | >2.8.0 |
47
47
 
48
48
  ### Configure for iOS
49
49
 
@@ -6,7 +6,7 @@ apply plugin: 'maven-publish'
6
6
  apply plugin: "de.undercouch.download"
7
7
 
8
8
  group = 'host.exp.exponent'
9
- version = '12.4.0'
9
+ version = '12.5.0'
10
10
 
11
11
  def REACT_NATIVE_BUILD_FROM_SOURCE = findProject(":ReactAndroid") != null
12
12
  def REACT_NATIVE_DIR = REACT_NATIVE_BUILD_FROM_SOURCE
@@ -103,7 +103,7 @@ android {
103
103
  minSdkVersion safeExtGet("minSdkVersion", 21)
104
104
  targetSdkVersion safeExtGet("targetSdkVersion", 33)
105
105
  versionCode 31
106
- versionName "12.4.0"
106
+ versionName "12.5.0"
107
107
 
108
108
  externalNativeBuild {
109
109
  cmake {
package/build/GLView.d.ts CHANGED
@@ -40,6 +40,7 @@ export declare class GLView extends React.Component<GLViewProps> {
40
40
  render(): JSX.Element;
41
41
  _setNativeRef: (nativeRef: ComponentOrHandle) => void;
42
42
  _onSurfaceCreate: ({ nativeEvent: { exglCtxId } }: SurfaceCreateEvent) => void;
43
+ componentWillUnmount(): void;
43
44
  startARSessionAsync(): Promise<any>;
44
45
  createCameraTextureAsync(cameraRefOrHandle: ComponentOrHandle): Promise<WebGLTexture>;
45
46
  destroyObjectAsync(glObject: WebGLObject): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"GLView.d.ts","sourceRoot":"","sources":["../src/GLView.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,yBAAyB,EACzB,eAAe,EACf,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAIxB,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AASF;;;GAGG;AACH,qBAAa,MAAO,SAAQ,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC;IACtD,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC;IAEvB,MAAM,CAAC,YAAY;;MAEjB;IAEF;;;;;;;OAOG;WACU,kBAAkB,IAAI,OAAO,CAAC,yBAAyB,CAAC;IAKrE;;;;OAIG;WACU,mBAAmB,CAAC,IAAI,CAAC,EAAE,yBAAyB,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK7F;;;;;OAKG;WACU,iBAAiB,CAC5B,IAAI,CAAC,EAAE,yBAAyB,GAAG,MAAM,EACzC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,UAAU,CAAC;IAKtB,MAAM,CAAC,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,yBAAyB,GAAG,SAAS,CACrD;IAEjC,SAAS,EAAE,iBAAiB,CAAQ;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,MAAM;IA0BN,aAAa,cAAe,iBAAiB,KAAG,IAAI,CAKlD;IAEF,gBAAgB,mCAAoC,kBAAkB,KAAG,IAAI,CAQ3E;IAGI,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC;IAQnC,wBAAwB,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAoBrF,kBAAkB,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAOjE;;;;OAIG;IACG,iBAAiB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,UAAU,CAAC;CAO5E"}
1
+ {"version":3,"file":"GLView.d.ts","sourceRoot":"","sources":["../src/GLView.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,yBAAyB,EACzB,eAAe,EACf,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAIxB,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAUF;;;GAGG;AACH,qBAAa,MAAO,SAAQ,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC;IACtD,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC;IAEvB,MAAM,CAAC,YAAY;;MAEjB;IAEF;;;;;;;OAOG;WACU,kBAAkB,IAAI,OAAO,CAAC,yBAAyB,CAAC;IAKrE;;;;OAIG;WACU,mBAAmB,CAAC,IAAI,CAAC,EAAE,yBAAyB,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM7F;;;;;OAKG;WACU,iBAAiB,CAC5B,IAAI,CAAC,EAAE,yBAAyB,GAAG,MAAM,EACzC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,UAAU,CAAC;IAKtB,MAAM,CAAC,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,yBAAyB,GAAG,SAAS,CACnD;IAEnC,SAAS,EAAE,iBAAiB,CAAQ;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,MAAM;IA0BN,aAAa,cAAe,iBAAiB,KAAG,IAAI,CAKlD;IAEF,gBAAgB,mCAAoC,kBAAkB,KAAG,IAAI,CAQ3E;IAEF,oBAAoB,IAAI,IAAI;IAOtB,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC;IAQnC,wBAAwB,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAoBrF,kBAAkB,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAOjE;;;;OAIG;IACG,iBAAiB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,UAAU,CAAC;CAO5E"}
package/build/GLView.js CHANGED
@@ -2,9 +2,10 @@ import { NativeModulesProxy, UnavailabilityError, requireNativeViewManager, Code
2
2
  import * as React from 'react';
3
3
  import { Platform, View, findNodeHandle } from 'react-native';
4
4
  import { configureLogging } from './GLUtils';
5
- import { createWorkletContextProvider } from './GLWorkletContextProvider';
5
+ import { createWorkletContextManager } from './GLWorkletContextManager';
6
6
  const { ExponentGLObjectManager, ExponentGLViewManager } = NativeModulesProxy;
7
7
  const NativeView = requireNativeViewManager('ExponentGLView');
8
+ const workletContextManager = createWorkletContextManager();
8
9
  // @needsAudit
9
10
  /**
10
11
  * A View that acts as an OpenGL ES render target. On mounting, an OpenGL ES context is created.
@@ -34,6 +35,7 @@ export class GLView extends React.Component {
34
35
  */
35
36
  static async destroyContextAsync(exgl) {
36
37
  const exglCtxId = getContextId(exgl);
38
+ unregisterGLContext(exglCtxId);
37
39
  return ExponentGLObjectManager.destroyContextAsync(exglCtxId);
38
40
  }
39
41
  /**
@@ -46,7 +48,7 @@ export class GLView extends React.Component {
46
48
  const exglCtxId = getContextId(exgl);
47
49
  return ExponentGLObjectManager.takeSnapshotAsync(exglCtxId, options);
48
50
  }
49
- static getWorkletContext = createWorkletContextProvider();
51
+ static getWorkletContext = workletContextManager.getContext;
50
52
  nativeRef = null;
51
53
  exglCtxId;
52
54
  render() {
@@ -75,6 +77,11 @@ export class GLView extends React.Component {
75
77
  this.props.onContextCreate(gl);
76
78
  }
77
79
  };
80
+ componentWillUnmount() {
81
+ if (this.exglCtxId) {
82
+ unregisterGLContext(this.exglCtxId);
83
+ }
84
+ }
78
85
  // @docsMissing
79
86
  async startARSessionAsync() {
80
87
  if (!ExponentGLViewManager.startARSessionAsync) {
@@ -116,6 +123,12 @@ export class GLView extends React.Component {
116
123
  }
117
124
  }
118
125
  GLView.NativeView = NativeView;
126
+ function unregisterGLContext(exglCtxId) {
127
+ if (global.__EXGLContexts) {
128
+ delete global.__EXGLContexts[String(exglCtxId)];
129
+ }
130
+ workletContextManager.unregister?.(exglCtxId);
131
+ }
119
132
  // Get the GL interface from an EXGLContextId
120
133
  const getGl = (exglCtxId) => {
121
134
  if (!global.__EXGLContexts) {
@@ -1 +1 @@
1
- {"version":3,"file":"GLView.js","sourceRoot":"","sources":["../src/GLView.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n NativeModulesProxy,\n UnavailabilityError,\n requireNativeViewManager,\n CodedError,\n} from 'expo-modules-core';\nimport * as React from 'react';\nimport { Platform, View, findNodeHandle } from 'react-native';\n\nimport { configureLogging } from './GLUtils';\nimport {\n ComponentOrHandle,\n SurfaceCreateEvent,\n GLSnapshot,\n ExpoWebGLRenderingContext,\n SnapshotOptions,\n GLViewProps,\n} from './GLView.types';\nimport { createWorkletContextProvider } from './GLWorkletContextProvider';\n\n// @docsMissing\nexport type WebGLObject = {\n id: number;\n};\n\ndeclare let global: any;\n\nconst { ExponentGLObjectManager, ExponentGLViewManager } = NativeModulesProxy;\n\nconst NativeView = requireNativeViewManager('ExponentGLView');\n\n// @needsAudit\n/**\n * A View that acts as an OpenGL ES render target. On mounting, an OpenGL ES context is created.\n * Its drawing buffer is presented as the contents of the View every frame.\n */\nexport class GLView extends React.Component<GLViewProps> {\n static NativeView: any;\n\n static defaultProps = {\n msaaSamples: 4,\n };\n\n /**\n * Imperative API that creates headless context which is devoid of underlying view.\n * It's useful for headless rendering or in case you want to keep just one context per application and share it between multiple components.\n * It is slightly faster than usual context as it doesn't swap framebuffers and doesn't present them on the canvas,\n * however it may require you to take a snapshot in order to present its results.\n * Also, keep in mind that you need to set up a viewport and create your own framebuffer and texture that you will be drawing to, before you take a snapshot.\n * @return A promise that resolves to WebGL context object. See [WebGL API](#webgl-api) for more details.\n */\n static async createContextAsync(): Promise<ExpoWebGLRenderingContext> {\n const { exglCtxId } = await ExponentGLObjectManager.createContextAsync();\n return getGl(exglCtxId);\n }\n\n /**\n * Destroys given context.\n * @param exgl WebGL context to destroy.\n * @return A promise that resolves to boolean value that is `true` if given context existed and has been destroyed successfully.\n */\n static async destroyContextAsync(exgl?: ExpoWebGLRenderingContext | number): Promise<boolean> {\n const exglCtxId = getContextId(exgl);\n return ExponentGLObjectManager.destroyContextAsync(exglCtxId);\n }\n\n /**\n * Takes a snapshot of the framebuffer and saves it as a file to app's cache directory.\n * @param exgl WebGL context to take a snapshot from.\n * @param options\n * @return A promise that resolves to `GLSnapshot` object.\n */\n static async takeSnapshotAsync(\n exgl?: ExpoWebGLRenderingContext | number,\n options: SnapshotOptions = {}\n ): Promise<GLSnapshot> {\n const exglCtxId = getContextId(exgl);\n return ExponentGLObjectManager.takeSnapshotAsync(exglCtxId, options);\n }\n\n static getWorkletContext: (contextId: number) => ExpoWebGLRenderingContext | undefined =\n createWorkletContextProvider();\n\n nativeRef: ComponentOrHandle = null;\n exglCtxId?: number;\n\n render() {\n const {\n onContextCreate, // eslint-disable-line no-unused-vars\n msaaSamples,\n ...viewProps\n } = this.props;\n\n return (\n <View {...viewProps}>\n <NativeView\n ref={this._setNativeRef}\n style={{\n flex: 1,\n ...(Platform.OS === 'ios'\n ? {\n backgroundColor: 'transparent',\n }\n : {}),\n }}\n onSurfaceCreate={this._onSurfaceCreate}\n msaaSamples={Platform.OS === 'ios' ? msaaSamples : undefined}\n />\n </View>\n );\n }\n\n _setNativeRef = (nativeRef: ComponentOrHandle): void => {\n if (this.props.nativeRef_EXPERIMENTAL) {\n this.props.nativeRef_EXPERIMENTAL(nativeRef);\n }\n this.nativeRef = nativeRef;\n };\n\n _onSurfaceCreate = ({ nativeEvent: { exglCtxId } }: SurfaceCreateEvent): void => {\n const gl = getGl(exglCtxId);\n\n this.exglCtxId = exglCtxId;\n\n if (this.props.onContextCreate) {\n this.props.onContextCreate(gl);\n }\n };\n\n // @docsMissing\n async startARSessionAsync(): Promise<any> {\n if (!ExponentGLViewManager.startARSessionAsync) {\n throw new UnavailabilityError('expo-gl', 'startARSessionAsync');\n }\n return await ExponentGLViewManager.startARSessionAsync(findNodeHandle(this.nativeRef));\n }\n\n // @docsMissing\n async createCameraTextureAsync(cameraRefOrHandle: ComponentOrHandle): Promise<WebGLTexture> {\n if (!ExponentGLObjectManager.createCameraTextureAsync) {\n throw new UnavailabilityError('expo-gl', 'createCameraTextureAsync');\n }\n\n const { exglCtxId } = this;\n\n if (!exglCtxId) {\n throw new Error(\"GLView's surface is not created yet!\");\n }\n\n const cameraTag = findNodeHandle(cameraRefOrHandle);\n const { exglObjId } = await ExponentGLObjectManager.createCameraTextureAsync(\n exglCtxId,\n cameraTag\n );\n return { id: exglObjId } as WebGLTexture;\n }\n\n // @docsMissing\n async destroyObjectAsync(glObject: WebGLObject): Promise<boolean> {\n if (!ExponentGLObjectManager.destroyObjectAsync) {\n throw new UnavailabilityError('expo-gl', 'destroyObjectAsync');\n }\n return await ExponentGLObjectManager.destroyObjectAsync(glObject.id);\n }\n\n /**\n * Same as static [`takeSnapshotAsync()`](#glviewtakesnapshotasyncgl-options),\n * but uses WebGL context that is associated with the view on which the method is called.\n * @param options\n */\n async takeSnapshotAsync(options: SnapshotOptions = {}): Promise<GLSnapshot> {\n if (!GLView.takeSnapshotAsync) {\n throw new UnavailabilityError('expo-gl', 'takeSnapshotAsync');\n }\n const { exglCtxId } = this;\n return await GLView.takeSnapshotAsync(exglCtxId, options);\n }\n}\n\nGLView.NativeView = NativeView;\n\n// Get the GL interface from an EXGLContextId\nconst getGl = (exglCtxId: number): ExpoWebGLRenderingContext => {\n if (!global.__EXGLContexts) {\n throw new CodedError(\n 'ERR_GL_NOT_AVAILABLE',\n 'GL is currently not available. (Have you enabled remote debugging? GL is not available while debugging remotely.)'\n );\n }\n const gl = global.__EXGLContexts[String(exglCtxId)];\n\n configureLogging(gl);\n\n return gl;\n};\n\nconst getContextId = (exgl?: ExpoWebGLRenderingContext | number): number => {\n const exglCtxId = exgl && typeof exgl === 'object' ? exgl.contextId : exgl;\n\n if (!exglCtxId || typeof exglCtxId !== 'number') {\n throw new Error(`Invalid EXGLContext id: ${String(exglCtxId)}`);\n }\n return exglCtxId;\n};\n"]}
1
+ {"version":3,"file":"GLView.js","sourceRoot":"","sources":["../src/GLView.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n NativeModulesProxy,\n UnavailabilityError,\n requireNativeViewManager,\n CodedError,\n} from 'expo-modules-core';\nimport * as React from 'react';\nimport { Platform, View, findNodeHandle } from 'react-native';\n\nimport { configureLogging } from './GLUtils';\nimport {\n ComponentOrHandle,\n SurfaceCreateEvent,\n GLSnapshot,\n ExpoWebGLRenderingContext,\n SnapshotOptions,\n GLViewProps,\n} from './GLView.types';\nimport { createWorkletContextManager } from './GLWorkletContextManager';\n\n// @docsMissing\nexport type WebGLObject = {\n id: number;\n};\n\ndeclare let global: any;\n\nconst { ExponentGLObjectManager, ExponentGLViewManager } = NativeModulesProxy;\n\nconst NativeView = requireNativeViewManager('ExponentGLView');\nconst workletContextManager = createWorkletContextManager();\n\n// @needsAudit\n/**\n * A View that acts as an OpenGL ES render target. On mounting, an OpenGL ES context is created.\n * Its drawing buffer is presented as the contents of the View every frame.\n */\nexport class GLView extends React.Component<GLViewProps> {\n static NativeView: any;\n\n static defaultProps = {\n msaaSamples: 4,\n };\n\n /**\n * Imperative API that creates headless context which is devoid of underlying view.\n * It's useful for headless rendering or in case you want to keep just one context per application and share it between multiple components.\n * It is slightly faster than usual context as it doesn't swap framebuffers and doesn't present them on the canvas,\n * however it may require you to take a snapshot in order to present its results.\n * Also, keep in mind that you need to set up a viewport and create your own framebuffer and texture that you will be drawing to, before you take a snapshot.\n * @return A promise that resolves to WebGL context object. See [WebGL API](#webgl-api) for more details.\n */\n static async createContextAsync(): Promise<ExpoWebGLRenderingContext> {\n const { exglCtxId } = await ExponentGLObjectManager.createContextAsync();\n return getGl(exglCtxId);\n }\n\n /**\n * Destroys given context.\n * @param exgl WebGL context to destroy.\n * @return A promise that resolves to boolean value that is `true` if given context existed and has been destroyed successfully.\n */\n static async destroyContextAsync(exgl?: ExpoWebGLRenderingContext | number): Promise<boolean> {\n const exglCtxId = getContextId(exgl);\n unregisterGLContext(exglCtxId);\n return ExponentGLObjectManager.destroyContextAsync(exglCtxId);\n }\n\n /**\n * Takes a snapshot of the framebuffer and saves it as a file to app's cache directory.\n * @param exgl WebGL context to take a snapshot from.\n * @param options\n * @return A promise that resolves to `GLSnapshot` object.\n */\n static async takeSnapshotAsync(\n exgl?: ExpoWebGLRenderingContext | number,\n options: SnapshotOptions = {}\n ): Promise<GLSnapshot> {\n const exglCtxId = getContextId(exgl);\n return ExponentGLObjectManager.takeSnapshotAsync(exglCtxId, options);\n }\n\n static getWorkletContext: (contextId: number) => ExpoWebGLRenderingContext | undefined =\n workletContextManager.getContext;\n\n nativeRef: ComponentOrHandle = null;\n exglCtxId?: number;\n\n render() {\n const {\n onContextCreate, // eslint-disable-line no-unused-vars\n msaaSamples,\n ...viewProps\n } = this.props;\n\n return (\n <View {...viewProps}>\n <NativeView\n ref={this._setNativeRef}\n style={{\n flex: 1,\n ...(Platform.OS === 'ios'\n ? {\n backgroundColor: 'transparent',\n }\n : {}),\n }}\n onSurfaceCreate={this._onSurfaceCreate}\n msaaSamples={Platform.OS === 'ios' ? msaaSamples : undefined}\n />\n </View>\n );\n }\n\n _setNativeRef = (nativeRef: ComponentOrHandle): void => {\n if (this.props.nativeRef_EXPERIMENTAL) {\n this.props.nativeRef_EXPERIMENTAL(nativeRef);\n }\n this.nativeRef = nativeRef;\n };\n\n _onSurfaceCreate = ({ nativeEvent: { exglCtxId } }: SurfaceCreateEvent): void => {\n const gl = getGl(exglCtxId);\n\n this.exglCtxId = exglCtxId;\n\n if (this.props.onContextCreate) {\n this.props.onContextCreate(gl);\n }\n };\n\n componentWillUnmount(): void {\n if (this.exglCtxId) {\n unregisterGLContext(this.exglCtxId);\n }\n }\n\n // @docsMissing\n async startARSessionAsync(): Promise<any> {\n if (!ExponentGLViewManager.startARSessionAsync) {\n throw new UnavailabilityError('expo-gl', 'startARSessionAsync');\n }\n return await ExponentGLViewManager.startARSessionAsync(findNodeHandle(this.nativeRef));\n }\n\n // @docsMissing\n async createCameraTextureAsync(cameraRefOrHandle: ComponentOrHandle): Promise<WebGLTexture> {\n if (!ExponentGLObjectManager.createCameraTextureAsync) {\n throw new UnavailabilityError('expo-gl', 'createCameraTextureAsync');\n }\n\n const { exglCtxId } = this;\n\n if (!exglCtxId) {\n throw new Error(\"GLView's surface is not created yet!\");\n }\n\n const cameraTag = findNodeHandle(cameraRefOrHandle);\n const { exglObjId } = await ExponentGLObjectManager.createCameraTextureAsync(\n exglCtxId,\n cameraTag\n );\n return { id: exglObjId } as WebGLTexture;\n }\n\n // @docsMissing\n async destroyObjectAsync(glObject: WebGLObject): Promise<boolean> {\n if (!ExponentGLObjectManager.destroyObjectAsync) {\n throw new UnavailabilityError('expo-gl', 'destroyObjectAsync');\n }\n return await ExponentGLObjectManager.destroyObjectAsync(glObject.id);\n }\n\n /**\n * Same as static [`takeSnapshotAsync()`](#glviewtakesnapshotasyncgl-options),\n * but uses WebGL context that is associated with the view on which the method is called.\n * @param options\n */\n async takeSnapshotAsync(options: SnapshotOptions = {}): Promise<GLSnapshot> {\n if (!GLView.takeSnapshotAsync) {\n throw new UnavailabilityError('expo-gl', 'takeSnapshotAsync');\n }\n const { exglCtxId } = this;\n return await GLView.takeSnapshotAsync(exglCtxId, options);\n }\n}\n\nGLView.NativeView = NativeView;\n\nfunction unregisterGLContext(exglCtxId: number) {\n if (global.__EXGLContexts) {\n delete global.__EXGLContexts[String(exglCtxId)];\n }\n workletContextManager.unregister?.(exglCtxId);\n}\n\n// Get the GL interface from an EXGLContextId\nconst getGl = (exglCtxId: number): ExpoWebGLRenderingContext => {\n if (!global.__EXGLContexts) {\n throw new CodedError(\n 'ERR_GL_NOT_AVAILABLE',\n 'GL is currently not available. (Have you enabled remote debugging? GL is not available while debugging remotely.)'\n );\n }\n const gl = global.__EXGLContexts[String(exglCtxId)];\n\n configureLogging(gl);\n\n return gl;\n};\n\nconst getContextId = (exgl?: ExpoWebGLRenderingContext | number): number => {\n const exglCtxId = exgl && typeof exgl === 'object' ? exgl.contextId : exgl;\n\n if (!exglCtxId || typeof exglCtxId !== 'number') {\n throw new Error(`Invalid EXGLContext id: ${String(exglCtxId)}`);\n }\n return exglCtxId;\n};\n"]}
@@ -0,0 +1,6 @@
1
+ import { ExpoWebGLRenderingContext } from './GLView.types';
2
+ export declare function createWorkletContextManager(): {
3
+ getContext: (contextId: number) => ExpoWebGLRenderingContext | undefined;
4
+ unregister?: (contextId: number) => void;
5
+ };
6
+ //# sourceMappingURL=GLWorkletContextManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GLWorkletContextManager.d.ts","sourceRoot":"","sources":["../src/GLWorkletContextManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAU3D,wBAAgB,2BAA2B,IAAI;IAC7C,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,yBAAyB,GAAG,SAAS,CAAC;IACzE,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C,CA0BA"}
@@ -0,0 +1,37 @@
1
+ // This method needs to be in a separate file because react-native-reanimated
2
+ // import wrapped in try catch does not work correctly with inlineRequires option
3
+ // in metro.config.js
4
+ //
5
+ // It looks like in generated bundle "react-native-reanimated" is not present
6
+ // in _dependencyMap, but references to it count it as if it was, e.g. bundle contains
7
+ // a line "(0, _$$_REQUIRE(_dependencyMap[15], "./GLUtils").configureLogging)(gl);"
8
+ // but dependencyMap contains only 15 elements
9
+ export function createWorkletContextManager() {
10
+ try {
11
+ // reanimated needs to be imported before any workletized code
12
+ // is created, but we don't want to make it dependency on expo-gl.
13
+ const { runOnUI } = require('react-native-reanimated');
14
+ return {
15
+ getContext: (contextId) => {
16
+ 'worklet';
17
+ return global.__EXGLContexts?.[String(contextId)];
18
+ },
19
+ unregister: (contextId) => {
20
+ runOnUI((contextId) => {
21
+ 'worklet';
22
+ if (global.__EXGLContexts) {
23
+ delete global.__EXGLContexts[String(contextId)];
24
+ }
25
+ })(contextId);
26
+ },
27
+ };
28
+ }
29
+ catch {
30
+ return {
31
+ getContext: () => {
32
+ throw new Error('Worklet runtime is not available');
33
+ },
34
+ };
35
+ }
36
+ }
37
+ //# sourceMappingURL=GLWorkletContextManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GLWorkletContextManager.js","sourceRoot":"","sources":["../src/GLWorkletContextManager.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,iFAAiF;AACjF,qBAAqB;AACrB,EAAE;AACF,6EAA6E;AAC7E,sFAAsF;AACtF,mFAAmF;AACnF,8CAA8C;AAC9C,MAAM,UAAU,2BAA2B;IAIzC,IAAI;QACF,8DAA8D;QAC9D,kEAAkE;QAClE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;QACvD,OAAO;YACL,UAAU,EAAE,CAAC,SAAiB,EAAyC,EAAE;gBACvE,SAAS,CAAC;gBACV,OAAO,MAAM,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;YACpD,CAAC;YACD,UAAU,EAAE,CAAC,SAAiB,EAAQ,EAAE;gBACtC,OAAO,CAAC,CAAC,SAAiB,EAAE,EAAE;oBAC5B,SAAS,CAAC;oBACV,IAAI,MAAM,CAAC,cAAc,EAAE;wBACzB,OAAO,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;qBACjD;gBACH,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAChB,CAAC;SACF,CAAC;KACH;IAAC,MAAM;QACN,OAAO;YACL,UAAU,EAAE,GAAG,EAAE;gBACf,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;YACtD,CAAC;SACF,CAAC;KACH;AACH,CAAC","sourcesContent":["import { ExpoWebGLRenderingContext } from './GLView.types';\n\n// This method needs to be in a separate file because react-native-reanimated\n// import wrapped in try catch does not work correctly with inlineRequires option\n// in metro.config.js\n//\n// It looks like in generated bundle \"react-native-reanimated\" is not present\n// in _dependencyMap, but references to it count it as if it was, e.g. bundle contains\n// a line \"(0, _$$_REQUIRE(_dependencyMap[15], \"./GLUtils\").configureLogging)(gl);\"\n// but dependencyMap contains only 15 elements\nexport function createWorkletContextManager(): {\n getContext: (contextId: number) => ExpoWebGLRenderingContext | undefined;\n unregister?: (contextId: number) => void;\n} {\n try {\n // reanimated needs to be imported before any workletized code\n // is created, but we don't want to make it dependency on expo-gl.\n const { runOnUI } = require('react-native-reanimated');\n return {\n getContext: (contextId: number): ExpoWebGLRenderingContext | undefined => {\n 'worklet';\n return global.__EXGLContexts?.[String(contextId)];\n },\n unregister: (contextId: number): void => {\n runOnUI((contextId: number) => {\n 'worklet';\n if (global.__EXGLContexts) {\n delete global.__EXGLContexts[String(contextId)];\n }\n })(contextId);\n },\n };\n } catch {\n return {\n getContext: () => {\n throw new Error('Worklet runtime is not available');\n },\n };\n }\n}\n"]}
@@ -52,13 +52,6 @@ void createWebGLRenderer(jsi::Runtime &runtime, EXGLContext *ctx, initGlesContex
52
52
  gl.setProperty(runtime, "supportsWebGL2", ctx->supportsWebGL2);
53
53
  gl.setProperty(runtime, "contextId", static_cast<double>(ctx->ctxId));
54
54
 
55
- // Legacy case for older SDKs in Expo Go
56
- bool legacyJs = !runtime.global().getProperty(runtime, "__EXGLConstructorReady").isBool();
57
- if (legacyJs) {
58
- installConstants(runtime, gl);
59
- ctx->supportsWebGL2 ? installWebGL2Methods(runtime, gl) : installWebGLMethods(runtime, gl);
60
- }
61
-
62
55
  jsi::Value jsContextMap = global.getProperty(runtime, EXGLContextsMapPropertyName);
63
56
  if (jsContextMap.isNull() || jsContextMap.isUndefined()) {
64
57
  global.setProperty(runtime, EXGLContextsMapPropertyName, jsi::Object(runtime));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-gl",
3
- "version": "12.4.0",
3
+ "version": "12.5.0",
4
4
  "description": "Provides GLView that acts as OpenGL ES render target and gives GL context object implementing WebGL 2.0 specification.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -49,5 +49,5 @@
49
49
  "peerDependencies": {
50
50
  "expo": "*"
51
51
  },
52
- "gitHead": "c8107d57eabaedff5d53bc8036d062db12a473c8"
52
+ "gitHead": "4ba50c428c8369bb6b3a51a860d4898ad4ccbe78"
53
53
  }
package/src/GLView.tsx CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  SnapshotOptions,
17
17
  GLViewProps,
18
18
  } from './GLView.types';
19
- import { createWorkletContextProvider } from './GLWorkletContextProvider';
19
+ import { createWorkletContextManager } from './GLWorkletContextManager';
20
20
 
21
21
  // @docsMissing
22
22
  export type WebGLObject = {
@@ -28,6 +28,7 @@ declare let global: any;
28
28
  const { ExponentGLObjectManager, ExponentGLViewManager } = NativeModulesProxy;
29
29
 
30
30
  const NativeView = requireNativeViewManager('ExponentGLView');
31
+ const workletContextManager = createWorkletContextManager();
31
32
 
32
33
  // @needsAudit
33
34
  /**
@@ -61,6 +62,7 @@ export class GLView extends React.Component<GLViewProps> {
61
62
  */
62
63
  static async destroyContextAsync(exgl?: ExpoWebGLRenderingContext | number): Promise<boolean> {
63
64
  const exglCtxId = getContextId(exgl);
65
+ unregisterGLContext(exglCtxId);
64
66
  return ExponentGLObjectManager.destroyContextAsync(exglCtxId);
65
67
  }
66
68
 
@@ -79,7 +81,7 @@ export class GLView extends React.Component<GLViewProps> {
79
81
  }
80
82
 
81
83
  static getWorkletContext: (contextId: number) => ExpoWebGLRenderingContext | undefined =
82
- createWorkletContextProvider();
84
+ workletContextManager.getContext;
83
85
 
84
86
  nativeRef: ComponentOrHandle = null;
85
87
  exglCtxId?: number;
@@ -127,6 +129,12 @@ export class GLView extends React.Component<GLViewProps> {
127
129
  }
128
130
  };
129
131
 
132
+ componentWillUnmount(): void {
133
+ if (this.exglCtxId) {
134
+ unregisterGLContext(this.exglCtxId);
135
+ }
136
+ }
137
+
130
138
  // @docsMissing
131
139
  async startARSessionAsync(): Promise<any> {
132
140
  if (!ExponentGLViewManager.startARSessionAsync) {
@@ -179,6 +187,13 @@ export class GLView extends React.Component<GLViewProps> {
179
187
 
180
188
  GLView.NativeView = NativeView;
181
189
 
190
+ function unregisterGLContext(exglCtxId: number) {
191
+ if (global.__EXGLContexts) {
192
+ delete global.__EXGLContexts[String(exglCtxId)];
193
+ }
194
+ workletContextManager.unregister?.(exglCtxId);
195
+ }
196
+
182
197
  // Get the GL interface from an EXGLContextId
183
198
  const getGl = (exglCtxId: number): ExpoWebGLRenderingContext => {
184
199
  if (!global.__EXGLContexts) {
@@ -0,0 +1,40 @@
1
+ import { ExpoWebGLRenderingContext } from './GLView.types';
2
+
3
+ // This method needs to be in a separate file because react-native-reanimated
4
+ // import wrapped in try catch does not work correctly with inlineRequires option
5
+ // in metro.config.js
6
+ //
7
+ // It looks like in generated bundle "react-native-reanimated" is not present
8
+ // in _dependencyMap, but references to it count it as if it was, e.g. bundle contains
9
+ // a line "(0, _$$_REQUIRE(_dependencyMap[15], "./GLUtils").configureLogging)(gl);"
10
+ // but dependencyMap contains only 15 elements
11
+ export function createWorkletContextManager(): {
12
+ getContext: (contextId: number) => ExpoWebGLRenderingContext | undefined;
13
+ unregister?: (contextId: number) => void;
14
+ } {
15
+ try {
16
+ // reanimated needs to be imported before any workletized code
17
+ // is created, but we don't want to make it dependency on expo-gl.
18
+ const { runOnUI } = require('react-native-reanimated');
19
+ return {
20
+ getContext: (contextId: number): ExpoWebGLRenderingContext | undefined => {
21
+ 'worklet';
22
+ return global.__EXGLContexts?.[String(contextId)];
23
+ },
24
+ unregister: (contextId: number): void => {
25
+ runOnUI((contextId: number) => {
26
+ 'worklet';
27
+ if (global.__EXGLContexts) {
28
+ delete global.__EXGLContexts[String(contextId)];
29
+ }
30
+ })(contextId);
31
+ },
32
+ };
33
+ } catch {
34
+ return {
35
+ getContext: () => {
36
+ throw new Error('Worklet runtime is not available');
37
+ },
38
+ };
39
+ }
40
+ }
@@ -1,3 +0,0 @@
1
- import { ExpoWebGLRenderingContext } from './GLView.types';
2
- export declare function createWorkletContextProvider(): (contextId: number) => ExpoWebGLRenderingContext | undefined;
3
- //# sourceMappingURL=GLWorkletContextProvider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"GLWorkletContextProvider.d.ts","sourceRoot":"","sources":["../src/GLWorkletContextProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAU3D,wBAAgB,4BAA4B,gBAKrB,MAAM,KAAG,yBAAyB,GAAG,SAAS,CASpE"}
@@ -1,25 +0,0 @@
1
- // This method needs to be in a separate file because react-native-reanimated
2
- // import wrapped in try catch does not work correctly with inlineRequires option
3
- // in metro.config.js
4
- //
5
- // It looks like in generated bundle "react-native-reanimated" is not present
6
- // in _dependencyMap, but references to it count it as if it was, e.g. bundle contains
7
- // a line "(0, _$$_REQUIRE(_dependencyMap[15], "./GLUtils").configureLogging)(gl);"
8
- // but dependencyMap contains only 15 elements
9
- export function createWorkletContextProvider() {
10
- try {
11
- // reanimated needs to be imported before any workletized code
12
- // is created, but we don't want to make it dependency on expo-gl.
13
- require('react-native-reanimated');
14
- return (contextId) => {
15
- 'worklet';
16
- return global.__EXGLContexts?.[String(contextId)];
17
- };
18
- }
19
- catch {
20
- return () => {
21
- throw new Error('Worklet runtime is not available');
22
- };
23
- }
24
- }
25
- //# sourceMappingURL=GLWorkletContextProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"GLWorkletContextProvider.js","sourceRoot":"","sources":["../src/GLWorkletContextProvider.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,iFAAiF;AACjF,qBAAqB;AACrB,EAAE;AACF,6EAA6E;AAC7E,sFAAsF;AACtF,mFAAmF;AACnF,8CAA8C;AAC9C,MAAM,UAAU,4BAA4B;IAC1C,IAAI;QACF,8DAA8D;QAC9D,kEAAkE;QAClE,OAAO,CAAC,yBAAyB,CAAC,CAAC;QACnC,OAAO,CAAC,SAAiB,EAAyC,EAAE;YAClE,SAAS,CAAC;YACV,OAAO,MAAM,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QACpD,CAAC,CAAC;KACH;IAAC,MAAM;QACN,OAAO,GAAG,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC,CAAC;KACH;AACH,CAAC","sourcesContent":["import { ExpoWebGLRenderingContext } from './GLView.types';\n\n// This method needs to be in a separate file because react-native-reanimated\n// import wrapped in try catch does not work correctly with inlineRequires option\n// in metro.config.js\n//\n// It looks like in generated bundle \"react-native-reanimated\" is not present\n// in _dependencyMap, but references to it count it as if it was, e.g. bundle contains\n// a line \"(0, _$$_REQUIRE(_dependencyMap[15], \"./GLUtils\").configureLogging)(gl);\"\n// but dependencyMap contains only 15 elements\nexport function createWorkletContextProvider() {\n try {\n // reanimated needs to be imported before any workletized code\n // is created, but we don't want to make it dependency on expo-gl.\n require('react-native-reanimated');\n return (contextId: number): ExpoWebGLRenderingContext | undefined => {\n 'worklet';\n return global.__EXGLContexts?.[String(contextId)];\n };\n } catch {\n return () => {\n throw new Error('Worklet runtime is not available');\n };\n }\n}\n"]}
@@ -1,25 +0,0 @@
1
- import { ExpoWebGLRenderingContext } from './GLView.types';
2
-
3
- // This method needs to be in a separate file because react-native-reanimated
4
- // import wrapped in try catch does not work correctly with inlineRequires option
5
- // in metro.config.js
6
- //
7
- // It looks like in generated bundle "react-native-reanimated" is not present
8
- // in _dependencyMap, but references to it count it as if it was, e.g. bundle contains
9
- // a line "(0, _$$_REQUIRE(_dependencyMap[15], "./GLUtils").configureLogging)(gl);"
10
- // but dependencyMap contains only 15 elements
11
- export function createWorkletContextProvider() {
12
- try {
13
- // reanimated needs to be imported before any workletized code
14
- // is created, but we don't want to make it dependency on expo-gl.
15
- require('react-native-reanimated');
16
- return (contextId: number): ExpoWebGLRenderingContext | undefined => {
17
- 'worklet';
18
- return global.__EXGLContexts?.[String(contextId)];
19
- };
20
- } catch {
21
- return () => {
22
- throw new Error('Worklet runtime is not available');
23
- };
24
- }
25
- }