Why does wxWidgets update drawing slower than Qt? - qt

I am using wxWidgets to draw a large flow chart, i.e. 625 x 26329 pixels. The program was transported from Qt to wxWidgets. It is easy in layout with a main frame which has a customized scroll window inside. The scroll window draws part of the chart every time within updated client region.
Now Qt and wxWidgets make much difference. When scrolling vertically with mouse rolling, Qt refreshs painting the chart very smoothly, while wxWidgets is slowly with flicker.
Can anyone tell me how to make the painting efficiently?

Are you sure it's slow? I would be wondering, I encounterd a different experience.
You mention flickering. Flickering is mostly result of too many refresh calls.
To prevent this you must use double buffering and this is the key.
Double buffering means to draw all stuff offscreen into a image / bitmap and after everything is drawn the image/bitmap is drawn fully (this is done really fast so no flickering :)! ).
Qt uses for default double buffering. That's why it looks everytime smooth.
However the downside of this approach is that it consumes performance.
wxWidgets doesn't bound you to that. Instead it says, it's your task to get double buffering.
Also you should look whether you aren't clipping the region you're drawing. Clipping under Windows with wxWidgets gave me a really better performance.
PS:
Yes, old question but I think it's still needed to know how the facts are.

Related

visIgraphLayout causing display issues for shiny app

I can share the code if needed but it felt like a lot to share to start, so I'll try to explain narratively. I am creating an interface to display network data (as you might have guessed from the title). My first issue has been going on for a few days where visIgraphLayout is not laying out my visual correctly. Regardless of using "full" or "square" as the "type", the network map extends beyond the edge of the display space. When I resize the interface window, then the map will snap to full. Why won't it simply resize automatically? If it matters, I do have the output space in a box element. Also, I have the layout styles working off radiobuttons, and when I switch between styles the map goes beyond the edges again.
Part 2 begins. While the above problem is annoying, it was livable. However, a new wrinkle popped up. I added some font size control to my visNodes code - i.e., radiobuttons set to switch between off (0), small (5), standard (14), and large (40) font size options. Once I implemented this code, when I resize the interface window, now the network map disappears completely after initial load. If I select a new label option, it will redraw but beyond the edges of the space.
All the issues resolve themselves if I ditch the visIgraphLayout, but then I lose the layout functionality which I really like.
I hope this is clear enough. I really appreciate any insights the community might provide. Be well.
I think I have figured out an answer. Long story short, certain pieces didn't work and play well with others. Went through and build it again, and all it good.
Cheers.

Use of QML Animations vs. Animation Files

I wonder, if it is more beneficial to use the abilities of QML for animations, or prefer to use animation files (such as GIF oder MNG) for simple, small-scale animations.
Examples for what I call "simple, small-scale animations" are:
turning Hourglasses
those rotating dots, known from video platforms, while loading
flashing alert symbols
those "recharging buttons" known from many RPGs used for special attacks
I don't know much about the internals of Qt, so I am unsure, whether I benefit from hardware acceleration, when programming the animations (e.g. image rotation) or not. And if so, whether this hardware acceleration outperforms the display of pre-calculated animations from GIF and MNG.
Greetings and thanks,
-m-
I wouldn't worry about things like this unless they visibly slow the performance of your application. Some points to consider:
The use cases you mentioned almost always involve only one "busy indicator" being visible at a time.
Both Image and AnimatedImage have the high DPI #*x file look-up.
Both Image and AnimatedImage support caching.
Both Image and AnimatedImage will use the Qt Quick scene graph to display the images (OpenGL textures, which should result in hardware acceleration).
AnimatedImage has to read several images, but won't require rotation.
Rotation of images is pretty cheap, as far as I know.
It's trivial to swap out one with the other, or with something else.
If you're looking for good general performance advice, read the Performance Considerations And Suggestions documentation.

Practical differences between SVG and Canvas within a ggvis & Shiny Context

I have already read
What is the difference between SVG and HTML5 Canvas?
&&
https://en.wikipedia.org/wiki/Canvas_element#Canvas_versus_Scalable_Vector_Graphics_.28SVG.29
So i am aware of the basic differences, but i was wondering if anyone had encountered any practical difference between the two within the context of ggvis and shiny apart from SVG inability to deal with NA's in the data
The short answer:
SVG would be easier for you, since selection and moving it around is already built in. SVG objects are DOM objects, so they have "click" handlers, etc.
DIVs are okay but clunky and have awful performance loading at large numbers.
Canvas has the best performance hands-down, but you have to implement all concepts of managed state (object selection, etc) yourself, or use a library.
The long answer:
HTML5 Canvas is simply a drawing surface for a bit-map. You set up to draw (Say with a color and line thickness), draw that thing, and then the Canvas has no knowledge of that thing: It doesn't know where it is or what it is that you've just drawn, it's just pixels. If you want to draw rectangles and have them move around or be selectable then you have to code all of that from scratch, including the code to remember that you drew them.
SVG on the other hand must maintain references to each object that it renders. Every SVG/VML element you create is a real element in the DOM. By default this allows you to keep much better track of the elements you create and makes dealing with things like mouse events easier by default, but it slows down significantly when there are a large number of objects
Those SVG DOM references mean that some of the footwork of dealing with the things you draw is done for you. And SVG is faster when rendering really large objects, but slower when rendering many objects.
A game would probably be faster in Canvas. A huge map program would probably be faster in SVG. If you do want to use Canvas, I have some tutorials on getting movable objects up and running here.
Canvas would be better for faster things and heavy bitmap manipulation (like animation), but will take more code if you want lots of interactivity.
I've run a bunch of numbers on HTML DIV-made drawing versus Canvas-made drawing. I could make a huge post about the benefits of each, but I will give some of the relevant results of my tests to consider for your specific application:
I made Canvas and HTML DIV test pages, both had movable "nodes." Canvas nodes were objects I created and kept track of in Javascript. HTML nodes were movable Divs.
I added 100,000 nodes to each of my two tests. They performed quite differently:
The HTML test tab took forever to load (timed at slightly under 5 minutes, chrome asked to kill the page the first time). Chrome's task manager says that tab is taking up 168MB. It takes up 12-13% CPU time when I am looking at it, 0% when I am not looking.
The Canvas tab loaded in one second and takes up 30MB. It also takes up 13% of CPU time all of the time, regardless of whether or not one is looking at it. (2013 edit: They've mostly fixed that)
Dragging on the HTML page is smoother, which is expected by the design, since the current setup is to redraw EVERYTHING every 30 milliseconds in the Canvas test. There are plenty of optimizations to be had for Canvas for this. (canvas invalidation being the easiest, also clipping regions, selective redrawing, etc.. just depends on how much you feel like implementing)
There is no doubt you could get Canvas to be faster at object manipulation as the divs in that simple test, and of course far faster in the load time. Drawing/loading is faster in Canvas and has far more room for optimizations, too (ie, excluding things that are off-screen is very easy).
Conclusion:
SVG is probably better for applications and apps with few items (less than 1000? Depends really)
Canvas is better for thousands of objects and careful manipulation, but a lot more code (or a library) is needed to get it off the ground.
HTML Divs are clunky and do not scale, making a circle is only possible with rounded corners, making complex shapes is possible but involves hundreds of tiny tiny pixel-wide divs. Madness ensues.
I have past content from the following link.
Please see this link for more details
HTML5 Canvas vs. SVG vs. div

QtQuick 2.0 scene on top of Direct3D scene

I have been trying to come up with a solution for having a QtQuick 2.0 scene together with a Direct3D scene for quite a while, but wasn’t very successful. My goal is to have a Direct3D engine running at reasonable speed (60 FPS?) together with QML UI on top. Both things run just fine at 150-200 FPS on their own. But when forced to cooperate together within one window, everything just goes bananas. I have investigated several approaches, but none of them seems to be sufficient enough:
Solution A: Rendering Direct3D scene into a texture, visualizing with QImage & QQuickPaintedItem
this solution works quite well and it seems to be the preferred one according to other people on the web. However it is TERRIBLY slow. I wasn’t able to have more than 18-20 FPS in full HD. The bottleneck was clearly in the texture transfer chain from GPU (D3D) to CPU (QImage) and back to GPU (QML renderer) each frame. Especially the CPU->GPU processing on the QML side was way too slow!
Solution B: Rendering QtQuick scene into a FBO, then using Direct3D texture
this is basically the previous solution other way round. The speed is a little bit better when the UI does not require an update. Once it starts animating, everything drops down to 18-20 FPS again. QOpenGLFramebufferObject::toImage() obviously takes its time. Implementing texture/FBO double buffering on both sides to reduce stalls does not really help.
Solution C: QQuickView with enabled transparency on top of QWidget with Direct3D scene
was not lucky with this approach either. It seems like the transparency works only when QQuickView is in its own window. Once I put it on top of my D3D QWidget within the same window, it immediately stopped working and became fully opaque. Someone was trying to do something similar there as well: http://qt-project.org/forums/viewthread/5484, but I had no luck with that solution at all. Maybe keeping two completely separated windows (main D3D window + frameless transparent QML window) on top of each other all time would do the trick, but that just sounds silly.
Solution X: Modify ANGLE library and try to extract & share D3D device context with my Direct3D renderer
haven’t tried this yet, avoiding any library modifications as long as possible. Would that even be a sensible option?
My obvious questions here are: Am I doing something wrong? What is the preferred solution? A, B, C, X or maybe something totally different? Can someone point me to the right direction?
TL;DR: What is the fastest way to render QML scene on top of Direct3D scene?
Sounds like you ideally want a bastard mix of Solution X and writing yourself a DirectX QPA plugin.
http://qt-project.org/wiki/Qt-Platform-Abstraction
I'd wager you'd make a lot of friends if you open sourced such an effort!!

Prevent Direct3D viewport image from scaling (SlimDX)

I have a Direct3D11 scene set up in SlimDX in a window. The rendering is done in a separate thread.
Is there a way to keep the renderer from stretching the image when it draws to the resized control? I've tried ModeDescription.Scaling = DisplayModeScaling.Centered and it doesn't seem to have any effect. Is there something I'm missing?
(I already am updating the render target size. The reason I ask this is that when I resize the control it stretches the image to fill the control for a split second before the render target gets updated with the new size. This has the result that as I resize it, it flickers terribly. If I could reset the render target just slightly faster it might get rid the the flicker. Keeping the image in the corner without scaling it is perfectly fine since ultimately it won't be scaling at all.)
Workaround 1: One can put the render target inside a control. When the window resizes only resize the control though a special method that first stops the rendering, then update the buffers and begins rendering again. It's a bit of hack, though. I have to wait for the render cycle to complete, then block it, then resize, then unblock.
Workaround 2: A similar workaround is to check for a resize flag in the render loop rather than interrupting it. The renderer should be able to draw directly without scaling. This is much more acceptable performancewise. However, a blocking call to the UI thread must be made to execute the actual resize.
Workaround 3: Rather than resizing the control at all, one could make it as large as the maximum size it could be, but clipped (inside the window). No resize is necessary, but a scissor rectangle must be maintained in a similar manner to the workarounds above unless you don't mind rendering a whole lot of offscreen pixels. Rendering twenty or so extra rows and columns of pixels does have the favorable effect of supplying immediate image at the edge when the window is resized back larger.
Ideally the resize should be done directly from the UI thread (no fooling around with delaying it and reentering the UI thread from the render thread). It's not the render thread's responsibility and it slows it down. Likewise, the buffer resize should be done in the render thread for maximum performance (no fooling around with waiting/blocking/resizing/unblocking). The only reason this does not work is that the render thread scales if the resize is done before the buffers are resized.
So my question still stands: Is there a way to render without scaling?
I am going to answer this in terms of the raw Win32 APIs involved, which might require a bit of finesse to translate to a managed .NET environment & SlimDX.
When you are dragging or resizing a window, windows basically hijacks your message pump and creates a new one specifically designed to do the resizing logic efficiently. This operation is more or less modal until it is completed. Many messages you would normally get are quite literally blocked until the resize or drag is completed. In the app terms you get a WM_ENTERSIZEMOVE when this behavior begins, and either WM_EXITSIZEMOVE or WM_CAPTURECHANGED when it ends. You need to check both of these messages, as alt-tabing out when doing a drag will send WM_CAPTURECHANGED and never a WM_EXITSIZEMOVE!
All this means that when you get a WM_ENTERSIZEMOVE you can set a flag and know that all WM_SIZE and WM_MOVE messages that occur afterwards are for the drag operation. Typically resizing rendertargets and tracking down and de-allocating all default pool resources is a very slow operation, and well worth defering until the drag/resize has completed. This has the side effect of making the window stretch which is exactly the same problem you are describing here, and you want to fix that.
It should be possible to add special handlers in WM_SIZE, WM_MOVE, or WM_SIZING, and WM_MOVING that forces a syncronous render and repaint via SendMessage (as opposed to PostMessage) when they occur, but you will need to make sure you only do this when inside the modal loop owned by WM_ENTERSIZEMOVE.
I would recommend either forcing the window to a fixed size (which seems rather common) or not redrawing the D3D control until the changes are done (that or simply clear it black).
There seems to be a way to do what you want, as I have seen games capable of changing size with no flicker, but I've no idea how that's done, unfortunately. Locking the window size and providing a menu was the old solution.

Resources