Slow Windows Painting

Does anyone have a way to get Windows apps built with 2017r2.1 to render faster than around 10fps for a 1920x1080 canvas which is only filling the screen black and then drawing a rectangle based on drag positions. Compiling with 2016r3 is a lot faster. I know windows rendering has changed but surely there is a way to draw graphics to the canvas faster than that.

I am storing x,y position on mouse down and drag events to render the rectangle, and then invalidating with no erase background.
OSX is not to bad on my retina 5K screen (~30fps).

Also windows is not passing through the areas() parameter if i invalidate only the areas i know have changed. Invalidating the entire screen compared ot the areas changed makes no difference to rendering speeds.

I have tried with and without hidpi support. 32 and 64 bit. Double buffer and erase backgrounds on and off on the canvas. Invalidating on mouse drag event and also a timer on different periods. All with no noticeable changes to rendering.

All i want to do is draw a selection rectangle over a prebuilt scene without it looking terrible.

I also tried moving the rendering to the window.paint event with the same results.

you mean something like this (simple example)

Public Property MX as Integer
Public Property MY as Integer
Public Property mx1 as Integer
Public Property my1 as Integer


Class CANVAS


Function MouseDown(X As Integer, Y As Integer) Handles MouseDown as Boolean
  mx=x
  my=y
  mx1=x
  my1=y
  self.Invalidate
  return true
End Function

Sub MouseDrag(X As Integer, Y As Integer) Handles MouseDrag
  mx1=x
  my1=y
  self.Invalidate
End Sub

Sub Paint(g As Graphics, areas() As REALbasic.Rect) Handles Paint
  g.ForeColor=&c000000
  g.fillrect 0,0,g.Width,g.Height
  g.ForeColor=&cff0000
  g.DrawRect mx,my,(mx1-mx),(my1-my)
End Sub


END CLASS

while it is simple… it is way faster than 10fps

Basically that is my test code. On a small window it is fine, but when you resize to a larger window it slows right down and the rectangle being drawn lags behind the mouse a lot.

Another test is to put

g.ForeColor=&c000000 g.fillrect 0,0,g.Width,g.Height

into the window1.paint event on a new project and then run and resize the window quickly. It cannot even keep up painting!

Tested on surface pro 4 it is doing about 15fps, windows 10 on vmware is about 10fps

EDIT: above lagging happens mostly on vmware, on the surface pro it leaves behind lines over the screen. Very odd.

runs with no lagging on a 2017 iMac 27" 5K Retina computer, and in the past I have run a more complex version of that test code, on various other machines with high rates of FPS.

It may have to due with the recent changes with WIndows underlying graphics library and not with Xojo (I’ve seen other topics discussing that, but haven’t paid alot of attention as that is not my platform of choice)

Which presumably is using software emulation of the Direct2D calls.

Which usually indicates that those areas() are being supplied, but aren’t keeping up.

In theory, you only need to paint the 2 areas which held the last known position of the rectangle, and the current position of the rectangle.
You can use static variables in the paint event to record those locations: if the mousedrag fires 600 times, you may only get 5 paint events.

Didn’t think about software emulation on vmware - i do have enable hardware acceleration on direct x 10 and open gl turned on. Maybe d2d is not part of that.
Surface pro renders between 120fps and 13 fps when a small window and full screen.

checking for a moved mouse is a good idea as well, as the mouse drag event always fires now.

All my tests showed that the areas.ubound was -1 but it would only update the buffer with the rendered part in that area, so it was half working. Just means you cannot exclude some rendering logic based on whats changing.

Rendering only on a moved mouse increases it to 20fps on surface pro which is getting a lot better.

Just tested rendering large hidpi image then selection rectangle on top and it is drawing nice and snappy with Jeff’s invalidate on moved mouse drag events.

Simple fix huge results. Thanks Jeff.

Enabling DoubleBuffer on a canvas means that no areas() are passed to the paint as the entire surface is drawn when a paint occurs.

This seems to be undocumented.

As the buffer is cleared on every flip you need to repaint the entire scene anyway so additional rendering logic is mute.

If you implemented your own painting logic and turned off double buffering, you could gain some additional speed but that would all depend on the target hardware and how much rendering you are doing every paint.

I have just seen you demo on feedback. If you just want a bounding box with nothing fancy, drop doublebuffering and pass your changed rects using invalidate and you will save a fair bit of speed as 95% of your canvas will not be altering.

All that being said, using your demo and going from 110 FPS @4k (fullscreen) in 2016r3 to 12 FPS @4k (fullscreen) in 2017r2.1 is just, well, shocking, part of me wonders if its actually hardware accelerated at all. Roll on the updated Windows framework.

It does look like it is software rendered, at least on my vmware images. What and when is this new updated windows framework? did they not just change the rendering to d2d last year?

and/or if Xojo has implemented Direct2D properly :wink:
It seems that all drawing is much slower compared to 2016r3. And i very much hope that the promised fixes for the Windows Framework issues (Xojo talks about ‘flickering’, but I think ‘slowness’ is a big issue, too) will be improved 2017r4.

One other example:
<https://xojo.com/issue/49944> Windows, Direct2D: Invalidating a Canvas and Updating a Control’s Position is lagging extremely