On the machine I tested that on it just like the cache, on two other machines it doesn't like the cache. Hit and miss, I eat my words and apologize.
Code: Select all
Structure Vector2:x.f:y.f:EndStructure
Procedure AddPathSpline(Array po.Vector2(1),Flags=0,roundness.f=0.5)
Protected n,i,close,coef.f=roundness/3
Protected.Vector2 b0,b1,b2,b3,c
n=ArraySize(po())+2
Dim p.Vector2(n)
If flags=#PB_Path_Relative:c\x=PathCursorX():c\y=PathCursorY():EndIf
For i=0 To n-2:p(i+1)\x=po(i)\x+c\x:p(i+1)\y=po(i)\y+c\y:Next
If p(n-1)\X = p(1)\X And p(n-1)\Y = p(1)\Y:close=1: p(0) = p(n-2): p(n) = p(2):Else:p(0) = p(2):p(n) = p(n-2):EndIf
MovePathCursor(p(1)\x,p(1)\y)
For i=1 To n-2
b0=p(i)
b3=p(i+1)
b1\x=b0\x+coef*(b3\x-p(i-1)\x)
b1\y=b0\y+coef*(b3\y-p(i-1)\y)
b2\x=b3\x-coef*(p(i+2)\x-b0\x)
b2\y=b3\y-coef*(p(i+2)\y-b0\y)
AddPathCurve(b1\x,b1\y, b2\x,b2\y, b3\x,b3\y)
Next
If close:ClosePath():EndIf
EndProcedure
Global Dim CosLookup.f(7)
Global Dim SinLookup.f(7)
Global Dim AngleOffset.f(7)
Procedure SetupTables()
Protected i.i, a.f
For i = 0 To 7
a = i * 2 * #PI / 8
CosLookup(i) = Cos(a)
SinLookup(i) = Sin(a)
AngleOffset(i) = i * 15
Next
EndProcedure
Global Dim p.Vector2(8)
Global TestDuration.i = 5000 ; 5 seconds
Global.i event, i
Global.f b, r, a
; -------------------------------------------
; --- TEST 1: ORIGINAL MATH (Full Vector Draw)
; -------------------------------------------
Procedure.i RunOriginalTest()
Protected Frames.i = 0
Protected.q StartTime, EndTime, CurrentTime, Frequency
QueryPerformanceFrequency_(@Frequency.q)
QueryPerformanceCounter_(@StartTime.q)
EndTime.q = StartTime + (TestDuration * Frequency / 1000)
Repeat
b + 0.04
For i=0 To 7
a.f=i*2*#PI/8
r=200+Sin(b+i*15)*50
p(i)\x=Cos(a)*r+300
p(i)\y=Sin(a)*r+300
Next
p(8)=p(0)
StartDrawing(CanvasOutput(0)):Box(0,0,600,400,$ff8888):StopDrawing()
StartVectorDrawing(CanvasVectorOutput(0))
AddPathSpline(p())
VectorSourceColor($ff000000):StrokePath(2)
StopVectorDrawing()
Frames + 1
event = WindowEvent()
QueryPerformanceCounter_(@CurrentTime.q)
Until CurrentTime > EndTime Or event = #PB_Event_CloseWindow
ProcedureReturn Frames
EndProcedure
; -------------------------------------------
; --- TEST 2: OPTIMIZED MATH (Full Vector Draw)
; -------------------------------------------
Procedure.i RunOptimizedTest()
Protected Frames.i = 0
Protected.q StartTime, EndTime, CurrentTime, Frequency
SetupTables()
QueryPerformanceFrequency_(@Frequency.q)
QueryPerformanceCounter_(@StartTime.q)
EndTime.q = StartTime + (TestDuration * Frequency / 1000)
Repeat
b + 0.04
For i=0 To 7
r = 200 + Sin(b + AngleOffset(i)) * 50
p(i)\x = CosLookup(i) * r + 300
p(i)\y = SinLookup(i) * r + 300
Next
p(8)=p(0)
StartDrawing(CanvasOutput(0)):Box(0,0,600,400,$ff8888):StopDrawing()
StartVectorDrawing(CanvasVectorOutput(0))
AddPathSpline(p())
VectorSourceColor($ff000000):StrokePath(2)
StopVectorDrawing()
Frames + 1
event = WindowEvent()
QueryPerformanceCounter_(@CurrentTime.q)
Until CurrentTime > EndTime Or event = #PB_Event_CloseWindow
ProcedureReturn Frames
EndProcedure
; -------------------------------------------
; --- TEST 3: OPTIMIZED MATH (Minimal Draw)
; -------------------------------------------
Procedure.i RunMinimalOptimizedTest()
Protected Frames.i = 0
Protected.q StartTime, EndTime, CurrentTime, Frequency
SetupTables()
QueryPerformanceFrequency_(@Frequency.q)
QueryPerformanceCounter_(@StartTime.q)
EndTime.q = StartTime + (TestDuration * Frequency / 1000)
Repeat
b + 0.04
For i=0 To 7
r = 200 + Sin(b + AngleOffset(i)) * 50
p(i)\x = CosLookup(i) * r + 300
p(i)\y = SinLookup(i) * r + 300
Next
p(8)=p(0)
StartDrawing(CanvasOutput(0))
Box(0,0,600,400,$ff8888)
FrontColor($ff0000ff)
For i = 0 To 7
Plot(p(i)\x, p(i)\y)
Next
StopDrawing()
Frames + 1
event = WindowEvent()
QueryPerformanceCounter_(@CurrentTime.q)
Until CurrentTime > EndTime Or event = #PB_Event_CloseWindow
ProcedureReturn Frames
EndProcedure
; -------------------------------------------
; --- TEST 4: ORIGINAL MATH (Minimal Draw)
; -------------------------------------------
Procedure.i RunMinimalOriginalTest()
Protected Frames.i = 0
Protected.q StartTime, EndTime, CurrentTime, Frequency
QueryPerformanceFrequency_(@Frequency.q)
QueryPerformanceCounter_(@StartTime.q)
EndTime.q = StartTime + (TestDuration * Frequency / 1000)
Repeat
b + 0.04
For i=0 To 7
a.f=i*2*#PI/8
r=200+Sin(b+i*15)*50
p(i)\x=Cos(a)*r+300
p(i)\y=Sin(a)*r+300
Next
p(8)=p(0)
StartDrawing(CanvasOutput(0))
Box(0,0,600,400,$ff8888)
FrontColor($ff0000ff)
For i = 0 To 7
Plot(p(i)\x, p(i)\y)
Next
StopDrawing()
Frames + 1
event = WindowEvent()
QueryPerformanceCounter_(@CurrentTime.q)
Until CurrentTime > EndTime Or event = #PB_Event_CloseWindow
ProcedureReturn Frames
EndProcedure
; -------------------------------------------
; --- MAIN BENCHMARK
; -------------------------------------------
Procedure LogMessage(text.s)
Protected ExistingText.s = GetGadgetText(1)
SetGadgetText(1, ExistingText + text.s + #CRLF$)
EndProcedure
OpenWindow(0, 0, 0, 600, 600, "Benchmark", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 600, 400)
EditorGadget(1, 0, 400, 600, 200, #PB_Editor_ReadOnly)
CompilerIf #PB_Compiler_Debugger
LogMessage("BENCHMARK DISABLED")
LogMessage("")
LogMessage("The PureBasic debugger is active.")
LogMessage("Please create a standalone .exe and run the")
LogMessage("file directly to get accurate performance results.")
CompilerElse
LogMessage("--- RUNNING BENCHMARK (5 SECONDS EACH) ---")
LogMessage(" ")
Define OriginalFrames.i = RunOriginalTest()
LogMessage("1. ORIGINAL MATH (Full Vector Draw):")
LogMessage(" Total Frames: " + OriginalFrames)
LogMessage(" Average FPS: " + StrF(OriginalFrames / (TestDuration / 1000)))
Define OptimizedFrames.i = RunOptimizedTest()
LogMessage(" ")
LogMessage("2. OPTIMIZED MATH (Full Vector Draw):")
LogMessage(" Total Frames: " + OptimizedFrames)
LogMessage(" Average FPS: " + StrF(OptimizedFrames / (TestDuration / 1000)))
Define MinimalFrames.i = RunMinimalOptimizedTest()
LogMessage(" ")
LogMessage("3. OPTIMIZED MATH (Minimal Draw):")
LogMessage(" Total Frames: " + MinimalFrames)
LogMessage(" Average FPS: " + StrF(MinimalFrames / (TestDuration / 1000)))
Define MinimalOriginalFrames.i = RunMinimalOriginalTest()
LogMessage(" ")
LogMessage("4. ORIGINAL MATH (Minimal Draw):")
LogMessage(" Total Frames: " + MinimalOriginalFrames)
LogMessage(" Average FPS: " + StrF(MinimalOriginalFrames / (TestDuration / 1000)))
LogMessage(" ")
LogMessage("--- TEST COMPLETE ---")
LogMessage("Benchmark finished. Close the window to exit.")
CompilerEndIf
Repeat
event = WaitWindowEvent()
Until event = #PB_Event_CloseWindow