Problems with Multiflip

Dee’s great tobii toolbox, Titta, allows to open two windows for the subject and the operator during calibration. Recently this functionality has stopped working, where the operator screen flickers without showing the content.

Digging down, Dee uses multiflip (5th parameter) to flip both windows at the same time:

Screen('Flip',wpnt(1),[],0,0,1);

This used to work, but now doesn’t. If I replace this with separate flips (using 4th parameter dontsync = 2 on the second one), then everything works again:

Screen('Flip',wpnt(1));
Screen('Flip',wpnt(2),[],[],2);

I made a simple testcase that causes flicker on my system:

function multifliptest()

	screenSize1 = [];
	screenSize2 = [0 0 1600 1000];
	bgColour = 0.5;

	ptb = mySetup(bgColour,screenSize1,screenSize2);

	% ---- prepare variables
	CloseWin = false;
	quit = KbName('escape');
	Priority(MaxPriority(ptb.win1)); %bump our priority to maximum allowed
	vbl(1) = Screen('Flip', ptb.win1);
	
	fprintf('\n\nGet ready...\n');
	
	while ~CloseWin
		Screen('gluDisk',ptb.win1,[1 0 0],randi(ptb.winRect1(3),1),randi(ptb.winRect1(3),1),10);
		Screen('gluDisk',ptb.win2,[0 1 0],randi(ptb.winRect2(3),1),randi(ptb.winRect2(3),1),10);
		% this causes flickering and failure to update on the win2 screen:
		Screen('Flip', ptb.win1, vbl(end) + ptb.halfisi,[],[],1);
		% this works fine:
		%Screen('Flip', ptb.win1, vbl(end) + ptb.halfisi);
		%Screen('Flip', ptb.win2,[],[],2);
		
		% ---- handle keyboard
		[~,~,keyCode] = KbCheck(-1);
		name = find(keyCode==1);
		if ~isempty(name)  
			switch name
				case quit
					CloseWin = true;
				otherwise
					disp('Cant match key!')
			end
		end
	end
	Screen('Flip',ptb.win1);
	Screen('Flip',ptb.win1);
end

function ptb = mySetup(bgColour, size1, size2)
	ptb.cleanup = onCleanup(@myCleanup);
	screens = Screen('Screens');
	if length(screens) ~= 2
		error('This test requires a dual display...')
	end
	PsychDefaultSetup(2);
	KbName('UnifyKeyNames');
	Screen('Preference', 'SkipSyncTests', 0);
	Screen('Preference', 'VisualDebugLevel', 6);
	Screen('Preference', 'Verbosity', 4);
	Screen('Preference','SyncTestSettings', 0.0008);
	PsychImaging('PrepareConfiguration');
	PsychImaging('AddTask', 'General', 'FloatingPoint32BitIfPossible');
	[ptb.win1, ptb.winRect1] = PsychImaging('OpenWindow', screens(2), bgColour, size1, [], [], [], 4);
	[ptb.win2, ptb.winRect2] = PsychImaging('OpenWindow', screens(1), bgColour, size2, [], [], [], 4);

	ptb.ifi = Screen('GetFlipInterval', ptb.win1);
	ptb.halfisi = ptb.ifi / 2;
	ptb.fps = 1 / ptb.ifi;
	Screen('BlendFunction', ptb.win1, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	Screen('BlendFunction', ptb.win2, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	disp('Screen Settings: ');
	disp(ptb);
end

function myCleanup()
	disp('Clearing up...')
	Priority(0);ListenChar(0);
	sca
end

Ubuntu 20.10, Latest PTB, MATLAB 2021a.

Hi Ian,

This discussion is relevant here:
https://github.com/Psychtoolbox-3/Psychtoolbox-3/issues/655

What do you think is the better way to work around the problem you found? I don’t want to go full stereo as that would force the user into dealing with stereo draw buffers all the time just for having an operator screen. Does your don’t sync flag work well in practice for you?

Hey Dee, ok that GitHub issue seems to clarify this although it is strange it used to work for me several months ago and now doesn’t (I didn’t try to bisect where this changed). My test case indeed doesn’t clear the frame before drawing, and e.g. your demos work ok with your workarounds (but when I pass in my PTB-windows, it fails, my PTB-windows are opened with a 0-1 color range, non-fullscreen operator, and some other differences that may explain the discrepancy)…

I use dontsync = 2 for my own code operator window, drawing the fixation area, stimulus positions and eye to a non-full screen window on the operator screen (0 on Linux). Timing is great, I check for dropped frames on the main display (1) and so far do not see an impact of the operator display at all using the Spectrum pro in a gaze contingent type task. I’d recommend it as a stable solution, though I don’t know how it will behave on Windows…