Monteverdi: Moving the mouse cursor uses 100% of a CPU
Mantis Issue 1228, reported by poughov, assigned to salbert, created: 2016-06-16
It looks like pixel peaking is very CPU heavy. Simply moving the mouse over the image view will occupy one CPU core at 100%. Because moving the mouse is such a common operation when using a computer I think no software should use so much CPU for that.
Steps To Reproduce: Open Monteverdi, open an image, move the mouse cursor and monitor CPU usage.
2016-06-16 16:28 - rashadkm: For instance, when I move mouse cursor, what I expect is simply mouse move like in any other window. So the usage of CPU to 101% is bad. But this is expected right?
I suggest to change the "other" renering stuff during mouse move to Ctrl+ Mouse move or whatever. This way, If I want pixel information or other contrast stuff, I still can have it with an extra key press. Only if user wanted.
When I simply move my mouse over the image or monteverdi window, nothing happens.
Expect mouse moved without 100% CPU
2016-06-17 09:29 - poughov: Please no. Let's not add more Ctrl+[...] shortcuts, it will only make things more confusing.
I talked with Julien about this issue and it's related with the way pixel peaking searches the list of tiles to find the one intersecting the mouse position. The problem is that this list is in arbitrary order and the search is essentially brute force.
I'm not familiar with that bit of code but some ideas: keep the list in most recently used order (like a LRU cache), use a spatial data structure for querying (e.g. quadtree) or add a small timer so that the search is only triggered right after the mouse has stopped moving.
2016-06-30 18:24 - salbert: At system level, cursor events are set the highest priority. Processes are interrupted when mouse moves. So, the mouse is always responsive, even if the system is fully busy.
The windowing system (window manager) forwards mouse events to graphical applications which read its parameters and send an internal (Qt in our case) mouse event which is processed by the GUI toolkit to manage widget behaviors and can be caught by user code (Monteverdi) to customize this behavior. This is what does the main event loop of Qt.
Qt mouse-event processing uses some CPU (traversal of widgets tree) as do the Monteverdi processing and the Ice pixel-picking.
So, I think it is normal the CPU usage is increasing because some behavior is being executed. Because it is a high priority event, the CPU usage should peak high but not last long (on my development laptop, the mouse cursor is pipelined on the 4 cores). Anyway, Qt uses threads to manage event-loop and graphical rendering. I think it would be problematic if system mouse cursor was lagging.
OTB-Ice pixel picking algorithm traverses tiles and test the mouse cursor coordinates against the bounding box of each tile and, if matched, get the pixel value from tile data. Cf. otbGlImageActor.cxx
As Victor said, we could remember the found tile and add a single before-loop test against that tile to quickly get it if the mouse cursor moved in the same tile (LRU-type algorithm).
On a 1920x1080 Full HD screen, there will be 31.64 256x256 tiles for each layer. For 10 layers, we'll have a 320 iteration to find the given tile which seems pretty low.
A better implementation would be to organize tiles by their region (chessboard layout) instead of linearly and access directly the tile from screen coordinates. But, this would be done for each otb::GlImageActor of the layer-stack because tiles are stored in each otb::GlImageActor.
The best data-structure/traversal algorithm would be to store tiles in a data-structure which is shared among all otb::GlImageActor instances and which organizes tiles of all layers under the same region key (tile regions matches exactly the same coordinates). So we would have a direct access to the tiles of all layers which one direct access.
I think that using a quad-tree would be more of an overcost that an optimization because of the number of tiles which are searched/rendered.
To conclude, I think this issue is more of a feature request/request for comments/improvement to the search algorithm than a bug.
2016-06-30 18:24 - salbert: Feedback expected.
2016-07-01 16:15 - poughov: > For 10 layers, we'll have a 320 iterations to find the given tile which seems pretty low.
The problem is how often it's done. Currently, do you know what is the frequency at which mouse-events are emitted?
2017-12-06 14:09 - poughov: Bug still present in 6.2