diff --git a/src/renderer/RenderDevice.cpp b/src/renderer/RenderDevice.cpp index 1fedf4e..6927546 100644 --- a/src/renderer/RenderDevice.cpp +++ b/src/renderer/RenderDevice.cpp @@ -1501,7 +1501,11 @@ RenderDevice::RenderDevice( SetRenderState(RenderState::ZFUNC, RenderState::Z_LESSEQUAL); // Retrieve a reference to the back buffer. - wnd->SetBackBuffer(new RenderTarget(this, SurfaceType::RT_DEFAULT, wnd->GetWidth(), wnd->GetHeight(), back_buffer_format)); + // vpinball-wasm: use pixel (device) size, not logical/CSS size - on Emscripten + // these differ by devicePixelRatio, and the GL viewport (RenderTarget.cpp's + // glViewport(0, 0, m_width, m_height)) must match the canvas's actual backing + // buffer or rendering only fills a fraction of it, anchored bottom-left. + wnd->SetBackBuffer(new RenderTarget(this, SurfaceType::RT_DEFAULT, wnd->GetPixelWidth(), wnd->GetPixelHeight(), back_buffer_format)); #elif defined(ENABLE_DX9) /////////////////////////////////// @@ -2168,10 +2172,19 @@ void RenderDevice::WaitForVSync(const bool asynchronous) m_vsyncCount++; m_presentTimestampReference = usec(); }; +#ifndef __EMSCRIPTEN__ if (asynchronous) std::thread(lambda).detach(); // Reuse thread ? (we always at most one running at a time) else lambda(); +#else + // vpinball-wasm: a single-threaded Emscripten build (no -pthread / + // SharedArrayBuffer) cannot construct real std::thread workers - run + // synchronously inline instead. This only updates m_vsyncCount/timestamp + // bookkeeping (the real vblank-wait branches above are already excluded + // for __STANDALONE__ builds), so synchronous execution is equivalent. + lambda(); +#endif } #if defined(ENABLE_BGFX)