Anti-aliasing broken - or rather, mechanism for picking the best visual is #35

Closed
svenstaro opened this Issue May 1, 2011 · 47 comments

Projects

None yet
@svenstaro

As per this thread the GlxContext::CreateContext function, while apparently able to pick the best visual for other given properties such as resolution and bit-depth, doesn't seem to honor the multisampling setting even on system that have those visuals available.

In fact, from hacking the code a little it seems to effectively always pick the first one (of glxinfo). Perhaps this function should be improved so that systems whose first visual doesn't support multisampling can also benefit from multisampling.

@LaurentGomila
Simple and Fast Multimedia Library member

Unfortunately, my virtualized Linux doesn't seem to support antialiased visuals, so I can't test this myself.

Could you, for each visual that is processed in GlxContext::CreateContext, add some debug code that prints all their attributes as well as the score they get (and the ID of the chosen one)?

@LaurentGomila LaurentGomila was assigned May 1, 2011
@timesqueezer

I did a bit of testing. My changes to GlxContext.cpp.
The output of the following gist is this.
Output of glxinfo.

I hope that this could help you a bit.

@LaurentGomila
Simple and Fast Multimedia Library member

Thanks, this is exactly what I needed.

Only one visual is found... there's definitely something wrong.

@LaurentGomila
Simple and Fast Multimedia Library member

I think I know what happens. The attributes I pass to XGetVisualInfo contain the visual ID, therefore there can only be one match. Should be easy to fix.

Thanks guys for your help.

@gavintlgold

Any work on this? If I knew how to use XGetVisualInfo properly I'd try to help.

@svenstaro

Learn it or wait until Laurent gets to work on this.

@gavintlgold

I was attempting to rewrite it to use glXChooseVisual instead of the current system. It ended up working okay, but didn't solve the problem. glXChooseVisual still seemed to choose the visual without antialiasing.

@LaurentGomila
Simple and Fast Multimedia Library member

Don't try to fix this, it won't work.

Actually it's more complicated than I thought. To solve the problem, the context would have to be created before the window, which is of course not how SFML works.

@svenstaro

Could this be solved by creating a dummy context just to grab the info? It may not be proper but it may just work for now.

@LaurentGomila
Simple and Fast Multimedia Library member

There is always a context (dummy or not) active when a window is created, it doesn't help because there's no info to grab.

The problem is that we must do this:

  • choose a visual according to context settings
  • create a window using this visual
  • create a context using this visual

... and SFML works like this:

  • create a window
  • create a context using the context settings

So, the problem is that X11 and GLX are too tied together, while SFML clearly separates these two concepts.

@MoreAxes

Has there been any progress on this issue so far?

@LaurentGomila
Simple and Fast Multimedia Library member

No. It's marked for SFML 2.x, so I won't work on it for SFML 2.0.

@polymeris

I have been looking at the code a bit. What's the purpose of the hidden window created @ /src/SFML/Window/Linux/GlxContext.cpp:95?
If we called createContext(...) before that, and used the determined bestVisual to create that window would that help? Or does the window @ /src/SFML/Window/Linux/WindowImplX11.cpp:157 have to be created with the proper visual to begin with?

EDIT: I see issues #200 and #319 might make the above question irrelevant.

@LaurentGomila
Simple and Fast Multimedia Library member

What's the purpose of the hidden window created @ /src/SFML/Window/Linux/GlxContext.cpp:95?

I haven't found any other way to create a context not bound to a real window.

If we called createContext(...) before that, and used the determined bestVisual to create that window would that help?

No, this constructor is used only for sf::RenderTexture. The constructor that constructs a window's context receives a pointer to the window -- which implies that the window is already created.

Or does the window @ /src/SFML/Window/Linux/WindowImplX11.cpp:157 have to be created with the proper visual to begin with?

Yes. That's the problem.

@polymeris

Thank you very much @LaurentGomila. This is a crucial bugfix for us Linux users. I will try it ASAP.

@LaurentGomila
Simple and Fast Multimedia Library member

Great, since I run Linux in a virtual machine with very poor OpenGL support (no anti-aliasing), more feedback will be useful.

@polymeris

This works perfectly 👍 (C#):

window = new RenderWindow(new VideoMode(800, 600), "GLTEST", Styles.Default, settings);

This doesn't:

window = new RenderWindow(someExistingHandleFromAWidget, settings);

someExistingHandleFromAWidget being a drawable handle to a Gtk.DrawingArea. Not sure if that's GTK's fault (the widget's context is created without support for AA) or SFML's.

Best way would be to let SFML create the window and Gtk use that, somehow.

@LaurentGomila
Simple and Fast Multimedia Library member

Since the context and window must be created with the same GLX visual, there's no way to make it work with an external window on which you have no control.

Thanks for the test.

@polymeris

Yeah, that's what I thought. But couldn't you create a child window with the desired visual?

@LaurentGomila
Simple and Fast Multimedia Library member

Hmm I haven't tried that, it could work.

@polymeris

It works :) Kinda... I get 4x multisampling even if I request 8x. O.o But that's better than nothing.
Also, I can't get it to resize. Not sure if I have to resize the parent window everytime or what else the bug could be.

@polymeris polymeris added a commit that referenced this issue Jul 5, 2013
@polymeris polymeris Create an X child window in the WindowImplX11 constructor if the exis…
…ting window the passed handle refers to does not meet the required ContextSettings. cf. issue #35

Resizing does not work. Note the introduction of m_parent (unnecessary?) and the WindowImplX11::setSize code
aa01aa1
@polymeris

That commit is just for reference. I am sure you can implement it in a cleaner way. Also, as said, it still has bugs.

@LaurentGomila
Simple and Fast Multimedia Library member

Thanks :)

