Class ALcdGXYAsynchronousPaintQueueManager
- Direct Known Subclasses:
TLcdGXYAsynchronousPaintQueueManager
An abstract manager for automatically assigning ILcdGXYAsynchronousPaintQueue
instances to asynchronously painted layers which do not yet have a paint queue.
When assigning paint queues to layers, you can choose to share queues, which has the following advantages:
- buffers can be shared, reducing memory overhead and view compositing overhead. This view compositing overhead is caused by compositing the painted results of the different paint queues into one result suited for the view. (A1)
- threads can be shared, reducing CPU overhead. On a multi-core system, one should consider having multiple paint queues to optimally use the available CPU resources. (A2)
Sharing also has some limitations:
- layers cannot share a paint queue if they are not adjacent. This means that two layers separated by a synchronously painted layer can never share a paint queue. (L1)
- the visual results from shared paint queues are only shown when all layers in the paint queue have been painted. This means that a slow layer will prevent a fast layer from being updated if both share the same paint queue. In such case, it might be better to use separate paint queues for the fast and slow layers. (L2)
- real-time and background layers cannot share a paint queue (L3)
This manager offers some basic functionality and operations to find an acceptable compromise
between resources and requirements. To do this, it divides a view's layers into paint blocks
. A paint block is a contiguous set of layers with the same paint queue. This paint
queue is only null
for synchronously painted layers and asynchronous layers not
managed by this manager. The manager provides methods to split
, merge
and replace
paint blocks.
Furthermore, it automatically:
- splits paint blocks when layers are added/moved/removed to ensure that limitations L1 and L3 are not violated.
- informs the implementation when layers are added/moved/removed providing it with the possibility to optimize the paint blocks by using the provided paint block operations.
- handles the possibility to insert the asynchronous layers in multiple views simultaneously.
Implementing classes should implement the following methods:
createAsynchronousPaintQueue(java.util.List)
, a factory method for creating paint queues for a given set of layersevaluateModifiedPaintBlocks(java.util.List<com.luciad.view.gxy.asynchronous.manager.ALcdGXYAsynchronousPaintQueueManager.PaintBlock>, com.luciad.view.gxy.ILcdGXYLayer)
, a method to further optimize the given paint blocks. Typical behavior of this method will merge paint blocks to make use of advantages A1 and A2, and split blocks to avoid limitation L2.
This manager has some limitations:
- The manager will only assign paint queues to
ILcdGXYAsynchronousLayerWrapper
instances which are added to the view with anull
queue, and not affect anyILcdGXYAsynchronousLayerWrapper
which is added with a non-null
queue. Even when the queue of such a wrapper is replaced by anull
queue afterwards, it will not be handled by this manager. - It is not allowed to manually change the paint queue of
ILcdGXYAsynchronousLayerWrapper
instances that are managed by an instance of this class.
Warning: all methods of this class must only be called on the Event Dispatch Thread (EDT).
- Since:
- 10.1
- See Also:
-
Nested Class Summary
Modifier and TypeClassDescriptionclass
A contiguous set of layers sharing the same paint queue. -
Constructor Summary
ModifierConstructorDescriptionprotected
Creates a newALcdGXYAsynchronousPaintQueueManager
which can manage theILcdGXYAsynchronousPaintQueue
s of theILcdGXYAsynchronousLayerWrapper
instances contained in a view. -
Method Summary
Modifier and TypeMethodDescriptionboolean
canMergePaintBlocks
(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlock, ALcdGXYAsynchronousPaintQueueManager.PaintBlock aAdjacentPaintBlock) Utility method to verify the prerequisites listed in themergePaintBlocks
method.protected abstract ILcdGXYAsynchronousPaintQueue
Factory method to create a newILcdGXYAsynchronousPaintQueue
that will be used byaLayers
.abstract void
evaluateModifiedPaintBlocks
(List<ALcdGXYAsynchronousPaintQueueManager.PaintBlock> aChangedPaintBlocks, ILcdGXYLayer aLayer) Method to inform the implementation thataChangedPaintBlocks
should be re-evaluated.Returns the view for which thisALcdGXYAsynchronousPaintQueueManager
is created.getPaintBlock
(ILcdGXYLayer aLayer) Returns thePaintBlock
containingaLayer
.Returns an ordered, unmodifiableList
of allPaintBlock
instances.final void
mergePaintBlocksSFCT
(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlockSFCT, ALcdGXYAsynchronousPaintQueueManager.PaintBlock aAdjacentPaintBlock) Merge the layers ofaPaintBlockSFCT
andaAdjacentPaintBlock
intoaPaintBlockSFCT
.replacePaintBlockSFCT
(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlock, ILcdGXYAsynchronousPaintQueue aPaintQueue) void
setGXYView
(ILcdGXYView aGXYView) Set the view for which thisALcdGXYAsynchronousPaintQueueManager
should manage the paint queues.splitPaintBlockSFCT
(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlockToSplitSFCT, int aFirstBlockSize) SplitaPaintBlockToSplitSFCT
in two separatePaintBlock
instances: the existingPaintBlock
containing the firstaFirstBlockSize
originalILcdGXYLayer
s, and a newPaintBlock
containing all remainingILcdGXYLayer
s.
-
Constructor Details
-
ALcdGXYAsynchronousPaintQueueManager
protected ALcdGXYAsynchronousPaintQueueManager()Creates a new
ALcdGXYAsynchronousPaintQueueManager
which can manage theILcdGXYAsynchronousPaintQueue
s of theILcdGXYAsynchronousLayerWrapper
instances contained in a view.Call
setGXYView
before using this manager.
-
-
Method Details
-
setGXYView
Set the view for which this
ALcdGXYAsynchronousPaintQueueManager
should manage the paint queues.For the initialization of this manager, it will create separate paint queues and corresponding
PaintBlock
s for every asynchronous layer withnull
queue in the view followed by a call to theevaluateModifiedPaintBlocks
method allowing to merge / split the createdPaintBlock
s. Once this initialization is finished, it will react on the events fired by the view and the layers.When this manager is already managing a view, calling this method with a non-null view is equivalent to calling this method successively with
null
andaGXYView
.Calling this method with a
null
view, will remove all attached listeners, and clear the internal state of the manager. It will also reset all the paint queues of the layers this manager is managing tonull
. Therefore, if this method is called when the layers are still contained in a view, it is necessary to set new paint queues to all asynchronous layers (e.g. by creating a newALcdGXYAsynchronousPaintQueueManager
for the view) before the layers are (re)painted.Once this method is called on an
ALcdGXYAsynchronousPaintQueueManager
that particular manager can no longer be used until a new non-null view is set, since all internal state is cleared. A possible use case of calling this method with a null view is if you want to change theALcdGXYAsynchronousPaintQueueManager
for a certain view.- Parameters:
aGXYView
- The view to manage, ornull
to deactivate this manager.
-
getPaintBlocks
Returns an ordered, unmodifiable
List
of allPaintBlock
instances. ThePaintBlock
at index 0 will contain theILcdGXYLayer
which has index 0 in the view.- Returns:
- an ordered, unmodifiable
List
of allPaintBlock
instances
-
getPaintBlock
Returns the
PaintBlock
containingaLayer
.- Parameters:
aLayer
- the layer to search the PaintBlock for.- Returns:
- the
PaintBlock
containingaLayer
.
-
evaluateModifiedPaintBlocks
public abstract void evaluateModifiedPaintBlocks(List<ALcdGXYAsynchronousPaintQueueManager.PaintBlock> aChangedPaintBlocks, ILcdGXYLayer aLayer) Method to inform the implementation that
aChangedPaintBlocks
should be re-evaluated. This method is called by the manager- when a new asynchronous layer is added to the view. For every new asynchronous layer a new paint queue is created, and a corresponding paint block is inserted. This method is then called including that new block and its neighbor blocks.
- when a synchronous layer is added to the view, causing an existing paint block to split.
Both parts of the split paint block will be included in
aChangedPaintBlocks
. - when an asynchronous layer is removed from the view.
aChangedPaintBlocks
will contain thePaintBlock
previously containing the layer. In case the paint block is empty and removed, the adjacentPaintBlock
instances will be contained inaChangedPaintBlocks
. - when a synchronous layer is removed, and the corresponding paint block becomes empty and is
removed as well.
aChangedPaintBlocks
will contain the adjacentPaintBlock
s of the removed instance. - when a layer is moved from index
x
to indexy
,aChangedPaintBlocks
will contain the samePaintBlock
s as when the layer was removed from indexx
and added to indexy
, as described above. - when the numberOfCachedBackgroundLayers property of the view changes. The list of changed paint blocks will contain the paint blocks which were split due to the original value of that property, and the paint blocks which are now split due to the new value of that property.
- when adding, removing and/or moving an
ILcdLayerTreeNode
with child layers, this method is only called once with theILcdLayerTreeNode
as parameter. TheList
of changed paint blocks will then include all relevantPaintBlock
s, based on the criteria listed above.
Typically, implementations of this method will call the
split
andmerge
methods of the manager to indicate which layers should share a paint queue.An example implementation of this method is one which tries to minimize the number of paint queues, by always merging adjacent paint blocks with a non-
null
queue.This method may be called from outside the manager as well, e.g. when the criteria to share a paint queue have been changed.
Note that this method will not be called when manual changes are applied to the paint blocks. For example, calling the merge, split and/or replace methods will not trigger this method.
- Parameters:
aChangedPaintBlocks
- AList
containing allPaintBlock
s remaining in this manager which must be re-evaluated. In case aPaintBlock
is removed or inserted, thisList
will also include the neighborPaintBlock
instances. The paint queue of thesePaintBlock
s will never benull
. ThePaintBlock
s in thisList
are ordered in the same way as in thegetPaintBlocks()
List
aLayer
- TheILcdGXYLayer
in which the change, triggering the call of this method, occurred, ornull
when the change was not triggered by a specific layer.
-
createAsynchronousPaintQueue
protected abstract ILcdGXYAsynchronousPaintQueue createAsynchronousPaintQueue(List<ILcdGXYAsynchronousLayerWrapper> aLayers) Factory method to create a new
ILcdGXYAsynchronousPaintQueue
that will be used byaLayers
. The returnedILcdGXYAsynchronousPaintQueue
must be a new instance, and must not be in use by any existingPaintBlock
.This method should always return a non-
null
paint queue which may be used by all layers inaLayers
. EitheraLayers
will only contain oneILcdGXYAsynchronousLayerWrapper
, or a set ofILcdGXYAsynchronousLayerWrapper
s which were already part of onePaintBlock
with a non-null
paint queue. Therefore this method should always be able to return a non-null
paint queue.The manager may wrap paint queues, so it may be that the returned
ILcdGXYAsynchronousPaintQueue
is not set directly as paint queue on the layers.The manager calls this method:
- Every time an asynchronous layer is added to the view, or moved outside its current paint
block. In such cases, the evaluateModifiedPaintBlocks can decided to merge the new
paint queue immediately with an existing one. Therefore it is recommended to return
ILcdGXYAsynchronousPaintQueue
instances which only allocate resources (e.g. a buffer and a separateThread
) when needed, and not on creation. - From the merge and split methods when no paint queue was specified for the resulting paint block.
- Parameters:
aLayers
- theILcdGXYAsynchronousLayerWrapper
s that will use the returnedILcdGXYAsynchronousPaintQueue
- Returns:
- a new
ILcdGXYAsynchronousPaintQueue
instance. Must not benull
- Every time an asynchronous layer is added to the view, or moved outside its current paint
block. In such cases, the evaluateModifiedPaintBlocks can decided to merge the new
paint queue immediately with an existing one. Therefore it is recommended to return
-
splitPaintBlockSFCT
public final ALcdGXYAsynchronousPaintQueueManager.PaintBlock splitPaintBlockSFCT(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlockToSplitSFCT, int aFirstBlockSize) Split
aPaintBlockToSplitSFCT
in two separatePaintBlock
instances: the existingPaintBlock
containing the firstaFirstBlockSize
originalILcdGXYLayer
s, and a newPaintBlock
containing all remainingILcdGXYLayer
s.The newly created
PaintBlock
will call thecreateAsynchronousPaintQueue
method to obtain its paint queue..- Parameters:
aPaintBlockToSplitSFCT
- ThePaintBlock
that will be split. Must have a non-null
paint queue.aFirstBlockSize
- The size of the first block. Must be greater than 0 and smaller thenaPaintBlockToSplit.getLayers().size()
- Returns:
- the newly created
PaintBlock
instance
-
canMergePaintBlocks
public boolean canMergePaintBlocks(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlock, ALcdGXYAsynchronousPaintQueueManager.PaintBlock aAdjacentPaintBlock) Utility method to verify the prerequisites listed in the
mergePaintBlocks
method. Returnstrue
when the mergePaintBlocks method can be called with the same arguments,false
otherwise.- Parameters:
aPaintBlock
- aPaintBlock
aAdjacentPaintBlock
- an adjacentPaintBlock
- Returns:
true
whenaPaintBlock
andaAdjacentPaintBlock
can be merged,false
otherwise- See Also:
-
mergePaintBlocksSFCT
public final void mergePaintBlocksSFCT(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlockSFCT, ALcdGXYAsynchronousPaintQueueManager.PaintBlock aAdjacentPaintBlock) Merge the layers of
aPaintBlockSFCT
andaAdjacentPaintBlock
intoaPaintBlockSFCT
.Merging two paint blocks is only possible if:
- the two
PaintBlock
instances are adjacent - the two
PaintBlock
instances have a non-null
paint queue. - merging the two
PaintBlock
s will not result in a paint queue which is used by background and non-background layers (see ILcdGXYView#getNumberOfCachedBackgroundLayers()).
The prerequisites of this method can be verified by using the
canMergePaintBlocks
method. It is up to the user of this method to verify those prerequisites before calling this method.- Parameters:
aPaintBlockSFCT
- ThePaintBlock
to which all layers ofaAdjacentPaintBlock
will be added.aAdjacentPaintBlock
- an adjacentPaintBlock
- See Also:
- the two
-
replacePaintBlockSFCT
public final ALcdGXYAsynchronousPaintQueueManager.PaintBlock replacePaintBlockSFCT(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlock, ILcdGXYAsynchronousPaintQueue aPaintQueue) Replace
aPaintBlock
by a newPaintBlock
withaPaintQueue
as paint queue.It is not possible to replace a
null
queue with anon-null
queue. When the paint queue ofaPaintBlock
is notnull
andaPaintQueue
isnull
, thecreateAsynchronousPaintQueue
method will be used to create a new paint queue.This method will have no effect when
aPaintQueue
is the paint queue ofaPaintBlock
, and just returnaPaintBlock
.- Parameters:
aPaintBlock
- ThePaintBlock
to replace.aPaintQueue
- TheILcdGXYAsynchronousPaintQueue
for the newPaintBlock
. Must not be used by any otherPaintBlock
, and can only benull
if the paint queue ofaPaintBlock
isnull
.- Returns:
- The new
PaintBlock
, oraPaintBlock
in caseaPaintQueue
is already the paint queue ofaPaintBlock
-
getGXYView
Returns the view for which thisALcdGXYAsynchronousPaintQueueManager
is created.- Returns:
- the view for which this
ALcdGXYAsynchronousPaintQueueManager
is created.
-