Skip to content
Snippets Groups Projects
Commit d5dadbf1 authored by Tobias Pietzsch's avatar Tobias Pietzsch
Browse files

WIP interval request aggregation

parent 7f6cbba6
No related branches found
No related tags found
No related merge requests found
...@@ -141,8 +141,12 @@ public class MultiResolutionRenderer ...@@ -141,8 +141,12 @@ public class MultiResolutionRenderer
*/ */
final AffineTransform3D scale; final AffineTransform3D scale;
private final double screenToViewerScale;
public ScreenScale( final int screenW, final int screenH, final double screenToViewerScale ) public ScreenScale( final int screenW, final int screenH, final double screenToViewerScale )
{ {
this.screenToViewerScale = screenToViewerScale;
w = ( int ) Math.ceil( screenToViewerScale * screenW ); w = ( int ) Math.ceil( screenToViewerScale * screenW );
h = ( int ) Math.ceil( screenToViewerScale * screenH ); h = ( int ) Math.ceil( screenToViewerScale * screenH );
scale = new AffineTransform3D(); scale = new AffineTransform3D();
...@@ -151,6 +155,37 @@ public class MultiResolutionRenderer ...@@ -151,6 +155,37 @@ public class MultiResolutionRenderer
scale.set( 0.5 * screenToViewerScale - 0.5, 0, 3 ); scale.set( 0.5 * screenToViewerScale - 0.5, 0, 3 );
scale.set( 0.5 * screenToViewerScale - 0.5, 1, 3 ); scale.set( 0.5 * screenToViewerScale - 0.5, 1, 3 );
} }
Interval requestedScreenInterval = null;
public void requestInterval( final Interval screenInterval )
{
requestedScreenInterval = requestedScreenInterval == null ? screenInterval : Intervals.union( requestedScreenInterval, screenInterval );
}
public Interval pullScreenInterval()
{
final Interval interval = requestedScreenInterval;
requestedScreenInterval = null;
return interval;
}
public double estimateIntervalRenderNanos( final double renderNanosPerPixel )
{
return renderNanosPerPixel * Intervals.numElements( scaleScreenInterval( requestedScreenInterval ) );
}
public Interval scaleScreenInterval( final Interval requestedScreenInterval )
{
// This is equivalent to
// Intervals.intersect( new FinalInterval( w, h ), Intervals.smallestContainingInterval( Intervals.scale( requestedScreenInterval, screenToViewerScale ) ) );
return Intervals.createMinMax(
Math.max( 0, ( int ) Math.floor( requestedScreenInterval.min( 0 ) * screenToViewerScale ) ),
Math.max( 0, ( int ) Math.floor( requestedScreenInterval.min( 1 ) * screenToViewerScale ) ),
Math.min( w - 1, ( int ) Math.ceil( requestedScreenInterval.max( 0 ) * screenToViewerScale ) ),
Math.min( h - 1, ( int ) Math.ceil( requestedScreenInterval.max( 1 ) * screenToViewerScale ) )
);
}
} }
private final ScreenScale[] screenScales; private final ScreenScale[] screenScales;
...@@ -479,12 +514,30 @@ public class MultiResolutionRenderer ...@@ -479,12 +514,30 @@ public class MultiResolutionRenderer
{ {
if ( renderingMayBeCancelled && projector != null ) if ( renderingMayBeCancelled && projector != null )
projector.cancel(); projector.cancel();
for ( ScreenScale screenScale : screenScales )
if ( screenScale != null )
screenScale.pullScreenInterval();
intervalMode = false;
newFrameRequest = true; newFrameRequest = true;
requestedScreenInterval = null;
intervalMode = false;
painterThread.requestRepaint(); painterThread.requestRepaint();
} }
public synchronized void requestRepaint( final Interval screenInterval )
{
if ( renderingMayBeCancelled || intervalMode )
{
if ( projector != null )
projector.cancel();
for ( final ScreenScale screenScale : screenScales )
screenScale.requestInterval( screenInterval );
intervalMode = true;
newIntervalRequest = true;
painterThread.requestRepaint();
}
else
requestRepaint();
}
private int suggestScreenScale( final Dimensions screenSize, final int numSources ) private int suggestScreenScale( final Dimensions screenSize, final int numSources )
{ {
final double intervalRenderNanos = renderNanosPerPixelAndSource.getAverage() * Intervals.numElements( screenSize ) * numSources; final double intervalRenderNanos = renderNanosPerPixelAndSource.getAverage() * Intervals.numElements( screenSize ) * numSources;
...@@ -547,7 +600,6 @@ public class MultiResolutionRenderer ...@@ -547,7 +600,6 @@ public class MultiResolutionRenderer
// =========== intervals ============= // =========== intervals =============
private Interval requestedScreenInterval;
private RenderResult currentRenderResult; private RenderResult currentRenderResult;
public static class IntervalRenderData public static class IntervalRenderData
...@@ -574,31 +626,45 @@ public class MultiResolutionRenderer ...@@ -574,31 +626,45 @@ public class MultiResolutionRenderer
private boolean paintInterval( final boolean newInterval ) private boolean paintInterval( final boolean newInterval )
{ {
if ( newInterval ) final boolean createProjector;
{ final ScreenScale screenScale;
cacheControl.prepareNextFrame(); final Interval requestedScreenInterval;
requestedIntervalScaleIndex = Math.max( currentScreenScaleIndex, suggestScreenScale( requestedScreenInterval, currentNumVisibleSources ) );
}
final boolean createProjector = newInterval || ( requestedIntervalScaleIndex != currentIntervalScaleIndex );
final VolatileProjector p; final VolatileProjector p;
synchronized ( this ) synchronized ( this )
{ {
if ( newInterval )
{
cacheControl.prepareNextFrame();
final double renderNanosPerPixel = currentNumVisibleSources * renderNanosPerPixelAndSource.getAverage();
for ( int i = currentScreenScaleIndex; i < screenScales.length; i++ )
{
final double renderTime = screenScales[ i ].estimateIntervalRenderNanos( renderNanosPerPixel );
if ( renderTime <= targetRenderNanos )
{
requestedIntervalScaleIndex = i;
break;
}
}
}
createProjector = newInterval || ( requestedIntervalScaleIndex != currentIntervalScaleIndex );
screenScale = screenScales[ requestedIntervalScaleIndex ];
requestedScreenInterval = screenScale.pullScreenInterval();
if ( createProjector ) if ( createProjector )
{ {
final Interval interval = scaleScreenInterval( requestedScreenInterval, requestedIntervalScaleIndex ); final Interval interval = screenScale.scaleScreenInterval( requestedScreenInterval );
intervalResult.init( intervalResult.init(
( int ) interval.dimension( 0 ), ( int ) interval.dimension( 0 ),
( int ) interval.dimension( 1 ) ); ( int ) interval.dimension( 1 ) );
final double intervalScale = screenScaleFactors[ requestedIntervalScaleIndex ]; final double intervalScale = screenScale.screenToViewerScale;
intervalResult.setScaleFactor( intervalScale ); intervalResult.setScaleFactor( intervalScale );
final double offsetX = interval.min( 0 ); final double offsetX = interval.min( 0 );
final double offsetY = interval.min( 1 ); final double offsetY = interval.min( 1 );
projector = createProjector( currentViewerState, requestedIntervalScaleIndex, intervalResult.getScreenImage(), offsetX, offsetY ); projector = createProjector( currentViewerState, requestedIntervalScaleIndex, intervalResult.getScreenImage(), offsetX, offsetY );
final Interval targetInterval = scaleScreenInterval( requestedScreenInterval, currentScreenScaleIndex ); final Interval targetInterval = screenScales[ currentScreenScaleIndex ].scaleScreenInterval( requestedScreenInterval );
final double relativeScale = screenScaleFactors[ currentScreenScaleIndex ] / intervalScale; final double relativeScale = screenScaleFactors[ currentScreenScaleIndex ] / intervalScale;
final double tx = interval.min( 0 ) * relativeScale; final double tx = interval.min( 0 ) * relativeScale;
final double ty = interval.min( 1 ) * relativeScale; final double ty = interval.min( 1 ) * relativeScale;
...@@ -645,9 +711,14 @@ public class MultiResolutionRenderer ...@@ -645,9 +711,14 @@ public class MultiResolutionRenderer
// restore interrupted state // restore interrupted state
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
screenScale.requestInterval( requestedScreenInterval );
iterateRepaintInterval( currentIntervalScaleIndex ); iterateRepaintInterval( currentIntervalScaleIndex );
} }
} }
else
{
screenScale.requestInterval( requestedScreenInterval );
}
} }
return success; return success;
...@@ -673,19 +744,4 @@ public class MultiResolutionRenderer ...@@ -673,19 +744,4 @@ public class MultiResolutionRenderer
Math.min( clipH - 1, ( int ) Math.ceil( requestedScreenInterval.max( 1 ) * scale ) ) Math.min( clipH - 1, ( int ) Math.ceil( requestedScreenInterval.max( 1 ) * scale ) )
); );
} }
public synchronized void requestRepaint( final Interval screenInterval )
{
if ( renderingMayBeCancelled || intervalMode )
{
if ( projector != null )
projector.cancel();
requestedScreenInterval = screenInterval;
intervalMode = true;
newIntervalRequest = true;
painterThread.requestRepaint();
}
else
requestRepaint();
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment