Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
B
BigDataViewer_Core_Extension
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
BioinformaticDataCompression
BigDataViewer_Core_Extension
Commits
7f6cbba6
Commit
7f6cbba6
authored
5 years ago
by
Tobias Pietzsch
Browse files
Options
Downloads
Patches
Plain Diff
Minor refactoring and javadoc
parent
1ce9aea3
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/main/java/bdv/viewer/render/MultiResolutionRenderer.java
+86
-71
86 additions, 71 deletions
src/main/java/bdv/viewer/render/MultiResolutionRenderer.java
with
86 additions
and
71 deletions
src/main/java/bdv/viewer/render/MultiResolutionRenderer.java
+
86
−
71
View file @
7f6cbba6
...
...
@@ -44,6 +44,7 @@ import net.imglib2.ui.PainterThread;
import
net.imglib2.ui.RenderTarget
;
import
net.imglib2.util.Intervals
;
/**
* A renderer that uses a coarse-to-fine rendering scheme. First, a small target
* image at a fraction of the canvas resolution is rendered. Then, increasingly
...
...
@@ -67,13 +68,10 @@ import net.imglib2.util.Intervals;
* scale is currently rendering, {@link #requestRepaint() repaint request} will
* cancel rendering, such that display remains interactive.
* <p>
* The renderer tries to maintain a per-frame rendering time close to a desired
* number of {@code targetRenderNanos} nanoseconds. If the rendering time (in
* nanoseconds) for the (currently) highest scaled screen image is above this
* threshold, a coarser screen scale is chosen as the highest screen scale to
* use. Similarly, if the rendering time for the (currently) second-highest
* scaled screen image is below this threshold, this finer screen scale chosen
* as the highest screen scale to use.
* The renderer tries to maintain a per-frame rendering time close to
* {@code targetRenderNanos} nanoseconds. The current highest screen scale is
* chosen to match this time based on per-output-pixel time measured in previous
* frames.
* <p>
* The renderer uses multiple threads (if desired).
* <p>
...
...
@@ -103,10 +101,18 @@ public class MultiResolutionRenderer
private
final
PainterThread
painterThread
;
/**
* C
urrently active projector, used to re-paint the display. It maps the
*
source data to
{@code
©
screenImage
s
}.
* C
reates projectors for rendering current {@code ViewerState} to a
* {@code screenImage}.
*/
private
VolatileProjector
projector
;
private
final
ProjectorFactory
projectorFactory
;
/**
* Controls IO budgeting and fetcher queue.
*/
private
final
CacheControl
cacheControl
;
// TODO: should be settable
private
final
long
[]
iobudget
=
new
long
[]
{
100
l
*
1000000
l
,
10
l
*
1000000
l
};
/**
* Scale factors from the {@link #display viewer canvas} to the
...
...
@@ -153,6 +159,9 @@ public class MultiResolutionRenderer
private
int
screenH
;
/**
* Maintains arrays for intermediate per-source render images and masks.
*/
private
final
RenderStorage
renderStorage
;
/**
...
...
@@ -170,26 +179,28 @@ public class MultiResolutionRenderer
private
final
MovingAverage
renderNanosPerPixelAndSource
;
/**
*
The index of the screen scale of the {@link #projector current
*
projector
}.
*
Currently active projector, used to re-paint the display. It maps the
*
source data to {@code ©screenImages
}.
*/
private
int
currentScreenScaleIndex
;
private
VolatileProjector
projector
;
/**
* The index of the screen scale which should be rendered next.
* Screen scale of the last successful (not cancelled) rendering pass in
* full-frame mode.
*/
private
int
requested
ScreenScaleIndex
;
private
int
current
ScreenScaleIndex
;
/**
* The index of the
coarsest
screen scale
currently used.
*
Rendering at finer screen scales may be cancelled
.
* The index of the screen scale
which should be rendered next in full-frame
*
mode
.
*/
private
int
max
ScreenScaleIndex
;
private
int
requested
ScreenScaleIndex
;
/**
* Whether the current rendering operation may be cancelled (to start a new
* one). Rendering may be cancelled unless we are rendering at the
* {@link #maxScreenScaleIndex coarsest screen scale}.
* (estimated) coarsest screen scale meeting the rendering time
* {@link #targetRenderNanos threshold}.
*/
private
boolean
renderingMayBeCancelled
;
...
...
@@ -204,24 +215,31 @@ public class MultiResolutionRenderer
private
int
currentNumVisibleSources
;
/**
*
Creates projectors for rendering current {@code ViewerState} to a
*
{@code screenImage
}.
*
Whether a full repaint was {@link #requestRepaint() requested}. This will
*
cause {@link CacheControl#prepareNextFrame()
}.
*/
private
final
ProjectorFactory
projectorFactory
;
private
boolean
newFrameRequest
;
/**
* Controls IO budgeting and fetcher queue.
* If {@code true}, then we are painting intervals currently.
* If {@code false}, then we are painting full frames.
*/
private
final
CacheControl
cacheControl
;
private
boolean
intervalMode
;
/**
*
Whether a repaint was {@link #requestRepaint() requested}. This will
*
cause {@link CacheControl#prepareNextFrame()}
.
*
Screen scale of the last successful (not cancelled) rendering pass in
*
interval mode
.
*/
private
boolean
newFrameRequest
;
private
int
currentIntervalScaleIndex
;
// TODO: should be settable
private
final
long
[]
iobudget
=
new
long
[]
{
100
l
*
1000000
l
,
10
l
*
1000000
l
};
private
int
requestedIntervalScaleIndex
;
/**
* Whether repainting of an interval was {@link #requestRepaint(Interval)
* requested}. This will cause {@link CacheControl#prepareNextFrame()}.
* Pending interval requests are obsoleted by full repaint requests.
*/
private
boolean
newIntervalRequest
;
/**
* @param display
...
...
@@ -276,8 +294,7 @@ public class MultiResolutionRenderer
renderNanosPerPixelAndSource
=
new
MovingAverage
(
3
);
renderNanosPerPixelAndSource
.
init
(
500
);
maxScreenScaleIndex
=
screenScales
.
length
-
1
;
requestedScreenScaleIndex
=
maxScreenScaleIndex
;
requestedScreenScaleIndex
=
screenScales
.
length
-
1
;
renderingMayBeCancelled
=
false
;
this
.
cacheControl
=
cacheControl
;
newFrameRequest
=
false
;
...
...
@@ -334,9 +351,15 @@ public class MultiResolutionRenderer
newFrameRequest
=
false
;
intervalMode
=
false
;
}
paintInterval
=
intervalMode
;
newInterval
=
newIntervalRequest
;
newIntervalRequest
=
false
;
if
(
newInterval
)
{
newIntervalRequest
=
false
;
intervalMode
=
true
;
}
paintInterval
=
intervalMode
;
}
if
(
paintInterval
)
...
...
@@ -347,8 +370,7 @@ public class MultiResolutionRenderer
cacheControl
.
prepareNextFrame
();
currentViewerState
=
viewerState
.
snapshot
();
currentNumVisibleSources
=
currentViewerState
.
getVisibleAndPresentSources
().
size
();
maxScreenScaleIndex
=
suggestScreenScale
(
new
FinalDimensions
(
screenW
,
screenH
),
currentNumVisibleSources
);
requestedScreenScaleIndex
=
maxScreenScaleIndex
;
requestedScreenScaleIndex
=
suggestScreenScale
(
new
FinalDimensions
(
screenW
,
screenH
),
currentNumVisibleSources
);
}
final
boolean
createProjector
=
newFrame
||
(
requestedScreenScaleIndex
!=
currentScreenScaleIndex
);
...
...
@@ -375,7 +397,7 @@ public class MultiResolutionRenderer
renderStorage
.
checkRenewData
(
screenScales
[
0
].
w
,
screenScales
[
0
].
h
,
currentNumVisibleSources
);
projector
=
createProjector
(
currentViewerState
,
requestedScreenScaleIndex
,
renderResult
.
getScreenImage
(),
0
,
0
);
requestNewFrameIfIncomplete
=
projectorFactory
.
requestNewFrameIfIncomplete
();
renderingMayBeCancelled
=
(
requestedScreenScaleIndex
<
maxScreenScaleIndex
)
;
renderingMayBeCancelled
=
!
newFrame
;
}
p
=
projector
;
}
...
...
@@ -406,7 +428,7 @@ public class MultiResolutionRenderer
// TODO else renderResult.setUpdated();
if
(
currentScreenScaleIndex
>
0
)
request
Repaint
(
currentScreenScaleIndex
-
1
);
iterate
Repaint
(
currentScreenScaleIndex
-
1
);
else
if
(
p
.
isValid
()
)
{
// indicate that rendering is complete
...
...
@@ -426,7 +448,7 @@ public class MultiResolutionRenderer
if
(
requestNewFrameIfIncomplete
)
requestRepaint
();
else
request
Repaint
(
currentScreenScaleIndex
);
iterate
Repaint
(
currentScreenScaleIndex
);
}
}
}
...
...
@@ -434,6 +456,20 @@ public class MultiResolutionRenderer
return
success
;
}
/**
* Request a repaint of the display from the painter thread, setting
* {@code requestedScreenScaleIndex} to the specified
* {@code screenScaleIndex}. This is used to repaint the
* {@code currentViewerState} in a loop, until everything is painted at
* highest resolution from valid data (or painting is interrupted by a new
* "real" {@link #requestRepaint()}.
*/
private
void
iterateRepaint
(
final
int
screenScaleIndex
)
{
requestedScreenScaleIndex
=
screenScaleIndex
;
painterThread
.
requestRepaint
();
}
/**
* Request a repaint of the display from the painter thread. The painter
* thread will trigger a {@link #paint} as soon as possible (that is,
...
...
@@ -449,20 +485,6 @@ public class MultiResolutionRenderer
painterThread
.
requestRepaint
();
}
/**
* Request a repaint of the display from the painter thread, setting
* {@code requestedScreenScaleIndex} to the specified
* {@code screenScaleIndex}. This is used to repaint the
* {@code currentViewerState} in a loop, until everything is painted at
* highest resolution from valid data (or painting is interrupted by a new
* "real" {@link #requestRepaint()}.
*/
private
void
requestRepaint
(
final
int
screenScaleIndex
)
{
requestedScreenScaleIndex
=
screenScaleIndex
;
painterThread
.
requestRepaint
();
}
private
int
suggestScreenScale
(
final
Dimensions
screenSize
,
final
int
numSources
)
{
final
double
intervalRenderNanos
=
renderNanosPerPixelAndSource
.
getAverage
()
*
Intervals
.
numElements
(
screenSize
)
*
numSources
;
...
...
@@ -526,12 +548,7 @@ public class MultiResolutionRenderer
// =========== intervals =============
private
Interval
requestedScreenInterval
;
private
boolean
intervalMode
;
private
boolean
newIntervalRequest
;
private
RenderResult
currentRenderResult
;
private
int
requestedIntervalScaleIndex
;
private
int
currentIntervalScaleIndex
;
private
int
maxIntervalScaleIndex
;
public
static
class
IntervalRenderData
{
...
...
@@ -560,8 +577,7 @@ public class MultiResolutionRenderer
if
(
newInterval
)
{
cacheControl
.
prepareNextFrame
();
maxIntervalScaleIndex
=
Math
.
max
(
currentScreenScaleIndex
,
suggestScreenScale
(
requestedScreenInterval
,
currentNumVisibleSources
)
);
requestedIntervalScaleIndex
=
maxIntervalScaleIndex
;
requestedIntervalScaleIndex
=
Math
.
max
(
currentScreenScaleIndex
,
suggestScreenScale
(
requestedScreenInterval
,
currentNumVisibleSources
)
);
}
final
boolean
createProjector
=
newInterval
||
(
requestedIntervalScaleIndex
!=
currentIntervalScaleIndex
);
...
...
@@ -588,7 +604,7 @@ public class MultiResolutionRenderer
final
double
ty
=
interval
.
min
(
1
)
*
relativeScale
;
intervalRenderData
=
new
IntervalRenderData
(
targetInterval
,
tx
,
ty
);
renderingMayBeCancelled
=
(
requestedIntervalScaleIndex
<
maxIntervalScaleIndex
)
;
renderingMayBeCancelled
=
!
newInterval
;
}
p
=
projector
;
}
...
...
@@ -605,13 +621,14 @@ public class MultiResolutionRenderer
currentRenderResult
.
patch
(
intervalResult
,
intervalRenderData
.
targetInterval
,
intervalRenderData
.
tx
,
intervalRenderData
.
ty
);
if
(
currentIntervalScaleIndex
>
currentScreenScaleIndex
)
request
RepaintInterval
(
currentIntervalScaleIndex
-
1
);
iterate
RepaintInterval
(
currentIntervalScaleIndex
-
1
);
else
if
(
p
.
isValid
()
)
{
if
(
requestedScreenScaleIndex
>=
0
)
{
// go back to "normal" rendering
intervalMode
=
false
;
renderingMayBeCancelled
=
false
;
if
(
requestedScreenScaleIndex
==
currentScreenScaleIndex
)
++
currentScreenScaleIndex
;
painterThread
.
requestRepaint
();
...
...
@@ -628,7 +645,7 @@ public class MultiResolutionRenderer
// restore interrupted state
Thread
.
currentThread
().
interrupt
();
}
request
RepaintInterval
(
currentIntervalScaleIndex
);
iterate
RepaintInterval
(
currentIntervalScaleIndex
);
}
}
}
...
...
@@ -636,6 +653,12 @@ public class MultiResolutionRenderer
return
success
;
}
private
void
iterateRepaintInterval
(
final
int
intervalScaleIndex
)
{
requestedIntervalScaleIndex
=
intervalScaleIndex
;
painterThread
.
requestRepaint
();
}
private
Interval
scaleScreenInterval
(
final
Interval
requestedScreenInterval
,
final
int
intervalScaleIndex
)
{
final
int
clipW
=
screenScales
[
intervalScaleIndex
].
w
;
...
...
@@ -651,15 +674,9 @@ public class MultiResolutionRenderer
);
}
private
void
requestRepaintInterval
(
final
int
intervalScaleIndex
)
{
requestedIntervalScaleIndex
=
intervalScaleIndex
;
painterThread
.
requestRepaint
();
}
public
synchronized
void
requestRepaint
(
final
Interval
screenInterval
)
{
if
(
renderingMayBeCancelled
)
if
(
renderingMayBeCancelled
||
intervalMode
)
{
if
(
projector
!=
null
)
projector
.
cancel
();
...
...
@@ -669,8 +686,6 @@ public class MultiResolutionRenderer
painterThread
.
requestRepaint
();
}
else
{
requestRepaint
();
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment