Canvas.Copy is taking too long to complete
David McFarlane
mcfarla9 at msu.edu
Wed Apr 24 13:44:46 UTC 2013
Hmm. I explored this issue myself three years ago, using EP1 (still my
favorite version for this type of exploration). I just dug up my test
program and ran it again on my trusty old XP laptop at home after
breakfast, and got times of 0.22 ms even for full screen copies, much as
I remember from before (where full screen means 1024 x 768; and yes,
that is less than a millisecond). To be sure, here is the core of my
test code:
t0 = clock.readmicrosec
dcnvs.copy cnvs
dt = clock.readmicrosec - t0
msgbox format$( dt/1000, "Standard" ) & " ms"
where all variables are defined and initialized earlier as expected
(dcnvs is set to Display.Canvas just for notational convenience).
Also, I looked at the Canvas.Copy topic in the E-Basic Help -- no
evidence that .Copy includes an implicit Display.WaitForVerticalBlank,
to the contrary, the code example there includes an explicit
Display.WaitForVerticalBlank just before the cnvs.Copy. I would be
*extremely* surprised if Canvas.Copy included a
Display.WaitForVerticalBlank, as that would greatly compromise its
utility (e.g., when wanting to Copy several segments to an offscreen
Canvas before copying the complete result to Display.Canvas).
So I do not know how to account for your results. Mind you, I did all
my tests using good-old EP1 with 1024x768 display resolution. For all I
know things changed with the latest EP version, or things get slower
with larger display resolutions. What EP version do you use? What
display resolution?
Michiel, I am especially puzzled by your results. Both of your tests
measure the total time to perform a Canvas.Copy and
Display.WaitForVerticalBlank, only in different orders. So you should
get the same time for both tests, regardless of whether Canvas.Copy
includes its own Display.WaitForVerticalBlank. What am I missing?
Nevertheless, Michiel's advice still stands -- as long as your program
does everything it needs to do within one screen refresh (and assuming
that you *do* synchronize visual displays to the screen refresh, as you
should), then that is good enough.
-----
David McFarlane
E-Prime training online:
http://psychology.msu.edu/Workshops_Courses/eprime.aspx
Twitter: @EPrimeMaster (twitter.com/EPrimeMaster)
/-----------
Stock reminder: 1) I do not work for PST. 2) PST's trained staff take
any and all questions at
http://support.pstnet.com/e%2Dprime/support/login.asp , and they strive
to respond to all requests in 24-48 hours, so make full use of it. 3)
In addition, PST takes questions at their Facebook page
(http://www.facebook.com/pages/Psychology-Software-Tools-Inc/241802160683
), and offers several instructional videos there and on their YouTube
channel (http://www.youtube.com/user/PSTNET ) (no Twitter feed yet,
though). 4) If you do get an answer from PST staff, please extend the
courtesy of posting their reply back here for the sake of others.
\-----------
Cognitology wrote:
> Hi,
>
> A quick look, but I think that you pretty much nailed it: it can take
> quite long to do any canvas operation. Given that your screen refresh
> rate presumably isn’t more than 100 Hz (and in any ways, your foveal
> vision isn’t), I don’t see the problem? Indeed, if you were to draw many
> things to the main canvas, one after the other, then indeed, it gets to
> be a problem, but as long as the only operation is copying a “preloaded”
> canvas to the shown one, it doesn’t matter all that much. Notice, given
> that you’re not using E-Prime’s stimdisplays, it’s not clear at what
> time the stimulus is actually displayed – only when it’s done sending
> the command. I think it’s generally better for critical timing aspects
> of your experiment to avoid canvas as much as possible. Personally, I
> think “critical timing” is when it concerns a subliminal vs barely
> supraliminal prime or some such, for other types of stimuli the 10 ms of
> (constant, therefore presumably stimulus independent) delay is of
> trivial concern.
>
>
>
> Just testing some of it myself, and I get values ranging between 15 and
> 17 – which is funny, given that my refresh rate is indeed 60, so it
> seems a bit like there’s some sort of display.waitforverticalblank built
> into canvas.copy. Curiously, this:
>
> For j = 1 To 100
>
> DrawFixation ‘this is just a custom function drawing a line to
> cnvsnext
>
> cnvs.copy cnvsnext
>
> display.waitforverticalblank
>
> debug.print clock.read - clocktime
>
> clocktime = clock.read
>
> Next j
>
>
>
> Gives me latencies equal to refresh rates (+- 1 ms).
>
> Whereas:
>
>
>
> For j = 1 To 100
>
> DrawFixation ‘this is just a custom function drawing a line to
> cnvsnext
>
> display.waitforverticalblank
>
> cnvs.copy cnvsnext
>
> debug.print clock.read - clocktime
>
> clocktime = clock.read
>
> Next j
>
>
>
> Gives me latencies equal to 2xrefresh rates. Somebody with young eyes
> should tell us if the first one doesn’t have cutting-off errors,
> otherwise I’d suggest there might be some sort of waitforverticalblank
> built into canvas.copy.
>
> Best,
>
>
>
> Michiel Sovijärvi-Spapé
>
>
>
> Helsinki Institute for Information Technology
>
> Aalto & University of Helsinki
>
> Finland
>
>
>
>
>
>
>
> BTW: notice that using debug.print also incurs a delay (last measured at
> 0.7 ms).
>
>
>
>
>
> *From:* e-prime at googlegroups.com [mailto:e-prime at googlegroups.com] *On
> Behalf Of *Tamar
> *Sent:* 24. April 2013 08:33
> *To:* e-prime at googlegroups.com
> *Subject:* Canvas.Copy is taking too long to complete
>
>
>
> I'm programming a visual experiment, and suffering from some timing
> issues. It seems that the line presenting the stimuli (canvas.copy) is
> considerably time consuming: 10-12 ms. I can't figure out the cause for
> this delay, and I would appreciate any help...
>
> Here is the relevant piece of code:
>
> ====== in an initializing inline script, at the begining of SessionProc:
> ======
> Set MainCanvas = Display.Canvas
> MainCanvas.fillColor = CColor(background_color)
> MainCanvas.clear
>
> For i = 1 To NumStim
> Set StimCanvases(i) = Display.CreateCanvas
>
> 'define destination rect as center of screen
> destRects(i).Left = Display.XRes/2-stim_w/2
> destRects(i).Top = Display.YRes/2-stim_h/2
> destRects(i).Right = Display.XRes/2+stim_w/2
> destRects(i).Bottom = Display.YRes/2+stim_h/2
>
> 'define source rect as upper left corner
> srcRects(i).Left = 0
> srcRects(i).Top = 0
> srcRects(i).Right = stim_w
> srcRects(i).Bottom = stim_h
>
> 'Load the image file
> StimCanvases(i).LoadImage "Stimuli/" & FileNames(i) & ".bmp"
>
> Next i
>
> ====== in the inline of TrialProc: =======
> Debug.Print "1:" & clock.read
> StartTrialTime = clock.read
> n = c.GetAttrib("CanvasNum")
> c.SetAttrib "TrialStart", StartTrialTime
> display.WaitForVerticalBlank
> Debug.Print "4:" & clock.read
> StartStimTime = clock.read
> c.SetAttrib "StimStart", StartStimTime
> Debug.Print "5:" & clock.read
> mainCanvas.copy StimCanvases(n),srcRects(n),destRects(n)
> Debug.Print "6:" & clock.read
>
>
> I've tried a few things:
> - to create variables taking the values of
> StimCanvases(n),srcRects(n),destRects(n) in the beginning of the trial,
> so the mainCanvas.copy line would not need to approach the arrays.
> - to present other simple canvases instead of my real stimuli (just a
> fixation, for example. or an empty canvas)
> - to draw something on the mainCanvas rather than copy a new canvas to
> it (e.g. mainCanvas.Circle).
>
> All of these takes 10-12 ms! (as calculated by subtracting time5 from
> time6). The only way I managed to get rid of the delay was to erase the
> entire row...
>
> Am I missing something here?...
>
> Thanks,
> Tamar
--
You received this message because you are subscribed to the Google Groups "E-Prime" group.
To unsubscribe from this group and stop receiving emails from it, send an email to e-prime+unsubscribe at googlegroups.com.
To post to this group, send email to e-prime at googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
More information about the Eprime
mailing list