ENIGMA Forums

General fluff => General ENIGMA => Topic started by: polygone on May 25, 2013, 03:51:50 pm

Title: SwapBuffers Issue
Post by: polygone on May 25, 2013, 03:51:50 pm
Hey can I get some feedback please if anybody else is experiencing this issue?
https://github.com/enigma-dev/enigma-dev/issues/165
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 26, 2013, 06:09:42 am
Yes, I have the flickering. Just like I had it before on a totally different system.
Title: Re: SwapBuffers Issue
Post by: forthevin on May 26, 2013, 06:18:54 am
I get the issue on my Windows system, but not my Linux system.
Title: Re: SwapBuffers Issue
Post by: polygone on May 26, 2013, 06:20:06 am
Interesting. It must be different in GM due to Direct X? But this was working for me before on this system, so something must have changed in ENIGMA or (I think) I may have updated a driver at some point which could have possibly affected it. But the fact that it doesn't seem to be working for anybody on Windows now suggests to me that something in ENIGMA has changed, but I have no idea what that could be?

This is what ENIGMA is using to set-up the drawing in WINDOWSstd.cpp:

Code: [Select]
void EnableDrawing (HGLRC *hRC)
{
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;

    enigma::window_hDC = GetDC (hWnd);
    ZeroMemory (&pfd, sizeof (pfd));
    pfd.nSize = sizeof (pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    iFormat = ChoosePixelFormat (enigma::window_hDC, &pfd);

    if (iFormat==0) { show_error("Total failure. Abort.",1); }

    SetPixelFormat (enigma::window_hDC, iFormat, &pfd);
    *hRC = wglCreateContext( enigma::window_hDC );
    wglMakeCurrent( enigma::window_hDC, *hRC );
}

Then SwapBuffers(enigma::window_hDC); for screen_refresh(). Looking through git though, none of this has changed in 3 years which is before I originally posted the raytracing example.
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 26, 2013, 06:49:17 am
I think something changed for you, not for ENIGMA. Because for me this has always been the case. Maybe others on win systems as well. You were one of the few who hadn't have the problem.
Title: Re: SwapBuffers Issue
Post by: polygone on May 26, 2013, 07:34:48 am
hmm I'm not sure.

Anyway this is the same problem that is cause draw_getpixel() to not work after screen_refresh() which is an incompatibility with GM. Also if you turn off background drawing in the room editor now, so the screen isn't cleared to a colour then this buffer swapping will also be seen.

You can test in this file:
https://www.box.com/s/p8w6bs1c0vf1gdj3ex9g

Press Right/Down to move the block on key press. E/S to move the block on key hold. At 30 fps pressing Right/Down to move the block doesn't cause the flickering to happen (because then it's getting drawn on both buffers, unless you press it super fast - you can get it to happen at lower frame rates) but if you use E/S to move on hold instead you will get the flickering.

So the solution to this problem is: Repeat all the drawing after a screen refresh so it's on both buffers. Or just don't call screen_refresh more than once :P
But I do also want to know why it's different in GM.
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 26, 2013, 12:22:25 pm
Well it is buggy because in double buffering the first image should be show on the screen, while the second is rendering, and then the second is flipped with the first one. So the first one holds the previous image all the time. Here though, they seem totally different. Like one part is drawn on one buffer and the other part is draw on the other. That is not how double buffering should work. So I think the problem could be elsewhere. Unless you can disable double buffering and test then.
Title: Re: SwapBuffers Issue
Post by: polygone on May 26, 2013, 12:41:03 pm
I've just realized there are going to be scenarios where a single screen_refresh() doesn't work properly. As per this file:
https://www.box.com/s/2oheia1qs3u9n14i5p7c

