Re: Full Screen Mode Blank

47 views
Skip to first unread message

David Meyer

unread,
Aug 22, 2016, 12:49:38 AM8/22/16
to Sam Clegg, native-cli...@googlegroups.com
I had an "aha!" moment right after sending this email, and figured out what was going on. This is a bug in the SDL1 webport and/or Pepper.

During full-screen transition, Instance_DidChangeView() is called 7 times in rapid succession (with the same full screen width and height). When the resize happens from javascript, Instance_DidChangeView() is only called once.

SDL_PrivateResize does not send SDL_VIDEORESIZE to the app if the resize event did not change the width or height. So only the first fullscreen resize event triggers SDL_VIDEORESIZE.

The PPAPI 2D context is refreshed when SetVideoMode is called in response to SDL_VIDEORESIZE. Because latter resize events are ignored, SDL continues to use the old (presumably now invalid) 2D context.

This leads to a race condition between the Instance_DidChangeView calls (which happen in the main thread) and the processing of PSE_INSTANCE_DIDCHANGEVIEW (which happens in the ppapi_simple worker thread). If all 7 calls to Instance_DidChangeView happen before the first PSE_INSTANCE_DIDCHANGEVIEW is processed, then the 2D context used by the app will be valid. If any of the Instance_DidChangeView calls happen after the first PSE_INSTANCE_DIDCHANGEVIEW is processed, then the context will be invalid.

I was able to fix this by patching t
he SDL NaCl driver to refresh its 2d context when a resize event occurs that doesn't change width/height.

But this raises two questions:

1) Is it expected that the graphics context becomes invalid after a DidChangeView which doesn't change the size?

2) Why does Chrome/PPAPI send 7 DidChangeView events when switching to full screen mode?

- pdox

On Sat, Aug 20, 2016 at 4:24 PM, David Meyer <pdo...@gmail.com> wrote:
I have a PNaCl app (doom) which works fine, except for full screen mode. Switching to full-screen mode works about 10% of the time, but 90% of the time results in a blank (all white) screen (tested on Mac OS X 10.10.5 with Chrome 52.0.2743.116 64-bit).

Resizing the NaCl object from javascript, i.e., updating the "width" and "height" attributes on the embed element, always works.

From the application's perspective, the code path for resize is identical for both javascript-triggered resize and full screen mode, so I'm thinking the bug is the result of some race condition in either PPAPI or Chrome?

Here's the app:

http://doom.pdox.net/fstest/

(Pepper 49 SDK, using SDL1 from webports @  97c086f983)

Here's how the full screen toggle works:
1) One-line patch to ppapi_simple calls a custom function in HandleInputEvent: http://doom.pdox.net/fstest/ppapi_simple.patch
2) Custom function issues SetFullScreen when it sees "w" or ALT-ENTER: http://doom.pdox.net/fstest/preprocess_event.txt

Here's what happens after the application window is resized:
1) PPAPI calls Instance_DidChangeView (in ppapi_simple)
2) ppapi_simple queues event PSE_INSTANCE_DIDCHANGEVIEW (event contains the new width and height)
3) The nacl driver (in SDL) receives the event and calls NACL_SetScreenResolution
4) NACL_SetScreenResolution stores the new resolution, and calls SDL_PrivateResize
5) SDL_PrivateResize issues SDL event SDL_VIDEORESIZE
6) The application code handles SDL_VIDEORESIZE by calling SDL_SetVideoMode with the new width and height:
    screen = SDL_SetVideoMode(new_width, new_height, /*bpp=*/8, SDL_SWSURFACE|SDL_HWPALETTE|SDL_RESIZABLE);
7) The next frame is drawn to SDL surface "screen" (the 320x200 doom output is scaled and centered to fit the surface)

Thanks!
- pdox


David Meyer

unread,
Aug 22, 2016, 12:49:39 AM8/22/16
to Sam Clegg, native-cli...@googlegroups.com

Ben Smith

unread,
Aug 24, 2016, 3:38:54 AM8/24/16
to Native-Client-Discuss, s...@chromium.org, pd...@alum.mit.edu, Vincent Scheib


On Sunday, August 21, 2016 at 9:49:38 PM UTC-7, David Meyer wrote:
I had an "aha!" moment right after sending this email, and figured out what was going on. This is a bug in the SDL1 webport and/or Pepper.

During full-screen transition, Instance_DidChangeView() is called 7 times in rapid succession (with the same full screen width and height). When the resize happens from javascript, Instance_DidChangeView() is only called once.

SDL_PrivateResize does not send SDL_VIDEORESIZE to the app if the resize event did not change the width or height. So only the first fullscreen resize event triggers SDL_VIDEORESIZE.

The PPAPI 2D context is refreshed when SetVideoMode is called in response to SDL_VIDEORESIZE. Because latter resize events are ignored, SDL continues to use the old (presumably now invalid) 2D context.

This leads to a race condition between the Instance_DidChangeView calls (which happen in the main thread) and the processing of PSE_INSTANCE_DIDCHANGEVIEW (which happens in the ppapi_simple worker thread). If all 7 calls to Instance_DidChangeView happen before the first PSE_INSTANCE_DIDCHANGEVIEW is processed, then the 2D context used by the app will be valid. If any of the Instance_DidChangeView calls happen after the first PSE_INSTANCE_DIDCHANGEVIEW is processed, then the context will be invalid.

I was able to fix this by patching t
he SDL NaCl driver to refresh its 2d context when a resize event occurs that doesn't change width/height.

But this raises two questions:

1) Is it expected that the graphics context becomes invalid after a DidChangeView which doesn't change the size?


I wouldn't be surprised, DidChangeView is called for a number of reasons (scrolling the viewport, for example) even if the size doesn't change.
 
2) Why does Chrome/PPAPI send 7 DidChangeView events when switching to full screen mode?

That's a good question. Vincent, can you recall?
Reply all
Reply to author
Forward
0 new messages