diff --git a/src/main/java/bdv/viewer/render/MultiResolutionRenderer.java b/src/main/java/bdv/viewer/render/MultiResolutionRenderer.java
index 80182b254d44e12bf3d74324601fa6f08156ebc5..e5f5e45854b5d214503e84d68844fddc2d3b929a 100644
--- a/src/main/java/bdv/viewer/render/MultiResolutionRenderer.java
+++ b/src/main/java/bdv/viewer/render/MultiResolutionRenderer.java
@@ -263,126 +263,186 @@ public class MultiResolutionRenderer
 	 */
 	public boolean paint( final ViewerState viewerState )
 	{
-		int screenW = display.getWidth();
-		int screenH = display.getHeight();
+		final int screenW = display.getWidth();
+		final int screenH = display.getHeight();
 		if ( screenW <= 0 || screenH <= 0 )
 			return false;
 
-		final boolean resized = screenScales.checkResize( screenW, screenH );
-
+		final boolean resized;
 		final boolean newFrame;
 		final boolean newInterval;
 		final boolean paintInterval;
+		final boolean prepareNextFrame;
+		boolean createProjector = false;
 		synchronized ( this )
 		{
+			resized = screenScales.checkResize( screenW, screenH );
+
 			newFrame = newFrameRequest || resized;
 			if ( newFrame )
 			{
-				newFrameRequest = false;
 				intervalMode = false;
-				// TODO: clear interval requests
+				screenScales.clearRequestedIntervals();
 			}
 
-			newInterval = newIntervalRequest;
+			newInterval = newIntervalRequest && !newFrame;
 			if ( newInterval )
 			{
-				newIntervalRequest = false;
 				intervalMode = true;
+				final double renderNanosPerPixel = renderNanosPerPixelAndSource.getAverage() * currentNumVisibleSources;
+				requestedIntervalScaleIndex = screenScales.suggestIntervalScreenScale( renderNanosPerPixel, currentScreenScaleIndex );
 			}
 
+			prepareNextFrame = newFrame || newInterval;
 			paintInterval = intervalMode;
+
+			if ( paintInterval )
+			{
+				createProjector = newInterval || ( requestedIntervalScaleIndex != currentIntervalScaleIndex );
+				if ( createProjector )
+					intervalRenderData = screenScales.pullIntervalRenderData( requestedIntervalScaleIndex, currentScreenScaleIndex );
+			}
+
+			newFrameRequest = false;
+			newIntervalRequest = false;
 		}
 
-		if ( paintInterval )
-			return paintInterval( newInterval );
+		if ( prepareNextFrame )
+			cacheControl.prepareNextFrame();
 
 		if ( newFrame )
 		{
-			cacheControl.prepareNextFrame();
 			currentViewerState = viewerState.snapshot();
 			currentNumVisibleSources = currentViewerState.getVisibleAndPresentSources().size();
 			final double renderNanosPerPixel = renderNanosPerPixelAndSource.getAverage() * currentNumVisibleSources;
 			requestedScreenScaleIndex = screenScales.suggestScreenScale( renderNanosPerPixel );
 		}
 
-		final boolean createProjector = newFrame || ( requestedScreenScaleIndex != currentScreenScaleIndex );
-
 		// the projector that paints to the screenImage.
 		final VolatileProjector p;
 
-		// TODO make field (for notifying of updates) ???
+		// holds new RenderResult, in case that a new projector is created in full frame mode
 		RenderResult renderResult = null;
 
-		// if creating a projector
+		// whether to request a newFrame, in case that a new projector is created in full frame mode
 		boolean requestNewFrameIfIncomplete = false;
 
-		synchronized ( this )
+		if ( paintInterval )
 		{
-			if ( createProjector )
+			intervalResult.init( intervalRenderData.width(), intervalRenderData.height() );
+			intervalResult.setScaleFactor( intervalRenderData.scale() );
+			synchronized ( this )
 			{
-				final ScreenScale screenScale = screenScales.get( requestedScreenScaleIndex );
+				if ( createProjector )
+				{
+					projector = createProjector( currentViewerState, requestedIntervalScaleIndex, intervalResult.getScreenImage(), intervalRenderData.offsetX(), intervalRenderData.offsetY() );
+					renderingMayBeCancelled = !newInterval;
+				}
+				p = projector;
+			}
+		}
+		else
+		{
+			createProjector = newFrame || ( requestedScreenScaleIndex != currentScreenScaleIndex );
+			synchronized ( this )
+			{
+				if ( createProjector )
+				{
+					final ScreenScale screenScale = screenScales.get( requestedScreenScaleIndex );
 
-				renderResult = display.getReusableRenderResult();
-				renderResult.init( screenScale.width(), screenScale.height() );
-				renderResult.setScaleFactor( screenScale.scale() );
+					renderResult = display.getReusableRenderResult();
+					renderResult.init( screenScale.width(), screenScale.height() );
+					renderResult.setScaleFactor( screenScale.scale() );
+					currentViewerState.getViewerTransform( renderResult.getViewerTransform() );
 
-				renderStorage.checkRenewData( screenScales.get( 0 ).width(), screenScales.get( 0 ).height(), currentNumVisibleSources );
-				projector = createProjector( currentViewerState, requestedScreenScaleIndex, renderResult.getScreenImage(), 0, 0 );
-				requestNewFrameIfIncomplete = projectorFactory.requestNewFrameIfIncomplete();
-				renderingMayBeCancelled = !newFrame;
+					renderStorage.checkRenewData( screenScales.get( 0 ).width(), screenScales.get( 0 ).height(), currentNumVisibleSources );
+					projector = createProjector( currentViewerState, requestedScreenScaleIndex, renderResult.getScreenImage(), 0, 0 );
+					requestNewFrameIfIncomplete = projectorFactory.requestNewFrameIfIncomplete();
+					renderingMayBeCancelled = !newFrame;
+				}
+				p = projector;
 			}
-			p = projector;
 		}
 
+
 		// try rendering
 		final boolean success = p.map( createProjector );
 		final long rendertime = p.getLastFrameRenderNanoTime();
 
+
 		synchronized ( this )
 		{
 			// if rendering was not cancelled...
 			if ( success )
 			{
-				if ( createProjector )
+				if ( paintInterval )
 				{
-					currentScreenScaleIndex = requestedScreenScaleIndex;
-					currentViewerState.getViewerTransform( renderResult.getViewerTransform() );
-					// TODO renderResult.setUpdated();
-					( ( RenderTarget ) display ).setRenderResult( renderResult );
-					currentRenderResult = renderResult;
+					if ( createProjector )
+						currentIntervalScaleIndex = requestedIntervalScaleIndex;
+
+					currentRenderResult.patch( intervalResult, intervalRenderData.targetInterval(), intervalRenderData.tx(), intervalRenderData.ty() );
 
-					if ( currentNumVisibleSources > 0 )
+					if ( currentIntervalScaleIndex > currentScreenScaleIndex )
+						iterateRepaintInterval( currentIntervalScaleIndex - 1 );
+					else if ( p.isValid() )
 					{
-						final int numRenderPixels = ( int ) Intervals.numElements( renderResult.getScreenImage() ) * currentNumVisibleSources;
-						renderNanosPerPixelAndSource.add( rendertime / ( double ) numRenderPixels );
+						if ( requestedScreenScaleIndex >= 0 )
+						{
+							// go back to "normal" rendering
+							intervalMode = false;
+							renderingMayBeCancelled = false;
+							if ( requestedScreenScaleIndex == currentScreenScaleIndex )
+								++currentScreenScaleIndex;
+							painterThread.requestRepaint();
+						}
+					}
+					else
+					{
+						usleep();
+						intervalRenderData.reRequest();
+						iterateRepaintInterval( currentIntervalScaleIndex );
 					}
-				}
-				// TODO else renderResult.setUpdated();
-
-				if ( currentScreenScaleIndex > 0 )
-					iterateRepaint( currentScreenScaleIndex - 1 );
-				else if ( p.isValid() )
-				{
-					// indicate that rendering is complete
-					requestedScreenScaleIndex = -1;
 				}
 				else
 				{
-					try
+					if ( createProjector )
 					{
-						Thread.sleep( 1 );
+						currentScreenScaleIndex = requestedScreenScaleIndex;
+						renderResult.setUpdated();
+						( ( RenderTarget ) display ).setRenderResult( renderResult );
+						currentRenderResult = renderResult;
+
+						if ( currentNumVisibleSources > 0 )
+						{
+							final int numRenderPixels = ( int ) Intervals.numElements( renderResult.getScreenImage() ) * currentNumVisibleSources;
+							renderNanosPerPixelAndSource.add( rendertime / ( double ) numRenderPixels );
+						}
 					}
-					catch ( final InterruptedException e )
+					else
+						currentRenderResult.setUpdated();
+
+					if ( !p.isValid() && requestNewFrameIfIncomplete )
+						requestRepaint();
+					else if ( currentScreenScaleIndex > 0 )
+						iterateRepaint( currentScreenScaleIndex - 1 );
+					else if ( p.isValid() )
 					{
-						// restore interrupted state
-						Thread.currentThread().interrupt();
+						// indicate that rendering is complete
+						requestedScreenScaleIndex = -1;
 					}
-					if( requestNewFrameIfIncomplete )
-						requestRepaint();
 					else
+					{
+						usleep();
 						iterateRepaint( currentScreenScaleIndex );
+					}
 				}
 			}
+			// if rendering was cancelled...
+			else
+			{
+				if ( paintInterval )
+					intervalRenderData.reRequest();
+			}
 		}
 
 		return success;
@@ -411,8 +471,6 @@ public class MultiResolutionRenderer
 	{
 		if ( renderingMayBeCancelled && projector != null )
 			projector.cancel();
-		screenScales.clearRequestedIntervals();
-		intervalMode = false;
 		newFrameRequest = true;
 		painterThread.requestRepaint();
 	}
@@ -424,12 +482,11 @@ public class MultiResolutionRenderer
 			if ( projector != null )
 				projector.cancel();
 			screenScales.requestInterval( screenInterval );
-			intervalMode = true;
 			newIntervalRequest = true;
-			painterThread.requestRepaint();
 		}
 		else
-			requestRepaint();
+			newFrameRequest = true;
+		painterThread.requestRepaint();
 	}
 
 	/**
@@ -480,90 +537,22 @@ public class MultiResolutionRenderer
 	private final RenderResult intervalResult;
 	private IntervalRenderData intervalRenderData;
 
-	private boolean paintInterval( final boolean newInterval )
+	private void iterateRepaintInterval( final int intervalScaleIndex )
 	{
-		final boolean createProjector;
-		final VolatileProjector p;
+		requestedIntervalScaleIndex = intervalScaleIndex;
+		painterThread.requestRepaint();
+	}
 
-		synchronized ( this )
+	private void usleep()
+	{
+		try
 		{
-			if ( newInterval )
-			{
-				cacheControl.prepareNextFrame();
-				final double renderNanosPerPixel = renderNanosPerPixelAndSource.getAverage() * currentNumVisibleSources;
-				requestedIntervalScaleIndex = screenScales.suggestIntervalScreenScale( renderNanosPerPixel, currentScreenScaleIndex );
-				newIntervalRequest = false; // TODO: done again here because of remaining synchronization issues...
-			}
-
-			createProjector = newInterval || ( requestedIntervalScaleIndex != currentIntervalScaleIndex );
-
-			if ( createProjector )
-			{
-				intervalRenderData = screenScales.pullIntervalRenderData( requestedIntervalScaleIndex, currentScreenScaleIndex );
-
-				intervalResult.init( intervalRenderData.width(), intervalRenderData.height() );
-				intervalResult.setScaleFactor( intervalRenderData.scale() );
-
-				projector = createProjector( currentViewerState, requestedIntervalScaleIndex, intervalResult.getScreenImage(), intervalRenderData.offsetX(), intervalRenderData.offsetY() );
-
-				renderingMayBeCancelled = !newInterval;
-			}
-			p = projector;
+			Thread.sleep( 1 );
 		}
-
-		final boolean success = p.map();
-
-		synchronized ( this )
+		catch ( final InterruptedException e )
 		{
-			// if rendering was not cancelled...
-			if ( success )
-			{
-				if ( createProjector )
-					currentIntervalScaleIndex = requestedIntervalScaleIndex;
-
-				currentRenderResult.patch( intervalResult, intervalRenderData.targetInterval(), intervalRenderData.tx(), intervalRenderData.ty() );
-
-				if ( currentIntervalScaleIndex > currentScreenScaleIndex )
-					iterateRepaintInterval( currentIntervalScaleIndex - 1 );
-				else if ( p.isValid() )
-				{
-					if ( requestedScreenScaleIndex >= 0 )
-					{
-						// go back to "normal" rendering
-						intervalMode = false;
-						renderingMayBeCancelled = false;
-						if ( requestedScreenScaleIndex == currentScreenScaleIndex )
-							++currentScreenScaleIndex;
-						painterThread.requestRepaint();
-					}
-				}
-				else
-				{
-					try
-					{
-						Thread.sleep( 1 );
-					}
-					catch ( final InterruptedException e )
-					{
-						// restore interrupted state
-						Thread.currentThread().interrupt();
-					}
-					intervalRenderData.reRequest();
-					iterateRepaintInterval( currentIntervalScaleIndex );
-				}
-			}
-			else
-			{
-				intervalRenderData.reRequest();
-			}
+			// restore interrupted state
+			Thread.currentThread().interrupt();
 		}
-
-		return success;
-	}
-
-	private void iterateRepaintInterval( final int intervalScaleIndex )
-	{
-		requestedIntervalScaleIndex = intervalScaleIndex;
-		painterThread.requestRepaint();
 	}
 }