#pragma once // it should be included only in EXWebGLMethods.cpp #include "EXGLNativeContext.h" #include "EXWebGLRenderer.h" #ifdef __ANDROID__ #include #include #endif #ifdef __APPLE__ #include #include #include #endif namespace expo { namespace gl_cpp { template inline jsi::Value exglGetActiveInfo( EXGLContext *ctx, jsi::Runtime &runtime, EXGLObjectId fProgram, GLuint index, GLenum lengthParam, Func glFunc) { if (fProgram == 0) { return nullptr; } GLsizei length; GLint size; GLenum type; std::string name; GLint maxNameLength; ctx->addBlockingToNextBatch([&] { GLuint program = ctx->lookupObject(fProgram); glGetProgramiv(program, lengthParam, &maxNameLength); name.resize(maxNameLength); glFunc(program, index, maxNameLength, &length, &size, &type, &name[0]); name.resize(length); }); if (name.size() == 0) { // name.length() may be larger return nullptr; } jsi::Object jsResult = createWebGLObject(runtime, EXWebGLClass::WebGLActiveInfo, {}).asObject(runtime); jsResult.setProperty(runtime, "name", jsi::String::createFromUtf8(runtime, name)); jsResult.setProperty(runtime, "size", size); jsResult.setProperty(runtime, "type", static_cast(type)); return jsResult; } template inline jsi::Value exglCall(EXGLContext *ctx, Func func, T &&... args) { ctx->addToNextBatch([=, args = std::make_tuple(std::forward(args)...)] { return std::apply(func, std::move(args)); }); } template inline jsi::Value exglUniformv(EXGLContext *ctx, Func func, GLuint uniform, size_t dim, std::vector &&data) { ctx->addToNextBatch([=, data{std::move(data)}] { func(uniform, static_cast(data.size() / dim), data.data()); }); return nullptr; } template inline jsi::Value exglUniformMatrixv( EXGLContext *ctx, Func func, GLuint uniform, GLboolean transpose, size_t dim, std::vector &&data) { ctx->addToNextBatch([=, data{std::move(data)}] { func(uniform, static_cast(data.size() / dim), transpose, data.data()); }); return nullptr; } template inline jsi::Value exglVertexAttribv(EXGLContext *ctx, Func func, GLuint index, std::vector &&data) { ctx->addToNextBatch([=, data{std::move(data)}] { func(index, data.data()); }); return nullptr; } inline jsi::Value exglIsObject(EXGLContext *ctx, EXGLObjectId id, std::function func) { GLboolean glResult; ctx->addBlockingToNextBatch([&] { glResult = func(ctx->lookupObject(id)); }); return glResult == GL_TRUE; } inline jsi::Value exglGenObject( EXGLContext *ctx, jsi::Runtime &runtime, std::function func, EXWebGLClass webglClass) { auto id = ctx->addFutureToNextBatch(runtime, [=] { GLuint buffer; func(1, &buffer); return buffer; }); return createWebGLObject(runtime, webglClass, {std::move(id)}); } inline jsi::Value exglCreateObject( EXGLContext *ctx, jsi::Runtime &runtime, std::function func, EXWebGLClass webglClass) { auto id = ctx->addFutureToNextBatch(runtime, [=] { return func(); }); return createWebGLObject(runtime, webglClass, {std::move(id)}); } inline jsi::Value exglDeleteObject(EXGLContext *ctx, EXGLObjectId id, std::function func) { ctx->addToNextBatch([=] { func(ctx->lookupObject(id)); }); return nullptr; } inline jsi::Value exglDeleteObject( EXGLContext *ctx, EXGLObjectId id, std::function func) { ctx->addToNextBatch([=] { GLuint buffer = ctx->lookupObject(id); func(1, &buffer); }); return nullptr; } inline jsi::Value exglUnimplemented(std::string name) { throw std::runtime_error("EXGL: " + name + "() isn't implemented yet!"); } } // namespace gl_cpp } // namespace expo