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
ILcdGXYAsynchronousLayerWrapperinstances which are added to the view with anullqueue, and not affect anyILcdGXYAsynchronousLayerWrapperwhich is added with a non-nullqueue. Even when the queue of such a wrapper is replaced by anullqueue afterwards, it will not be handled by this manager. - It is not allowed to manually change the paint queue of
ILcdGXYAsynchronousLayerWrapperinstances 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
Nested ClassesModifier and TypeClassDescriptionclassA contiguous set of layers sharing the same paint queue. -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedCreates a newALcdGXYAsynchronousPaintQueueManagerwhich can manage theILcdGXYAsynchronousPaintQueues of theILcdGXYAsynchronousLayerWrapperinstances contained in a view. -
Method Summary
Modifier and TypeMethodDescriptionbooleancanMergePaintBlocks(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlock, ALcdGXYAsynchronousPaintQueueManager.PaintBlock aAdjacentPaintBlock) Utility method to verify the prerequisites listed in themergePaintBlocksmethod.protected abstract ILcdGXYAsynchronousPaintQueueFactory method to create a newILcdGXYAsynchronousPaintQueuethat will be used byaLayers.abstract voidevaluateModifiedPaintBlocks(List<ALcdGXYAsynchronousPaintQueueManager.PaintBlock> aChangedPaintBlocks, ILcdGXYLayer aLayer) Method to inform the implementation thataChangedPaintBlocksshould be re-evaluated.Returns the view for which thisALcdGXYAsynchronousPaintQueueManageris created.getPaintBlock(ILcdGXYLayer aLayer) Returns thePaintBlockcontainingaLayer.Returns an ordered, unmodifiableListof allPaintBlockinstances.final voidmergePaintBlocksSFCT(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlockSFCT, ALcdGXYAsynchronousPaintQueueManager.PaintBlock aAdjacentPaintBlock) Merge the layers ofaPaintBlockSFCTandaAdjacentPaintBlockintoaPaintBlockSFCT.replacePaintBlockSFCT(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlock, ILcdGXYAsynchronousPaintQueue aPaintQueue) voidsetGXYView(ILcdGXYView aGXYView) Set the view for which thisALcdGXYAsynchronousPaintQueueManagershould manage the paint queues.splitPaintBlockSFCT(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlockToSplitSFCT, int aFirstBlockSize) SplitaPaintBlockToSplitSFCTin two separatePaintBlockinstances: the existingPaintBlockcontaining the firstaFirstBlockSizeoriginalILcdGXYLayers, and a newPaintBlockcontaining all remainingILcdGXYLayers.
-
Constructor Details
-
ALcdGXYAsynchronousPaintQueueManager
protected ALcdGXYAsynchronousPaintQueueManager()Creates a new
ALcdGXYAsynchronousPaintQueueManagerwhich can manage theILcdGXYAsynchronousPaintQueues of theILcdGXYAsynchronousLayerWrapperinstances contained in a view.Call
setGXYViewbefore using this manager.
-
-
Method Details
-
setGXYView
Set the view for which this
ALcdGXYAsynchronousPaintQueueManagershould manage the paint queues.For the initialization of this manager, it will create separate paint queues and corresponding
PaintBlocks for every asynchronous layer withnullqueue in the view followed by a call to theevaluateModifiedPaintBlocksmethod allowing to merge / split the createdPaintBlocks. 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
nullandaGXYView.Calling this method with a
nullview, 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 newALcdGXYAsynchronousPaintQueueManagerfor the view) before the layers are (re)painted.Once this method is called on an
ALcdGXYAsynchronousPaintQueueManagerthat 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 theALcdGXYAsynchronousPaintQueueManagerfor a certain view.- Parameters:
aGXYView- The view to manage, ornullto deactivate this manager.
-
getPaintBlocks
Returns an ordered, unmodifiable
Listof allPaintBlockinstances. ThePaintBlockat index 0 will contain theILcdGXYLayerwhich has index 0 in the view.- Returns:
- an ordered, unmodifiable
Listof allPaintBlockinstances
-
getPaintBlock
Returns the
PaintBlockcontainingaLayer.- Parameters:
aLayer- the layer to search the PaintBlock for.- Returns:
- the
PaintBlockcontainingaLayer.
-
evaluateModifiedPaintBlocks
public abstract void evaluateModifiedPaintBlocks(List<ALcdGXYAsynchronousPaintQueueManager.PaintBlock> aChangedPaintBlocks, ILcdGXYLayer aLayer) Method to inform the implementation that
aChangedPaintBlocksshould 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.
aChangedPaintBlockswill contain thePaintBlockpreviously containing the layer. In case the paint block is empty and removed, the adjacentPaintBlockinstances will be contained inaChangedPaintBlocks. - when a synchronous layer is removed, and the corresponding paint block becomes empty and is
removed as well.
aChangedPaintBlockswill contain the adjacentPaintBlocks of the removed instance. - when a layer is moved from index
xto indexy,aChangedPaintBlockswill contain the samePaintBlocks as when the layer was removed from indexxand 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
ILcdLayerTreeNodewith child layers, this method is only called once with theILcdLayerTreeNodeas parameter. TheListof changed paint blocks will then include all relevantPaintBlocks, based on the criteria listed above.
Typically, implementations of this method will call the
splitandmergemethods 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-
nullqueue.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- AListcontaining allPaintBlocks remaining in this manager which must be re-evaluated. In case aPaintBlockis removed or inserted, thisListwill also include the neighborPaintBlockinstances. The paint queue of thesePaintBlocks will never benull. ThePaintBlocks in thisListare ordered in the same way as in thegetPaintBlocks()ListaLayer- TheILcdGXYLayerin which the change, triggering the call of this method, occurred, ornullwhen the change was not triggered by a specific layer.
-
createAsynchronousPaintQueue
protected abstract ILcdGXYAsynchronousPaintQueue createAsynchronousPaintQueue(List<ILcdGXYAsynchronousLayerWrapper> aLayers) Factory method to create a new
ILcdGXYAsynchronousPaintQueuethat will be used byaLayers. The returnedILcdGXYAsynchronousPaintQueuemust be a new instance, and must not be in use by any existingPaintBlock.This method should always return a non-
nullpaint queue which may be used by all layers inaLayers. EitheraLayerswill only contain oneILcdGXYAsynchronousLayerWrapper, or a set ofILcdGXYAsynchronousLayerWrappers which were already part of onePaintBlockwith a non-nullpaint queue. Therefore this method should always be able to return a non-nullpaint queue.The manager may wrap paint queues, so it may be that the returned
ILcdGXYAsynchronousPaintQueueis 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
ILcdGXYAsynchronousPaintQueueinstances 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- theILcdGXYAsynchronousLayerWrappers that will use the returnedILcdGXYAsynchronousPaintQueue- Returns:
- a new
ILcdGXYAsynchronousPaintQueueinstance. 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
aPaintBlockToSplitSFCTin two separatePaintBlockinstances: the existingPaintBlockcontaining the firstaFirstBlockSizeoriginalILcdGXYLayers, and a newPaintBlockcontaining all remainingILcdGXYLayers.The newly created
PaintBlockwill call thecreateAsynchronousPaintQueuemethod to obtain its paint queue..- Parameters:
aPaintBlockToSplitSFCT- ThePaintBlockthat will be split. Must have a non-nullpaint queue.aFirstBlockSize- The size of the first block. Must be greater than 0 and smaller thenaPaintBlockToSplit.getLayers().size()- Returns:
- the newly created
PaintBlockinstance
-
canMergePaintBlocks
public boolean canMergePaintBlocks(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlock, ALcdGXYAsynchronousPaintQueueManager.PaintBlock aAdjacentPaintBlock) Utility method to verify the prerequisites listed in the
mergePaintBlocksmethod. Returnstruewhen the mergePaintBlocks method can be called with the same arguments,falseotherwise.- Parameters:
aPaintBlock- aPaintBlockaAdjacentPaintBlock- an adjacentPaintBlock- Returns:
truewhenaPaintBlockandaAdjacentPaintBlockcan be merged,falseotherwise- See Also:
-
mergePaintBlocksSFCT
public final void mergePaintBlocksSFCT(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlockSFCT, ALcdGXYAsynchronousPaintQueueManager.PaintBlock aAdjacentPaintBlock) Merge the layers of
aPaintBlockSFCTandaAdjacentPaintBlockintoaPaintBlockSFCT.Merging two paint blocks is only possible if:
- the two
PaintBlockinstances are adjacent - the two
PaintBlockinstances have a non-nullpaint queue. - merging the two
PaintBlocks 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
canMergePaintBlocksmethod. It is up to the user of this method to verify those prerequisites before calling this method.- Parameters:
aPaintBlockSFCT- ThePaintBlockto which all layers ofaAdjacentPaintBlockwill be added.aAdjacentPaintBlock- an adjacentPaintBlock- See Also:
- the two
-
replacePaintBlockSFCT
public final ALcdGXYAsynchronousPaintQueueManager.PaintBlock replacePaintBlockSFCT(ALcdGXYAsynchronousPaintQueueManager.PaintBlock aPaintBlock, ILcdGXYAsynchronousPaintQueue aPaintQueue) Replace
aPaintBlockby a newPaintBlockwithaPaintQueueas paint queue.It is not possible to replace a
nullqueue with anon-nullqueue. When the paint queue ofaPaintBlockis notnullandaPaintQueueisnull, thecreateAsynchronousPaintQueuemethod will be used to create a new paint queue.This method will have no effect when
aPaintQueueis the paint queue ofaPaintBlock, and just returnaPaintBlock.- Parameters:
aPaintBlock- ThePaintBlockto replace.aPaintQueue- TheILcdGXYAsynchronousPaintQueuefor the newPaintBlock. Must not be used by any otherPaintBlock, and can only benullif the paint queue ofaPaintBlockisnull.- Returns:
- The new
PaintBlock, oraPaintBlockin caseaPaintQueueis already the paint queue ofaPaintBlock
-
getGXYView
Returns the view for which thisALcdGXYAsynchronousPaintQueueManageris created.- Returns:
- the view for which this
ALcdGXYAsynchronousPaintQueueManageris created.
-