Page 1 of 1
Slow StartDrawing
Posted: Tue Nov 15, 2011 12:14 am
by Polo
Hello,
Here's a code to point out something rather annoying:
Code: Select all
If OpenWindow(0, 0, 0, 460, 400, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
canvas = CanvasGadget(#PB_Any , 10, 10, 380, 380, #PB_Canvas_ClipMouse)
t=ElapsedMilliseconds()
For i = 0 To 1000
StartDrawing(CanvasOutput(canvas))
StopDrawing()
Next
t2 = ElapsedMilliseconds() - t
MessageRequester("",Str(t2))
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
It doesn't do anything of course, however the start/end drawing takes 1500 milliseconds on my Mac. If i swap to ImageOutput with an image, it then takes 300 milliseconds.
It makes no sense to do 1000 Start/EndDrawing here, but my code is using several Start/endrawing to get the text width and lenght, and is very slow when parsing 1000 lines because of what I shown before.
Why is it taking 1.5 seconds to do nothing? Why is it slower than when using an image?
Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 3:09 am
by Demivec
Polo wrote:It doesn't do anything of course, however the start/end drawing takes 1500 milliseconds on my Mac. If i swap to ImageOutput with an image, it then takes 300 milliseconds.
It is my understanding that the CanvasGadget is double buffered. The ImageGagdet isn't double-buffered and so it makes sense that it would be faster.
Polo wrote:It makes no sense to do 1000 Start/EndDrawing here, but my code is using several Start/endrawing to get the text width and lenght, and is very slow when parsing 1000 lines because of what I shown before.
Whenever possible it is wise to combine operations that require Start/EndDrawing together so that any unnecessary delays are prevented.
Here's a
link that may prove useful.
Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 7:38 am
by Danilo
Code: Select all
If OpenWindow(0, 0, 0, 460, 400, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
canvas = CanvasGadget(#PB_Any , 10, 10, 380, 380, #PB_Canvas_ClipMouse)
Dim sizes(1000)
t=ElapsedMilliseconds()
If StartDrawing(CanvasOutput(canvas))
For i = 0 To 1000
sizes(i) = TextWidth(Space(i)+"abcdfefhhhkhkh")
Next
StopDrawing()
EndIf
t2 = ElapsedMilliseconds() - t
MessageRequester("",Str(t2))
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 9:33 am
by Polo
Demivec wrote:Polo wrote:It doesn't do anything of course, however the start/end drawing takes 1500 milliseconds on my Mac. If i swap to ImageOutput with an image, it then takes 300 milliseconds.
It is my understanding that the CanvasGadget is double buffered. The ImageGagdet isn't double-buffered and so it makes sense that it would be faster.
Drawing to an image doesn't use the ImageGadget

Can't use your code Danilo, if I'm calling StartDrawing many times it means it can't really be avoided! Although using a 1x1 image did the trick, my code is much faster now.
Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 12:16 pm
by Perkin
@Polo, - don't know whether it would be faster or not - can you just create an array of sizes for each individual character, which you fill in an initialising procedure, then when you need the width of a specific string, simply loop through each character and add the saved widths together?
You then shouldn't need all the StartDrawing/StopDrawing
EDIT: you should be able to speed this up as well.
Code: Select all
If OpenWindow(0, 0, 0, 460, 400, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
canvas = CanvasGadget(#PB_Any , 10, 10, 380, 380, #PB_Canvas_ClipMouse)
Dim SWid.l(255)
If StartDrawing(CanvasOutput(canvas))
For i = 32 To 127
SWid(i) = TextWidth(Chr(i))
Next
StopDrawing()
EndIf
t=ElapsedMilliseconds()
For i = 0 To 1000
dum.s=Space(i)+"abcdfefhhhkhkh"
res.l=0
For j=0 To Len(dum)-1
res+SWid(PeekC(@dum+j))
Next
Next
t2 = ElapsedMilliseconds() - t
MessageRequester("",Str(t2))
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 12:51 pm
by Perkin
As long as the text you need the width of is ASCII chars 32-127 then this is miles quicker,
change the timed loop to this
Code: Select all
For i = 0 To 1000
dum.s=Space(i)+"abcdfefhhhkhkh"
res.l=0
For j=32 To 127
res+(CountString(dum,Chr(j))*SWid(j))
Next
Next
Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 12:54 pm
by Polo
Well I'm using several fonts, with several sizes, and several attributes. Not sure I wanna store the data for everything....!
Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 12:55 pm
by Perkin
Ah well now, that makes a difference.
Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 1:08 pm
by Polo
Plus Textwidth("abcdef") will not necessarily returns the same as Textwidth("a")+Textwidth("b") especially with an Italic font, due to a Purebasic bug.
Anyway, using an ImageOutput is quite fast so I'm using that for now

Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 5:15 pm
by Trond
I think the canvas output is slow because on every StopDrawing() it tries to update the display. I'm just guessing here.
Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 5:38 pm
by Polo
Trond wrote:I think the canvas output is slow because on every StopDrawing() it tries to update the display. I'm just guessing here.
You're probably right, it'd explain everything.
Re: Slow StartDrawing
Posted: Tue Nov 15, 2011 7:55 pm
by idle
I think it's because it's preserving the alpha channel in it's drawing routine
which slows it down, you'd be better off doing all your internal drawing into an image
and then draw that to the canvas when it's done.