@LaurentGomila
Simple and Fast Multimedia Library member

I've changed the constructor the same way as you did, but it doesn't work for me, the child windows don't appear at all.

Here is my code: https://gist.github.com/LaurentGomila/5934572
I can't see any major difference with your code.

I'm testing with the X11 SFML example, and all I get is a black window.

And what bugs did you have, by the way? If you were referring to the setSize issue, don't worry about that, this kind of functions are for top-level windows, I won't even bother trying to make them work for child windows :)

@polymeris

The new windows is probably 1x1. Try replacing parentAttributes.width, parentAttributes.height with 480, 320 or something.
That is the bug I was referring to and trying to solve in setSize.
EDIT: Nevermind. parentAttributes.width, parentAttributes.height in the X11 example. But I also get a black window. Not sure what the problem is, there.

I get:
Failed to activate the window's context
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0.0"
after 11 requests (6 known processed) with 0 events remaining.

That might be a hint?

@LaurentGomila
Simple and Fast Multimedia Library member

No, the size is good. Could you try the X11 example with your implementation, and then with mine, and tell me which one works?

Your problem is probably that you don't call XFlush(display) before constructing the SFML window, so your parent window has no size yet. I do it in the X11 example so there's no problem.

@LaurentGomila
Simple and Fast Multimedia Library member

One more thing: in your code the container window is a GTK window, right? Could you test SFML event handling, and tell me which events work and which don't (with the old implementation, and then with your implementation -- forcing the child window to be created)?

Event handling was the most annoying issue with child windows, that would be so cool if this modification could fix that too.

Thanks.

@polymeris

No, the size is good. Could you try the X11 example with your implementation, and then with mine, and tell me which one works?

Neither works (since they are really the same). But in master the X11 example doesn't work either, for me. A problem with switching contexts, I think:
Failed to activate the window's context
My GTK code works.

@polymeris polymeris added a commit that referenced this issue Jul 5, 2013
@polymeris polymeris Cleanup WindowImplX11 (#35) 2f45b89
@polymeris

One more thing: in your code the container window is a GTK window, right? Could you test SFML event handling, and tell me which events work and which don't (with the old implementation, and then with your implementation -- forcing the child window to be created)?

Event handling was the most annoying issue with child windows, that would be so cool if this modification could fix that too.

In both cases, the HEAD of my x11_experiments branch, and of my master (which points to af81ac6, a commit before your changes), it's the same: only mouse move, mouse enter and mouse left work. Bear in mind that I have been using GTK's events instead of SFML's, so I haven't studied the later and might be doing something wrong.

I do this: window.MouseWheelMoved += delegate { Console.WriteLine("mouse wheel"); }; then this in the main loop: window.DispatchEvents();.

Events I tested:
Closed,
Resized,
LostFocus,
GainedFocus,
TextEntered, // I made a handler for this one but don't know what it does
KeyPressed,
KeyReleased,
MouseWheelMoved,
MouseButtonPressed,
MouseButtonReleased,
MouseMoved, // works
MouseEntered, // works
MouseLeft // works

@LaurentGomila
Simple and Fast Multimedia Library member

But in master the X11 example doesn't work either, for me.

Damn. It works perfectly for me, it will be hard to debug.

it's the same: only mouse move, mouse enter and mouse left work.

Button pressed/released doesn't work, even without the call to XSelectInput in the constructor? Too bad...

After thinking more about it, I don't think it is a good modification. Creating a child window instead of using the container directly can have bad side-effects: no effect if you set the focus to the container, unexpected results if you create other children in the container, etc.

I'll revert my local modifications and leave it like this for now.

@LaurentGomila
Simple and Fast Multimedia Library member

// I made a handler for this one but don't know what it does

When you enter text, it gives you the typed characters.

For example, "E" + "^" will give two KeyPressed events but only one TextEntered with the character "ê" on a french keyboard.

@germinolegrand

Correct behaviour for ^ handling should be you type "^" and then "E" to get an "Ê". If you do the contrary you sould see an "E" and a ^ ready for the next modifier, and if you type "^" then "^" you get "^^". (general behaviour i think). The ¨ works the same way.

@LaurentGomila
Simple and Fast Multimedia Library member

Yes, I meant "^" + "E". Sorry.

@polymeris

But in master the X11 example doesn't work either, for me.

Damn. It works perfectly for me, it will be hard to debug.

Disregard that. It doesn't even work in "old" SFML. Nothing to do with this issue.

After thinking more about it, I don't think it is a good modification. Creating a child window instead of using the container directly can have bad side-effects: no effect if you set the focus to the container, unexpected results if you create other children in the container, etc.

That's a pity. If you don't mind, I'll sleep over it and maybe later give it another try. I don't know enough about X to say if it makes sense or not. Or maybe I'll just see if the child window can be created in my game, because I haven't found any other way to get AA in the GTK widget.

@LaurentGomila
Simple and Fast Multimedia Library member

Disregard that. It doesn't even work in "old" SFML. Nothing to do with this issue.

Ok but it should work (and it has always worked for me), so this is still an issue.

@polymeris

Disregard that. It doesn't even work in "old" SFML. Nothing to do with this issue.

Ok but it should work (and it has always worked for me), so this is still an issue.

Meh. It works now. I was linking it against the debug build of sfml, and not updating that. Sorry. This makes me question my whole test procedure, above.

@polymeris

Good news :) I found a way to "embed" the SFML window into GTK: http://www.gtk.org/api/2.6/gtk/GtkSocket.html
A bit of a hack, but hey! it works. With AA!
Edit: Have added source to the wiki, for future reference.

