Improvements discussion

Hi all.
Glad to meet you again!
I’d like to propose this thread for discussing of possible improvements we could make to implement visualization/rendering and of course for all other stuff.

@ Gothic

  1. The full screen, rather than dirty area, clearing is because if you had a background or previous form clearing only the dirty area would leave a cutout effect…not too nice looking.

  2. On your screen calibration issue; have you ever been able to calibrate it properly? I know you set you couldn’t get it on .NET Clix or Glide. This makes me wonder if there might not be something wrong with your touch screen itself. Can you calibrate it properly with your own code?

Yes, I successfully calibrated it with my source code using wpf approach as well as using my own non-wpf approach.

Regarding the touch support approach that you used I have a suggestion, if you don’t mind.

I’m always open to suggestions.

I meant not only a single control dirty area, but all dirty areas.
At my video posted on the youtube you can see rendering without ever flushing all the screen, only dirty areas. All screen flushing at my Cobra with 7" display takes 40-50 msec. Dirty areas approach takes about 10-15.

The magic is how to handle all these dirty areas. And I assume flushing the largest possible amount of dirty areas would take exactly the time needed for a single full screen flush :wink:
More to say, the amount of dirty areas doesn’t impact the performance.

Regarding the touch…
In your approach you use polling the touch events in endless loop in a thread with the highest priority. Why not to use netmf approach based on event-driven model. You can see it in Glide’s code (GlideTouch.cs), I’m using this model as well.
Thus you can get rid of your endless loop, free additional resources and get gestures support as a bonus :wink:
Also this model is more precise than your one and I guess that could be a reason of not only my unsuccessful attempts to calibrate those 3 checkboxes in Clix and Gadgetos. I debugged you approach and very often got returned touch points just weird.
Not worth to mention that I spend about an hour tapping that check boxes with increasing fear))) in those 10 sec that you gave for this.

Also it’s worth to play around with
TouchCollectorConfiguration.TouchMoveFrequency and
TouchCollectorConfiguration.SamplingFrequency

the corresponding values of 500 and 200 work for me just well improving touch responsibilities and accuracy

It would be also nice to get Glide developers participating. I would like this thread to be not only my monologue.

Touch

  1. That was old code to begin with and in 1.2 it’s seriously out-dated; I think you’ll like the new method. It still has to run a thread but the priority is lower and it uses message queue.

  2. Event driven locks up on modals and app domains; that’s why it was stripped to begin with.

  3. I’ve increased the timeout to 30 seconds instead of 10

  4. I actually tried the events straight out of the IEventListener this time around again, issue still being locking during modals; and going through the full list of touches not raised during a modal after the modal is closed. I even attempted to deal with this by discarding messages withing a certain timeframe but the timestamp given seems to in no way be close to the System.Date timestamp. In my testing they were off as much as 10hrs. Not sure why.

  5. During intense methods you can always suspend the touch Graphics.PauseTouch gain some speed back. This is done automatically for things like Graphics.ScreenTransistion and Graphics.Bounce.

I handled touch events in such a way that controls don’t assign to them. It would lead to processing touch events by all the controls simultaneously and making a decision by each of them what to do next.
I use the event listener itself for decision what control have to get the touch event by tracking the touch point underneath hierarchy and cashing recently chosen control. Just something like this:


private static Control touchTarget;

.......

private static void TouchManager_TouchDown(object sender, TouchEventArgs e)
        {
            GetTouchTarget(e.GetPoint());
            if (touchTarget != null)
                touchTarget.RaiseTouchDownEvent(e);
        }

...........

private static void GetTouchTarget(Point p)
        {
            if (TouchCapture.Captured != null)
                touchTarget = TouchCapture.Captured;
            else if (touchTarget != null && touchTarget.ContainsScreenPoint(p))
                return;
            else if (mainWindow != null)
                touchTarget = mainWindow.ChildFromScreenPoint(p);
            else
                touchTarget = null;
        }


where TouchCapture class is an analog of the one from MS.

Form Graphics

  1. Everything derives from 1 of 2 base classes; you can as well it’s in the docs.
  2. You can inherit from a Form yourself.
  3. Override the Render(bool flush) method.

I would love to fill the needs of everyone in a single library but that’s just not realistic.

If you want to move a form around without artifacts, without clearing the screen, or anything else you can use everything exactly the way it is and only have to recode one method of one control.

Like I said on my forum, we do the same thing for modals. They derive from the Form control but in addition they keep a buffered image of the screen so they can “darken” areas the form isn’t using.

Of course using ManualResetEvent would block the main thread as well as the touch listener. Maybe to try to put touch listener in a separate thread so it would serve for modal and regular forms equally. Without starting a new touch polling thread for modal form? Just thoughts.
Maybe to do just this:


private static Control touchTarget;
private static Form modalForm;

......................

private static void GetTouchTarget(Point p)
        {
            [b]if (modalForm != null)
                touchTarget = modalForm;[/b]
            else if (TouchCapture.Captured != null)
                touchTarget = TouchCapture.Captured;
            else if (touchTarget != null && touchTarget.ContainsScreenPoint(p))
                return;
            else if (mainWindow != null)
                touchTarget = mainWindow.ChildFromScreenPoint(p);
            else
                touchTarget = null;
        }


and route all touch events to modal form with main form not being receiving touch events?

This would be also valid for Glide.

I temporarily postponed developing touch branch and get all forces forwarded to rendering core. Could you play with this idea if you want?

Trust me, I tried it. :wink:

I’ll try it out as well asap :slight_smile:

Back to rendering.
I’m now testing my video examples on the Cobra with 7" display. As I presumed things are much slower now. Also I see some small artifacts like frame drops sometimes which never appeared in emulator. Just playing with labels count, their updating frequency and window moving speed. Not being a maniac it’s still quiet possible to get excellent results with hardware.

Just for those not familiar with, it’s a link to video with testings of Glide, .NET Clix and my library on a definite task in emulator.
[url]Glide, .NET Clix and my library performance - YouTube

Did you try it with placing a touch event listener on its own separate thread?

One more benefit of separate thread is to have controls touch responsible while intensive rendering.

JFYI, wouldn’t it be better for Clix demo not to forbid running on the hardware but simply show some watermark or warning text right before flushing; just to allow people to try the product on the real hardware.
I think many people would thank you for that :slight_smile:

Some interesting time information on rendering (Cobra + 7" display):

Bitmap Clear, 800x480: 00:00:00.0120309
Bitmap Flush, 800x480: 00:00:00.0371465
Bitmap GetPixel, 800x480: 00:00:00.0003250
Bitmap SetPixel, 800x480: 00:00:00.0003901
Bitmap Blend a=256, 800x480: 00:00:00.0399479
Bitmap Blend a=127, 800x480: 00:00:01.2195883
Bitmap Blend a=10, 800x480: 00:00:01.2195683
Bitmap Blend a=0, 800x480: 00:00:00.0006304
Bitmap DrawImage 1, 800x480: 00:00:00.0400499
Bitmap DrawImage 2, 800x480: 00:00:00.0403511
Bitmap DrawImage 2, 200x200, center: 00:00:00.0046052
Bitmap DrawImage 2, 20x20, center: 00:00:00.0006930
Bitmap DrawRectangle, 800x480: 00:00:00.1247743
new Bitmap, 800x480: 00:00:00.0117430
Bitmap Dispose, 800x480: 00:00:00.0003555