Skip to content
This repository has been archived by the owner on Feb 17, 2022. It is now read-only.

Full screen problems #8

Open
dreamlayers opened this issue Feb 22, 2015 · 15 comments
Open

Full screen problems #8

dreamlayers opened this issue Feb 22, 2015 · 15 comments

Comments

@dreamlayers
Copy link
Contributor

Full screen mode can be initiated externally from the shell via Module.requestFullScreen(), bypassing SDL, or via SDL functions.

Externally initiated full screen mode is close to working properly:

SDL-initiated full screen mode has more serious issues:

  • SDL_WINDOW_FULLSCREEN_DESKTOP causes resize events to 300x150 followed by the requested size if it differs from 300x150. That's the CSS size that Emscripten_VideoInit() reports as the desktop display mode. Shouldn't it be reporting the true desktop resolution?
  • DOSBox uses SDL_GetDisplayBounds(), which also reports 300x150 from the reported desktop mode via SDL_AddBasicVideoDisplay().
  • Emscripten_SetWindowFullscreen() unsets the full screen flags, which causes the SDL_UpdateFullscreenMode() call at the end of SDL_CreateWindow() to leave full screen mode.
  • The HTML5 library method used by SDL is incompatible with the browser library method used by the shell. Using both causes problems. Using the browser library method first and then using the HTML5 library method destroys the web page, leaving just the canvas. (Edit: Reported at: After using the Fullscreen button, HTML5 library full screen functions fail emscripten-core/emscripten#3283)
  • The Em-DOSBox display sometimes disappears during the first switch to or from full screen mode. This is fixed by later switches and doesn't repeat.
@Daft-Freak
Copy link
Member

This should fix the first two SDL fullscreen issues: https://github.com/emscripten-ports/SDL2/compare/desktop_resolution

@Daft-Freak
Copy link
Member

Fullscreening in CreateWindow doesn't work as it isn't called from an event handler. The unsetting of the flags prevents SDL from thinking it's fullscreen when it isn't.

@dreamlayers
Copy link
Contributor Author

Yes, https://github.com/emscripten-ports/SDL2/compare/desktop_resolution fixes the first two SDL fullscreen issues.

DOSBox assumes that fullscreen status only changes when it explicitly changes that. I don't know if DOSBox is wrong in assuming that or if SDL video drivers aren't supposed to change full screen status by themselves. SDL temporarily falsely assuming it is in full screen before an event truly allows full screen seems better than the application falsely assuming it is in full screen indefinitely.

@Daft-Freak
Copy link
Member

I've updated that branch to only clear the flags if fullscreen isn't possible. I also seem to be hitting the issue you mentioned in #7 in the SDL fullscreen case.

juj added a commit that referenced this issue Mar 15, 2015
@juj
Copy link
Contributor

juj commented Mar 17, 2015

There are multiple issues being reported here, @dreamlayers, if you can help build up failing tests for these (or post separate bugs with STR steps) and separate these to ones that are clear bugs that we should fix, and the ones that need more discussion e.g. due to not accounting a specific use case, that would be helpful for picking up fixes.

Daft-Freak pushed a commit that referenced this issue Oct 20, 2016
Robert Folland

When running this little test program with SDL2 on Wayland it often crashes in SDL_Init.

From a backtrace it is apparent that there is a race condition in creating a xkb_context_ref. Sometimes it is 0x0.

By moving the relevant lines higher up in Wayland_VideoInit (in SDL2-2.0.4/src/video/wayland/SDL_waylandvideo.c:302) this seems to get fixed.

I moved the call to WAYLAND_xkb_context_new() up to before the call to WAYLAND_wl_display_connect().

Here is the test program (just a loop of init and quit), and a backtrace from gdb:

#include <cstdio>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <unistd.h>
#include <iostream>

int main(int argc, char **argv)
{
    int count = atoi(argv[1]);

    for (int i = 0; i < count; i++) {
        std::cout << "Init " << i << std::endl;
        if (SDL_Init(SDL_INIT_VIDEO) < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                         "Couldn't initialize SDL: %s\n",
                         SDL_GetError());
            return 1;
        }
        std::cout << "Quit" << std::endl;
        SDL_Quit();
    }
    return 0;
}