@konstin

I'm still facing this problem both with SFML 2.2 under Ubuntu 14.04 with proprietary nvidia drivers. This is code I use:

    sf::ContextSettings settings;
    settings.antialiasingLevel = 8;
    sf::RenderWindow window(sf::VideoMode(width, height), "title", sf::Style::Default, settings);
    std::cout << window.getSettings().antialiasingLevel << std::endl;

The last line only prints 0.

In the package sources of Ubuntu 14.04 there is only version 2.1, so I compiled SFML from source, but the there was still no antialiasing. My graphics card definitely supports antialiasing. Here is my glxinfo.

@Bromeon
Simple and Fast Multimedia Library member

@konstin Have you used the latest GitHub version (not SFML 2.2)? There have been some recent changes to context handling. Do you see the error message in the console?

@konstin

With latest git I see these messages:

Warning: The created OpenGL context does not fully meet the settings that were requested
Requested: version = 2.1 ; depth bits = 0 ; stencil bits = 0 ; AA level = 8 ; core = false ; debug = false
Created: version = 4.5 ; depth bits = 0 ; stencil bits = 0 ; AA level = 0 ; core = false ; debug = false

And btw my program doesn't work anymore because there seems to be an issue with the mouse coordinates. EDIT: The Problem is that I no more get local but only global mouse coordinates.

@binary1248
Simple and Fast Multimedia Library member

What is the output of glxinfo?

@binary1248
Simple and Fast Multimedia Library member
@konstin

With #862 the programm crashes on startup with the following message, both with and without antialiasing enabled:

X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  78 (X_CreateColormap)
  Serial number of failed request:  20
  Current serial number in output stream:  23

I can't get a stacktrace because the programm exits immediatly after printing the message.

@minirop

@konstin add a breakpoint on exit and/or abort (not sure which one). that should do the trick.

@konstin

Thanks, setting breakpoints on two syscalls (exit and exit_group) gave me a stacktrace:

(gdb) bt
#0  0x00007ffff6c291c9 in __GI__exit (status=status@entry=1) at ../sysdeps/unix/sysv/linux/_exit.c:32
#1  0x00007ffff6ba266b in __run_exit_handlers (status=1, listp=<optimized out>, run_list_atexit=run_list_atexit@entry=true) at exit.c:97
#2  0x00007ffff6ba26f5 in __GI_exit (status=<optimized out>) at exit.c:104
#3  0x00007ffff60186b8 in _XDefaultError () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#4  0x00007ffff60187ed in _XError () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#5  0x00007ffff60157e7 in ?? () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#6  0x00007ffff6015895 in ?? () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#7  0x00007ffff60161d5 in _XEventsQueued () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#8  0x00007ffff6018f25 in _XGetRequest () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#9  0x00007ffff5ffdd42 in _XGetWindowAttributes () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#10 0x00007ffff5ffdf31 in XGetWindowAttributes () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#11 0x00007ffff7981c09 in sf::priv::GlxContext::createContext(sf::priv::GlxContext*, unsigned int, sf::ContextSettings const&) () from /usr/local/lib/libsfml-window.so.2.2
#12 0x00007ffff79825c5 in sf::priv::GlxContext::GlxContext(sf::priv::GlxContext*) () from /usr/local/lib/libsfml-window.so.2.2
#13 0x00007ffff796eed1 in sf::priv::GlContext::globalInit() () from /usr/local/lib/libsfml-window.so.2.2
#14 0x00007ffff796fa47 in sf::GlResource::GlResource() () from /usr/local/lib/libsfml-window.so.2.2
#15 0x00007ffff79718ae in sf::Window::Window() () from /usr/local/lib/libsfml-window.so.2.2
#16 0x00007ffff7bc1e39 in sf::RenderWindow::RenderWindow(sf::VideoMode, sf::String const&, unsigned int, sf::ContextSettings const&) () from /usr/local/lib/libsfml-graphics.so.2.2
#17 0x00000000004030da in main () at Aufgabe2.cpp:90
@binary1248
Simple and Fast Multimedia Library member

@konstin can you try again now? I updated the branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment