Closed sergeyext closed 4 years ago
Trying out
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main()
{
if (glewInit() != GLEW_OK) {
std::cout << "No glew" << std::endl;
return 1;
}
if (glfwInit() != GLFW_TRUE) {
std::cout << "No glfw" << std::endl;
return 2;
}
auto w = glfwCreateWindow(100, 100, "Foo", 0, 0);
glfwMakeContextCurrent(w);
GLuint bufId;
glGenBuffers(1, &bufId);
glBindBuffer(GL_ARRAY_BUFFER, bufId);
glBufferData(GL_ARRAY_BUFFER, 256, nullptr, GL_STATIC_DRAW);
glClearColor(1,1,0,1);
glClear(GL_COLOR_BUFFER_BIT);
std::cout << "done" << std::endl;
return 0;
}
with
em++ a.cpp -o a.html -s USE_PTHREADS=1 -s USE_GLFW=3 -s USE_WEBGL2=1 -std=c++11
does work for me, tried on incoming
branch at 576f6399ef3997606017660912074d88762ce2a1
The above code gives
Perhaps the STR is missing a detail?
Updating to 1.38.36 solved the problem. Previous version was 1.38.31.
Problem is still here, adding more detail to the issue.
@juj I started with your example with your command line and it worked. Then I added -s OFFSCREENCANVAS_SUPPORT=1 -s OFFSCREEN_FRAMEBUFFER=1
and got crash:
/home/sergey/code/emsdk/fastcomp/emscripten/system/lib/pthread/library_pthread.c,446,emscripten_async_queue_call_on_thread") at Error
at jsStackTrace (http://localhost:8003/ems_thread.js:1157:13)
at stackTrace (http://localhost:8003/ems_thread.js:1174:12)
at abort (http://localhost:8003/ems_thread.js:10393:44)
at ___assert_fail (http://localhost:8003/ems_thread.js:1802:7)
at _emscripten_async_queue_call_on_thread (wasm-function[282]:76)
at _emscripten_async_queue_on_thread_ (wasm-function[283]:837)
at _glBufferData (wasm-function[267]:208)
at _main (wasm-function[95]:252)
at Object.Module._main (http://localhost:8003/ems_thread.js:9743:33)
at Object.callMain (http://localhost:8003/ems_thread.js:10225:30)
The whole command line was
em++ a.cpp -o a.html -g -s USE_PTHREADS=1 -s USE_GLFW=3 -s USE_WEBGL2=1 -s OFFSCREENCANVAS_SUPPORT=1 -s OFFSCREEN_FRAMEBUFFER=1 -std=c++11
May be related to https://github.com/emscripten-core/emscripten/issues/8638
test_webgl_offscreen_canvas_in_pthread fails in good working browser. Am i starting test correctly? "EMCC_DEBUG=1 python tests/runner.py browser.test_webgl_offscreen_canvas_in_pthread"
...
is it expected -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 to break -s OFFSCREENCANVAS_SUPPORT=1 and -s OFFSCREEN_FRAMEBUFFER=1 ? (with wasm & pthreads, as in provided example)
Hmm, I think GLFW may not have been updated to support multithreading. If you use HTML5 context creation API, that is multithreading compatible.
This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant.
I am having more or less exactly the same problem as the OP, however i am using EGL instead of GLFW for context creation.
Currently i am creating my context like this:
// create a GL context...
EGLint numConfigs;
EGLint majorVersion;
EGLint minorVersion;
EGLConfig config;
EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE};
// create an RGBA-mode context
// specify depth, stencil, accumulator sizes (GLint)
EGLint attribList[] =
{
EGL_DEPTH_SIZE, rc.GetDepthSize(),
EGL_ALPHA_SIZE, 8,
EGL_STENCIL_SIZE, 0,
//EGL_ACCUMBITS, 0 // doesn't seem to exist TODO is this needed?
};
// obtai and egl display
static Display* x_display = NULL;
m_display = eglGetDisplay((EGLNativeDisplayType)x_display);
if ( m_display == EGL_NO_DISPLAY )
{
throw std::runtime_error("no display!");
}
if (!eglInitialize(m_display, &majorVersion, &minorVersion))
{
throw std::runtime_error("init failed!");
}
// Get configs
if (!eglGetConfigs(m_display, NULL, 0, &numConfigs))
{
throw std::runtime_error("get configs failed!");
}
// Choose config
if( !eglChooseConfig(m_display, attribList, &config, 1, &numConfigs))
{
throw std::runtime_error("choose config failed!");
}
// Create a surface
m_surface = eglCreateWindowSurface(m_display, config, NULL, NULL);
// Create a GL context
auto ctx = eglCreateContext(m_display, config, EGL_NO_CONTEXT, contextAttribs);
// make the context current: i.e. bind the buffer to the context to make it current!
eglMakeCurrent(m_display, m_surface, m_surface, m_rc->GetContext());
std::cout << "context creation successful!" << std::endl;
It was possible to call functions some functions like glClearColor(...)
that indeed had a effect on the canvas that i created.
But calling glBufferData
created exactly the same error as @sergeyext described.
I am also using the flags -s OFFSCREEN_FRAMEBUFFER=1
(to use OpenGL with pthreads at all) and -sOFFSCREENCANVAS_SUPPORT=1
(the error stayed the same, wether i enabled this or not).
After reading through this PR https://github.com/emscripten-core/emscripten/pull/5580 which was not merged, i think that the combination of EGL and pthreads is currently not working right @juj ? Would it be better to use the HTML5 context creation API in this case?
After reading through this PR https://github.com/emscripten-core/emscripten/pull/5580 which was not merged, i think that the combination of EGL and pthreads is currently not working right @juj ?
Even without #5580, EGL should work in pthreads enabled programs, IF the GL context is created on the main browser thread, and all GL and EGL calls are restricted to happen only on the main browser thread.
The idea with #5580 was that it would enable use of EGL in pthreads as well, when paired with the OffscreenCanvas feature (although EGL+OffscreenCanvas was never developed as part of #5580).
If you want to use WebGL in a pthread via OffscreenCanvas, using HTML5 context creation API will enable that.
Ah thank you very much, this explains my problems pretty good. I was creating a egl context inside a std::thread (which I think uses pthreads under the hood) and wondering where all those threading errors come from. Activating the offscreen canvas flag on link time didn't change the situation, because #5580 wasn't merged.
I now switched to the HTML5 context creation API and things work pretty well.
One thing I wonder is if the egl solution would be able to allow creating contexts in a pthread via proxying the calls to the main browser thread. That's what I am currently doing with the HTML5 api, because using offscreen canvas (without proxying) with std::thread instead of pthread don't seem to work.
The following code
being compiled with flags
-s USE_PTHREADS=1 -s USE_GLFW=3 -s USE_WEBGL2=1
crashes withAssertion failed: target_thread, at: /path/to/emsdk/emscripten/1.38.31/system/lib/pthread/library_pthread.c,355,emscripten_async_queue_call_on_thread
onglBufferData
call.It works correctly if we comment out
glBufferData
or build the code without threading support. Threading and shared buffers in browser are enabled and a minimal example withClearColor()
andClear()
work correctly even from a worker thread.Also crashes with webgl1.