Closed kavika13 closed 6 years ago
I also have the same problem if I use the latest dev build.
I built from source, and I tracked down where this starts happening to this commit: 2752bbcfb048054e27cef0005f39b6df8d68deda
When running it in the OpenGL profiler, I see that the viewport somehow keeps swapping to a 0x0 size when rendering the front buffer. It doesn't do this in older versions.
I am using OSX 10.11.5 (El Capitan).
In the comments, I noticed some references to window.setActive
. If I call this after creating my render texture, it starts rendering correctly. None of the docs that I've seen say this should be required.
Strange... I can't reproduce this issue on Windows or Linux. Commit 2752bbcfb048054e27cef0005f39b6df8d68deda didn't touch any platform-specific context behaviour, so it puzzles me why it breaks just on OS X.
Can you try throwing in sf::Content::getActiveContext()
calls after every line in your example and see what they return?
0x0
before the render window is created.0x7fa8c8f030a0
after the render window is created.0x7fa8c8d0d310
after the render texture is created.window.setActive()
call before window.isOpen
, then the value stays the same after creating the render texture, and doesn't change after calling setActive
.It also stays the same as it was after creating the render texture if I stick calls inside the loop, between draw calls, etc.
Just out of curiosity, does this problem exist when you use the feature/no_internal_context branch?
I am still getting the problem with the commit from that branch.
Contexts are now showing:
0x0
until the render texture is created, even if the render window has been created0x7fce7bc283c0
after the render texture is createdwindow.setActive()
I have created some traces on my machine of just the OpenGL calls. The traces are against the last working commit and against the commit from feature/no_internal_context. In each trace, I have trimmed everything after the first fully setup draw loop (where the calls start to become identical each iteration).
I can throw up gists if you're interested. I could also make another trace on my machine of the first problematic commit.
This might be a regression of the operating system: it works fine on Yosemite 10.10.5.
Just had my hands on a 10.11.5 and 10.11.6 and I can confirm the bug. :-/
So... what exactly does this mean? Or in other words, what do we do? :confused:
I also notice that every time a render texture is created, the context seems to get messed up:
window.setActive()
Expected: Rendering happens normally
Actual: Black screen
If I add a step 5 (another call to window.setActive()
) or remove step 4, then the window renders normally. I can repro the bug no matter which of the two render textures I actually use to do my rendering.
So... what exactly does this mean? Or in other words, what do we do?
I don't know, this goes beyond my understanding of OpenGL, sadly.
@kavika13 is there a reason why all the CGLSetCurrentContext
calls are missing? Those are the ones that are interesting and relevant...
I can't really tell you why the trace looks like it does. I copied and pasted it after compiling the sample against various versions of the SFML library. If OpenGL calls are missing, it is either because my trace tool isn't very good (OSX OpenGL debugger), or because SFML isn't emitting those calls.
I am in the middle of learning OpenGL for a different project, so I might be able to actually help you out in a few weeks here ;)
Bump. @kavika13 any news?
Just that I know a bit more OpenGL now ;) Nothing about context switching, but maybe I'll learn through this. I will take a look again.
I am still scratching my head over it. I have tried putting in a bunch of debug print statements in various places in the code, and no smoking guns are emerging. Nearly all of them are coming up with very similar results. I only saw differences when I started looking at the OSX specific context layer, when tracing calls to which context pointer had "makecurrent" called on it. I can get you those traces if it would somehow be helpful.
Maybe, as you mentioned, the fact that we're not seeing calls to CGLSetCurrentContext
at all is somehow telling? Putting up the OpenGL Profiler traces for an older version of OSX that doesn't repro the bug might be useful, so we could compare them to the traces I've produced - @mantognini ?
There were some (minor?) API changes, defining the nullability of a bunch of the OpenGL parameters and return types:
I don't know if that is making a difference in being able to actually call the APIs or not, especially if SFML isn't using the lower level APIs (I can't really tell - it seems to be using the Cocoa API which I think wraps those calls...?).
There's also a few versions of release notes for OSX that mention NSOpenGLContext changes here: https://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKitOlderNotes/
I turned on context tracing in OpenGL profiler (found the button).
I noticed that if I don't call window.setActive();
before the loop that there is a context switch between these two lines:
45 0x7fd415847e00 56.94 µs glCheckFramebufferStatus(GL_FRAMEBUFFER); returns: GL_FRAMEBUFFER_COMPLETE
46 0x7fd413064800 1.04 µs glBindTexture(GL_TEXTURE_2D, 0);
If I call window.setActive();
before the loop, then there is not a context switch at that point:
45 0x7f8f7c06c400 61.28 µs glCheckFramebufferStatus(GL_FRAMEBUFFER); returns: GL_FRAMEBUFFER_COMPLETE
46 0x7f8f7c06c400 0.71 µs glBindTexture(GL_TEXTURE_2D, 0);
When I add the call window.setActive();
, then the next context switch happens right after the call to glFlush();
. If I don't call it, then the contexts are not switched after the first call to glFlush();
(but they are switched just after subsequent calls, like normal).
I don't know if this helps to pinpoint anything, or if it is just another symptom.
I also found that if I remove the call to window.setActive
, but move the call to window.display();
to be at the top of my loop, things display correctly. In that case, the contexts switch rapidly once, then go back to normal:
0x7fd4a206ba00 153.82 µs glCheckFramebufferStatus(GL_FRAMEBUFFER); returns: GL_FRAMEBUFFER_COMPLETE
0x7fd4a2067a00 2932.84 µs CGLFlushDrawable();
0x7fd4a206ba00 0.70 µs glBindTexture(GL_TEXTURE_2D, 0);
// ... rest of calls are on 0x7fd4a206ba00 until the next glFlush(); call ...
@kavika13 Can you give this a try again with SFML 2.4.1 - maybe there's been a fix on Apple's side?
Although NVIDIA and Intel graphic drivers were updated as part of security updates, 10.11.6 is still triggering the issue. :-/
I still see the bug when linking against 2.4.1, and don't see the bug against 2.3.1.
I am now on OSX 10.12.2
@kavika13 Can you provide the same full traces before and after that commit as you did before, except this time with context tracing enabled? It would help greatly in understanding the problem.
@kavika13 and @mantognini Try this patch:
diff --git a/src/SFML/Graphics/RenderTarget.cpp b/src/SFML/Graphics/RenderTarget.cpp
index 4faa7ddb..48ec7e76 100644
--- a/src/SFML/Graphics/RenderTarget.cpp
+++ b/src/SFML/Graphics/RenderTarget.cpp
@@ -373,6 +373,12 @@ void RenderTarget::resetGLStates()
// Check here to make sure a context change does not happen after activate(true)
bool shaderAvailable = Shader::isAvailable();
+ // Workaround for states not being properly reset on
+ // macOS unless a context switch really takes place
+ #if defined(SFML_SYSTEM_MACOS)
+ setActive(false);
+ #endif
+
if (setActive(true))
{
// Make sure that extensions are initialized
@binary1248 This seems to do the trick, thanks.
I invite others to test this as well by checking out the bugfix/osx_render_target
branch.
Have same issue. Tried to test new branch, but had some troubles. More info here: https://en.sfml-dev.org/forums/index.php?topic=22786.0
Update --- As a conclusion of my investigations: this patch didn't fixed my issue. everything renders normally if there's something drawn on RenderWindow except the sprite with RenderTexture (as in my example code).
Not sure if it's related, but on SFML 2.4.2, RenderTexture
s work for me (via SFML.NET) but I have this really strange issue where a specific one isn't clearing, unless I call CopyToImage()
on its texture.
I get a black screen when using a render texture with SFML 2.4.0 (edit: or 2.4.1). If I switch to using the window object directly and bypass the render texture, it works correctly. If I use SFML 2.3.2 with the render texture, it also works correctly.
I am using a late-2013 Macbook Pro with the Intel Iris Pro.
Here's a small-ish program that reproduces the issue on 2.4.0: