@(#)MultiTile.txt 1.11 Proposal: Improvements in Multi-tile Processing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Brian Burkhalter Created: 8 February 2000 Revised: 12/18/00 CHANGES DURING COMMUNITY REVIEW ------------------------------- . Clarified specification of queueTiles(), cancelTiles(), and prefetchTiles() in PlanarImage, in particular with respect to use of the TileScheduler of the default instance of the JAI class. PROPOSAL -------- 1. Tile Scheduling Interface 1.1 TileScheduler 1.1.1 Class Comments Change to read: /** * A class implementing a mechanism for scheduling tile calculation. * In various implementations tile computation may make use of multithreading * and multiple simultaneous network connections for improved performance. * *

If multithreading is used then the implementation of the interface * must be thread-safe. In particular it must be possible to invoke any of * the tile scheduling methods on the same image simultaneously from different * threads and obtain the same results as if all invocations had been from * the same thread. * *

Errors and exceptions which occur within the scheduler and which prevent * tile computation will be thrown via the usual mechanism for all blocking * methods, i.e., those which perform the computations while the invoking * thread blocks. Failure conditions encountered in computations effected * via non-blocking methods will be indicated by notifying any listeners. * In neither case is it expected that the tiles will be re-scheduled for * computation this instead being left to the application. */ 1.1.2 javax.media.jai.TileScheduler: Add some method specifications /** * Suggests to the scheduler the degree of parallelism to use in * processing invocations of scheduleTiles(). For * example, this might set the number of threads to spawn. It is * legal to implement this method as a no-op. * *

In the Sun Microsystems reference implementation of TileScheduler * this method sets the number of worker threads actually used for tile * computation. Ideally this number should equal the number of processors * actually available on the system. It is the responsibility of the * application to set this value as the number of processors is not * available via the virtual machine. A parallelism value of zero * indicates that all tile computation will be effected in the primary * thread. A parallelism value of N indicates that there will be * N worker threads in addition to the primary scheduler thread. * In JAI the parallelism defaults to a value of 2 unless explicity set * by the application. * * @param parallelism The suggested degree of parallelism. * @throws IllegalArgumentException if parallelism * is negative. */ void setParallelism(int parallelism); /** * Returns the degree of parallelism of the scheduler. */ int getParallelism(); /** * Identical to setParallelism() but applies only to * prefetchTiles(). */ void setPrefetchParallelism(int parallelism); /** * Identical to getParallelism() but applies only to * prefetchTiles(). */ int getPrefetchParallelism(); /** * Suggests to the scheduler the priority to assign to processing * effected by scheduleTiles(). For example, this might * set thread priority. Values outside of the accepted priority range * will be clamped to the nearest extremum. An implementation may clamp * the prefetch priority to less than the scheduling priority. It is * legal to implement this method as a no-op. * *

In the Sun Microsystems reference implementation of TileScheduler * this method sets the priority of the worker threads used for tile * computation. Its initial value is Thread.NORM_PRIORITY. * * @param priority The suggested priority. */ void setPriority(int priority); /** * Returns the priority of scheduleTiles() processing. */ int getPriority(); /** * Identical to setPriority() but applies only to * prefetchTiles(). * *

In the Sun Microsystems reference implementation of * TileScheduler, this method sets the priority of any threads * spawned to prefetch tiles. Its initial value is * Thread.MIN_PRIORITY. */ void setPrefetchPriority(int priority); /** * Identical to getPriority() but applies only to * prefetchTiles(). */ int getPrefetchPriority(); 1.1.3 Reference Implementation The Sun reference implementation of TileScheduler would be updated according to the above specification change. 1.2 javax.media.jai.JAI: Add a method /** * Constructs a TileScheduler with the default parallelism * and priorities. * *

In the Sun Microsystems reference implementation of TileScheduler * the default parallelism is 2, default priority is * THREAD.NORM_PRIORITY, default prefetch parallelism is 1, * and default prefetch priority is THREAD.MIN_PRIORITY. */ public static TileScheduler createTileScheduler() {} 2. Tile Computation Events 2.1 Define an interface TileComputationListener /** * Interface to monitor when tiles have been computed. */ public interface TileComputationListener extends EventListener { /** * Returns true if this listener prefers to be * notified on a per tile basis. */ boolean isPerTileListener(); /** * To be invoked after each tile is computed if and only if * isPerTileListener() returns true. */ void tileComputed(PlanarImage image, int tileX, int tileY, Raster tile); /** * To be invoked after all tiles in a requested block have been computed * if and only if isPerTileListener() returns * false. */ void tilesComputed(PlanarImage image, Point[] tileIndices, Raster[] tiles); /** * Notifies the listener that the indicated set of tiles could not * be computed due to an exceptional situation having occurred. The * action of this method is independent of the value returned by * isPerTileListener() and therefore may indicate a multiple * tile computation failure even if isPerTileListener() * returns true. Details regarding the error condition * may be obtained via the Throwable parameter. */ void tileComputationFailure(PlanarImage image, Point[] tileIndices, Throwable situation); } 2.2 Add two methods to TileScheduler /** * Schedule a list of tiles for computation. The supplied listeners * will be notified after each tile has been computed or when the * entire list of tiles has been computed depending on the value * returned by listener.isPerTileListener(). This * method ideally should be non-blocking. If the TileScheduler * implementation uses multithreading, it is at the discretion of the * implementation which thread invokes the * TileComputationListener methods. Separate arrays * are provided for the two different types of listeners so that they * mat be pre-sorted by the caller. The scheduler is not obliged to * verify whether the listeners in the respective arrays are of the * expected type. * *

In the Sun Microsystems reference implementation of * TileScheduler the TileComputationListener * methods are invoked by the thread which performs the actual * tile computation. This will be the primary thread if the * parallelism is zero, or a worker thread if it is positive. * * @param target An OpImage whose tiles are to be computed. * @param tileIndices A list of tile indices indicating which tiles * to schedule for computation. * @param tileListeners TileComputationListeners the * listener.isPerTileListener() of which should * return true; may be null. * @param blockListeners TileComputationListeners the * listener.isPerTileListener() of which should * return false; may be null. * @throws IllegalArgumentException if target, * tileIndices, or tileIndices * is null. */ void scheduleTiles(PlanarImage target, Point[] tileIndices, TileComputationListener[] tileListeners, TileComputationListener[] blockListeners); /** * Issues an advisory cancellation request to the * TileScheduler stating that the indicated tiles of the * specified image should not be processed. The handling of this request * is at the discretion of the scheduler which may cancel tile processing * in progress and remove tiles from its internal queue, remove tiles from * the queue but not terminate current processing, or simply do nothing. * *

In the Sun Microsystems reference implementation of * TileScheduler the second tile cancellation option is * implemented, i.e., tiles are removed from the internal queue but * computation already in progress is not terminated. If there is at * least one worker thread this method should be non-blocking. Any tiles * allowed to complete computation subsequent to this call are complete * and will be treated as if they had not been cancelled, e.g., with * respect to caching, notification of registered listeners, etc. * Furthermore, cancelling a tile request in no way invalidates the tile * as a candidate for future recomputation. * * @throws IllegalArgumentException if target or * tileIndices is null. */ void cancelTiles(PlanarImage target, Point[] tileIndices); 2.3 Modify PlanarImage Several changes will be made to accommodate registration and usage of TileComputationListeners. The algorithms and structures used internally to implement these changes are intentionally not specified at the API level. 2.3.1 Make PlanarImage becomes a tile computation event source Add two methods: /** * Adds a TileComputationListener to the list of * registered TileComputationListeners. This listener * will be notified when tiles requested via queueTiles() * have been computed. * * @param listener The TileComputationListener to register. * @throws IllegalArgumentException if listener is * null. */ public synchronized void addTileComputationListener(TileComputationListener listener) {} /** * Removes a TileComputationListener from the list of * registered TileComputationListeners. * * @param listener The TileComputationListener to unregister. * @throws IllegalArgumentException if listener is * null. */ public synchronized void removeTileComputationListener(TileComputationListener listener) {} 2.3.2 Add listener retrieval method /** * Retrieves a snapshot of the set of all registered * TileComputationListeners as of the moment this * method is invoked. * * @return All TileComputationListeners or * null if there are none. */ public TileComputationListener[] getTileComputationListeners(boolean arePerTileListeners) {} 2.3.3 Implement queueTiles() /** * Queues a list of tiles for computation. Registered listeners * will be notified after each tile has been computed or when the * entire list of tiles has been computed depending on the value * returned by listener.isPerTileListener(). Some * implementations may spawn a thread or threads to compute * the tiles. * * The TileScheduler of the default instance of the * JAI class is used to process the tiles. If this * TileScheduler has a positive parallelism this * method will be non-blocking. * * @throws IllegalArgumentException If tileIndices is * null. */ public void queueTiles(Point[] tileIndices) {} 2.3.4 Implement cancelTiles() /** * Issue an advisory cancellation request to nullify processing of * the indicated tiles. It is legal to implement this method as a no-op. * *

The cancellation request is forwarded to the * TileScheduler of the default instance of the * JAI class. * * @throws IllegalArgumentException If tileIndices is * null. */ public void cancelTiles(Point[] tileIndices) {} 2.3.5 prefetchTiles() Clarify specification: /** * Hints that the given tiles might be needed in the near future. * Some implementations may spawn a thread or threads * to compute the tiles while others may ignore the hint. * * The TileScheduler of the default instance of the * JAI class is used to prefetch the tiles. If this * TileScheduler has a positive prefetch parallelism this * method will be non-blocking. * * @param tileIndices A list of tile indices indicating which tiles * to prefetch. * * @throws IllegalArgumentException If tileIndices is * null. */ public void prefetchTiles(Point[] tileIndices) {} 2.4 Modify OpImage 2.4.1 Override PlanarImage.queueTiles() /** * Queues a list of tiles for computation. Registered listeners * will be notified after each tile has been computed or when the * entire list of tiles has been computed depending on the value * returned by listener.isPerTileListener(). * * @throws IllegalArgumentException If tileIndices is * null. */ public void queueTiles(Point[] tileIndices) {} 2.4.2 Override PlanarImage.cancelTiles() /** * Issue an advisory cancellation request to nullify processing of * the indicated tiles via the TileScheduler for this image. * * @throws IllegalArgumentException If tileIndices is * null. */ public void cancelTiles(Point[] tileIndices) {} 2.5 Modify RenderedOp 2.5.1 Override PlanarImage.queueTiles() /** * Queues a list of tiles for computation. Registered listeners * will be notified after each tile has been computed or when the * entire list of tiles has been computed depending on the value * returned by listener.isPerTileListener(). * * @throws IllegalArgumentException If tileIndices is * null. */ public void queueTiles(Point[] tileIndices) {} This method will call the queueTiles() method of its rendering. 2.5.2 Override PlanarImage.cancelTiles() /** * Issue an advisory cancellation request to nullify processing of * the indicated tiles. * * @throws IllegalArgumentException If tileIndices is * null. */ public void cancelTiles(Point[] tileIndices) {} This method will call the cancelTiles() method of its rendering.