Init 12
Quit
Init 13

Program received signal SIGSEGV, Segmentation fault.
xkb_context_ref (ctx=ctx@entry=0x0) at src/context.c:156
156         ctx->refcnt++;
(gdb) bt
#0  xkb_context_ref (ctx=ctx@entry=0x0) at src/context.c:156
#1  0x00007ffff5e1cd4c in xkb_keymap_new (ctx=0x0, format=XKB_KEYMAP_FORMAT_TEXT_V1, flags=flags@entry=XKB_KEYMAP_COMPILE_NO_FLAGS) at src/keymap-priv.c:65
#2  0x00007ffff5e1c6cc in xkb_keymap_new_from_buffer (ctx=<optimized out>,
    buffer=0x7ffff7fd5000 "xkb_keymap {\nxkb_keycodes \"(unnamed)\" {\n\tminimum = 8;\n\tmaximum = 255;\n\t<ESC>", ' ' <repeats 16 times>, "= 9;\n\t<AE01>", ' ' <re
peats 15 times>, "= 10;\n\t<AE02>", ' ' <repeats 15 times>, "= 11;\n\t<AE03>", ' ' <repeats 15 times>, "= 12;\n\t<AE04>", ' ' <repeats 12 times>..., length=48090,
    format=<optimized out>, flags=<optimized out>) at src/keymap.c:191
#3  0x00007ffff7b8ea4e in keyboard_handle_keymap (data=0x6169b0, keyboard=<optimized out>, format=<optimized out>, fd=5, size=48091)
    at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/video/wayland/SDL_waylandevents.c:269
#4  0x00007ffff64501f0 in ffi_call_unix64 () from /usr/lib/libffi.so.6
#5  0x00007ffff644fc58 in ffi_call () from /usr/lib/libffi.so.6
#6  0x00007ffff665be3e in wl_closure_invoke (closure=closure@entry=0x61f000, flags=flags@entry=1, target=<optimized out>, target@entry=0x616d20,
    opcode=opcode@entry=0, data=<optimized out>) at src/connection.c:949
#7  0x00007ffff6658be0 in dispatch_event (display=<optimized out>, queue=<optimized out>) at src/wayland-client.c:1274
#8  0x00007ffff6659db4 in dispatch_queue (queue=0x617398, display=0x6172d0) at src/wayland-client.c:1420
#9  wl_display_dispatch_queue_pending (display=0x6172d0, queue=0x617398) at src/wayland-client.c:1662
#10 0x00007ffff665a0cf in wl_display_roundtrip_queue (display=0x6172d0, queue=0x617398) at src/wayland-client.c:1085
#11 0x00007ffff7b8faa0 in Wayland_VideoInit (_this=<optimized out>) at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/video/wayland/SDL_waylandvideo.c:302
#12 0x00007ffff7b7aed6 in SDL_VideoInit_REAL (driver_name=<optimized out>, driver_name@entry=0x0) at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/video/SDL_video.c:513
#13 0x00007ffff7ae0ee7 in SDL_InitSubSystem_REAL (flags=16416) at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/SDL.c:173
#14 0x0000000000400b24 in main (argc=2, argv=0x7fffffffebb8) at vplay-init.cpp:13
(gdb)
@AlexanderKotliar
Copy link

The test should use SDL and be iterative (set emscripten_set_main_loop), sdl2_gl_frames_swap.c from Emscripten tests shows this problem: when Fullscreen buttom is pressed there is a black screen. As I can see, Emscripten_HandleFullscreenChange was significantly changed compared to worked version.

@Daft-Freak
Copy link
Member

This a very old issue, most of the points listed are fixed. You're probably having another issue. (Though if you're using the generated fullscreen button, that's expected to be a bit broken.)

@AlexanderKotliar
Copy link

Yes, I mean generated fullscreen button from standart html output.

@Daft-Freak
Copy link
Member

