emscripten-core / emscripten-core/emscripten

Canvas is the wrong size for the graphics when writing directly to pixels and using a high DPI and using SDL_WINDOW_ALLOW_HIGHDPI

Open
#22,944 9 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

Please include the following in your bug report:

**Version of emscripten/emsdk:**
3.1.71

**Full link command and output with `-v` appended:**

```inhahe@Logoplex3:~$ em++ /mnt/d/visual\ studio\ projects/scribbles3/sdl2bug.cpp -s WASM=1 -s USE_SDL=2 -o sdl2bug.html -sALLOW_MEMORY_GROWTH -v
"/home/inhahe/emsdk/upstream/bin/clang++" -target wasm32-unknown-emscripten -fignore-exceptions -mno-bulk-memory -mno-nontrapping-fptoint -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/home/inhahe/emsdk/upstream/emscripten/cache/sysroot -DEMSCRIPTEN -isystem /home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include/SDL2 -Xclang -iwithsysroot/include/compat -v "/mnt/d/visual studio projects/scribbles3/sdl2bug.cpp" -c -o /tmp/emscripten_temp_cpdzmkie/sdl2bug_0.o
clang version 20.0.0git (https:/github.com/llvm/llvm-project d6344c1cd0d099f8d99ee320f33fc9254dbe8288)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/inhahe/emsdk/upstream/bin
(in-process)
"/home/inhahe/emsdk/upstream/bin/clang-20" -cc1 -triple wasm32-unknown-emscripten -emit-obj -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name sdl2bug.cpp -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -target-feature -bulk-memory -target-feature -nontrapping-fptoint -fvisibility=hidden -debugger-tuning=gdb -fdebug-compilation-dir=/home/inhahe -v -fcoverage-compilation-dir=/home/inhahe -resource-dir /home/inhahe/emsdk/upstream/lib/clang/20 -isystem /home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include/SDL2 -D EMSCRIPTEN -isysroot /home/inhahe/emsdk/upstream/emscripten/cache/sysroot -internal-isystem /home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten/c++/v1 -internal-isystem /home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1 -internal-isystem /home/inhahe/emsdk/upstream/lib/clang/20/include -internal-isystem /home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fignore-exceptions -fexceptions -fcolor-diagnostics -iwithsysroot/include/compat -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -o /tmp/emscripten_temp_cpdzmkie/sdl2bug_0.o -x c++ "/mnt/d/visual studio projects/scribbles3/sdl2bug.cpp"
clang -cc1 version 20.0.0git based upon LLVM 20.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten/c++/v1"
ignoring nonexistent directory "/home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
/home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include/SDL2
/home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include/compat
/home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1
/home/inhahe/emsdk/upstream/lib/clang/20/include
/home/inhahe/emsdk/upstream/emscripten/cache/sysroot/include
End of search list.
/home/inhahe/emsdk/upstream/bin/clang --version
/home/inhahe/emsdk/upstream/bin/wasm-ld -o sdl2bug.wasm /tmp/emscripten_temp_cpdzmkie/sdl2bug_0.o -L/home/inhahe/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten /home/inhahe/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libSDL2.a -lGL-getprocaddr -lal -lhtml5 -lstubs-debug -lnoexit -lc-debug -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-debug-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmp0gqt38m2libemscripten_js_symbols.so --strip-debug --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_init --export=_emscripten_stack_alloc --export=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --export=_emscripten_stack_restore --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --max-memory=2147483648 --initial-heap=16777216 --no-entry --stack-first --table-base=1
/home/inhahe/emsdk/upstream/bin/llvm-objcopy sdl2bug.wasm sdl2bug.wasm --remove-section=.debug* --remove-section=producers
/home/inhahe/emsdk/upstream/bin/wasm-emscripten-finalize --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers sdl2bug.wasm -o sdl2bug.wasm --detect-features
/home/inhahe/emsdk/node/20.18.0_64bit/bin/node /home/inhahe/emsdk/upstream/emscripten/src/compiler.mjs /tmp/tmpapet3dfw.json
/home/inhahe/emsdk/node/20.18.0_64bit/bin/node /home/inhahe/emsdk/upstream/emscripten/tools/preprocessor.mjs /tmp/emscripten_temp_cpdzmkie/settings.js shell.html
```
I've made a minimal example that exhibits this behavior.
Ideally, the whole canvas should turn red.
But on a high-DPI screen, the canvas is about 1.5x the size of the graphics (the red square).
Changing the canvas size is CSS only shrinks the whole thing, with the red square still taking only a portion of the canvas.
The parts of the canvas not used show up in black.
Honestly, I'm not sure how this stuff works well enough to know whether this is an Emscripten bug or an SDL bug. But... I have a version of the same program for the desktop instead of the web, and it doesn't have this problem.
```
#include
#include

int width = 1000;
int height = 1000;

struct Context
{
SDL_Renderer* renderer = nullptr;
SDL_Window* window = nullptr;
SDL_Surface* surface = nullptr;
SDL_PixelFormat* pixel_format_surface = nullptr;
};

void mainloop(void* arg)
{
Context* context = static_cast(arg);
SDL_RenderClear(context->renderer);
uint8_t* pixels = (uint8_t*)(context->surface->pixels);
int pitch = context->surface->pitch;
int color = SDL_MapRGBA(context->pixel_format_surface, 255, 0, 0, 255);
if (SDL_MUSTLOCK(context->surface)) SDL_LockSurface(context->surface);
uint8_t* sp_pixels = nullptr;
for (int y = 0; y < height; y++)
{
sp_pixels = pixels + y * pitch;
for (int x = 0; x < width; x++)
{
*(uint32_t*)sp_pixels = color;
sp_pixels += 4;
}
}
if (SDL_MUSTLOCK(context->surface)) SDL_UnlockSurface(context->surface);
SDL_UpdateWindowSurface(context->window);
}

int main(int argc, char* argv[])
{
Context context;
SDL_Init(SDL_INIT_VIDEO);
context.window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_ALLOW_HIGHDPI);
context.surface = SDL_GetWindowSurface(context.window);
context.pixel_format_surface = context.surface->format;
emscripten_set_main_loop_arg(mainloop, &context, 0, 1);
}
```
Here's a screenshot of how it looks on my display:
![image](https://github.com/user-attachments/assets/c699f27d-52ed-4f0c-b477-945670ab4c76)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.