/usr/share/psychtoolbox-3/PsychTests/PerceptualVBLSyncTest.m is in psychtoolbox-3-common 3.0.11.20131230.dfsg1-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | function PerceptualVBLSyncTest(screen, stereomode, fullscreen, doublebuffer, maxduration, vblSync, testdualheadsync)
% PerceptualVBLSyncTest(screen, stereomode, fullscreen, doublebuffer, maxduration, vblSync, testdualheadsync)
%
% Perceptual synchronization test for synchronization of Screen('Flip') and
% Screen('WaitBlanking') to the vertical retrace.
%
% Arguments:
% 'screen' Either a single screen handle, or none (in which case the
% display with the maximum id will be used), or a vector of two handles in
% stereomode 10, e.g., [0 1] if you want to output to screens 0 and 1. You
% can also pass a vector of two screens when stereomode is not set to 10.
% In this case two separate (non-stereo) onscreen windows will be opened on
% both displays and they will get flipped in multiflip mode 2. That means
% that the first display (first element of 'screen') is synced to VBL, but
% the 2nd one is synced to bufferswaps of the first one. This is a
% straightforward test to check if two displays of a stereosetup run with a
% synchronized retrace cycle (good!) or if they are phase-shifted or
% drifting against each other (not good!).
%
% 'stereomode' Which stereomode to use? Defaults to zero, ie. no stereo.
%
% 'fullscreen' Fullscreen presentation? Defaults to 1 ie. yes. In
% non-fullscreen mode, no proper synchronization of bufferswaps can be
% expected.
%
% 'doublebuffer' Single- or double-buffering (1). Defaults to 1. In single
% buffer mode there is no sync to retrace, so this is a good way to
% simulate the tearing artifacts that would happen on sync failure, just to
% get an impression.
%
% 'maxduration' Maximum runtime of test: Runs until keypress or maxduration
% seconds have elapsed (Default is 10 seconds).
%
% 'vblSync' If 1, synchronize bufferswaps to vertical retrace of monitor,
% otherwise (setting 0) swap immediately without sync, ie., usually with tearing.
%
% 'testdualheadsync' If 1, and 'vblSync' is zero, manually wait until the video
% scanout position reaches half the height of the display, then swap. If this
% is done on a multi-display setup and the video scanout cycles of all the
% participating displays are properly synchronized, you should see a "static"
% crack line roughly at half the height of the display, maybe a bit lower. If
% you see a wandering crack line, at least on some displays, or you see vertical
% offsets of the position of the crack line between displays, then the displays
% are not properly synchronized, ie., not suitable for artifact free binocular
% stimulation. Caveat: This logic has been developed and tested specifically
% for testing on Linux with a single X-Screen spanning multiple displays. It may
% or may not be suitable to assess other operating systems or display configurations.
%
% After starting this test, you should see a flickering greyish background
% that flickers in a homogenous way - without cracks or weird moving patterns
% in the flickering area. If you see an imhogenous flicker, this means that
% synchronization of stimulus onset to the vertical retrace doesn't work due
% to some serious bug or limitation of your graphics hardware or its driver.
% If you don't know what this means, you can test this script with parameter
% doublebuffer == 0 to artificially create a synchronization failure.
%
% On many systems you should also see some emerging pattern of yellow horizontal lines.
% These lines should be tightly concentrated/clustered in the topmost area of
% the screen. Lots of yellow lines in the middle or bottom area or even
% randomly distributed lines indicate some bug in the driver of your graphics
% hardware. This is a common problem of all ATI graphics adapters on MacOS-X
% versions earlier than OS-X 10.4.3 when running a dual-display setup...
%
% A second reason for distributed yellow lines could be bad timing on your
% machine, e.g., due to background activity by virus scanners or the Spotlight
% indexing service on OS-X. Turn these off for conducting your studies!
%
% History:
% 01/28/06 mk Written. Replaces the built-in flickertest of Screen('OpenWindow')
% on multi-display setups. That test wasn't well received :(
% Check for presence of OpenGL PTB.
AssertOpenGL;
if nargin < 4
doublebuffer = [];
end
if isempty(doublebuffer)
% Use double-buffered windows by default: Single-buffered ones can't sync to
% retrace and are discouraged anyway. Setting doublebuffer=0 is an easy way
% to reproduce the visual pattern created by a complete sync-failure though.
doublebuffer=1;
end;
doublebuffer=doublebuffer+1;
if nargin < 2
stereomode = [];
end
if isempty(stereomode)
% Use non-stereo display by default.
stereomode=0;
end;
if nargin < 3
fullscreen = [];
end
if isempty(fullscreen)
fullscreen=1;
end;
if nargin < 1
screen = [];
end
if isempty(screen)
if stereomode == 10
screen(1) = max(Screen('Screens')) - 1;
screen(2) = max(Screen('Screens'));
if screen(1)<0
error('Stereomode 10 only works on setups with two attached displays!');
end
else
screen=max(Screen('Screens'));
end
end;
if nargin < 5
maxduration = [];
end
if isempty(maxduration)
maxduration = 10;
end
if nargin < 6
vblSync = [];
end
if isempty(vblSync)
vblSync = 1;
end
if nargin < 7
testdualheadsync = [];
end
if isempty(testdualheadsync)
testdualheadsync = 0;
end
thickness = (1-vblSync) * 4 + 1;
try
if fullscreen
rect1=[];
rect2=[];
else
rect1=InsetRect(Screen('GlobalRect', screen(1)), 1, 0);
if length(screen)>1
rect2=InsetRect(Screen('GlobalRect', screen(2)), 1, 0);
end
end;
help PerceptualVBLSyncTest;
fprintf('Press ENTER key to start the test. The test will stop after 10 seconds\n');
fprintf('or any keypress...\n');
KbStrokeWait;
if stereomode~=10
% Standard case:
[win , winRect]=Screen('OpenWindow', screen(1), 0, rect1, [], doublebuffer, stereomode);
if length(screen)>1
win2 = Screen('OpenWindow', screen(2), 0, rect2, [], doublebuffer, stereomode);
end
else
% Special case for dual-window stereo:
% Setup master window:
[win , winRect]=Screen('OpenWindow', screen(1), 0, rect1, [], doublebuffer, stereomode);
% Setup slave window:
Screen('OpenWindow', screen(2), 0, rect2, [], doublebuffer, stereomode);
end
flickerRect = InsetRect(winRect, 100, 0);
color = 0;
deadline = GetSecs + maxduration;
beampos=0;
ifi = Screen('GetFlipInterval', win);
VBLTimestamp = Screen('Flip', win, 0, 2);
while (~KbCheck) && (GetSecs < deadline)
% Draw left eye view (if stereo enabled):
Screen('SelectStereoDrawBuffer', win, 0);
% Draw alternating black/white rectangle:
Screen('FillRect', win, color, flickerRect);
% If beamposition is available (on OS-X), visualize it via yellow horizontal line:
if (beampos>=0), Screen('DrawLine', win, [255 255 0], 0, beampos, winRect(3), beampos, thickness); end;
% Same for right-eye view...
Screen('SelectStereoDrawBuffer', win, 1);
Screen('FillRect', win, color, flickerRect);
if (beampos>=0), Screen('DrawLine', win, [255 255 0], 0, beampos, winRect(3), beampos, thickness); end;
if stereomode == 0 && length(screen)>1
Screen('FillRect', win2, color, flickerRect);
Screen('DrawingFinished', win2, 0, 2);
Screen('DrawingFinished', win, 0, 2);
multiflip = 2;
else
multiflip = 0;
end
% Alternate drawing color from white -> black, or black -> white
color=255 - color;
if doublebuffer>1
if vblSync
% Flip buffer on next vertical retrace, query rasterbeam position on flip, if available:
[VBLTimestamp, StimulusOnsetTime, FlipTimestamp, Missed, beampos] = Screen('Flip', win, VBLTimestamp + ifi/2, 2, [], multiflip);
else
if testdualheadsync == 1
Screen('DrawingFinished', win, 0, 1);
beampos = -1000;
while abs(beampos - winRect(4)/2) > 5
beampos = Screen('GetWindowInfo', win, 1);
end
end
% Flip immediately without sync to vertical retrace, do clear
% backbuffer after flip for visualization purpose:
VBLTimestamp = Screen('Flip', win, VBLTimestamp + ifi/2, 0, 2, multiflip);
% Above flip won't return a 'beampos' in non-VSYNC'ed mode,
% so we query it manually:
beampos = Screen('GetWindowInfo', win, 1);
% Throttle a little bit for visualization purpose:
WaitSecs('YieldSecs', 0.005);
end
else
% Just wait a bit in non-buffered case:
pause(0.001);
end;
end;
Screen('CloseAll');
return;
catch
Screen('CloseAll');
end;
|