Skip to content

Commit ac2b074

Browse files
committed
emsc: use soft fullscreen mode
1 parent 17c9fcc commit ac2b074

3 files changed

Lines changed: 94 additions & 4 deletions

File tree

build/emscripten/conanfile.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[requires]
22
ruis/[>=0.5.278]@cppfw/main
33
ruis-render-opengles/[>=0.0.0]@cppfw/main
4+
5+
[generators]
6+
AutotoolsDeps

config/emsc.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ this_static_lib_only := true
1212
# Suppress version-check warning due to https://github.com/conan-io/conan-center-index/pull/26247
1313
this_cxxflags += -Wno-version-check
1414

15-
this_cxxflags += -D RUISAPP_RENDER_OPENGLES
15+
# this_cxxflags += -D RUISAPP_RENDER_OPENGLES
1616

1717
this_cxxflags += -fwasm-exceptions
1818
this_cxxflags += -sSUPPORT_LONGJMP=wasm
@@ -23,6 +23,7 @@ this_ldflags += -sMEMORY_GROWTH_GEOMETRIC_STEP=1.0
2323

2424
this_cxxflags += -pthread
2525
this_ldflags += -pthread
26+
this_ldflags += -Wno-pthreads-mem-growth
2627

2728
this_cxxflags += --use-port=sdl2
2829
this_ldflags += --use-port=sdl2

src/ruisapp/glue/sdl/glue.cxx

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2828

2929
#if CFG_OS_NAME == CFG_OS_NAME_EMSCRIPTEN
3030
# include <emscripten.h>
31+
# include <emscripten/html5.h>
3132
#endif
3233

3334
#if CFG_COMPILER == CFG_COMPILER_MSVC
@@ -374,6 +375,37 @@ class window_wrapper : public utki::destructable
374375

375376
SDL_Window* const window;
376377

378+
#if CFG_OS_NAME == CFG_OS_NAME_EMSCRIPTEN
379+
static bool on_emscripten_canvas_size_changed_callback(int event_type, const void* reserved, void* user_data)
380+
{
381+
if (!user_data) {
382+
std::cout << "emscripten_get_canvas_element_size(#canvas): user_data is nullptr" << std::endl;
383+
return false;
384+
}
385+
auto* ww = reinterpret_cast<sdl_window_wrapper*>(user_data);
386+
387+
double width;
388+
double height;
389+
390+
if (auto res = emscripten_get_element_css_size("#canvas", &width, &height);
391+
res != EMSCRIPTEN_RESULT_SUCCESS)
392+
{
393+
std::cout << "emscripten_get_canvas_element_size(#canvas): failed, error = " << res << std::endl;
394+
return false;
395+
}
396+
397+
// std::cout << "emscripten_get_canvas_element_size(#canvas): new canvas size = " << width << " " << height << std::endl;
398+
399+
SDL_SetWindowSize(
400+
ww->window, //
401+
int(width),
402+
int(height)
403+
);
404+
405+
return true;
406+
}
407+
#endif
408+
377409
sdl_window_wrapper(const window_params& wp) :
378410
scale_factor(get_display_scaling_factor()),
379411
window([&]() {
@@ -395,12 +427,46 @@ class window_wrapper : public utki::destructable
395427
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, ver.minor);
396428
}
397429

398-
auto dims = wp.dims.to<ruis::real>();
430+
#if CFG_OS_NAME == CFG_OS_NAME_EMSCRIPTEN
431+
// Change to soft fullscreen mode before creating the window to set correct OpenGL viewport initially.
432+
{
433+
EmscriptenFullscreenStrategy strategy{};
434+
strategy = {
435+
.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH,
436+
.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF,
437+
.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST,
438+
.canvasResizedCallback = &sdl_window_wrapper::on_emscripten_canvas_size_changed_callback,
439+
.canvasResizedCallbackUserData = this
440+
};
441+
emscripten_enter_soft_fullscreen("#canvas", &strategy);
442+
}
399443

400-
#if CFG_OS_NAME != CFG_OS_NAME_EMSCRIPTEN
444+
auto dims = []() {
445+
double width;
446+
double height;
447+
448+
if (auto res = emscripten_get_element_css_size("#canvas", &width, &height);
449+
res != EMSCRIPTEN_RESULT_SUCCESS)
450+
{
451+
throw std::runtime_error(
452+
utki::cat(
453+
"emscripten_get_canvas_element_size(#canvas): failed, error = ", //
454+
res
455+
)
456+
);
457+
}
458+
return ruis::vec2(
459+
ruis::real(width), //
460+
ruis::real(height)
461+
);
462+
}();
463+
#else
464+
auto dims = wp.dims.to<ruis::real>();
401465
dims *= this->scale_factor;
402466
#endif
403467

468+
// std::cout << "dims = " << dims << std::endl;
469+
404470
SDL_Window* window = SDL_CreateWindow(
405471
wp.title.c_str(),
406472
SDL_WINDOWPOS_UNDEFINED,
@@ -412,6 +478,7 @@ class window_wrapper : public utki::destructable
412478
if (!window) {
413479
std::runtime_error(utki::cat("Could not create SDL window, SDL_Error: ", SDL_GetError()));
414480
}
481+
415482
return window;
416483
}())
417484
{}
@@ -591,10 +658,25 @@ application::application(std::string name, const window_params& wp) :
591658
)),
592659
directory(get_application_directories(this->name))
593660
{
661+
auto& ww = get_impl(*this);
662+
663+
// Get actual window size, as it can differ from requested one.
664+
int width;
665+
int height;
666+
SDL_GetWindowSize(ww.window.window, &width, &height);
667+
668+
auto dims = ruis::vec2(ruis::real(width), ruis::real(height));
669+
670+
// std::cout << "actual window size = " << dims << std::endl;
671+
672+
#if CFG_OS_NAME == CFG_OS_NAME_EMSCRIPTEN
673+
dims *= ww.window.scale_factor;
674+
#endif
675+
594676
this->update_window_rect(
595677
ruis::rect(
596678
{0, 0}, //
597-
ruis::vec2(ruis::real(wp.dims.x()), ruis::real(wp.dims.y())) * get_impl(*this).window.scale_factor
679+
dims
598680
)
599681
);
600682
}
@@ -711,6 +793,10 @@ void main_loop_iteration(void* user_data)
711793
// window dimensions and update the viewport later only once
712794
new_win_dims.x() = ruis::real(e.window.data1);
713795
new_win_dims.y() = ruis::real(e.window.data2);
796+
#if CFG_OS_NAME == CFG_OS_NAME_EMSCRIPTEN
797+
new_win_dims *= ww.window.scale_factor;
798+
#endif
799+
// std::cout << "new window dims = " << new_win_dims << std::endl;
714800
break;
715801
case SDL_WINDOWEVENT_ENTER:
716802
handle_mouse_hover(*app, true, 0);

0 commit comments

Comments
 (0)