Clarifications about the new renderer (HW9)

Report any Hollywood bugs here
Post Reply
User avatar
Allanon
Posts: 732
Joined: Sun Feb 14, 2010 7:53 pm
Location: Italy
Contact:

Clarifications about the new renderer (HW9)

Post 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")
User avatar
airsoftsoftwair
Posts: 5425
Joined: Fri Feb 12, 2010 2:33 pm
Location: Germany
Contact:

Re: Clarifications about the new renderer (HW9)

Post 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!
User avatar
Allanon
Posts: 732
Joined: Sun Feb 14, 2010 7:53 pm
Location: Italy
Contact:

Re: Clarifications about the new renderer (HW9)

Post by Allanon »

Oh yes, thank you very much, now I have a clearer picture :)
Post Reply