~ubuntu-branches/ubuntu/trusty/psychtoolbox-3/trusty-proposed

« back to all changes in this revision

Viewing changes to Psychtoolbox/PsychTests/VBLSyncTest.m

  • Committer: Package Import Robot
  • Author(s): Yaroslav Halchenko
  • Date: 2013-11-19 23:34:50 UTC
  • mfrom: (3.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20131119233450-f7nf92vb8qavjmk8
Tags: 3.0.11.20131017.dfsg1-3
Upload to unsable since fresh glew has arrived to sid!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
function VBLSyncTest(n, numifis, loadjitter, clearmode, stereo, flushpipe, synchronous)
2
 
% VBLSyncTest(n, numifis, loadjitter, clearmode, stereo, flushpipe, synchronous)
 
1
function VBLSyncTest(n, numifis, loadjitter, clearmode, stereo, flushpipe, synchronous, usedpixx)
 
2
% VBLSyncTest(n, numifis, loadjitter, clearmode, stereo, flushpipe, synchronous, usedpixx)
3
3
%
4
4
% Tests syncing of PTB-OSX to the vertical retrace (VBL) and demonstrates
5
5
% how to implement the old Screen('WaitBlanking') behaviour with
90
90
% compatible stereo display hardware, e.g., CrystalEyes shutter glasses.
91
91
%
92
92
%
93
 
%
94
93
% flushpipe = Mark end of drawing commands to improve presentation timing.
95
94
% PTB knows a new command Screen('DrawingFinished') which, when properly used,
96
95
% will give PTB hints on how to optimize drawing of stimuli: This allows to draw
106
105
% but degrades performance significantly in real experiments.
107
106
%
108
107
%
 
108
% usedpixx = 1 Use a DataPixx/ViewPixx/ProPixx device for external
 
109
% timestamping of stimulus onset, as a correctness test for Screen('Flip')
 
110
% timestamping. Disabled (0) by default.
 
111
%
 
112
%
109
113
% EXAMPLES:
110
114
%
111
115
% VBLSyncTest(1000, 0, 0.6, 0, 0, 1, 0) -- Render 1000 consecutive frames,
199
203
 
200
204
%%% VBLSyncTest(1000, 0, 0.6, 0, 0, 1, 0)
201
205
 
202
 
if nargin < 1
 
206
if nargin < 1 || isempty(n)
203
207
    n = 600;
204
208
end
205
209
 
206
 
if nargin < 2
 
210
if nargin < 2 || isempty(numifis)
207
211
    numifis = 1;
208
212
end
209
213
 
210
 
if nargin < 3
 
214
if nargin < 3 || isempty(loadjitter)
211
215
    loadjitter = 0;
212
216
end
213
217
 
214
 
if nargin < 4
 
218
if nargin < 4 || isempty(clearmode)
215
219
    clearmode = 0;
216
220
end
217
221
 
218
 
if nargin < 5
 
222
if nargin < 5 || isempty(stereo)
219
223
    stereo = 0;
220
224
end
221
225
 
222
 
if nargin < 6
 
226
if nargin < 6 || isempty(flushpipe)
223
227
    flushpipe = 0;
224
228
end
225
229
 
226
 
if nargin < 7
 
230
if nargin < 7 || isempty(synchronous)
227
231
    synchronous = 0;
228
232
end
229
233
 
 
234
if nargin < 8 || isempty(usedpixx)
 
235
    usedpixx = 0;
 
236
end
 
237
 
230
238
try
231
239
        % This script calls Psychtoolbox commands available only in OpenGL-based 
232
240
        % versions of the Psychtoolbox. (So far, the OS X Psychtoolbox is the
234
242
        % an error message if someone tries to execute this script on a computer without
235
243
        % an OpenGL Psychtoolbox
236
244
        AssertOpenGL;
237
 
        
 
245
    
 
246
    if IsWin && 0
 
247
        % Enforce use of DWM on Windows-Vista and later: This simulates the
 
248
        % situation of Windows-8 or later on Windows-Vista and Windows-7:
 
249
        Screen('Preference','ConserveVRAM', 16384); % Force use of DWM.
 
250
    end
 
251
    
238
252
        % Get the list of Screens and choose the one with the highest screen number.
239
253
        % Screen 0 is, by definition, the display with the menu bar. Often when 
240
254
        % two monitors are connected the one without the menu bar is used as 
241
 
        % the stimulus display.  Chosing the display with the highest dislay number is 
 
255
        % the stimulus display.  Chosing the display with the highest display number is 
242
256
        % a best guess about where you want the stimulus displayed.  
243
257
        screens=Screen('Screens');
244
258
        screenNumber=max(screens);
249
263
 
250
264
    % Open double-buffered window: Optionally enable stereo output if
251
265
    % stereo == 1.
252
 
    w=Screen('OpenWindow',screenNumber, 0,[],32,2, stereo);
 
266
    PsychImaging('PrepareConfiguration')
 
267
    if usedpixx
 
268
        % Use DataPixx for external timestamping for quick basic correctness
 
269
        % tests.
 
270
        PsychImaging('AddTask', 'General', 'UseDataPixx');
 
271
    end
 
272
    w=PsychImaging('OpenWindow',screenNumber, 0,[],[],[], stereo);
253
273
    
254
274
    % Query effective stereo mode, as Screen() could have changed it behind our
255
275
    % back, e.g., if we asked for mode 1 but Screen() had to fallback to
307
327
    td=ts;
308
328
    so=ts;
309
329
    tSecondary = ts;
 
330
    sodpixx = ts;
310
331
    
311
332
    % Compute random load distribution for provided loadjitter value:
312
333
    wt=rand(1,n)*(loadjitter*ifi);
346
367
            tdeadline=0;
347
368
        end;
348
369
        
 
370
        if usedpixx
 
371
            % Ask for a Datapixx onset timestamp for next 'Flip':
 
372
            PsychDataPixx('LogOnsetTimestamps', 1);
 
373
        end
 
374
        
349
375
        % Flip: The clearmode argument specifies if flip should clear the
350
376
        % drawing buffer after flip (=0 - default), keep it "as is"
351
377
        % for incremental drawing/updating of stims (=1) or don't do
363
389
        % beampos > screen height means that flip returned during the VBL
364
390
        % interval. Small values << screen height are also ok,
365
391
        % they just indicate either a slower machine or some types of flat-panels...
366
 
        [ tvbl so(i) flipfin(i) missest(i) beampos(i)]=Screen('Flip', w, tdeadline, clearmode);
 
392
        if usedpixx && IsOctave
 
393
            % Workaround for Datapixx + Octave bug in January 2013 ptb:
 
394
            tvbl = Screen('Flip', w, tdeadline, clearmode);
 
395
            so(i) = tvbl;
 
396
        else
 
397
            [ tvbl so(i) flipfin(i) missest(i) beampos(i)]=Screen('Flip', w, tdeadline, clearmode);
 
398
        end
367
399
 
368
 
        % Special code for debugging: Disabled by default - Not for pure
 
400
        if usedpixx
 
401
            % Ask for a Datapixx onset timestamp from last 'Flip':
 
402
            [boxTime, sodpixx(i)] = PsychDataPixx('GetLastOnsetTimestamp'); %#ok<ASGLU>
 
403
        end
 
404
        
 
405
        % Special code for DWM debugging: Disabled by default - Not for pure
369
406
        % mortals!
370
 
        if IsWin & 0 %#ok<AND2>
 
407
        tSecondary(i) = 0;
 
408
        if IsWin && 0
371
409
                        while 1
372
 
                                winfo = Screen('GetWindowInfo', w); %#ok<NASGU>
373
 
                %                               fprintf('QUERY %i : t = %0.10f  : LastVBL = %0.10f  : VBLCount = %i\n', i, GetSecs, winfo.LastVBLTime, winfo.VBLCount);
374
 
                                wdminfo = Screen('GetWindowInfo', w, 2) %#ok<NOPRT>
375
 
                                
 
410
                WaitSecs('YieldSecs', 0.001);
 
411
                                wdminfo = Screen('GetWindowInfo', w, 2);
376
412
 
377
 
                                if isstruct(wdminfo)
378
 
                                        if (i > 1) && (tSecondary(i-1) == wdminfo.OnsetVBLTime)
379
 
                        %                                               fprintf('DELAYED: %i %0.10f \n', i, wdminfo.OnsetVBLTime);
380
 
                                                continue;
381
 
                                        else
382
 
                                                if (i>1)
383
 
                                                        %fprintf('---> tnew - told = %0.10f \n', wdminfo.OnsetVBLTime - tSecondary(i-1));
384
 
                                                end
385
 
                                        end
386
 
                                        tSecondary(i) = wdminfo.OnsetVBLTime;                                   
387
 
                                        break;
388
 
                                else
389
 
                                        tSecondary(i) = 0;
390
 
                                        break;
391
 
                                end
 
413
                if ~isstruct(wdminfo)
 
414
                    break;
 
415
                end
 
416
                
 
417
                if wdminfo.cDXPresentConfirmed == wdminfo.cDXPresentSubmitted
 
418
                    tSecondary(i) = wdminfo.qpcVBlank - ((wdminfo.cDXRefresh - wdminfo.cDXRefreshConfirmed) * wdminfo.qpcRefreshPeriod);
 
419
                    tvbl = tSecondary(i);
 
420
                    so(i) = tSecondary(i);
 
421
                    break;
 
422
                end
392
423
                        end
393
 
        else
394
 
            tSecondary(i) = 0;            
395
424
        end
396
425
        
397
426
        % Record timestamp for later use:
445
474
    % Close display: If we skipped/missed any presentation deadline during
446
475
    % Flip, Psychtoolbox will automatically display some warning message on the Matlab
447
476
    % console:
448
 
    Screen('CloseAll');
 
477
    sca;
449
478
    
450
479
    % Plot all our measurement results:
451
480
 
510
539
                fprintf('Average discrepancy between DWM and beamposition timestamping is %f msecs, stddev = %f msecs.\n', mean((tSecondary - so) * 1000), std((tSecondary - so) * 1000));
511
540
    end
512
541
    
 
542
    if usedpixx
 
543
        figure;
 
544
        plot((so - sodpixx) * 1000);
 
545
        title('Time delta in msecs onset according to Flip - onset according to DataPixx:');
 
546
                fprintf('Average discrepancy between Flip timestamping and DataPixx is %f msecs, stddev = %f msecs.\n', mean((so - sodpixx) * 1000), std((so - sodpixx) * 1000));        
 
547
    end
 
548
    
513
549
    % Count and output number of missed flip on VBL deadlines:
514
550
    numbermisses=0;
 
551
    numberearly=0;
 
552
    
515
553
    if numifis > 0
516
554
        if (stereo == 11) && (numifis == 1)
517
555
            % Special case: Stereomode 11 can't do better than one swap
522
560
        for i=2:n
523
561
            if (ts(i)-ts(i-1) > ifi*(numifis+0.5))
524
562
                numbermisses=numbermisses+1;
525
 
            end;
526
 
        end;
 
563
            end
 
564
            
 
565
            if (ts(i)-ts(i-1) < ifi*(numifis-0.5))
 
566
                numberearly=numberearly+1;
 
567
            end
 
568
        end
527
569
    else
528
570
        if stereo == 11
529
571
            % Special case: Stereomode 11 can't do better than one swap
534
576
        for i=2:n
535
577
            if (ts(i)-ts(i-1) > ifi*1.5)
536
578
                numbermisses=numbermisses+1;
537
 
            end;
538
 
        end;
539
 
    end;
 
579
            end
 
580
                        
 
581
            if (ts(i)-ts(i-1) < ifi*(numifis-0.5))
 
582
                numberearly=numberearly+1;
 
583
            end
 
584
        end
 
585
    end
540
586
 
541
587
    % Output some summary and say goodbye...
542
588
    fprintf('PTB missed %i out of %i stimulus presentation deadlines.\n', numbermisses, n);
543
589
    fprintf('One missed deadline is ok and an artifact of the measurement.\n');
 
590
    
 
591
    fprintf('PTB completed %i stimulus presentations before the requested target time.\n', numberearly);
 
592
    if numberearly > 0
 
593
        fprintf('CAUTION: Completing flips too early should *never ever happen*! Your system has\n');
 
594
        fprintf('CAUTION: a serious bug or misconfiguration in its graphics driver!!!\n');
 
595
    end
544
596
    fprintf('Have a look at the plots for more details...\n');
545
597
    
546
598
    % Done.
547
 
catch
 
599
catch %#ok<*CTCH>
548
600
    % This "catch" section executes in case of an error in the "try" section
549
601
    % above. Importantly, it closes the onscreen window if its open and
550
602
    % shuts down realtime-scheduling of Matlab:
551
 
    Screen('CloseAll');
 
603
    sca;
 
604
    
552
605
    % Disable realtime-priority in case of errors.
553
606
    Priority(0);
554
607
    psychrethrow(psychlasterror);