1 #pragma once
2 // it should be included only in EXWebGLMethods.cpp
3
4 #include "EXGLNativeContext.h"
5 #include "EXWebGLRenderer.h"
6
7 #ifdef __ANDROID__
8 #include <GLES3/gl3.h>
9 #include <GLES3/gl3ext.h>
10 #endif
11 #ifdef __APPLE__
12 #include <OpenGLES/EAGL.h>
13 #include <OpenGLES/ES3/gl.h>
14 #include <OpenGLES/ES3/glext.h>
15 #endif
16
17 namespace expo {
18 namespace gl_cpp {
19
20 template <typename Func>
exglGetActiveInfo(EXGLContext * ctx,jsi::Runtime & runtime,EXGLObjectId fProgram,GLuint index,GLenum lengthParam,Func glFunc)21 inline jsi::Value exglGetActiveInfo(
22 EXGLContext *ctx,
23 jsi::Runtime &runtime,
24 EXGLObjectId fProgram,
25 GLuint index,
26 GLenum lengthParam,
27 Func glFunc) {
28 if (fProgram == 0) {
29 return nullptr;
30 }
31
32 GLsizei length;
33 GLint size;
34 GLenum type;
35 std::string name;
36 GLint maxNameLength;
37
38 ctx->addBlockingToNextBatch([&] {
39 GLuint program = ctx->lookupObject(fProgram);
40 glGetProgramiv(program, lengthParam, &maxNameLength);
41 name.resize(maxNameLength);
42
43 glFunc(program, index, maxNameLength, &length, &size, &type, &name[0]);
44 name.resize(length);
45 });
46
47 if (name.size() == 0) { // name.length() may be larger
48 return nullptr;
49 }
50
51 jsi::Object jsResult =
52 createWebGLObject(runtime, EXWebGLClass::WebGLActiveInfo, {}).asObject(runtime);
53 jsResult.setProperty(runtime, "name", jsi::String::createFromUtf8(runtime, name));
54 jsResult.setProperty(runtime, "size", size);
55 jsResult.setProperty(runtime, "type", static_cast<double>(type));
56 return jsResult;
57 }
58
59 template <typename Func, typename... T>
exglCall(EXGLContext * ctx,Func func,T &&...args)60 inline jsi::Value exglCall(EXGLContext *ctx, Func func, T &&... args) {
61 ctx->addToNextBatch([=, args = std::make_tuple(std::forward<T>(args)...)] {
62 return std::apply(func, std::move(args));
63 });
64 }
65
66 template <typename Func, typename T>
67 inline jsi::Value
exglUniformv(EXGLContext * ctx,Func func,GLuint uniform,size_t dim,std::vector<T> && data)68 exglUniformv(EXGLContext *ctx, Func func, GLuint uniform, size_t dim, std::vector<T> &&data) {
69 ctx->addToNextBatch([=, data{std::move(data)}] {
70 func(uniform, static_cast<int>(data.size() / dim), data.data());
71 });
72 return nullptr;
73 }
74
75 template <typename Func, typename T>
exglUniformMatrixv(EXGLContext * ctx,Func func,GLuint uniform,GLboolean transpose,size_t dim,std::vector<T> && data)76 inline jsi::Value exglUniformMatrixv(
77 EXGLContext *ctx,
78 Func func,
79 GLuint uniform,
80 GLboolean transpose,
81 size_t dim,
82 std::vector<T> &&data) {
83 ctx->addToNextBatch([=, data{std::move(data)}] {
84 func(uniform, static_cast<int>(data.size() / dim), transpose, data.data());
85 });
86 return nullptr;
87 }
88
89 template <typename Func, typename T>
90 inline jsi::Value
exglVertexAttribv(EXGLContext * ctx,Func func,GLuint index,std::vector<T> && data)91 exglVertexAttribv(EXGLContext *ctx, Func func, GLuint index, std::vector<T> &&data) {
92 ctx->addToNextBatch([=, data{std::move(data)}] { func(index, data.data()); });
93 return nullptr;
94 }
95
96 inline jsi::Value
exglIsObject(EXGLContext * ctx,EXGLObjectId id,std::function<GLboolean (GLuint)> func)97 exglIsObject(EXGLContext *ctx, EXGLObjectId id, std::function<GLboolean(GLuint)> func) {
98 GLboolean glResult;
99 ctx->addBlockingToNextBatch([&] { glResult = func(ctx->lookupObject(id)); });
100 return glResult == GL_TRUE;
101 }
102
exglGenObject(EXGLContext * ctx,jsi::Runtime & runtime,std::function<void (GLsizei,EXGLObjectId *)> func,EXWebGLClass webglClass)103 inline jsi::Value exglGenObject(
104 EXGLContext *ctx,
105 jsi::Runtime &runtime,
106 std::function<void(GLsizei, EXGLObjectId *)> func,
107 EXWebGLClass webglClass) {
108 auto id = ctx->addFutureToNextBatch(runtime, [=] {
109 GLuint buffer;
110 func(1, &buffer);
111 return buffer;
112 });
113 return createWebGLObject(runtime, webglClass, {std::move(id)});
114 }
115
exglCreateObject(EXGLContext * ctx,jsi::Runtime & runtime,std::function<GLuint ()> func,EXWebGLClass webglClass)116 inline jsi::Value exglCreateObject(
117 EXGLContext *ctx,
118 jsi::Runtime &runtime,
119 std::function<GLuint()> func,
120 EXWebGLClass webglClass) {
121 auto id = ctx->addFutureToNextBatch(runtime, [=] { return func(); });
122 return createWebGLObject(runtime, webglClass, {std::move(id)});
123 }
124
125 inline jsi::Value
exglDeleteObject(EXGLContext * ctx,EXGLObjectId id,std::function<void (EXGLObjectId)> func)126 exglDeleteObject(EXGLContext *ctx, EXGLObjectId id, std::function<void(EXGLObjectId)> func) {
127 ctx->addToNextBatch([=] { func(ctx->lookupObject(id)); });
128 return nullptr;
129 }
130
exglDeleteObject(EXGLContext * ctx,EXGLObjectId id,std::function<void (GLsizei,const EXGLObjectId *)> func)131 inline jsi::Value exglDeleteObject(
132 EXGLContext *ctx,
133 EXGLObjectId id,
134 std::function<void(GLsizei, const EXGLObjectId *)> func) {
135 ctx->addToNextBatch([=] {
136 GLuint buffer = ctx->lookupObject(id);
137 func(1, &buffer);
138 });
139 return nullptr;
140 }
141
exglUnimplemented(std::string name)142 inline jsi::Value exglUnimplemented(std::string name) {
143 throw std::runtime_error("EXGL: " + name + "() isn't implemented yet!");
144 }
145
146 } // namespace gl_cpp
147 } // namespace expo
148