]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/VolatileImageCache.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / utils / VolatileImageCache.java
index f7a297cc13105fbbf760b9642e6f449ae66647e1..0a8d2ba1978d1d84f6b80df4b38df0e8b2bdd041 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.scenegraph.utils;\r
-\r
-import java.awt.GraphicsConfiguration;\r
-import java.awt.Image;\r
-import java.awt.Transparency;\r
-import java.awt.image.VolatileImage;\r
-import java.lang.ref.Reference;\r
-import java.lang.ref.SoftReference;\r
-import java.util.LinkedHashMap;\r
-import java.util.Map;\r
-import java.util.concurrent.atomic.AtomicInteger;\r
-\r
-/**\r
- * @author Antti Villberg\r
- */\r
-public class VolatileImageCache {\r
-\r
-    private static final boolean DEBUG = false;\r
-\r
-    private static VolatileImageCache instance = null;\r
-\r
-    private VolatileImageCache() {\r
-    }\r
-\r
-    public static VolatileImageCache getInstance() {\r
-        if (instance == null) {\r
-            instance = new VolatileImageCache();\r
-        }\r
-        return instance;\r
-    }\r
-\r
-    /**\r
-     * The max allowed size of the cache in megapixels. The amount of actual\r
-     * consumed (video) memory is approximately 4 times this.\r
-     */\r
-    private static final int MAX_SIZE = 8 * 1024 * 1024;\r
-\r
-\r
-    /**\r
-     * Current size of the cache in megapixels.\r
-     */\r
-    private int size = 0;\r
-    private int counter = 0;\r
-\r
-    class VolatileImageProviderImpl implements VolatileImageProvider {\r
-        private final int id;\r
-        private final int w;\r
-        private final int h;\r
-\r
-        private Reference<VolatileImage> imageRef = null;\r
-\r
-        public VolatileImageProviderImpl(int w, int h) {\r
-            this.id = counter++;\r
-            this.w = w;\r
-            this.h = h;\r
-        }\r
-\r
-        private VolatileImage dereferenceImage() {\r
-            return imageRef != null ? imageRef.get() : null;\r
-        }\r
-\r
-        public VolatileImage get(GraphicsConfiguration gc, AtomicInteger _validateResult) {\r
-            int validateResult = VolatileImage.IMAGE_INCOMPATIBLE;\r
-            VolatileImage vimg = dereferenceImage();\r
-            //System.out.println("GC: " + gc);\r
-            if (vimg != null)\r
-                validateResult = vimg.validate(gc);\r
-\r
-            if (validateResult == VolatileImage.IMAGE_RESTORED) {\r
-                if (DEBUG)\r
-                    System.out.println("VOLATILE IMAGE RESTORED for PROVIDER " + this);\r
-            }\r
-            if (validateResult == VolatileImage.IMAGE_INCOMPATIBLE) {\r
-                if (DEBUG)\r
-                    System.out.println("(RE)CREATING VOLATILE IMAGE FOR PROVIDER " + this);\r
-                vimg = gc.createCompatibleVolatileImage(w, h, Transparency.TRANSLUCENT);\r
-\r
-                if (vimg == null) {\r
-                    throw new IllegalStateException(this + ": got null VolatileImage from GraphicsConfiguration " + gc);\r
-                } else {\r
-                    this.imageRef = new SoftReference<VolatileImage>(vimg);\r
-\r
-                    // Implement move to front required for LRU\r
-                    synchronized (cache) {\r
-                        Object oldObject = cache.remove(this);\r
-                        boolean wasCached = oldObject == this;\r
-                        cache.put(this, this);\r
-                        if (!wasCached) {\r
-                            size += w * h;\r
-\r
-                            if (DEBUG)\r
-                                debug(this, cache.size(), size - w*h, size, "created new image");\r
-                        } else {\r
-                            //if (DEBUG)\r
-                            //    debug(this, cache.size(), size, size, "LRU move-to-front");\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-\r
-            if (_validateResult != null)\r
-                _validateResult.set(validateResult);\r
-\r
-            return vimg;\r
-        }\r
-\r
-        public void dispose() {\r
-            int newSize;\r
-            synchronized (cache) {\r
-                newSize = size;\r
-                Object removed = cache.remove(this);\r
-                if (removed == this) {\r
-                    newSize -= w * h;\r
-                    size = newSize;\r
-\r
-                    if (DEBUG)\r
-                        debug(this, cache.size(), newSize + w*h, newSize, "explicitly disposed");\r
-                }\r
-                if (imageRef != null) {\r
-                    flushImageRef(imageRef);\r
-                    imageRef = null;\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    private static final String MSG = "[provider #%-10d @%-8x][image (%-3d,%-3d)][cache entries=%-4d, old size=%-10d, new size=%-10d, size change=%-+6d] %s";\r
-\r
-    private static void debug(VolatileImageProviderImpl i, int entries, int oldSize, int newSize, String msg) {\r
-        if (DEBUG) {\r
-            int sizeChange = newSize - oldSize;\r
-            String s = String.format(MSG, i.id, i.hashCode(), i.w, i.h, entries, oldSize, newSize, sizeChange, msg);\r
-            System.out.println(s);\r
-        }\r
-    }\r
-\r
-    private final Map<VolatileImageProviderImpl,VolatileImageProviderImpl> cache = new LinkedHashMap<VolatileImageProviderImpl, VolatileImageProviderImpl>(50, .75F, true) {\r
-        private static final long serialVersionUID = 5946026822169837291L;\r
-        @Override\r
-        protected boolean removeEldestEntry(Map.Entry<VolatileImageProviderImpl,VolatileImageProviderImpl> eldest) {\r
-            boolean result = size > MAX_SIZE;\r
-            if (result) {\r
-//                new Exception().printStackTrace();\r
-                VolatileImageProviderImpl impl = eldest.getKey();\r
-                size -= impl.w*impl.h;\r
-\r
-                //debug(impl, impl.imageId, cache.size(), oldSize, size, "cache full, dumping oldest");\r
-\r
-                flushImageRef(impl.imageRef);\r
-                impl.imageRef = null;\r
-            }\r
-            return result;\r
-        }\r
-    };\r
-\r
-    private static final void flushImageRef(Reference<? extends Image> imageRef) {\r
-        if (imageRef != null) {\r
-            Image img = imageRef.get();\r
-            imageRef.clear();\r
-            if (img != null)\r
-                img.flush();\r
-        }\r
-    }\r
-\r
-    VolatileImageProvider create(int w, int h) {\r
-//        System.out.println("VolatileImageProvider.create(" + w + ", " + h + ")");\r
-        VolatileImageProviderImpl result = new VolatileImageProviderImpl(w, h);\r
-        return result;\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.scenegraph.utils;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.image.VolatileImage;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author Antti Villberg
+ */
+public class VolatileImageCache {
+
+    private static final boolean DEBUG = false;
+
+    private static VolatileImageCache instance = null;
+
+    private VolatileImageCache() {
+    }
+
+    public static VolatileImageCache getInstance() {
+        if (instance == null) {
+            instance = new VolatileImageCache();
+        }
+        return instance;
+    }
+
+    /**
+     * The max allowed size of the cache in megapixels. The amount of actual
+     * consumed (video) memory is approximately 4 times this.
+     */
+    private static final int MAX_SIZE = 8 * 1024 * 1024;
+
+
+    /**
+     * Current size of the cache in megapixels.
+     */
+    private int size = 0;
+    private int counter = 0;
+
+    class VolatileImageProviderImpl implements VolatileImageProvider {
+        private final int id;
+        private final int w;
+        private final int h;
+
+        private Reference<VolatileImage> imageRef = null;
+
+        public VolatileImageProviderImpl(int w, int h) {
+            this.id = counter++;
+            this.w = w;
+            this.h = h;
+        }
+
+        private VolatileImage dereferenceImage() {
+            return imageRef != null ? imageRef.get() : null;
+        }
+
+        public VolatileImage get(GraphicsConfiguration gc, AtomicInteger _validateResult) {
+            int validateResult = VolatileImage.IMAGE_INCOMPATIBLE;
+            VolatileImage vimg = dereferenceImage();
+            //System.out.println("GC: " + gc);
+            if (vimg != null)
+                validateResult = vimg.validate(gc);
+
+            if (validateResult == VolatileImage.IMAGE_RESTORED) {
+                if (DEBUG)
+                    System.out.println("VOLATILE IMAGE RESTORED for PROVIDER " + this);
+            }
+            if (validateResult == VolatileImage.IMAGE_INCOMPATIBLE) {
+                if (DEBUG)
+                    System.out.println("(RE)CREATING VOLATILE IMAGE FOR PROVIDER " + this);
+                vimg = gc.createCompatibleVolatileImage(w, h, Transparency.TRANSLUCENT);
+
+                if (vimg == null) {
+                    throw new IllegalStateException(this + ": got null VolatileImage from GraphicsConfiguration " + gc);
+                } else {
+                    this.imageRef = new SoftReference<VolatileImage>(vimg);
+
+                    // Implement move to front required for LRU
+                    synchronized (cache) {
+                        Object oldObject = cache.remove(this);
+                        boolean wasCached = oldObject == this;
+                        cache.put(this, this);
+                        if (!wasCached) {
+                            size += w * h;
+
+                            if (DEBUG)
+                                debug(this, cache.size(), size - w*h, size, "created new image");
+                        } else {
+                            //if (DEBUG)
+                            //    debug(this, cache.size(), size, size, "LRU move-to-front");
+                        }
+                    }
+                }
+            }
+
+            if (_validateResult != null)
+                _validateResult.set(validateResult);
+
+            return vimg;
+        }
+
+        public void dispose() {
+            int newSize;
+            synchronized (cache) {
+                newSize = size;
+                Object removed = cache.remove(this);
+                if (removed == this) {
+                    newSize -= w * h;
+                    size = newSize;
+
+                    if (DEBUG)
+                        debug(this, cache.size(), newSize + w*h, newSize, "explicitly disposed");
+                }
+                if (imageRef != null) {
+                    flushImageRef(imageRef);
+                    imageRef = null;
+                }
+            }
+        }
+    }
+
+    private static final String MSG = "[provider #%-10d @%-8x][image (%-3d,%-3d)][cache entries=%-4d, old size=%-10d, new size=%-10d, size change=%-+6d] %s";
+
+    private static void debug(VolatileImageProviderImpl i, int entries, int oldSize, int newSize, String msg) {
+        if (DEBUG) {
+            int sizeChange = newSize - oldSize;
+            String s = String.format(MSG, i.id, i.hashCode(), i.w, i.h, entries, oldSize, newSize, sizeChange, msg);
+            System.out.println(s);
+        }
+    }
+
+    private final Map<VolatileImageProviderImpl,VolatileImageProviderImpl> cache = new LinkedHashMap<VolatileImageProviderImpl, VolatileImageProviderImpl>(50, .75F, true) {
+        private static final long serialVersionUID = 5946026822169837291L;
+        @Override
+        protected boolean removeEldestEntry(Map.Entry<VolatileImageProviderImpl,VolatileImageProviderImpl> eldest) {
+            boolean result = size > MAX_SIZE;
+            if (result) {
+//                new Exception().printStackTrace();
+                VolatileImageProviderImpl impl = eldest.getKey();
+                size -= impl.w*impl.h;
+
+                //debug(impl, impl.imageId, cache.size(), oldSize, size, "cache full, dumping oldest");
+
+                flushImageRef(impl.imageRef);
+                impl.imageRef = null;
+            }
+            return result;
+        }
+    };
+
+    private static final void flushImageRef(Reference<? extends Image> imageRef) {
+        if (imageRef != null) {
+            Image img = imageRef.get();
+            imageRef.clear();
+            if (img != null)
+                img.flush();
+        }
+    }
+
+    VolatileImageProvider create(int w, int h) {
+//        System.out.println("VolatileImageProvider.create(" + w + ", " + h + ")");
+        VolatileImageProviderImpl result = new VolatileImageProviderImpl(w, h);
+        return result;
+    }
+
+}