The problem is that the fullscreen button uses the old Browser.requestFullscreen API and SDL uses the newer emscripten_request_fullscreen_strategy API. As mentioned in this issue, using the first API breaks the second. (emscripten-core/emscripten#3283)

Also, now that we use emscripten_set_canvas_element_size instead of emscripten_set_canvas_size, the old Browser.setCanvasSize never gets called which results in Browser.requestFullscreensetting the canvas size to 0.

@kripken
Copy link
Member

kripken commented Sep 16, 2019

I wasn't aware of that inconsistency. Can we make the button use the new API, or is there a problem with that?

@Daft-Freak
Copy link
Member

Hmm, doing that was mentioned in emscripten-core/emscripten#3283. The fact that SDL2 uses the resize callback from emscripten_request_fullscreen_strategy may be a problem.

@kripken
Copy link
Member

kripken commented Sep 17, 2019

Thanks @Daft-Freak, I'll comment there.

@eduardodoria
Copy link

I have described a similar situation emscripten-core/emscripten#8590

@tuket
Copy link

tuket commented Sep 23, 2020

By default SDL2 captures all input so the browser doesn't handle pressing F11 to enter fullscreen mode.
Calling emscripten_request_fullscreen from the SDL the event loop doesn't work because

This function can be called anywhere, but for web security reasons its associated request can only be raised inside the event handler for a user-generated event (for example a key, mouse or touch press/release).

So when digging the SDL2 code I found that when an event gets pushed to the queue, the watcher callbacks get called. That is useful for the following workaround:

SDL_AddEventWatch([](void*, SDL_Event* event) -> int{
    if((event->type == SDL_KEYDOWN || event->type == SDL_KEYUP) && event->key.keysym.sym == SDLK_F11) {
        emscripten_request_fullscreen(0, 0);
        printf("F11 watch\n");
    }
    return 1;
}, 0);

However, I don't understand why it doesn't work if I pass the id of the canvas as the first parameter (documentation). I have to pass null.

// none of these two seem to work
emscripten_request_fullscreen("canvas", 0);
emscripten_request_fullscreen("#canvas", 0);

Even though it works both in Firefox and Chrome, I get an error in the console:

Screenshot from 2020-09-23 21-52-01

@jrynkiew
Copy link

I remember having a similar problem, and I think the reason is that the behaviour of emscripten has changed, specifically how it handles identifying the canvas object. I remember playing around with -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=0 compilation flag. I think that helped, but then I gave up on that method too.

Daft-Freak pushed a commit that referenced this issue May 7, 2021
Make sure the thread is actually paused, and context backep-up, before
SurfaceView is destroyed (eg surfaceDestroyed() actually returns).

Add a timeout when surfaceDestroyed() is called, and check 'backup_done' variable.

It prevents crashes like:

  #00  pc 000000000000c0d0  /system/lib64/libutils.so (android::RefBase::incStrong(void const*) const+8)
  #1  pc 000000000000c7f4  /vendor/lib64/egl/eglSubDriverAndroid.so (EglAndroidWindowSurface::UpdateBufferList(ANativeWindowBuffer*)+284)
  #2  pc 000000000000c390  /vendor/lib64/egl/eglSubDriverAndroid.so (EglAndroidWindowSurface::DequeueBuffer()+240)
  #3  pc 000000000000bb10  /vendor/lib64/egl/eglSubDriverAndroid.so (EglAndroidWindowSurface::GetBuffer(EglSubResource*, EglMemoryDesc*)+64)
  #4  pc 000000000032732c  /vendor/lib64/egl/libGLESv2_adreno.so (EglWindowSurface::UpdateResource(EsxContext*)+116)
  #5  pc 0000000000326dd0  /vendor/lib64/egl/libGLESv2_adreno.so (EglWindowSurface::GetResource(EsxContext*, EsxResource**, EsxResource**, int)+56)
  #6  pc 00000000002ae484  /vendor/lib64/egl/libGLESv2_adreno.so (EsxContext::AcquireBackBuffer(int)+364)
  #7  pc 0000000000249680  /vendor/lib64/egl/libGLESv2_adreno.so (EsxContext::Clear(unsigned int, unsigned int, unsigned int, EsxClearValues*)+1800)
  #8  pc 00000000002cb52c  /vendor/lib64/egl/libGLESv2_adreno.so (EsxGlApiParamValidate::GlClear(EsxDispatch*, unsigned int)+132)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants