Main Site Documentation

About Glide, Pyxis, Gadgetos, NET Clix graphics performance


#1

Hi all.

For the beginning I’d like to tell some words about WPF.
WPF is a great presentation technology allowing creating any UI interfaces with any complexity and any beauty you can ever imagine. Another big advantage is its dynamic data binding. The equivalent technologies are Silverlight for Web UI and Silverlight for Windows Phone.
But it’s worth to mention that WPF requires significant hardware resources for its dynamic layouting. Not even every notebook can present WPF UI smoothly and without simplification. On Windows OS, WPF is based on DirectX technology when a huge amount of calculations is handled by GPU (processor of graphics card) which is hundred times more powerful than CPU. Providing simplified WPF model to NETMF by Microsoft is great but UI’s created with it are still yet not acceptable in performance on devices like Cobra and ChipworkX where all calculations are handled by a single processor. Adding any dynamics to layout hangs it up dramatically.

As a solution, another way was chosen - rendering directly to a bitmap and flushing it to the screen - a technique similar to the one being a standard in game development. This way is used in such libraries as Glide, Pyxis, Gadgetos and .NET Clix (sincerely, there are not many products for today to choose from). More to say, Pyxis/Gadgetos are also a try to create some kind of OS for netmf – thanks to Skewworks, great job indeed!

I did some workaround with these libraries.

Glide
I created a Form and placed three TextBlocks on it. Next I added a new thread with a loop in which I periodically (once a second) assign a system time value to text property of these text blocks. Result is all three text blocks update only once and then freeze forever.

Pyxis/Gadgetos (+ most possibly NET Clix)
I created a Form with a background image and placed a panel on it. Panel has 4 Labels, 2 autosized, 2 with fixed size. Next I added a new thread with a loop in which I periodically (once a second) assign a system time value to text property of these labels. Result is form doesnt display its background image, labels with autosizing update their text on the screen only once and then freeze forever, labels with fixed size keep updating but without clearing their background area that leads to overlaying a text with each updating and getting a mess instead of text.

Next, I overviewed the source code of Pyxis. It uses a rendering technique which could be named like so called bubble notification. Due to it, controls with static size render only themselves if needed, while controls being able to change their size dependently on their properties (like labels etc.) cause its parent to rerender himself and all his children hierarchy, even those not needed to. Now lets consider a situation when we have a form with a dozen of panels, each of which contains a label and a panel, which contains a label and a panel and so on… up to 5 levels of hierarchy. Then we want all the labels to display some dynamic text. Can you imagine what will it end up with? With completely dead UI.
I guess Gadgetos and NET Clix use the same technique. And what about Glide?

In game development the other way is used. Theres a main loop which constantly makes all control hierarchy to update and to render. With such a technique we could never experienced the issues mentioned above. With a huge control amount we could miss some values from displaying but have some stable fps. With bubble notification – we couldnt.

And dont forget that NET Clix is 30$ and Glide for commercial use is 1000$.

Now is the question.
I have a production project with some number of H-bridges with current sensors connected to analog pins of Cobra. The task is to monitor their power consumption as fast as possible (lets say a couple times a second). Used are the progress bars for graphic form representation and labels for numeric one. Due to my workaround with mentioned libraries I cant use any of them for such a quite simple situation.

I would like the libraries creators to correct me if I did anything wrong and, if possible, to give me any recommendation for my project task. For now the only way that I see is to port to netmf my 2D GUI controls library made for XNA games.

Thank you.


#2

As far as Pyxis 2 and labels that’s outdated code; you shouldn’t have those issues with Gadgetos’ beta and you definitely won’t have it with .NET Clix. We do still use the same bubble method where required. It’s just a fact of life when you have a transparent backcolor that you need to render anything behind it first in order to have the render function properly. If you set it to be a solid backcolor this isn’t an issue at all.

Also for you example with panels and labels; a transparent child only requires it’s parent to refresh…not it’s parent’s parent and so on. And again, that’s just the nature of transparency. If you don’t need it to be transparent that won’t be an issue.


#3

I’m agree that with solid back color thing are a bit easier.

I’ve just looked at the code of Label in Gadgetos.
So far we have:


public override void Render(bool flush)
    {
        int width = base._w;
        int height = base._h;
        if (((base._parent != null) && (base._parent.ScreenBuffer != null)) && ((base._visible && !base._suspend) && (this._font != null)))
        {
            base._parent.ScreenBuffer.SetClippingRectangle(base._parent.Left, base._parent.Top, base._parent.Width, base._parent.Height);
            if (this._autosize)
            {
                this._font.ComputeExtent(this._text, out width, out height);
            }
            if (!this._transparent)
            {
                base._parent.ScreenBuffer.DrawRectangle(Color.Black, 0, this.Left, this.Top, width, height, 0, 0, this._bkg, 0, 0, this._bkg, 0, 0, 0x100);
            }
            base._parent.ScreenBuffer.DrawTextInRect(this._text, this.Left, this.Top, width, height, 1, this._color, this._font);
            if (flush)
            {
                base._parent.Flush(this.Left, this.Top, base._w, base._h);
            }
        }
    }

nothing specific. Almost the same like in Pyxis.

And Text property:


public string Text
    {
        get
        {
            return this._text;
        }
        set
        {
            this._text = value;
            if (this._transparent || this._autosize)
            {
                if (base._parent != null)
                {
                    base._parent.Render(true);
                }
            }
            else
            {
                this.Render(true);
            }
        }
    }

so if label is autosized or transparent we have this line working:


base._parent.Render(true); //(was base._parent.Render(); in Pyxis, so now it forces the parent to flush)

Let’s look at the parent Render method (for example, our panel):


public override void Render(bool flush)
    {
        if (((base._parent != null) && (base._parent.ScreenBuffer != null)) && (base._visible && !base._suspend))
        {
            base._parent.ScreenBuffer.SetClippingRectangle(base._parent.Left, base._parent.Top, base._parent.Width, base._parent.Height);
            base._parent.ScreenBuffer.DrawRectangle(this._bkg, 0, this.Left, this.Top, base._w, base._h, 0, 0, this._bkg, 0, 0, this._bkg, 0, 0, 0x100);
            for (int i = 0; i < base._children.Count; i++)
            {
                try
                {
                    ((Control) base._children[i]).Render();
                }
                catch (Exception)
                {
                }
            }
            if (flush)
            {
                base._parent.Flush(this.Left, this.Top, base._w, base._h);
            }
        }
    }

especially at this part:


     for (int i = 0; i < base._children.Count; i++)
            {
                try
                {
                    ((Control) base._children[i]).Render();
                }
                catch (Exception)
                {
                }
            }

Which means that panel must rerender all its children. Or, in another words, changing the only one Label’s text will cause all(!!!) panel children to redraw. What if children amount will be about 100 for example? And there will be another labels among them?
And what if panel also has transparent background? I see, you hardcoded it to be opaque:


base._parent.ScreenBuffer.DrawRectangle(........, 0x100);

and didn’t give users any chance to tune panel transparency! Although semitransparent panels look more professionally.

And if panel is semitransparent, you will have to force the panel parent to redraw its children. And so on, and so on! So the amount of redrawing objects increases geometrically.


#4

Gus, are you there?
Could you please make it clear about Glide techniques?


#5

I am not sure what your question is.


#6

Which rendering technique does Glide use? Bubble notification (like Pyxis, Gadgetos, .NET Clix do) or updating/rendering scene graph in a loop (like all games do)?


#7

It keeps a rendered bitmap of the window and only changes things when absolutely necessary. This uses more ram but make things a lot faster. NETMF systems have few MBs of RAM so this is not an issue but speed is needed.


#8

So it also uses bubble notification technology :(.
And is capable of all issues mentioned above.

Could you reproduce the model I wrote about in the beginning?

Or at least try my experiment:

?


#9

It’s a quiet simple task: to have a form with 3 textblocks showing system time. In fact neither of Glide, Pyxis, Gadgetos can do this. What’s the matter?


#10

::slight_smile:


#11

So none of these libraries could be used in production now.
Guys, you should fix your Glide asap 'cause serious people would wonder for what the price of 1000$ is.
The price of .NET Clix is more than reasonable :wink: Skewworks, if you would use another rendering approach in Gadgetos your product would be best of the best. Just try rendering to bitmap in a loop in separate thread and play with thread priorities for render manager and input manager.

So far the only way particular for me is porting my XNA 2D controls library to netmf.

JFYI: I did some little modifications (using game development approach) to Pyxis code and now I have stable form with background image with 4 labels with transparent background showing system time and one showing current FPS and 4 checkboxes. They all are on semitransparent black panel (looks just like Android UI :slight_smile: ) and their values are updating ten times a second. No problems.


#12

Just dreaming about ChipworkX or Hydra kit as bonus for investigation and QA job ::slight_smile:


#13

@ Gothic
[ol]Pyxis 2 is outdated, but open-source; feel free to fix anything you find
Gadgetos is in early beta; bring any issues you have and we’ll address them
.NET Clix is commercial; any issue you find will be fixed quickly
I’m finishing up a push for .NET Clix 1.1 right now to get out today; it will address any label issues (please note on no version is there an issue the with textbox rendering as far as I’m aware)[/ol]

I’ve taken to heart all of your issues and doing the best I can to get them filled for you immediately.
One thing I won’t be changing, however, is the panel. I feel transparency on this would be sparsely used and would only serve to leave the user less space for their application.

.NET Clix does have a base class for making controls though, just like Windows, so you can make your own version of the panel to suit your needs. The new document covers these base classes.


#14

@ skewworks
I believe all will be ok with your products :wink:
One thing that can drive myself easier now is that you’ll firstly try this simple model

and confirm it works w/o problem though :slight_smile:


#15

Sorry, it’s deep-deep night at my place so I really had to sleep yet :slight_smile:
Hope to hear soon from all of you, guys!
I’d truly like you products to be perfect!


#16

.NET Clix 1.1 is now available (with an emulator only demo version as well). I tested out your issue with 10 transparent labels constantly updating their text, no issues.

http://www.skewworks.com/products/DOTNETClix


#17

It’s a very good news!

I’ve played with it a bit. And now I have some suggestions.

It would be so nice to add unicode fonts support to those classes that use texts and fonts but don’t have font parameter in constructor or font property. Especially dialog boxes and some other classes. As for me, my native language is russian, so I really do need such a support.

This also concerns the virtual keyboard. I know it’s a quiet piece of additional work. Maybe the possible solution is to make virtual keybord class abstract and allow inheritance for creating keybords for specific languages … smth like that. In further versions.

Also to my mind it’s not good to allow using library in emulator only. It would be interesting to test it on a device. Maybe you could make periodically popuping message about trial instead?


#18

@ skewworks

I did some additional speed tests:


        public static void Main()
        {
            Form frmMain = new Form();
            Panel panel = new Panel(10, 10, 400, 450, Colors.Orange);
            frmMain.AddChild(panel);

            int y = 10;
            for (int i = 0; i < 40; i++)
            {
                panel.AddChild(new Label("", 4, y));
                y += 10;
            }
            y = 10;
            for (int i = 0; i < 40; i++)
            {
                panel.AddChild(new Label("", 100, y));
                y += 10;
            }
            y = 10;
            for (int i = 0; i < 40; i++)
            {
                panel.AddChild(new Label("", 200, y));
                y += 10;
            }

            Graphics.ActiveContainer = frmMain;

            new Thread(delegate()
            {
                while (true)
                {
                    DateTime dt = DateTime.Now;

                    string hour = (dt.Hour < 10) ? "0" + dt.Hour.ToString() : dt.Hour.ToString();
                    string minute = (dt.Minute < 10) ? "0" + dt.Minute.ToString() : dt.Minute.ToString();
                    string second = (dt.Second < 10) ? "0" + dt.Second.ToString() : dt.Second.ToString();
                    string result = hour + ":" + minute + ":" + second;

                    foreach (Label lbl in panel.Children)
                        lbl.Text = result;

                }
            }
            ).Start();
        }

So we have a form with a panel containing 3 columns with 30 labels each (total 90 labels), displaying system time.

[italic]NET Clix:[/italic]
In emulator: labels update one after another and it looks like a wave. One updating pass takes 11 seconds.

[italic]My game dev approach:[/italic]
In emulator: all label update simultaneously, one updating pass takes 1.1 seconds.
On the device: all label update simultaneously, one updating pass takes 5.3 seconds.

Device used is Cobra with 7" display.

It would be very interesting to test this model with Clix on a device though. But in emulator game dev approach performance is 10 times faster then bubbling notification approach.
It’s because of (as I wrote earlier)


#19

Also consider my modifications take about 10 minutes and there is no optimization yet.


#20

@ Gothic Maestro
You seem to know plenty about graphics so why not help this community by building a library? I am sure others will appreciate any contribution.