Hold space to test, and you will see that the wrong drawn text is shown (because it's showing the text from the previous buffer). If you uncomment the other screen_refresh then it will display the correct text. The fact that it works at all to draw on the screen is kind of a hack that relies on the likelihood that the previous frame is the same.

EDIT: I've just thought of adding a moving object to it. When you do that you can see more easily that it jumps back when you hold space. So this is going to look nasty for people on Windows that use screen_refresh for a pause screen (which is common) because it's going to skip the frame back when they pause and it will be noticeable.
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 27, 2013, 03:21:33 am
Yes I can confirm the problem in your second test as well. But I still seems very wrong for me. That is not how double buffering works. There should not be two different frames, as you can only see the one that has finished rendering and the other which is still rendering. Here we see two completely rendered frames, but with differences because it just renders on one buffer, then flips and renders on the other. In the end we have two buffers with alternating frames. Maybe I am just than idiot and this is how double buffering works, but then everyone should have this problem.

Poly have you tried disabling double buffering and testing? Maybe enable triple buffering?
Title: Re: SwapBuffers Issue
Post by: Goombert on May 27, 2013, 03:49:54 am
Yah ExDeus is right, the whole point of double buffering is to get rid of flickering, you continue to draw what was last drawn while drawing the new stuff then swap at the end of draw events.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 03:57:33 am
I'm not sure how to swap to triple buffering? Wouldn't you need a fbo? I read this:
http://www.opengl.org/wiki/Swap_Interval

In any case I don't think triple buffering would resolve it. Since it will be swapping the buffers the same.

As for single buffering, yes that's going to work but it looks terrible as the drawing is done automatically.

I'm not sure if the double buffering is set-up correctly or not, and if not how to make it correct. I read something about WGL_DOUBLE_BUFFER_ARB not sure if we should be using that or how to use it?

EDIT: This source here: https://github.com/vanfanel/SDL12-kms-dispmanx/blob/master/src/video/wincommon/SDL_wingl.c seems to be doing shit with it for the pixel format crap.
Title: Re: SwapBuffers Issue
Post by: Goombert on May 27, 2013, 04:12:39 am
Polygonz, hey bud, no lol I do not think I don't, no I'm %99.9999 percent certain you do not need a VBO. Vertex Buffer Objects just take the vertices in a model and pack them together into an object that handles storage and sends them to the GPU for fast rendering, so I do not know what that would have to do with tripple buffering?

Also while we are on fixing the double buffering and swapping, we should also take the oppurtunity to finally add MSAA and SSAA to the loop so it can down sample and then we can have some nice Anti-aliasing.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 04:16:06 am
fbo*
Title: Re: SwapBuffers Issue
Post by: Goombert on May 27, 2013, 04:25:47 am
Oh ok yes that would make sense, hey are you on IRC? I got Ism's network functions working and made a simple client to server example and http request ^_^

Edit:
(http://oi43.tinypic.com/2wd109c.jpg)
I made it do a simple http request and query our websites code ^_^
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 27, 2013, 06:23:10 am
Quote
As for single buffering, yes that's going to work but it looks terrible as the drawing is done automatically.
"That's going work" means you haven't tried it. Because as I said, this is not how double buffering works. So either it's not double buffering problem in the first place, or we just configure double buffering wrong in the GL init.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 06:32:56 am
Quote
As for single buffering, yes that's going to work but it looks terrible as the drawing is done automatically.
"That's going work" means you haven't tried it.
I have tried it, it just draws everything immediately which doesn't look good and isn't GM compatible either. It's not swapping any buffers so it's not going to experience any of the problems we're having with this.

I'm not sure what's wrong but this source might be doing it right: https://github.com/vanfanel/SDL12-kms-dispmanx/blob/master/src/video/wincommon/SDL_wingl.c  ie we should be setting wglChoosePixelFormatARB for WGL .

I've also seen PFD_SWAP_EXCHANGE and PFD_SWAP_COPY that can be used with WGL not sure if copy might be needed?

But I don't really know what I'm doing with any of this so you probably shouldn't expect me to be the one that fixes anything.
Title: Re: SwapBuffers Issue
Post by: Goombert on May 27, 2013, 06:48:50 am
Yep, if we are adding a frame buffer object, we need to set it up for anti-aliasing while we are at it so that it does not need written 2x.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 06:52:29 am
I don't support fbos
Title: Re: SwapBuffers Issue
Post by: Goombert on May 27, 2013, 06:55:49 am
Well then that will go into OpenGL3, and whatever you do support goes into OpenGL1, so Deus I guess just focus on the OpenGL3 implementation, polygonz is the only one who OGL1 is needed for anyway besides Tsumi, and a few others.

I'm gone buy you a new computer polygonz :P
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 07:28:45 am
Ha ha ha ha ha ha ha

ha

ha

ha ha ha ha.

OK Josh is gonna love this one. I got the screen_refresh back working for me!! I knew I wasn't crazy and it worked properly before. And here's how I did it:
I turned Windows Vista Aero back on!

Turning it off (which I did a few months ago) is apparently what fucked it. Even though it probably shouldn't have seemed likely I just had this sudden flash of realization that, that was what caused it to stop working for me. So yeah erm, I guess we should sort of figure out wtf's going on with aero and double buffering.
Title: Re: SwapBuffers Issue
Post by: forthevin on May 27, 2013, 08:03:16 am
I haven't looked into the issue, but I think this page is useful for understanding how GM handles repainting: http://gamemaker.info/en/manual/405_11_repaint.
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 27, 2013, 08:39:12 am
My Win7 Aero is on all the time. So that fix ain't working for me.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 08:43:43 am
Yeah but it gives an indication of where the problem lies. It also shows that ENIGMA might well not actually be set-up incorrectly.

Maybe try turning Aero off? See if that changes anything for you?
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 27, 2013, 09:00:31 am
Nop, didn't help. It is also present in both GL1 and GL3.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 09:05:38 am
Maybe it's related to your 60fps stuff?
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 27, 2013, 09:34:22 am
I had the same problem even when set_synchronization(false) worked. Though I don't remember exactly if I tested that specifically. So if anyone is willing to fix set_synchronization then I could test.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 09:36:50 am
Well try uncomment set_synchronization back in. You will need to add the GL header back in that was removed .. look in the file history of Windowsstd.cpp.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 10:22:15 am
More specifically it's the "enable desktop composition" effect that needs to be turned on in System -> Advanced -> Performance -> Effects. You can only turn it on when aero is set on though.

Information About

The desktop composition visual experience feature, introduced since Vista, fundamentally changed the way applications display pixels on the screen. When desktop composition is enabled, individual windows no longer draw directly to the screen or primary display device as they did in previous versions of Windows. Instead, their drawing is redirected to off-screen surfaces in video memory, which are then rendered into a desktop image and presented on the display.

Desktop composition is performed by the Desktop Window Manager Session Manager (DWM) service. Through desktop composition, DWM enables visual effects on the desktop as well as various Aero features such as thumbnail previews, Aero themes, glass window frames (transparency), 3-D window transition animations, Windows Flip and Windows Flip3D, and high resolution support.

This will show you how to enable or disable Desktop Composition using different options in Windows 7 and Vista.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 10:46:20 am
I'm trying to find information about it through Google and post what I find here.

Quote
DWM's rendering of the screen is double-buffered. However, if it grabs your buffer between erasing and painting... it's going to show up as a visible artefact. So you still need to double buffer. The double buffering occurs on the desktop (i.e. it draws the next desktop view completely and then flips), not on the off-screen buffers that each window is drawn to.

Quote
Windows 7 uses Desktop Window Manager in a different way than Vista, however, and if you disable Aero applications can't take advantage of the double buffering and resulting vertical sync improvements that DWM offers. So you actually are causing worse playback when you think you are turning off what appears to be a resource hog! Many IT pros routinely set up systems with all the pretty user interface options turned off for that very reason.

Quote
What All This Means for the OpenGL Developer
GDI compatibility notes
GDI usage over 3D accelerated regions is incompatible with Windows Aero, so developers have two options:

Disable Windows Aero
Do not use GDI on top of OpenGL rendering.
Windows Vista introduces the new pixelformat flag PFD_SUPPORT_COMPOSITION (defined in the Driver Development Kit's wingdi.h as 0x00008000). Creating an OpenGL context for a pixelformat without this flag will disable composition for the duration of the process which created the context. The flag is mutually exclusive with PFD_SUPPORT_GDI.

If a developer must use GDI on top of an OpenGL context, use the following rules:

Create an OpenGL context using a pixelformat with GDI support (PFD_SUPPORT_GDI flag set). As this flag is mutually exclusive with PFD_SUPPORT_COMPOSITION, this will disable Aero for the lifetime of the current process.
Don't use BeginPaint/EndPaint outside the WM_PAINT message handling.
As on Windows XP, use the API synchronization calls whenever necessary: GdiFlush to synchronize GDI with OpenGL rendering and glFinish for the converse.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 11:22:53 am
A separate bug I've just noticed with this raytracer is the rending is completely messed up in fullscreen mode. It's just coming out at these weird squares.
Title: Re: SwapBuffers Issue
Post by: Goombert on May 27, 2013, 11:46:38 am
Windowing systems need bridged also so the hWnd gets exposed so that it can be attached to a d3ddevice as well.
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 27, 2013, 12:19:34 pm
Nope, set_syncronisation() didn't fix that. You can re-implement that function using GLEW like here: http://3dengine.org/Disable_vsync . So it basically is just this:
Code: [Select]
void set_synchronization(bool enable)
{
    wglSwapIntervalEXT(enable);
}
Note:
1) This function should not be in WindowsSTD, but in OpenGL graphics system for obvious reasons (best one being that it is not platform specific).
2) You will need to include wglew.h, not just glew.h (it should have been included anyway, dunno why it isn't) inside the general/OpenGLHeaders.h.
3) When you do that there will be some problems with inlined min and max functions inside GSColors. I just renamed them to mini and maxi as they are used right there for some clamping, nothing more (and moved them under enigma_user, but I guess that is not necessary).
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 12:22:31 pm
You can still commit to the repo yourself Deus  XD
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 12:23:35 pm
Anyway read through what I put. Specifically, check if "enable desktop composition" is definitely set for you..
Title: Re: SwapBuffers Issue
Post by: Josh @ Dreamland on May 27, 2013, 12:24:16 pm
Here's the issue: wgl is platform-specific. On Windows, it's wgl. On Linux, it's glx. Moreover, wglew is specifically for Windows. We need a Bridges/ folder between platforms and graphics/audio/widget systems.
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 27, 2013, 12:26:10 pm
Yeah my bad. Somehow forgot that glew is for windows. Anyway, it's possible to re-implement for windows then.

And I checked, I have everything, including "enable desktop composition" turned on.
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 12:28:11 pm
Yeah my bad. Somehow forgot that glew is for windows. Anyway, it's possible to re-implement for windows then.

And I checked, I have everything, including "enable desktop composition" turned on.
OK. But possibly it's being disabled by your driver when you run the application?
Title: Re: SwapBuffers Issue
Post by: polygone on May 27, 2013, 12:53:04 pm
Also that fullscreen bug I mentioned before, looks like this:

http://i.imgur.com/h1CIBcV.png
Title: Re: SwapBuffers Issue
Post by: TheExDeus on May 27, 2013, 12:57:11 pm
Quote
OK. But possibly it's being disabled by your driver when you run the application?
It shouldn't be. Especially when ran in windowed mode. I also tried full screen and full screen with display resolution set to the room. In all cases the same result. But as I said, I got this problem with another, totally unrelated PC. Different hardware, clean install etc. So it must be larger than that. Maybe I will try my laptop with AMD later and see if has the same problem.

edit: After a quick profiling I found the problem is setting the room_speed large. The room_speed = 1000 makes the whole thing CPU bound. Even when vsync is on and only 60FPS is possible. But the bound is actually a lot lower than that. At room_speed 59 I get 3% CPU load, at room_speed 60 I get 25%.

edit2: With vsync off I get 0-3% load even with 60FPS. Or 500fps for that matter. But 600FPS again give 25% load. I think the CPU bottlenecks when I make it draw more than I can actually draw. Maybe the opposite, it bottlenecks when I ask for I/O while I can draw a lot faster. Anyway, we should multithread ENIGMA at least partially, so I/O is one thread drawing another.
Title: Re: SwapBuffers Issue
Post by: Goombert on May 27, 2013, 08:08:57 pm
Yes just as Josh said though guys, you should be creating the bridges folder for windowing, because we also need it to hook up a DX device to it.