bkaradzic / bgfx

Cross-platform, graphics API agnostic, "Bring Your Own Engine/Framework" style rendering library.
https://bkaradzic.github.io/bgfx/overview.html
BSD 2-Clause "Simplified" License
15.02k stars 1.95k forks source link

OS X El Capitan window resize #831

Open aagr opened 8 years ago

aagr commented 8 years ago

In Windows when I resize a window in an example, the window's contents remain visible. In Mac OS the window's contents disappear and only reappear when I let go of the left mouse button.

Any hints on what may be going on?

Keyframe commented 8 years ago

I know it might be a bit late... I'm new to bgfx and still sniffing through code before I even start properly.

If you're using those entry files in examples, you can see there's entry_osx.mm. In it, there's an event handler for windowDidResize which carries live resize handling. There are a few more though: https://developer.apple.com/reference/appkit/nswindowdelegate?language=objc but it doesn't matter.

What matters is that rendering is not done during this call, which makes it look modal. I still have very vague idea how bgfx works, but if there's a render call at the end of void windowDidResize(, such as bgfx::renderFrame();, then you will get a live update.

Trouble is, since I'm not failiar yet with bgfx, this isn't enough and will render errors/glitches while updating. I think you would also have to clear the buffer between calls, like with setViewClear or something else (I've tried, but failed).

I only discovered this because I'm using SDL which makes it impossible to avoid this blocking behaviour. It really sucks balls to have a modal thing like that ruin everything. With bgfx at least you have all these wonderful entry functions done for you to start with.

james4k commented 8 years ago

I believe you need to make sure the backbuffer is synced/flipped before the resize event returns. IIRC, bgfx does this on the next frame, but it's been some time since I've looked at this.

On Oct 1, 2016 7:44 PM, "Dominik Susmel" notifications@github.com wrote:

I know it might be a bit late... I'm new to bgfx and still sniffing through code before I even start properly.

If you're using those entry files in examples, you can see there's entry_osx.mm. In it, there's an event handler for windowDidResize which carries live resize handling. There are a few more though: https://developer.apple.com/reference/appkit/ nswindowdelegate?language=objc but it doesn't matter.

What matters is that rendering is not done during this call, which makes it look modal. I still have very vague idea how bgfx works, but if there's a render call at the end of void windowDidResize(, such as bgfx::renderFrame();, then you will get a live update.

Trouble is, since I'm not failiar yet with bgfx, this isn't enough and will render errors/glitches while updating. I think you would also have to clear the buffer between calls, like with setViewClear or something else (I've tried, but failed).

I only discovered this because I'm using SDL which makes it impossible to avoid this blocking behaviour. It really sucks balls to have a modal thing like that ruin everything. With bgfx at least you have all these wonderful entry functions done for you to start with.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/bkaradzic/bgfx/issues/831#issuecomment-250946624, or mute the thread https://github.com/notifications/unsubscribe-auth/AAuwMqI6iuCQS5p8h-SdpV2Lootbny0Oks5qvv5OgaJpZM4JB60J .

Keyframe commented 8 years ago

TBH, I just had a quick look into the entry function since I prefer if I could use SDL. Adding bgfx::RenderFrame(); did work, but with glitches as predicted!

Note, if you use SDL you will have same modal blanking even if you handle SDL_WINDOWEVENT_RESIZED and SDL_WINDOWEVENT_SIZE_CHANGED in your SDL_PollEvent. Trick is to utilize SDL_SetEventFilter and add a function to that in which you handle those two events - and then the usual, grab new dimensions, bgfx reset, clear the buffer (just in case) and render. Why it doesn't work from SDL_PollEvent but works from SDL_SetEventFilter (racing before PollEvent) is beyond me, but it works. Just lost an hour or two on this, in case you or someone wants to use SDL instead.

this could/should be closed.

james4k commented 8 years ago

OK, just checked, and basically you want to make sure to use BGFX_RESET_FLIP_AFTER_RENDER along with calling bgfx::renderFrame in the resize event. Otherwise the framebuffer flip happens on the next frame.

bigfatbrowncat commented 8 years ago

FYI, this issue could be somehow related to the one I reported: https://github.com/bkaradzic/bgfx/issues/577

Keyframe commented 8 years ago

@bigfatbrowncat I put up a gist with SDL2 and BGFX, written in C here: https://gist.github.com/Keyframe/1d605c8feb91b6d8b868d84674696476

Main features are that it's not using BGFX's entry (since it's C) and supports live resizing as well as going fullscreen and back (mapped to F10 in my example). It also remembers what res you had of the window when you go back from fullscreen. There is only one caveat, and that is that as long as you click resize handle on your window it stops updating and updates only when you move. This is a (cross) OS limitation and other applications suffer from it too (I've checked Blender and After Effects). Idea was to make a starting point for an elegant window handling with live resize as well as going to and back from full screen. It's there now, albeit I haven't documented it. Easy to understand though. One thing I put in is when you call for certain fullscreen resolution, SDL negotiates from OS which one is the closest supported if the one you want isn't. So you always get a fullscreen, even the closest match and you get values which you got as well. More elegant way would be to always go to FULLSCREEN_DESKTOP for best user experience, but that's something you choose, it's not a technical issue.

Example is for MacOS only, but all you have to do is fill in those platform data inits (uncomment) and you're good to go.

I still have to check if there is more optimal way (I don't see one). For example, @bkaradzic said common idiom is to put bgfx render/draw inside a message pump. This example's draw is outside of it, since it doesn't render anything (it renders debug prints). If you put draw inside a message pump then you'll get a crash since you have to (I presume) have everything within same thread. It would take some bit of shuffling code around to make it happen, but I still don't see the point of not doing it just like this. It spawns its own thread anyways and you can't control affinity. So, as far as I'm concerned this is the way it 'just works', until it doesn't.

Here's a gif of demoing it: http://susmel.com/temp/Untitled.gif Glitch when fullscreen and back is due to quicktime screencast recording, otherwise not present.

bkaradzic commented 8 years ago

It looks good. I'll port your C example to entry_sdl.