Hi, Grisu. Like I said, I tried each bit individually. All of the time is being lost to the Flip command. As to what you said about keeping math out of the function, I agree with you. The above function was generated by a tool I was using.
tonyg, I'll add some test code to this post. In the meantime, I've narrowed down the problem.
I am using event hooks and a single timer to refresh the canvases. Everything seems OK at 10 or 20, but as I creep the refresh timer up, the problem starts to appear. Around 65-70, the window becomes unresponsive to any events and the time taken to draw the canvases starts leaping up.
My first thought was that the timer was just firing too often and the drawing was hogging all the resources. I thought maybe the draw operation were getting stacked on top of one another - a second one starting before the first finished - but I added a "lock" to my logic loop, so the drawing function would not run again if it hadn't completed the last time, and it had no effect.
I have a sneaking suspicion I am doing something really obvious and really stupid, and that this is all refresh-rate related, somehow. Especially since my desktop refresh rate is at 75 and the draw time in the code below settles on 13-14ms as the timer Hz are increased, which seems like a bit much for coincidence.
Here's some hastily thrown together source code:
SuperStrict
Import maxgui.drivers
SetGraphicsDriver(GLMax2DDriver())
Global MainWindow:TGadget
MainWindow = CreateWindow:TGadget("Logic_Gui", 220, 155, 830, 629, Null,
WINDOW_TITLEBAR | WINDOW_RESIZABLE | WINDOW_MENU | WINDOW_STATUS | WINDOW_CLIENTCOORDS)
Global Canvas1:TGadget
Canvas1 = CreateCanvas:TGadget(2, 2, 300, 216, MainWindow, Null)
Global Canvas2:TGadget
Canvas2 = CreateCanvas:TGadget(518, 2, 300, 216, MainWindow, Null)
AddHook(EmitEventHook, HookHandler)
Global Which:Byte = 0
Global OneCanvas:Int = 0
Global TimeTakenSingle:Int = 0
Global TimeTakenDouble:Int = 0
Global DrawTimer:TTimer = CreateTimer(100)
While (WaitEvent() <> EVENT_WINDOWCLOSE)
Wend
Function HookHandler:Object(iId:Int, tData:Object, tContext:Object)
Local Event:TEvent = TEvent(TData)
Select Event.id
Case EVENT_TIMERTICK
Select Event.source
Case DrawTimer
Select Which & 1
Case True
Local s:Int = MilliSecs()
SetGraphics(CanvasGraphics(Canvas1))
Flip 0
SetGraphics(CanvasGraphics(Canvas2))
Cls
DrawText("Both canvases drawn in " + TimeTakenDouble + "ms.", 10, 60)
Flip 0
TimeTakenDouble = MilliSecs() - s
Which:~ 1
Return Null
Case False
Local s:Int = MilliSecs()
SetGraphics(CanvasGraphics(Canvas1))
Cls
DrawText("One canvas drawn in " + TimeTakenSingle + "ms.", 10, 60)
Flip 0
TimeTakenSingle = MilliSecs() - s
Which:~ 1
Return Null
End Select
End Select
End Select
Return TData
End Function
Two things to note: 1) The timer refresh rate is really half of what it says, since every other loop draws a single canvas instead of both canvases. 2) There is a point between working smoothly and failing entirely as you push up the timer refresh rate where the draw time is high for the first 2-6 seconds of program execution, then settles down to a more reasonable rate. I tried throwing a "sleep" in before starting the timer, but it did nothing.
One other odd symptom: clicking (and/or holding) down a mouse button on the title bar causes a big spike in draw times when drawing two canvases, but not when only drawing one.
On my computer, total meltdown is achieved somewhere around 140 ticks/second. I need to be able to reliably refresh at around 60Hz for the application I have in mind. I could probably get things semi-working by only redrawing the canvases when they are "dirty", but a timer simplifies things for me, especially since the dirty canvases can come in big groups.
|