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
1db8f1db
Commit
1db8f1db
authored
5 years ago
by
Tobias Pietzsch
Browse files
Options
Downloads
Patches
Plain Diff
WIP
parent
d5d2e9e0
No related branches found
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
+104
-98
104 additions, 98 deletions
src/main/java/bdv/viewer/render/MultiResolutionRenderer.java
with
104 additions
and
98 deletions
src/main/java/bdv/viewer/render/MultiResolutionRenderer.java
+
104
−
98
View file @
1db8f1db
...
@@ -28,12 +28,8 @@
...
@@ -28,12 +28,8 @@
*/
*/
package
bdv.viewer.render
;
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
java.util.concurrent.ExecutorService
;
import
net.imglib2.Interval
;
import
net.imglib2.Interval
;
import
net.imglib2.RandomAccessibleInterval
;
import
net.imglib2.RandomAccessibleInterval
;
import
net.imglib2.Volatile
;
import
net.imglib2.Volatile
;
...
@@ -44,6 +40,12 @@ import net.imglib2.ui.PainterThread;
...
@@ -44,6 +40,12 @@ import net.imglib2.ui.PainterThread;
import
net.imglib2.ui.RenderTarget
;
import
net.imglib2.ui.RenderTarget
;
import
net.imglib2.util.Intervals
;
import
net.imglib2.util.Intervals
;
import
bdv.cache.CacheControl
;
import
bdv.util.MovingAverage
;
import
bdv.viewer.ViewerState
;
import
bdv.viewer.render.ScreenScales.IntervalRenderData
;
import
bdv.viewer.render.ScreenScales.ScreenScale
;
/**
/**
* A renderer that uses a coarse-to-fine rendering scheme. First, a small target
* 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
* image at a fraction of the canvas resolution is rendered. Then, increasingly
...
@@ -191,6 +193,12 @@ public class MultiResolutionRenderer
...
@@ -191,6 +193,12 @@ public class MultiResolutionRenderer
*/
*/
private
boolean
newIntervalRequest
;
private
boolean
newIntervalRequest
;
// =========== intervals ==========================================================================================
private
RenderResult
currentRenderResult
;
private
final
RenderResult
intervalResult
;
private
IntervalRenderData
intervalRenderData
;
// =========== intervals ==========================================================================================
/**
/**
* @param display
* @param display
* The canvas that will display the images we render.
* The canvas that will display the images we render.
...
@@ -256,6 +264,59 @@ public class MultiResolutionRenderer
...
@@ -256,6 +264,59 @@ public class MultiResolutionRenderer
accumulateProjectorFactory
);
accumulateProjectorFactory
);
}
}
/**
* Request a repaint of the display from the painter thread. The painter
* thread will trigger a {@link #paint} as soon as possible (that is,
* immediately or after the currently running {@link #paint} has completed).
*/
public
synchronized
void
requestRepaint
()
{
if
(
renderingMayBeCancelled
&&
projector
!=
null
)
projector
.
cancel
();
newFrameRequest
=
true
;
painterThread
.
requestRepaint
();
}
/**
* Request a repaint of the given {@code interval} of the display from the
* painter thread. The painter thread will trigger a {@link #paint} as soon
* as possible (that is, immediately or after the currently running
* {@link #paint} has completed).
*/
public
synchronized
void
requestRepaint
(
final
Interval
interval
)
{
if
(
!
intervalMode
&&
!
renderingMayBeCancelled
)
{
/*
* We are currently rendering a full frame at the coarsest
* resolution. There is no point in painting an interval now. Just
* request a new full frame.
*/
newFrameRequest
=
true
;
}
else
{
if
(
renderingMayBeCancelled
&&
projector
!=
null
)
projector
.
cancel
();
screenScales
.
requestInterval
(
interval
);
newIntervalRequest
=
true
;
}
painterThread
.
requestRepaint
();
}
/**
* DON'T USE THIS.
* <p>
* This is a work around for JDK bug
* https://bugs.openjdk.java.net/browse/JDK-8029147 which leads to
* ViewerPanel not being garbage-collected when ViewerFrame is closed. So
* instead we need to manually let go of resources...
*/
public
void
kill
()
{
projector
=
null
;
renderStorage
.
clear
();
}
/**
/**
* Render image at the {@link #requestedScreenScaleIndex requested screen
* Render image at the {@link #requestedScreenScaleIndex requested screen
...
@@ -268,15 +329,14 @@ public class MultiResolutionRenderer
...
@@ -268,15 +329,14 @@ public class MultiResolutionRenderer
if
(
screenW
<=
0
||
screenH
<=
0
)
if
(
screenW
<=
0
||
screenH
<=
0
)
return
false
;
return
false
;
final
boolean
resized
;
final
boolean
newFrame
;
final
boolean
newFrame
;
final
boolean
newInterval
;
final
boolean
newInterval
;
final
boolean
paintInterval
;
final
boolean
paintInterval
;
final
boolean
prepareNextFrame
;
final
boolean
prepareNextFrame
;
boolean
createProjector
=
false
;
final
boolean
createProjector
;
synchronized
(
this
)
synchronized
(
this
)
{
{
resized
=
screenScales
.
checkResize
(
screenW
,
screenH
);
final
boolean
resized
=
screenScales
.
checkResize
(
screenW
,
screenH
);
newFrame
=
newFrameRequest
||
resized
;
newFrame
=
newFrameRequest
||
resized
;
if
(
newFrame
)
if
(
newFrame
)
...
@@ -302,6 +362,11 @@ public class MultiResolutionRenderer
...
@@ -302,6 +362,11 @@ public class MultiResolutionRenderer
if
(
createProjector
)
if
(
createProjector
)
intervalRenderData
=
screenScales
.
pullIntervalRenderData
(
requestedIntervalScaleIndex
,
currentScreenScaleIndex
);
intervalRenderData
=
screenScales
.
pullIntervalRenderData
(
requestedIntervalScaleIndex
,
currentScreenScaleIndex
);
}
}
else
{
createProjector
=
newFrame
||
(
requestedScreenScaleIndex
!=
currentScreenScaleIndex
);
}
newFrameRequest
=
false
;
newFrameRequest
=
false
;
newIntervalRequest
=
false
;
newIntervalRequest
=
false
;
...
@@ -327,26 +392,18 @@ public class MultiResolutionRenderer
...
@@ -327,26 +392,18 @@ public class MultiResolutionRenderer
// whether to request a newFrame, in case that a new projector is created in full frame mode
// whether to request a newFrame, in case that a new projector is created in full frame mode
boolean
requestNewFrameIfIncomplete
=
false
;
boolean
requestNewFrameIfIncomplete
=
false
;
if
(
paintInterval
)
synchronized
(
this
)
{
{
intervalResult
.
init
(
intervalRenderData
.
width
(),
intervalRenderData
.
height
()
);
if
(
createProjector
)
intervalResult
.
setScaleFactor
(
intervalRenderData
.
scale
()
);
synchronized
(
this
)
{
{
if
(
createProjector
)
if
(
paintInterval
)
{
{
intervalResult
.
init
(
intervalRenderData
.
width
(),
intervalRenderData
.
height
()
);
intervalResult
.
setScaleFactor
(
intervalRenderData
.
scale
()
);
projector
=
createProjector
(
currentViewerState
,
requestedIntervalScaleIndex
,
intervalResult
.
getScreenImage
(),
intervalRenderData
.
offsetX
(),
intervalRenderData
.
offsetY
()
);
projector
=
createProjector
(
currentViewerState
,
requestedIntervalScaleIndex
,
intervalResult
.
getScreenImage
(),
intervalRenderData
.
offsetX
(),
intervalRenderData
.
offsetY
()
);
renderingMayBeCancelled
=
!
newInterval
;
renderingMayBeCancelled
=
!
newInterval
;
}
}
p
=
projector
;
else
}
}
else
{
createProjector
=
newFrame
||
(
requestedScreenScaleIndex
!=
currentScreenScaleIndex
);
synchronized
(
this
)
{
if
(
createProjector
)
{
{
final
ScreenScale
screenScale
=
screenScales
.
get
(
requestedScreenScaleIndex
);
final
ScreenScale
screenScale
=
screenScales
.
get
(
requestedScreenScaleIndex
);
...
@@ -360,8 +417,8 @@ public class MultiResolutionRenderer
...
@@ -360,8 +417,8 @@ public class MultiResolutionRenderer
requestNewFrameIfIncomplete
=
projectorFactory
.
requestNewFrameIfIncomplete
();
requestNewFrameIfIncomplete
=
projectorFactory
.
requestNewFrameIfIncomplete
();
renderingMayBeCancelled
=
!
newFrame
;
renderingMayBeCancelled
=
!
newFrame
;
}
}
p
=
projector
;
}
}
p
=
projector
;
}
}
...
@@ -377,37 +434,31 @@ public class MultiResolutionRenderer
...
@@ -377,37 +434,31 @@ public class MultiResolutionRenderer
{
{
if
(
paintInterval
)
if
(
paintInterval
)
{
{
if
(
createProjector
)
currentIntervalScaleIndex
=
requestedIntervalScaleIndex
;
currentIntervalScaleIndex
=
requestedIntervalScaleIndex
;
currentRenderResult
.
patch
(
intervalResult
,
intervalRenderData
.
targetInterval
(),
intervalRenderData
.
tx
(),
intervalRenderData
.
ty
()
);
currentRenderResult
.
patch
(
intervalResult
,
intervalRenderData
.
targetInterval
(),
intervalRenderData
.
tx
(),
intervalRenderData
.
ty
()
);
if
(
currentIntervalScaleIndex
>
currentScreenScaleIndex
)
if
(
currentIntervalScaleIndex
>
currentScreenScaleIndex
)
iterateRepaintInterval
(
currentIntervalScaleIndex
-
1
);
iterateRepaintInterval
(
currentIntervalScaleIndex
-
1
);
else
if
(
p
.
isValid
()
)
else
if
(
p
.
isValid
()
)
{
{
// if full frame rendering was not yet complete
if
(
requestedScreenScaleIndex
>=
0
)
if
(
requestedScreenScaleIndex
>=
0
)
{
{
// go back to
"normal"
rendering
// go back to
full frame
rendering
intervalMode
=
false
;
intervalMode
=
false
;
renderingMayBeCancelled
=
false
;
if
(
requestedScreenScaleIndex
==
currentScreenScaleIndex
)
if
(
requestedScreenScaleIndex
==
currentScreenScaleIndex
)
++
currentScreenScaleIndex
;
++
currentScreenScaleIndex
;
painterThread
.
requestRepaint
();
painterThread
.
requestRepaint
();
}
}
}
}
else
else
{
usleep
();
intervalRenderData
.
reRequest
();
iterateRepaintInterval
(
currentIntervalScaleIndex
);
iterateRepaintInterval
(
currentIntervalScaleIndex
);
}
}
}
else
else
{
{
currentScreenScaleIndex
=
requestedScreenScaleIndex
;
if
(
createProjector
)
if
(
createProjector
)
{
{
currentScreenScaleIndex
=
requestedScreenScaleIndex
;
renderResult
.
setUpdated
();
renderResult
.
setUpdated
();
(
(
RenderTarget
)
display
).
setRenderResult
(
renderResult
);
(
(
RenderTarget
)
display
).
setRenderResult
(
renderResult
);
currentRenderResult
=
renderResult
;
currentRenderResult
=
renderResult
;
...
@@ -423,18 +474,11 @@ public class MultiResolutionRenderer
...
@@ -423,18 +474,11 @@ public class MultiResolutionRenderer
if
(
!
p
.
isValid
()
&&
requestNewFrameIfIncomplete
)
if
(
!
p
.
isValid
()
&&
requestNewFrameIfIncomplete
)
requestRepaint
();
requestRepaint
();
else
if
(
currentScreenScaleIndex
>
0
)
else
if
(
p
.
isValid
()
&&
currentScreenScaleIndex
==
0
)
iterateRepaint
(
currentScreenScaleIndex
-
1
);
else
if
(
p
.
isValid
()
)
{
// indicate that rendering is complete
// indicate that rendering is complete
requestedScreenScaleIndex
=
-
1
;
requestedScreenScaleIndex
=
-
1
;
}
else
else
{
iterateRepaint
(
Math
.
max
(
0
,
currentScreenScaleIndex
-
1
)
);
usleep
();
iterateRepaint
(
currentScreenScaleIndex
);
}
}
}
}
}
// if rendering was cancelled...
// if rendering was cancelled...
...
@@ -458,49 +502,37 @@ public class MultiResolutionRenderer
...
@@ -458,49 +502,37 @@ public class MultiResolutionRenderer
*/
*/
private
void
iterateRepaint
(
final
int
screenScaleIndex
)
private
void
iterateRepaint
(
final
int
screenScaleIndex
)
{
{
if
(
screenScaleIndex
==
currentScreenScaleIndex
)
usleep
();
requestedScreenScaleIndex
=
screenScaleIndex
;
requestedScreenScaleIndex
=
screenScaleIndex
;
painterThread
.
requestRepaint
();
painterThread
.
requestRepaint
();
}
}
/**
private
void
iterateRepaintInterval
(
final
int
intervalScaleIndex
)
* Request a repaint of the display from the painter thread. The painter
* thread will trigger a {@link #paint} as soon as possible (that is,
* immediately or after the currently running {@link #paint} has completed).
*/
public
synchronized
void
requestRepaint
()
{
if
(
renderingMayBeCancelled
&&
projector
!=
null
)
projector
.
cancel
();
newFrameRequest
=
true
;
painterThread
.
requestRepaint
();
}
public
synchronized
void
requestRepaint
(
final
Interval
screenInterval
)
{
{
if
(
renderingMayBeCancelled
||
intervalMo
de
)
if
(
intervalScaleIndex
==
currentIntervalScaleIn
de
x
)
{
{
if
(
projector
!=
null
)
intervalRenderData
.
reRequest
();
projector
.
cancel
();
usleep
();
screenScales
.
requestInterval
(
screenInterval
);
newIntervalRequest
=
true
;
}
}
else
requestedIntervalScaleIndex
=
intervalScaleIndex
;
newFrameRequest
=
true
;
painterThread
.
requestRepaint
();
painterThread
.
requestRepaint
();
}
}
/**
/**
* DON'T USE THIS.
* Wait for 1ms so that fetcher threads get a chance to do work.
* <p>
* This is a work around for JDK bug
* https://bugs.openjdk.java.net/browse/JDK-8029147 which leads to
* ViewerPanel not being garbage-collected when ViewerFrame is closed. So
* instead we need to manually let go of resources...
*/
*/
p
ublic
void
kill
()
p
rivate
void
usleep
()
{
{
projector
=
null
;
try
renderStorage
.
clear
();
{
Thread
.
sleep
(
1
);
}
catch
(
final
InterruptedException
e
)
{
// restore interrupted state
Thread
.
currentThread
().
interrupt
();
}
}
}
private
VolatileProjector
createProjector
(
private
VolatileProjector
createProjector
(
...
@@ -529,30 +561,4 @@ public class MultiResolutionRenderer
...
@@ -529,30 +561,4 @@ public class MultiResolutionRenderer
CacheIoTiming
.
getIoTimeBudget
().
reset
(
iobudget
);
CacheIoTiming
.
getIoTimeBudget
().
reset
(
iobudget
);
return
projector
;
return
projector
;
}
}
// =========== intervals ==========================================================================================
private
RenderResult
currentRenderResult
;
private
final
RenderResult
intervalResult
;
private
IntervalRenderData
intervalRenderData
;
private
void
iterateRepaintInterval
(
final
int
intervalScaleIndex
)
{
requestedIntervalScaleIndex
=
intervalScaleIndex
;
painterThread
.
requestRepaint
();
}
private
void
usleep
()
{
try
{
Thread
.
sleep
(
1
);
}
catch
(
final
InterruptedException
e
)
{
// restore interrupted state
Thread
.
currentThread
().
interrupt
();
}
}
}
}
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