New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
macOS event dispatching broken #852
Comments
Useful references…
|
I actually had a stab at ChipmunkV's idea (installing a custom dispatcher): master...Birch-san:set-event-dispatcher I have no idea what I'm doing. At the time of writing: my custom event dispatcher compiles, and openage runs, but we still have a white screen followed by a black screen. A good reference for how to build a custom event dispatcher is here (MIT License, peper0@GitHub): https://github.com/peper0/qtasio/blob/master/qasioeventdispatcher.cpp Note: peper0's code includes private headers such as: #include "private/qabstracteventdispatcher_p.h"
#include "private/qtimerinfo_unix_p.h" We're not supposed to do that. It has the following message:
I think we can live without those private headers anyway. |
I also considered "maybe a custom event dispatcher is overkill. could we just filter out events instead?" master...Birch-san:event-flags I believe no matter what combination of events that I filtered out: I still ended up with a black screen, and the animated graph never appeared. These are the notes that I took at the time:
Maybe I should've also tried filters on |
There's also this: I wonder if the event dispatch problem is just with some platform-specific events. So maybe we could see some change if we filtered them out. |
Btw, the magic commit is no panacea. This is a video of what openage looks like with the magic commit: https://www.youtube.com/watch?v=9GmwKreWg6I Ignore the blue tint — that's an endianness problem that is now fixed.
|
Btw, I've started the event dispatcher too. And probably I've started from that piece of code where it's created (to make sure that it's created before the QApplication). The The possible places to attach a dispatcher are: About the events: the OS-level event loop is handled by SDL, input events for Qt are synthesized by the openage from the SDL events. There shouldn't be any way for the events from OS to get into Qt. edit: actually, haven't done much at all - https://github.com/ChipmunkV/openage/commits/event-dispatcher |
I continued to investigate this. I've put useful stuff into this branch, you can comment out bits that you don't want to use: master...Birch-san:event-dispatch-2 The main things that you may find yourself commenting out are:
I've demonstrated here:
Things that I noticed…
In case you're interested, this is what I observe when I use the no-op event dispatcher:
So, that's various things that didn't work. I do caution that writing a custom event dispatcher could be very hard. Here's I see that Qt5 has the following event dispatcher implementations:
Maybe we could use the UNIX one or the glib one somehow. But I assume the macOS one exists for a reason. Some of this stuff is private, so it may be non-trivial to copy-paste. Maybe we can construct an instance and delegate to it? You can have a look at that source like so: git clone git://code.qt.io/qt/qt5.git
cd qt5
git checkout v5.8.0
cd qtbase
git submodule update --init --recursive . But seriously I've no idea what I'm doing. |
https://doc.qt.io/qt-5/qeventloop.html#exec
Do we definitely need to use |
That's where I'm at: VelorumS@13ad763 The most relevant part is
|
There's not really much in my code. All it does is:
But it seems you're significantly past no-op. I'll checkout your commit and see whether it does anything interesting on macOS so far. |
I encountered this at compile-time:
Changed it to TimerInfoList, encountered this SIGSEGV when launching the app. Maybe that's expected behaviour, but reporting it just in case macOS run information is useful at this stage. |
regarding Is it from Qt4.8's |
That branch is not runnable, but I think that it should crash in some different way. The dispatcher is not from the Then it requested to add timers, so I've taken a I've launched your version, and it seems to do fine on Linux. The With this version the P. S. I think that all the code for this change has to be platform-independent. |
When I make the changes that you recommended (Birch-san/openage@event-dispatch-2...Birch-san:event-dispatch-3):
I find that the game actually works exactly like it does with the magic commit. It even works if I remove these guards
So… perhaps the no-op event dispatcher is significantly better than I realised.
EDIT 2: actually, looks like installing the no-op event dispatcher does more than just nothing. If I turn it off, then the only thing we see is a black screen with the performance graph, fps and build details. that's even less than we saw with the magic commit. which means "installing a custom event dispatcher + commenting out calls to processEvents()" renders less than "using default event dispatcher + commenting out calls to processEvents()". it's weird that they're not equivalent. (since I'm not calling processEvents(), I'm surprised it makes a difference which event dispatcher I'm using). I guess there's still the remaining problem of "UI elements keep disappearing" (just like in the magic commit). |
Ok, then it's If the UI elements still keep disappearing then there is probably a rendering bug with the FBO: it's given to the Engine too early. Whole scenegraph nodes are missing. There is a debug mode to see separate elements: Maybe But we still can't rule out the processEvent-related cause because the UI elements aren't flickering every frame. They suddenly disappear after the event processing. |
Wow, glFinish() did the trick! The UI elements no longer disappear. |
This is where I put glFinish(): Birch-san/openage@event-dispatch-3...Birch-san:event-dispatch-4 |
Currently both GL contexts are in one thread. Linux drivers are okay if there is no GL synchronization used in this case. But macOS drivers are probably using some intermediate per-context GL command queues, so they need sync in this case too. Edit: or maybe any FBO needs a sync? |
Is that what the glFinish() does? Or is there some other problem remaining? |
Yes, it does that. Just need to read Internet on how people use FBOs with |
Does the "poor man's event dispatcher" do everything we need it to do? it doesn't implement timers, it doesn't implement socket notifiers. the only thing it really does is call also it looks like it uses glib: //QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); //unix dispatcher use this
QCoreApplication::sendPostedEvents(); //glib dispatcher call this after every call of "awake". Not sure whether Is it okay for this to use glib? is that fine for Windows? doesn't seem like we had to add any dependencies to make this work. |
Maybe a less hacky solution (i.e. one that actually implements a full event dispatcher) would be to find a way to explicitly ask for the glib-based event dispatcher described in |
There is no API for asking for the platform-specific dispatchers. I think that it's more robust to write a cross-platform implementation of the dispatcher and use it on all platforms. The goal of the event dispatchers is to get input events from the platform, but we're passing SDL input events through the One last thing that bothers me: when we were doing this things without custom event dispatcher: #ifndef __APPLE__
this->app.processEvents();
#endif
...
#ifdef __APPLE__
if (QThread::currentThread() != QCoreApplication::instance()->thread())
this->callback_processor.processEvents();
#else
... so there are no calls to |
I checked which DTrace probes were exposed for the sudo dtrace -p "$(pgrep run)" -ln 'pid$target:QtCore:*sendPostedEvents*:entry {}'
I captured each distinct stack (4 frames deep), and how many times that stack occurred: sudo dtrace -p "$(pgrep run)" -n 'pid$target:QtCore:*sendPostedEvents*:entry { @[ustack(20)] = count(); }' When we use the poor-man's event dispatcher, and allow all our calls to When we use the magic commit (i.e. where we do not install a custom event dispatcher, but do delete our call to And just for fun, here's what it looks like if we do both (i.e. where we install a custom event dispather and delete our calls to processEvents()): stack traces. EDIT: updated Gists to give you 20 stack frames instead of 4 EDIT 2: In each of these cases: I only launched the app for a second or so. I did not necessarily wait for textures to load, nor for game to begin. but in each case I did confirm that the graph was rendering stats on-screen. |
From looking at the results of the magic commit, we see that a call through the SDL2 (presumably With event dispatcher and allowing calls to So we can fix all by adding Need to just implement the timers in the dispatcher. Can test it by pasting http://doc.qt.io/qt-5/qml-qtqml-timer.html example somewhere in the openage qml code: Item {
Timer {
interval: 500
running: true
repeat: true
onTriggered: time.text = Date().toString()
}
Text { id: time }
} |
I think we may not need to implement our own timer. I was able to integrate the default Birch-san/openage@event-dispatch-4...Birch-san:event-dispatch-6 I tried putting that timer UI in a few places. First I tried sane places, but it wasn't visible (maybe default font color is black? tried changing that, but didn't help). Next I put it in progressively more horrifying places until it finally showed up: The timer updates live, so I assume that confirms that the timer events work. Sometimes (50% of the time?) no QML ever appears: The first time I noticed that problem was as of commit Birch-san@3c081a8: Basically I took the implementation of processEvents() that you provided (which implemented socket notifiers), and added timers by referring to https://code.woboq.org/qt5/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp.html However there are parts of its logic which I skipped. Maybe that explains why the QML sometimes fails to appear. If we take the approach from my branch: we would become dependent on qtimerinfo_unix_p.h: https://code.woboq.org/qt5/qtbase/src/corelib/kernel/qtimerinfo_unix_p.h.html Also it means incorporating some LGPL3 header code from Qt (maybe this is fine; we are GPL3, which I assume is a superset). I don't see a version of QTimerInfo for any other platform. Is this why you recommended that we write our own cross-platform implementation? that seems like it would be a reasonably big job. especially since it concerns time: we've had experiences with time code failing to compile on macOS (or worse: failing to compile on slightly old versions of macOS). so a cross-platform timerinfo may be difficult. Trying to figure out where to go from here. I assume that if I copy What are the repercussions of just using the magic commit + glFinish()? would it mean we simply have no event processing? the game seemed to work despite that. |
Other platforms are probably using the OS-specific API to implement timers. The
I haven't tested, but I think that the GUI animations will play instantly or won't play at all. To check that, set the |
I think this was now fixed by #995, please test. |
#828 figured out that for a successful mac run the event dispatching for mac needs to be changed.
This has to be fixed properly.
The text was updated successfully, but these errors were encountered: