diff --git a/src/main/java/bdv/viewer/render/MultiResolutionRenderer.java b/src/main/java/bdv/viewer/render/MultiResolutionRenderer.java index 4eb37fa357a2c935fc8a567e0052ff3703064f40..80182b254d44e12bf3d74324601fa6f08156ebc5 100644 --- a/src/main/java/bdv/viewer/render/MultiResolutionRenderer.java +++ b/src/main/java/bdv/viewer/render/MultiResolutionRenderer.java @@ -31,6 +31,7 @@ package bdv.viewer.render; import bdv.cache.CacheControl; import bdv.util.MovingAverage; import bdv.viewer.ViewerState; +import bdv.viewer.render.ScreenScales.IntervalRenderData; import bdv.viewer.render.ScreenScales.ScreenScale; import java.util.concurrent.ExecutorService; import net.imglib2.Interval; @@ -279,6 +280,7 @@ public class MultiResolutionRenderer { newFrameRequest = false; intervalMode = false; + // TODO: clear interval requests } newInterval = newIntervalRequest; @@ -448,8 +450,8 @@ public class MultiResolutionRenderer final ViewerState viewerState, final int screenScaleIndex, final RandomAccessibleInterval< ARGBType > screenImage, - final double offsetX, - final double offsetY ) + final int offsetX, + final int offsetY ) { /* * This shouldn't be necessary, with @@ -475,33 +477,12 @@ public class MultiResolutionRenderer private RenderResult currentRenderResult; - public static class IntervalRenderData - { - private final Interval targetInterval; - - private final double tx; - - private final double ty; - - public IntervalRenderData( - final Interval targetInterval, - final double tx, - final double ty ) - { - this.targetInterval = targetInterval; - this.tx = tx; - this.ty = ty; - } - } - private final RenderResult intervalResult; private IntervalRenderData intervalRenderData; private boolean paintInterval( final boolean newInterval ) { final boolean createProjector; - final ScreenScale screenScale; - final Interval requestedScreenInterval; final VolatileProjector p; synchronized ( this ) @@ -511,29 +492,19 @@ public class MultiResolutionRenderer 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 ); - screenScale = screenScales.get( requestedIntervalScaleIndex ); - requestedScreenInterval = screenScale.pullScreenInterval(); if ( createProjector ) { - final Interval interval = screenScale.scaleScreenInterval( requestedScreenInterval ); - intervalResult.init( - ( int ) interval.dimension( 0 ), - ( int ) interval.dimension( 1 ) ); - final double intervalScale = screenScale.scale(); - intervalResult.setScaleFactor( intervalScale ); - final double offsetX = interval.min( 0 ); - final double offsetY = interval.min( 1 ); - projector = createProjector( currentViewerState, requestedIntervalScaleIndex, intervalResult.getScreenImage(), offsetX, offsetY ); - - final Interval targetInterval = screenScales.get( currentScreenScaleIndex ).scaleScreenInterval( requestedScreenInterval ); - final double relativeScale = screenScales.get( currentScreenScaleIndex ).scale() / intervalScale; - final double tx = interval.min( 0 ) * relativeScale; - final double ty = interval.min( 1 ) * relativeScale; - intervalRenderData = new IntervalRenderData( targetInterval, tx, ty ); + 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; } @@ -550,7 +521,7 @@ public class MultiResolutionRenderer if ( createProjector ) currentIntervalScaleIndex = requestedIntervalScaleIndex; - currentRenderResult.patch( intervalResult, intervalRenderData.targetInterval, intervalRenderData.tx, intervalRenderData.ty ); + currentRenderResult.patch( intervalResult, intervalRenderData.targetInterval(), intervalRenderData.tx(), intervalRenderData.ty() ); if ( currentIntervalScaleIndex > currentScreenScaleIndex ) iterateRepaintInterval( currentIntervalScaleIndex - 1 ); @@ -577,13 +548,13 @@ public class MultiResolutionRenderer // restore interrupted state Thread.currentThread().interrupt(); } - screenScale.requestInterval( requestedScreenInterval ); + intervalRenderData.reRequest(); iterateRepaintInterval( currentIntervalScaleIndex ); } } else { - screenScale.requestInterval( requestedScreenInterval ); + intervalRenderData.reRequest(); } } diff --git a/src/main/java/bdv/viewer/render/ScreenScales.java b/src/main/java/bdv/viewer/render/ScreenScales.java index 7b46e57b3b28c41a0091a10575456034ddad530e..74cc6d41347ef2ee1c36c5afbdb66cd6e2094ec5 100644 --- a/src/main/java/bdv/viewer/render/ScreenScales.java +++ b/src/main/java/bdv/viewer/render/ScreenScales.java @@ -176,7 +176,7 @@ public class ScreenScales return interval; } - public double estimateIntervalRenderNanos( final double renderNanosPerPixel ) + double estimateIntervalRenderNanos( final double renderNanosPerPixel ) { return renderNanosPerPixel * Intervals.numElements( scaleScreenInterval( requestedScreenInterval ) ); } @@ -213,4 +213,86 @@ public class ScreenScales return scaleTransform; } } + + + public IntervalRenderData pullIntervalRenderData( final int intervalScaleIndex, final int targetScaleIndex ) + { + return new IntervalRenderData( intervalScaleIndex, targetScaleIndex ); + } + + public class IntervalRenderData + { + private final int renderScaleIndex; + + private final Interval screenInterval; + + private final Interval renderInterval; + + private final Interval targetInterval; + + private final double tx; + + private final double ty; + + public IntervalRenderData( final int renderScaleIndex, final int targetScaleIndex ) + { + this.renderScaleIndex = renderScaleIndex; + final ScreenScale screenScale = get( renderScaleIndex ); + screenInterval = screenScale.pullScreenInterval(); + renderInterval = screenScale.scaleScreenInterval( screenInterval ); + + final ScreenScale targetScale = get( targetScaleIndex ); + targetInterval = targetScale.scaleScreenInterval( screenInterval ); + + final double relativeScale = targetScale.scale() / screenScale.scale(); + tx = renderInterval.min( 0 ) * relativeScale; + ty = renderInterval.min( 1 ) * relativeScale; + } + + public void reRequest() + { + get( renderScaleIndex ).requestInterval( screenInterval ); + } + + public int width() + { + return ( int ) renderInterval.dimension( 0 ); + } + + public int height() + { + return ( int ) renderInterval.dimension( 1 ); + } + + public int offsetX() + { + return ( int ) renderInterval.min( 0 ); + } + public int offsetY() + { + return ( int ) renderInterval.min( 1 ); + } + + public double scale() + { + return get( renderScaleIndex ).scale(); + } + + public Interval targetInterval() + { + return targetInterval; + } + + public double tx() + { + return tx; + } + + public double ty() + { + return ty; + } + } + + }