Page 1 of 1

Clarifications about the new renderer (HW9)

Posted: Thu Apr 08, 2021 9:24 am
by Allanon
Hello Andreas,
I've noticed a little performance decrese using rendering functions so I written a little script and I've got these results drawing 10000 filled boxes, the avarage is referred to each single box rendered:

Code: Select all

Display opened with its standard values.
-> Elapsed: 7581ms, Avarage:0.75

Display opened setting the software renderer = true.
-> Elapsed: 1105ms, Avarage:0.11

Display opened with software renderer = false, encapsulated the box rendering loop in BeginRefresh/EndRefresh.
-> Elapsed: 76ms, Avarage:0

Display opened with software renderer = true, encapsulated the box rendering loop in BeginRefresh/EndRefresh.
-> Elapsed: 1077ms, Avarage:0.1
As you can see the very strange behaviour is on the first case where each box is rendered every 0.75 ms and it's a way slower than the second test which uses the software renderer.
It seems that it's not related with the VSync, infact with VSync enabled the rendering time increases a lot.
I don't understand if this is the normal behaviour or not :)

Here is my test script:

Code: Select all

/* This is a test to measure rendering */

@DISPLAY 1, { width = 800, height = 600 }
Local w, h = 800, 600
Local loops = 10000
SetFillStyle(#FILLCOLOR)

; SoftwareRenderer = Default (OFF)
; Refresh Block = None
DebugPrint("1. Display with its standard values and filled boxes.")
StartTimer(1)
For Local i = 0 To loops
  Local x = Rnd(750)
  Local y = Rnd(550)
  Box(x, y, 50, 50, GetRandomColor())
Next
Local el = GetTimer(1)
DebugPrint("Elapsed: " .. el .. "ms, Avarage:" .. Int(el/loops*100)/100)
;--------------------------------
; SoftwareRenderer = ON
; Refresh Block = None
DebugPrint("2. Display with software renderer.")
CreateDisplay(2, 
  { Width = 800, 
    Height = 600,
    SoftwareRenderer = True
    })
OpenDisplay(2)
CloseDisplay(1)

StartTimer(1)
For Local i = 0 To loops
  Local x = Rnd(750)
  Local y = Rnd(550)
  Box(x, y, 50, 50, GetRandomColor())
Next
Local el = GetTimer(1)
DebugPrint("Elapsed: " .. el .. "ms, Avarage:" .. Int(el/loops*100)/100)

;--------------------------------
; SoftwareRenderer = OFF
; Refresh Block = Enabled
DebugPrint("3. Display with software renderer OFF + Refresh Block.")
CreateDisplay(3, 
  { Width = 800, 
    Height = 600,
    SoftwareRenderer = False
    })
OpenDisplay(3)
CloseDisplay(2)

StartTimer(1)
BeginRefresh()
For Local i = 0 To loops
  Local x = Rnd(750)
  Local y = Rnd(550)
  Box(x, y, 50, 50, GetRandomColor())
Next
EndRefresh()
Local el = GetTimer(1)
DebugPrint("Elapsed: " .. el .. "ms, Avarage:" .. Int(el/loops*100)/100)
;--------------------------------
; SoftwareRenderer = ON
; Refresh Block = Enabled
DebugPrint("4. Display with software renderer ON + Refresh Block.")
CreateDisplay(4, 
  { Width = 800, 
    Height = 600,
    SoftwareRenderer = True
    })
OpenDisplay(4)
CloseDisplay(3)

StartTimer(1)
BeginRefresh()
For Local i = 0 To loops
  Local x = Rnd(750)
  Local y = Rnd(550)
  Box(x, y, 50, 50, GetRandomColor())
Next
EndRefresh()
Local el = GetTimer(1)
DebugPrint("Elapsed: " .. el .. "ms, Avarage:" .. Int(el/loops*100)/100)
;--------------------------------
DebugPrompt("HIT ENTER TO CLOSE")

Re: Clarifications about the new renderer (HW9)

Posted: Tue Apr 13, 2021 12:51 pm
by airsoftsoftwair
Allanon wrote: Thu Apr 08, 2021 9:24 am I don't understand if this is the normal behaviour or not :)
It is normal behaviour. The new, Direct2D-based renderer is just a double buffer internally. So for every piece you draw, buffers will be flipped and the whole display will be redrawn. Thus, with your code, for every 50x50 rectangle you draw, the whole display will be redrawn which will of course be slower than the old software renderer which just has to draw 50x50 pixels in that case.

That's why it's recommended to use BeginRefresh() and EndRefresh() with the new Direct2D-based renderer so that you always refresh full frames. For example, let's assume that 50 rectangles make up a single frame and you want to draw 200 frames. Then you do this:

Code: Select all

For Local i = 1 To 200
  BeginRefresh	
  For Local j = 1 To 50
    Local x = Rnd(750)
    Local y = Rnd(550)
    Box(x, y, 50, 50, GetRandomColor())
  Next  
  EndRefresh
Next
This will be much faster because Direct2D will only refresh on EndRefresh() and not on every Box() call. With the new renderer you always have to think in frames, not in individual drawing operations. Drawing as fast as possible with the old software renderer doesn't make too much sense anyway because it draws much faster than the monitor refreshes and than the eye can see. It's only interesting for benchmark purposes but I don't see any practical use in it...

Btw, I have also seen that you benchmark BeginRefresh() and EndRefresh() with the old software renderer but that doesn't make any sense because the software renderer doesn't support BeginRefresh() and EndRefresh() because it will always draw immediately.

Hope this clarifies some things!

Re: Clarifications about the new renderer (HW9)

Posted: Wed Apr 14, 2021 11:09 am
by Allanon
Oh yes, thank you very much, now I have a clearer picture :)