function ClutTimeTest
% Times the speed of SetClut and LoadClut relative to WaitBlanking.
% 
% This was written to assess the apparently slow loading of the CLUT 
% in the ATI Radeon 7200 PCI, aka "Radeon Mac Edition (PCI)".

% 8/8/02 dgp Wrote it, based on timeclut.m by David Jones <djones@ece.mcmaster.ca> 
%            and Anthony Helou.
% 8/8/02 dgp Fixed minor bug that resulted in inconsistent results.
% 8/9/02 dgp As suggested by Doug Taylor, removed slow call to Shuffle that was
%            affecting the reported timing. Added test of "wait for blanking" condition,
%            which was reported to alleviate tearing.
% 8/9/02 dgp Set BlankingDuration to zero during testing.
% 8/16/02 dgp Fixed bug reported by David Jones that assumed BlackIndex>WhiteIndex.

n=4;	% number of iterations
profileLoadClut=0;
fprintf('ClutTimeTest\n');
for s=Screen('Screens')
	PrepareScreen(s);
	DescribeScreen(s);
	oldAskSetClut=Screen(s,'Preference','AskSetClutDriverToWaitForBlanking');
	oldSetClutCalls=Screen(s,'Preference','SetClutCallsWaitBlanking',0);
	oldBlankingDuration=Screen(s,'Preference','BlankingDuration',0);
	window=Screen(s,'OpenWindow');
	Screen(window,'PutImage',linspace(BlackIndex(s),WhiteIndex(s),32),Screen(s,'Rect'));
	clut=ClutDefault(s);
	for askSetClut=0:1
		for wait=0:~askSetClut
			DescribeScreen(-2);
			Screen(s,'Preference','AskSetClutDriverToWaitForBlanking',askSetClut);
			Screen(s,'Preference','SetClutCallsWaitBlanking',wait);
			fprintf('AskSetClutDriverToWaitForBlanking %d\n',Screen(s,'Preference','AskSetClutDriverToWaitForBlanking'));
			fprintf('SetClutCallsWaitBlanking %d\n',Screen(s,'Preference','SetClutCallsWaitBlanking'));
			for i=1:n
				Screen(s,'WaitBlanking');
				t(i)=GetSecs;
			end
			hz=(n-1)/(t(n)-t(1));
			fprintf('%-12s loops at %4.0f Hz\n','WaitBlanking',hz);
			duration=1/hz;
			for i=1:n
				Screen(s,'SetClut',clut);
				t(i)=GetSecs;
			end
			hz=(n-1)/(t(n)-t(1));
			fprintf('%-12s loops at %4.0f Hz\n','SetClut',hz);
			if profileLoadClut &  ~askSetClut & ~wait
				LoadClut(s,clut);profile loadclut;n=1000;clear t
			end
			for i=1:n
				LoadClut(s,clut);
				t(i)=GetSecs;
			end
			hz=(n-1)/(t(n)-t(1));
			fprintf('%-12s loops at %4.0f Hz\n','LoadClut',hz);
			if profileLoadClut & ~askSetClut & ~wait
				profile report; profile off;n=4;clear t
			end
			for i=1:n
				Screen(s,'WaitBlanking');
				tw(i)=GetSecs; 
				Screen(s,'SetClut',clut);
				t(i)=GetSecs;
			end
			hz=2*(n-1)/(t(n)-t(1));
			fprintf('Time from end of WaitBlanking to end of SetClut is %.0f%% of frame.\n',100*mean(t-tw)/duration);
			for i=1:n
				Screen(s,'WaitBlanking');
				tw(i)=GetSecs; 
				LoadClut(s,clut);
				t(i)=GetSecs;
			end
			hz=2*(n-1)/(t(n)-t(1));
			fprintf('Time from end of WaitBlanking to end of LoadClut is %.0f%% of frame.\n',100*mean(t-tw)/duration);
		end
	end
	Screen('CloseAll');
	Screen(s,'Preference','AskSetClutDriverToWaitForBlanking',oldAskSetClut);
	Screen(s,'Preference','SetClutCallsWaitBlanking',oldSetClutCalls);
	Screen(s,'Preference','BlankingDuration',oldBlankingDuration);
	RestoreScreen(s);
end
DescribeScreen(-1);
