71 SurfaceManager sMgr = imgaccessor.getSurfaceManager(img);
72 if (sMgr == null) {
73 /*
74 * In practice only a BufferedImage will get here.
75 */
76 try {
77 BufferedImage bi = (BufferedImage) img;
78 sMgr = new BufImgSurfaceManager(bi);
79 setManager(bi, sMgr);
80 } catch (ClassCastException e) {
81 throw new IllegalArgumentException("Invalid Image variant");
82 }
83 }
84 return sMgr;
85 }
86
87 public static void setManager(Image img, SurfaceManager mgr) {
88 imgaccessor.setSurfaceManager(img, mgr);
89 }
90
91 private ConcurrentHashMap cacheMap;
92
93 /**
94 * Return an arbitrary cached object for an arbitrary cache key.
95 * Other objects can use this mechanism to store cached data about
96 * the source image that will let them save time when using or
97 * manipulating the image in the future.
98 * <p>
99 * Note that the cache is maintained as a simple Map with no
100 * attempts to keep it up to date or invalidate it so any data
101 * stored here must either not be dependent on the state of the
102 * image or it must be individually tracked to see if it is
103 * outdated or obsolete.
104 * <p>
105 * The SurfaceData object of the primary (destination) surface
106 * has a StateTracker mechanism which can help track the validity
107 * and "currentness" of any data stored here.
108 * For convenience and expediency an object stored as cached
109 * data may implement the FlushableCacheData interface specified
110 * below so that it may be notified immediately if the flush()
111 * method is ever called.
112 */
113 public Object getCacheData(Object key) {
114 return (cacheMap == null) ? null : cacheMap.get(key);
115 }
116
117 /**
118 * Store an arbitrary cached object for an arbitrary cache key.
119 * See the getCacheData() method for notes on tracking the
120 * validity of data stored using this mechanism.
121 */
122 public void setCacheData(Object key, Object value) {
123 if (cacheMap == null) {
124 synchronized (this) {
125 if (cacheMap == null) {
126 cacheMap = new ConcurrentHashMap(2);
127 }
128 }
129 }
130 cacheMap.put(key, value);
131 }
132
133 /**
134 * Returns the main SurfaceData object that "owns" the pixels for
135 * this SurfaceManager. This SurfaceData is used as the destination
136 * surface in a rendering operation and is the most authoritative
137 * storage for the current state of the pixels, though other
138 * versions might be cached in other locations for efficiency.
139 */
140 public abstract SurfaceData getPrimarySurfaceData();
141
142 /**
143 * Restores the primary surface being managed, and then returns the
144 * replacement surface. This is called when an accelerated surface has
145 * been "lost", in an attempt to auto-restore its contents.
146 */
228 * objects for their cached copies.
229 */
230 public Object getProxyKey();
231 }
232
233 /**
234 * Releases system resources in use by ancillary SurfaceData objects,
235 * such as surfaces cached in accelerated memory. Subclasses should
236 * override to release any of their flushable data.
237 * <p>
238 * The default implementation will visit all of the value objects
239 * in the cacheMap and flush them if they implement the
240 * FlushableCacheData interface.
241 */
242 public synchronized void flush() {
243 flush(false);
244 }
245
246 synchronized void flush(boolean deaccelerate) {
247 if (cacheMap != null) {
248 Iterator i = cacheMap.values().iterator();
249 while (i.hasNext()) {
250 Object o = i.next();
251 if (o instanceof FlushableCacheData) {
252 if (((FlushableCacheData) o).flush(deaccelerate)) {
253 i.remove();
254 }
255 }
256 }
257 }
258 }
259
260 /**
261 * An interface for Objects used in the SurfaceManager cache
262 * to implement if they have data that should be flushed when
263 * the Image is flushed.
264 */
265 public static interface FlushableCacheData {
266 /**
267 * Flush all cached resources.
268 * The deaccelerated parameter indicates if the flush is
|
71 SurfaceManager sMgr = imgaccessor.getSurfaceManager(img);
72 if (sMgr == null) {
73 /*
74 * In practice only a BufferedImage will get here.
75 */
76 try {
77 BufferedImage bi = (BufferedImage) img;
78 sMgr = new BufImgSurfaceManager(bi);
79 setManager(bi, sMgr);
80 } catch (ClassCastException e) {
81 throw new IllegalArgumentException("Invalid Image variant");
82 }
83 }
84 return sMgr;
85 }
86
87 public static void setManager(Image img, SurfaceManager mgr) {
88 imgaccessor.setSurfaceManager(img, mgr);
89 }
90
91 private ConcurrentHashMap<Object,Object> cacheMap;
92
93 /**
94 * Return an arbitrary cached object for an arbitrary cache key.
95 * Other objects can use this mechanism to store cached data about
96 * the source image that will let them save time when using or
97 * manipulating the image in the future.
98 * <p>
99 * Note that the cache is maintained as a simple Map with no
100 * attempts to keep it up to date or invalidate it so any data
101 * stored here must either not be dependent on the state of the
102 * image or it must be individually tracked to see if it is
103 * outdated or obsolete.
104 * <p>
105 * The SurfaceData object of the primary (destination) surface
106 * has a StateTracker mechanism which can help track the validity
107 * and "currentness" of any data stored here.
108 * For convenience and expediency an object stored as cached
109 * data may implement the FlushableCacheData interface specified
110 * below so that it may be notified immediately if the flush()
111 * method is ever called.
112 */
113 public Object getCacheData(Object key) {
114 return (cacheMap == null) ? null : cacheMap.get(key);
115 }
116
117 /**
118 * Store an arbitrary cached object for an arbitrary cache key.
119 * See the getCacheData() method for notes on tracking the
120 * validity of data stored using this mechanism.
121 */
122 public void setCacheData(Object key, Object value) {
123 if (cacheMap == null) {
124 synchronized (this) {
125 if (cacheMap == null) {
126 cacheMap = new ConcurrentHashMap<>(2);
127 }
128 }
129 }
130 cacheMap.put(key, value);
131 }
132
133 /**
134 * Returns the main SurfaceData object that "owns" the pixels for
135 * this SurfaceManager. This SurfaceData is used as the destination
136 * surface in a rendering operation and is the most authoritative
137 * storage for the current state of the pixels, though other
138 * versions might be cached in other locations for efficiency.
139 */
140 public abstract SurfaceData getPrimarySurfaceData();
141
142 /**
143 * Restores the primary surface being managed, and then returns the
144 * replacement surface. This is called when an accelerated surface has
145 * been "lost", in an attempt to auto-restore its contents.
146 */
228 * objects for their cached copies.
229 */
230 public Object getProxyKey();
231 }
232
233 /**
234 * Releases system resources in use by ancillary SurfaceData objects,
235 * such as surfaces cached in accelerated memory. Subclasses should
236 * override to release any of their flushable data.
237 * <p>
238 * The default implementation will visit all of the value objects
239 * in the cacheMap and flush them if they implement the
240 * FlushableCacheData interface.
241 */
242 public synchronized void flush() {
243 flush(false);
244 }
245
246 synchronized void flush(boolean deaccelerate) {
247 if (cacheMap != null) {
248 Iterator<Object> i = cacheMap.values().iterator();
249 while (i.hasNext()) {
250 Object o = i.next();
251 if (o instanceof FlushableCacheData) {
252 if (((FlushableCacheData) o).flush(deaccelerate)) {
253 i.remove();
254 }
255 }
256 }
257 }
258 }
259
260 /**
261 * An interface for Objects used in the SurfaceManager cache
262 * to implement if they have data that should be flushed when
263 * the Image is flushed.
264 */
265 public static interface FlushableCacheData {
266 /**
267 * Flush all cached resources.
268 * The deaccelerated parameter indicates if the flush is
|