expo-gl 56.0.3 → 56.0.5
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 +11 -0
- package/android/CMakeLists.txt +3 -0
- package/android/build.gradle +58 -2
- package/android/src/main/cpp/EXGLJniApi.cpp +9 -7
- package/android/src/main/java/expo/modules/gl/GLModule.kt +12 -0
- package/android/src/main/java/expo/modules/gl/cpp/EXGL.java +1 -0
- package/common/EXGLContextManager.cpp +3 -1
- package/common/EXGLContextManager.h +8 -1
- package/common/EXGLImageUtils.cpp +16 -15
- package/common/EXGLImageUtils.h +6 -15
- package/common/EXGLNativeApi.cpp +8 -3
- package/common/EXGLNativeApi.h +5 -0
- package/common/EXGLNativeContext.cpp +13 -10
- package/common/EXGLNativeContext.h +19 -25
- package/common/EXJsiArgsTransform.h +58 -117
- package/common/EXJsiUtils.h +40 -23
- package/common/EXTypedArrayApi.cpp +79 -63
- package/common/EXTypedArrayApi.h +72 -42
- package/common/EXWebGLMethods.cpp +22 -1439
- package/common/EXWebGLMethods.h +6 -1
- package/common/EXWebGLMethodsDraw.cpp +862 -0
- package/common/EXWebGLMethodsHelpers.h +31 -40
- package/common/EXWebGLMethodsMacros.h +51 -0
- package/common/EXWebGLMethodsTextures.cpp +541 -0
- package/common/EXWebGLRenderer.cpp +119 -76
- package/common/EXWebGLRenderer.h +19 -7
- package/common/pch.h +21 -0
- package/expo-module.config.json +1 -1
- package/ios/ExpoGLModule.swift +11 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/{56.0.3/expo.modules.gl-56.0.3-sources.jar → 56.0.5/expo.modules.gl-56.0.5-sources.jar} +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5-sources.jar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5-sources.jar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5-sources.jar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5-sources.jar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.aar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.aar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.aar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/{56.0.3/expo.modules.gl-56.0.3.module → 56.0.5/expo.modules.gl-56.0.5.module} +22 -22
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/{56.0.3/expo.modules.gl-56.0.3.pom → 56.0.5/expo.modules.gl-56.0.5.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.5/expo.modules.gl-56.0.5.pom.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/maven-metadata.xml +4 -4
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/maven-metadata.xml.sha512 +1 -1
- package/package.json +3 -3
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3-sources.jar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3-sources.jar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3-sources.jar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3-sources.jar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.aar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.aar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.aar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.aar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.gl/56.0.3/expo.modules.gl-56.0.3.pom.sha512 +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,17 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 56.0.5 — 2026-05-19
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Install `WebGLRenderingContext` and `WebGL2RenderingContext` globals and their numeric constants at module init so libraries that read them before any GL context is created no longer crash. ([#45865](https://github.com/expo/expo/pull/45865) by [@tsapeta](https://github.com/tsapeta))
|
|
18
|
+
- Make `WebGL2RenderingContext` inherit from `WebGLRenderingContext`, matching the WebGL spec. `gl2 instanceof WebGLRenderingContext` now returns `true` for WebGL2 contexts, and shared constants and methods are no longer duplicated on the WebGL2 prototype. ([#45871](https://github.com/expo/expo/pull/45871) by [@tsapeta](https://github.com/tsapeta))
|
|
19
|
+
|
|
20
|
+
## 56.0.4 — 2026-05-15
|
|
21
|
+
|
|
22
|
+
_This version does not introduce any user-facing changes._
|
|
23
|
+
|
|
13
24
|
## 56.0.3 — 2026-05-06
|
|
14
25
|
|
|
15
26
|
_This version does not introduce any user-facing changes._
|
package/android/CMakeLists.txt
CHANGED
|
@@ -21,6 +21,8 @@ add_library(
|
|
|
21
21
|
${COMMON_DIR}/EXGLContextManager.cpp
|
|
22
22
|
${COMMON_DIR}/EXGLContextManager.h
|
|
23
23
|
${COMMON_DIR}/EXWebGLMethods.cpp
|
|
24
|
+
${COMMON_DIR}/EXWebGLMethodsTextures.cpp
|
|
25
|
+
${COMMON_DIR}/EXWebGLMethodsDraw.cpp
|
|
24
26
|
${COMMON_DIR}/EXWebGLMethods.h
|
|
25
27
|
${COMMON_DIR}/EXWebGLRenderer.cpp
|
|
26
28
|
${COMMON_DIR}/EXWebGLRenderer.h
|
|
@@ -46,4 +48,5 @@ target_compile_options(
|
|
|
46
48
|
-Wno-unused-parameter
|
|
47
49
|
-Wshorten-64-to-32
|
|
48
50
|
-Wstrict-prototypes)
|
|
51
|
+
target_precompile_headers(${PACKAGE_NAME} PRIVATE ${COMMON_DIR}/pch.h)
|
|
49
52
|
target_link_libraries(${PACKAGE_NAME} ReactAndroid::jsi ${LOG_LIB} ${GLES_LIB} android)
|
package/android/build.gradle
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import groovy.json.JsonSlurper
|
|
2
|
+
|
|
1
3
|
plugins {
|
|
2
4
|
id 'com.android.library'
|
|
3
5
|
id 'expo-module-gradle-plugin'
|
|
@@ -9,7 +11,7 @@ def reactNativeArchitectures() {
|
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
group = 'host.exp.exponent'
|
|
12
|
-
version = '56.0.
|
|
14
|
+
version = '56.0.5'
|
|
13
15
|
|
|
14
16
|
android {
|
|
15
17
|
if (rootProject.hasProperty("ndkPath")) {
|
|
@@ -22,7 +24,7 @@ android {
|
|
|
22
24
|
namespace "expo.modules.gl"
|
|
23
25
|
defaultConfig {
|
|
24
26
|
versionCode 31
|
|
25
|
-
versionName "56.0.
|
|
27
|
+
versionName "56.0.5"
|
|
26
28
|
|
|
27
29
|
externalNativeBuild {
|
|
28
30
|
cmake {
|
|
@@ -61,3 +63,57 @@ dependencies {
|
|
|
61
63
|
compileOnly 'com.facebook.soloader:soloader:0.8.2'
|
|
62
64
|
compileOnly 'com.facebook.react:react-android'
|
|
63
65
|
}
|
|
66
|
+
|
|
67
|
+
// Generates minimal stub PCH files from an empty header so the IDE's C++ engine
|
|
68
|
+
// doesn't fail during sync. Near-instant unlike the full ExpoHeader.pch.
|
|
69
|
+
// The actual build regenerates proper PCH files via ninja.
|
|
70
|
+
def cxxDir = project.file(".cxx")
|
|
71
|
+
def generateStubPCHTask = tasks.register("generateStubPCH") {
|
|
72
|
+
dependsOn("configureCMakeDebug")
|
|
73
|
+
|
|
74
|
+
doLast {
|
|
75
|
+
if (!cxxDir.exists()) {
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
cxxDir.eachFileRecurse { file ->
|
|
80
|
+
if (file.name != "compile_commands.json") {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
new JsonSlurper().parseText(file.text).each { entry ->
|
|
85
|
+
if (!entry.file.endsWith("cmake_pch.hxx.cxx")) {
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
def pchFile = new File(entry.file.substring(0, entry.file.length() - ".cxx".length()) + ".pch")
|
|
90
|
+
|
|
91
|
+
if (!pchFile.exists() || pchFile.length() == 0) {
|
|
92
|
+
def stubHeader = new File(entry.directory, "stub_pch.hxx")
|
|
93
|
+
stubHeader.text = ""
|
|
94
|
+
|
|
95
|
+
def cmd = entry.command
|
|
96
|
+
// Replace the forced-include path: `-Xclang -include -Xclang <path>/cmake_pch.hxx`
|
|
97
|
+
.replaceAll(/-Xclang -include -Xclang [^\s]+cmake_pch\.hxx(?=\s)/, "-Xclang -include -Xclang ${stubHeader.absolutePath}")
|
|
98
|
+
// Replace the source file operand: `<path>/cmake_pch.hxx.cxx`
|
|
99
|
+
.replaceAll(/[^\s]+cmake_pch\.hxx\.cxx/, stubHeader.absolutePath)
|
|
100
|
+
|
|
101
|
+
def process = new ProcessBuilder(cmd.split(" ").toList())
|
|
102
|
+
.directory(new File(entry.directory))
|
|
103
|
+
.redirectErrorStream(true)
|
|
104
|
+
.start()
|
|
105
|
+
if (process.waitFor() != 0) {
|
|
106
|
+
throw new GradleException("Stub PCH generation failed: ${process.inputStream.text}")
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Ensure PCH is older than source so ninja rebuilds the real one during build
|
|
111
|
+
pchFile.setLastModified(new File(entry.file).lastModified() - 1)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
tasks.register("prepareKotlinBuildScriptModel") {
|
|
118
|
+
dependsOn(generateStubPCHTask)
|
|
119
|
+
}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
#include <stdint.h>
|
|
2
|
-
|
|
3
1
|
#include <jni.h>
|
|
4
2
|
#include <thread>
|
|
5
|
-
#include <android/log.h>
|
|
6
3
|
|
|
7
|
-
#include <jsi/jsi.h>
|
|
8
4
|
#include "EXGLNativeApi.h"
|
|
9
5
|
#include "EXPlatformUtils.h"
|
|
10
6
|
|
|
@@ -12,7 +8,7 @@ extern "C" {
|
|
|
12
8
|
|
|
13
9
|
// JNIEnv is valid only inside the same thread that it was passed from
|
|
14
10
|
// to support worklet we need register it from UI thread
|
|
15
|
-
thread_local JNIEnv*
|
|
11
|
+
thread_local JNIEnv *threadLocalEnv;
|
|
16
12
|
|
|
17
13
|
JNIEXPORT jint JNICALL
|
|
18
14
|
Java_expo_modules_gl_cpp_EXGL_EXGLContextCreate
|
|
@@ -20,6 +16,12 @@ Java_expo_modules_gl_cpp_EXGL_EXGLContextCreate
|
|
|
20
16
|
return EXGLContextCreate();
|
|
21
17
|
}
|
|
22
18
|
|
|
19
|
+
JNIEXPORT void JNICALL
|
|
20
|
+
Java_expo_modules_gl_cpp_EXGL_EXGLInstallWebGLBindings
|
|
21
|
+
(JNIEnv *env, jclass clazz, jlong jsiPtr) {
|
|
22
|
+
EXGLInstallWebGLBindings((void *) jsiPtr);
|
|
23
|
+
}
|
|
24
|
+
|
|
23
25
|
JNIEXPORT void JNICALL
|
|
24
26
|
Java_expo_modules_gl_cpp_EXGL_EXGLContextPrepare
|
|
25
27
|
(JNIEnv *env, jclass clazz, jlong jsiPtr, jint exglCtxId, jobject glContext) {
|
|
@@ -31,7 +33,7 @@ Java_expo_modules_gl_cpp_EXGL_EXGLContextPrepare
|
|
|
31
33
|
std::function<void(void)> flushMethod = [glContextRef, flushMethodRef] {
|
|
32
34
|
threadLocalEnv->CallVoidMethod(glContextRef, flushMethodRef);
|
|
33
35
|
};
|
|
34
|
-
EXGLContextPrepare((void*) jsiPtr, exglCtxId, flushMethod);
|
|
36
|
+
EXGLContextPrepare((void *) jsiPtr, exglCtxId, flushMethod);
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
JNIEXPORT void JNICALL
|
|
@@ -77,7 +79,7 @@ Java_expo_modules_gl_cpp_EXGL_EXGLContextGetObject
|
|
|
77
79
|
return EXGLContextGetObject(exglCtxId, exglObjId);
|
|
78
80
|
}
|
|
79
81
|
|
|
80
|
-
JNIEXPORT
|
|
82
|
+
JNIEXPORT jboolean JNICALL
|
|
81
83
|
Java_expo_modules_gl_cpp_EXGL_EXGLContextNeedsRedraw
|
|
82
84
|
(JNIEnv *env, jclass clazz, jint exglCtxId) {
|
|
83
85
|
return EXGLContextNeedsRedraw(exglCtxId);
|
|
@@ -5,12 +5,14 @@ import android.os.Bundle
|
|
|
5
5
|
import android.util.SparseArray
|
|
6
6
|
import android.view.View
|
|
7
7
|
import expo.modules.interfaces.camera.CameraViewInterface
|
|
8
|
+
import expo.modules.gl.cpp.EXGL
|
|
8
9
|
import expo.modules.kotlin.Promise
|
|
9
10
|
import expo.modules.kotlin.exception.CodedException
|
|
10
11
|
import expo.modules.kotlin.exception.Exceptions
|
|
11
12
|
import expo.modules.kotlin.functions.Queues
|
|
12
13
|
import expo.modules.kotlin.modules.Module
|
|
13
14
|
import expo.modules.kotlin.modules.ModuleDefinition
|
|
15
|
+
import expo.modules.kotlin.runtime.MainRuntime
|
|
14
16
|
|
|
15
17
|
private class InvalidCameraViewException :
|
|
16
18
|
CodedException("Provided view tag don't point to valid instance of the camera view")
|
|
@@ -24,6 +26,16 @@ class GLModule : Module() {
|
|
|
24
26
|
override fun definition() = ModuleDefinition {
|
|
25
27
|
Name("ExpoGL")
|
|
26
28
|
|
|
29
|
+
OnCreate {
|
|
30
|
+
val runtime = appContext.runtime as? MainRuntime ?: return@OnCreate
|
|
31
|
+
val jsRuntimePointer = runtime.reactContext?.javaScriptContextHolder?.get() ?: 0L
|
|
32
|
+
if (jsRuntimePointer != 0L) {
|
|
33
|
+
runtime.schedule {
|
|
34
|
+
EXGL.EXGLInstallWebGLBindings(jsRuntimePointer)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
27
39
|
AsyncFunction("destroyObjectAsync") { exglObjId: Int ->
|
|
28
40
|
val glObject = mGLObjects[exglObjId]
|
|
29
41
|
?: return@AsyncFunction false
|
|
@@ -8,6 +8,7 @@ public class EXGL {
|
|
|
8
8
|
SoLoader.loadLibrary("expo-gl");
|
|
9
9
|
}
|
|
10
10
|
public static native int EXGLContextCreate();
|
|
11
|
+
public static native void EXGLInstallWebGLBindings(long jsCtxPtr);
|
|
11
12
|
public static native void EXGLContextPrepare(long jsCtxPtr, int exglCtxId, Object glContext);
|
|
12
13
|
public static native void EXGLContextPrepareWorklet(int exglCtxId);
|
|
13
14
|
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include "pch.h"
|
|
4
|
+
|
|
3
5
|
#include <shared_mutex>
|
|
4
|
-
|
|
6
|
+
|
|
7
|
+
#include "EXGLNativeApi.h"
|
|
5
8
|
|
|
6
9
|
namespace expo {
|
|
7
10
|
namespace gl_cpp {
|
|
8
11
|
|
|
12
|
+
class EXGLContext;
|
|
13
|
+
|
|
9
14
|
using ContextWithLock = std::pair<EXGLContext *, std::shared_lock<std::shared_mutex>>;
|
|
10
15
|
|
|
11
16
|
EXGLContextId ContextCreate();
|
|
17
|
+
|
|
12
18
|
ContextWithLock ContextGet(EXGLContextId id);
|
|
19
|
+
|
|
13
20
|
void ContextDestroy(EXGLContextId id);
|
|
14
21
|
|
|
15
22
|
} // namespace gl_cpp
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#define STBI_ONLY_JPEG
|
|
4
4
|
#define STBI_ONLY_PNG
|
|
5
5
|
#define STB_IMAGE_IMPLEMENTATION
|
|
6
|
+
|
|
6
7
|
#include "stb_image.h"
|
|
7
8
|
|
|
8
9
|
namespace jsi = facebook::jsi;
|
|
@@ -47,14 +48,14 @@ void flipPixels(GLubyte *pixels, size_t bytesPerRow, size_t rows) {
|
|
|
47
48
|
return;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
GLuint middle = (GLuint)rows / 2;
|
|
51
|
-
GLuint intsPerRow = (GLuint)bytesPerRow / sizeof(GLuint);
|
|
52
|
-
GLuint remainingBytes = (GLuint)bytesPerRow - intsPerRow * sizeof(GLuint);
|
|
51
|
+
GLuint middle = (GLuint) rows / 2;
|
|
52
|
+
GLuint intsPerRow = (GLuint) bytesPerRow / sizeof(GLuint);
|
|
53
|
+
GLuint remainingBytes = (GLuint) bytesPerRow - intsPerRow * sizeof(GLuint);
|
|
53
54
|
|
|
54
|
-
for (GLuint rowTop = 0, rowBottom = (GLuint)rows - 1; rowTop < middle; ++rowTop, --rowBottom) {
|
|
55
|
+
for (GLuint rowTop = 0, rowBottom = (GLuint) rows - 1; rowTop < middle; ++rowTop, --rowBottom) {
|
|
55
56
|
// Swap in packs of sizeof(GLuint) bytes
|
|
56
|
-
GLuint *iTop = (GLuint *)(pixels + rowTop * bytesPerRow);
|
|
57
|
-
GLuint *iBottom = (GLuint *)(pixels + rowBottom * bytesPerRow);
|
|
57
|
+
GLuint *iTop = (GLuint *) (pixels + rowTop * bytesPerRow);
|
|
58
|
+
GLuint *iBottom = (GLuint *) (pixels + rowBottom * bytesPerRow);
|
|
58
59
|
GLuint iTmp;
|
|
59
60
|
GLuint n = intsPerRow;
|
|
60
61
|
do {
|
|
@@ -64,8 +65,8 @@ void flipPixels(GLubyte *pixels, size_t bytesPerRow, size_t rows) {
|
|
|
64
65
|
} while (--n > 0);
|
|
65
66
|
|
|
66
67
|
// Swap remainder bytes
|
|
67
|
-
GLubyte *bTop = (GLubyte *)iTop;
|
|
68
|
-
GLubyte *bBottom = (GLubyte *)iBottom;
|
|
68
|
+
GLubyte *bTop = (GLubyte *) iTop;
|
|
69
|
+
GLubyte *bBottom = (GLubyte *) iBottom;
|
|
69
70
|
GLubyte bTmp;
|
|
70
71
|
switch (remainingBytes) {
|
|
71
72
|
case 3:
|
|
@@ -117,11 +118,11 @@ void decodeURI(char *dst, const char *src) {
|
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
std::shared_ptr<uint8_t> loadImage(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
jsi::Runtime &runtime,
|
|
122
|
+
const jsi::Object &jsPixels,
|
|
123
|
+
int *fileWidth,
|
|
124
|
+
int *fileHeight,
|
|
125
|
+
int *fileComp) {
|
|
125
126
|
auto localUriProp = jsPixels.getProperty(runtime, "localUri");
|
|
126
127
|
if (localUriProp.isString()) {
|
|
127
128
|
auto localUri = localUriProp.asString(runtime).utf8(runtime);
|
|
@@ -132,8 +133,8 @@ std::shared_ptr<uint8_t> loadImage(
|
|
|
132
133
|
decodeURI(localPath, localUri.c_str() + 7);
|
|
133
134
|
|
|
134
135
|
return std::shared_ptr<uint8_t>(
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
stbi_load(localPath, fileWidth, fileHeight, fileComp, STBI_rgb_alpha),
|
|
137
|
+
[](void *data) { stbi_image_free(data); });
|
|
137
138
|
}
|
|
138
139
|
return std::shared_ptr<uint8_t>(nullptr);
|
|
139
140
|
}
|
package/common/EXGLImageUtils.h
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
#include <GLES3/gl3.h>
|
|
5
|
-
#include <GLES3/gl3ext.h>
|
|
6
|
-
#endif
|
|
7
|
-
#ifdef __APPLE__
|
|
8
|
-
#include <OpenGLES/ES3/gl.h>
|
|
9
|
-
#endif
|
|
10
|
-
|
|
11
|
-
#include <jsi/jsi.h>
|
|
12
|
-
#include <vector>
|
|
3
|
+
#include "pch.h"
|
|
13
4
|
|
|
14
5
|
namespace expo {
|
|
15
6
|
namespace gl_cpp {
|
|
@@ -19,10 +10,10 @@ GLuint bytesPerPixel(GLenum type, GLenum format);
|
|
|
19
10
|
void flipPixels(GLubyte *pixels, size_t bytesPerRow, size_t rows);
|
|
20
11
|
|
|
21
12
|
std::shared_ptr<uint8_t> loadImage(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
facebook::jsi::Runtime &runtime,
|
|
14
|
+
const facebook::jsi::Object &jsPixels,
|
|
15
|
+
int *fileWidth,
|
|
16
|
+
int *fileHeight,
|
|
17
|
+
int *fileComp);
|
|
27
18
|
} // namespace gl_cpp
|
|
28
19
|
} // namespace expo
|
package/common/EXGLNativeApi.cpp
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#include "EXGLNativeApi.h"
|
|
2
2
|
#include "EXGLContextManager.h"
|
|
3
3
|
#include "EXGLNativeContext.h"
|
|
4
|
+
#include "EXWebGLRenderer.h"
|
|
4
5
|
|
|
5
6
|
using namespace expo::gl_cpp;
|
|
6
7
|
|
|
@@ -8,10 +9,14 @@ EXGLContextId EXGLContextCreate() {
|
|
|
8
9
|
return ContextCreate();
|
|
9
10
|
}
|
|
10
11
|
|
|
12
|
+
void EXGLInstallWebGLBindings(void *jsiPtr) {
|
|
13
|
+
installWebGLConstructorsAndConstants(*reinterpret_cast<jsi::Runtime *>(jsiPtr));
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
void EXGLContextPrepare(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
void *jsiPtr,
|
|
18
|
+
EXGLContextId exglCtxId,
|
|
19
|
+
std::function<void(void)> flushMethod) {
|
|
15
20
|
auto [exglCtx, lock] = ContextGet(exglCtxId);
|
|
16
21
|
if (exglCtx) {
|
|
17
22
|
exglCtx->prepareContext(*reinterpret_cast<jsi::Runtime *>(jsiPtr), flushMethod);
|
package/common/EXGLNativeApi.h
CHANGED
|
@@ -28,6 +28,11 @@ typedef unsigned int EXGLObjectId;
|
|
|
28
28
|
|
|
29
29
|
EXGLContextId EXGLContextCreate();
|
|
30
30
|
|
|
31
|
+
// [JS thread] Install the `WebGLRenderingContext` / `WebGL2RenderingContext`
|
|
32
|
+
// global constructors and their numeric constants so they are reachable from
|
|
33
|
+
// JS before any GL context is created. `runtime` is a raw `jsi::Runtime *`.
|
|
34
|
+
void EXGLInstallWebGLBindings(void *runtime);
|
|
35
|
+
|
|
31
36
|
#ifdef __cplusplus
|
|
32
37
|
// [JS thread] Create an EXGL context and return its id number. Saves the
|
|
33
38
|
// JavaScript interface object (has a WebGLRenderingContext-style API) at
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#include "EXGLNativeContext.h"
|
|
2
|
+
|
|
3
|
+
#include <future>
|
|
4
|
+
|
|
2
5
|
#include "EXPlatformUtils.h"
|
|
3
6
|
|
|
4
7
|
namespace expo {
|
|
@@ -34,7 +37,7 @@ void EXGLContext::maybeResolveWorkletContext(jsi::Runtime &runtime) {
|
|
|
34
37
|
return;
|
|
35
38
|
}
|
|
36
39
|
uintptr_t rawWorkletRuntimePointer =
|
|
37
|
-
|
|
40
|
+
*reinterpret_cast<uintptr_t *>(workletRuntimeArrayBuffer.data(runtime));
|
|
38
41
|
jsi::Runtime *workletRuntime = reinterpret_cast<jsi::Runtime *>(rawWorkletRuntimePointer);
|
|
39
42
|
this->maybeWorkletRuntime = workletRuntime;
|
|
40
43
|
}
|
|
@@ -45,7 +48,7 @@ void EXGLContext::prepareWorkletContext() {
|
|
|
45
48
|
}
|
|
46
49
|
jsi::Runtime &runtime = *this->maybeWorkletRuntime;
|
|
47
50
|
createWebGLRenderer(
|
|
48
|
-
|
|
51
|
+
runtime, this, initialGlesContext, runtime.global().getPropertyAsObject(runtime, "global"));
|
|
49
52
|
tryRegisterOnJSRuntimeDestroy(runtime);
|
|
50
53
|
}
|
|
51
54
|
|
|
@@ -76,8 +79,8 @@ void EXGLContext::addBlockingToNextBatch(Op &&op) {
|
|
|
76
79
|
// [JS thread] Enqueue a function and return an EXGL object that will get mapped
|
|
77
80
|
// to the function's return value when it is called on the GL thread.
|
|
78
81
|
jsi::Value EXGLContext::addFutureToNextBatch(
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
jsi::Runtime &runtime,
|
|
83
|
+
std::function<unsigned int(void)> &&op) noexcept {
|
|
81
84
|
auto exglObjId = createObject();
|
|
82
85
|
addToNextBatch([=] {
|
|
83
86
|
assert(objects.find(exglObjId) == objects.end());
|
|
@@ -94,8 +97,8 @@ void EXGLContext::flush(void) {
|
|
|
94
97
|
std::lock_guard<std::mutex> lock(backlogMutex);
|
|
95
98
|
std::swap(backlog, copy);
|
|
96
99
|
}
|
|
97
|
-
for (const auto &batch
|
|
98
|
-
for (const auto &op
|
|
100
|
+
for (const auto &batch: copy) {
|
|
101
|
+
for (const auto &op: batch) {
|
|
99
102
|
op();
|
|
100
103
|
}
|
|
101
104
|
}
|
|
@@ -128,10 +131,10 @@ void EXGLContext::tryRegisterOnJSRuntimeDestroy(jsi::Runtime &runtime) {
|
|
|
128
131
|
// `jsi::Runtime` is being destroyed and that will trigger destructor of
|
|
129
132
|
// `InvalidateCacheOnDestroy` class which will invalidate JSI PropNameID cache.
|
|
130
133
|
global.setProperty(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
runtime,
|
|
135
|
+
OnJSRuntimeDestroyPropertyName,
|
|
136
|
+
jsi::Object::createFromHostObject(
|
|
137
|
+
runtime, std::make_shared<InvalidateCacheOnDestroy>(runtime)));
|
|
135
138
|
}
|
|
136
139
|
|
|
137
140
|
glesContext EXGLContext::prepareOpenGLESContext() {
|
|
@@ -1,28 +1,11 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include "
|
|
4
|
-
|
|
5
|
-
#ifdef __ANDROID__
|
|
6
|
-
#include <GLES3/gl3.h>
|
|
7
|
-
#include <GLES3/gl3ext.h>
|
|
8
|
-
#endif
|
|
9
|
-
#ifdef __APPLE__
|
|
10
|
-
#include <OpenGLES/EAGL.h>
|
|
11
|
-
#include <OpenGLES/ES3/gl.h>
|
|
12
|
-
#include <OpenGLES/ES3/glext.h>
|
|
13
|
-
#endif
|
|
3
|
+
#include "pch.h"
|
|
14
4
|
|
|
15
|
-
#include "EXTypedArrayApi.h"
|
|
16
|
-
|
|
17
|
-
#include <exception>
|
|
18
|
-
#include <future>
|
|
19
5
|
#include <set>
|
|
20
|
-
#include <sstream>
|
|
21
|
-
#include <unordered_map>
|
|
22
|
-
#include <vector>
|
|
23
|
-
|
|
24
|
-
#include <jsi/jsi.h>
|
|
25
6
|
|
|
7
|
+
#include "EXGLNativeApi.h"
|
|
8
|
+
#include "EXTypedArrayApi.h"
|
|
26
9
|
#include "EXJsiUtils.h"
|
|
27
10
|
#include "EXPlatformUtils.h"
|
|
28
11
|
#include "EXWebGLRenderer.h"
|
|
@@ -48,10 +31,13 @@ class EXGLContext {
|
|
|
48
31
|
using Op = std::function<void(void)>;
|
|
49
32
|
using Batch = std::vector<Op>;
|
|
50
33
|
|
|
51
|
-
|
|
34
|
+
public:
|
|
52
35
|
EXGLContext(EXGLContextId ctxId) : ctxId(ctxId) {}
|
|
36
|
+
|
|
53
37
|
void prepareContext(jsi::Runtime &runtime, std::function<void(void)> flushMethod);
|
|
38
|
+
|
|
54
39
|
void maybeResolveWorkletContext(jsi::Runtime &runtime);
|
|
40
|
+
|
|
55
41
|
void prepareWorkletContext();
|
|
56
42
|
|
|
57
43
|
// --- Queue handling --------------------------------------------------------
|
|
@@ -67,8 +53,10 @@ class EXGLContext {
|
|
|
67
53
|
|
|
68
54
|
// [JS thread] Send the current 'next' batch to GL and make a new 'next' batch
|
|
69
55
|
void endNextBatch() noexcept;
|
|
56
|
+
|
|
70
57
|
// [JS thread] Add an Op to the 'next' batch
|
|
71
58
|
void addToNextBatch(Op &&op) noexcept;
|
|
59
|
+
|
|
72
60
|
// [JS thread] Add a blocking operation to the 'next' batch -- waits for the
|
|
73
61
|
// queued function to run before returning
|
|
74
62
|
void addBlockingToNextBatch(Op &&op);
|
|
@@ -86,8 +74,9 @@ class EXGLContext {
|
|
|
86
74
|
// To make it work lookupObject can be called only on GL thread
|
|
87
75
|
//
|
|
88
76
|
jsi::Value addFutureToNextBatch(
|
|
89
|
-
|
|
90
|
-
|
|
77
|
+
jsi::Runtime &runtime,
|
|
78
|
+
std::function<unsigned int(void)> &&op
|
|
79
|
+
) noexcept;
|
|
91
80
|
|
|
92
81
|
// [GL thread] Do all the remaining work we can do on the GL thread
|
|
93
82
|
// triggered by call to flushOnGLThread
|
|
@@ -102,21 +91,26 @@ class EXGLContext {
|
|
|
102
91
|
// mutex on the mapping.
|
|
103
92
|
|
|
104
93
|
EXGLObjectId createObject(void) noexcept;
|
|
94
|
+
|
|
105
95
|
void destroyObject(EXGLObjectId exglObjId) noexcept;
|
|
96
|
+
|
|
106
97
|
void mapObject(EXGLObjectId exglObjId, GLuint glObj) noexcept;
|
|
98
|
+
|
|
107
99
|
GLuint lookupObject(EXGLObjectId exglObjId) noexcept;
|
|
108
100
|
|
|
109
101
|
void tryRegisterOnJSRuntimeDestroy(jsi::Runtime &runtime);
|
|
102
|
+
|
|
110
103
|
glesContext prepareOpenGLESContext();
|
|
104
|
+
|
|
111
105
|
void maybeReadAndCacheSupportedExtensions();
|
|
112
106
|
|
|
113
|
-
|
|
107
|
+
private:
|
|
114
108
|
// Queue
|
|
115
109
|
Batch nextBatch;
|
|
116
110
|
std::vector<Batch> backlog;
|
|
117
111
|
std::mutex backlogMutex;
|
|
118
112
|
|
|
119
|
-
|
|
113
|
+
public:
|
|
120
114
|
EXGLContextId ctxId;
|
|
121
115
|
// Worklet runtime is stored here only to avoid it passing through Java/Obj-C.
|
|
122
116
|
// It should only be used in prepareContext and prepareWorkletContext.
|