< prev index next >
modules/javafx.graphics/src/main/java/javafx/scene/shape/PredefinedMeshManager.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -23,21 +23,79 @@
* questions.
*/
package javafx.scene.shape;
+import java.lang.ref.SoftReference;
import java.util.HashMap;
final class PredefinedMeshManager {
-
- private static final PredefinedMeshManager INSTANCE = new PredefinedMeshManager();
private static final int INITAL_CAPACITY = 17; // TODO
private static final float LOAD_FACTOR = 0.75f;
- private HashMap<Integer, TriangleMesh> boxCache = null;
- private HashMap<Integer, TriangleMesh> sphereCache = null;
- private HashMap<Integer, TriangleMesh> cylinderCache = null;
+ private static class TriangleMeshCache {
+ HashMap<Integer, SoftReference<TriangleMesh>> cache = new HashMap<>(INITAL_CAPACITY, LOAD_FACTOR);
+
+ private TriangleMesh get(Integer key) {
+ cleanCache();
+ return (cache.containsKey(key))? cache.get(key).get() : null;
+ }
+
+ private void put(Integer key, TriangleMesh mesh) {
+ cleanCache();
+ if (mesh != null) {
+ cache.put(key, new SoftReference<TriangleMesh>(mesh));
+ }
+ }
+
+ private void cleanCache() {
+ Integer[] entriesToRemove = new Integer[cache.size()];
+ int count = 0;
+ for (HashMap.Entry<Integer, SoftReference<TriangleMesh>> entry : cache.entrySet()) {
+ if (entry.getValue().get() == null) {
+ entriesToRemove[count++] = entry.getKey();
+ }
+ }
+ for (int i = 0; i < count; ++i) {
+ cache.remove(entriesToRemove[i]);
+ }
+ }
+
+ private void clear() {
+ cache.clear();
+ }
+
+ private int size() {
+ cleanCache();
+ return cache.size();
+ }
+
+ // for testing purpose
+ private void printState(String name) {
+ System.out.println(name + " size: " + size());
+ }
+
+ private void invalidateMesh(Integer key) {
+ if (cache.containsKey(key)) {
+ TriangleMesh mesh = cache.get(key).get();
+ if (mesh != null) {
+ mesh.decRef();
+ int count = mesh.getRefCount();
+ if (count == 0) {
+ cache.remove(key);
+ }
+ } else {
+ cache.remove(key);
+ }
+ }
+ }
+ }
+
+ private static final PredefinedMeshManager INSTANCE = new PredefinedMeshManager();
+ private TriangleMeshCache boxCache = null;
+ private TriangleMeshCache sphereCache = null;
+ private TriangleMeshCache cylinderCache = null;
private PredefinedMeshManager() {}
static PredefinedMeshManager getInstance() {
return INSTANCE;
@@ -88,44 +146,23 @@
return mesh;
}
synchronized void invalidateBoxMesh(int key) {
if (boxCache != null) {
- TriangleMesh mesh = boxCache.get(key);
- if (mesh != null) {
- mesh.decRef();
- int count = mesh.getRefCount();
- if (count == 0) {
- boxCache.remove(key);
- }
- }
+ boxCache.invalidateMesh(key);
}
}
synchronized void invalidateSphereMesh(int key) {
if (sphereCache != null) {
- TriangleMesh mesh = sphereCache.get(key);
- if (mesh != null) {
- mesh.decRef();
- int count = mesh.getRefCount();
- if (count == 0) {
- sphereCache.remove(key);
- }
- }
+ sphereCache.invalidateMesh(key);
}
}
synchronized void invalidateCylinderMesh(int key) {
if (cylinderCache != null) {
- TriangleMesh mesh = cylinderCache.get(key);
- if (mesh != null) {
- mesh.decRef();
- int count = mesh.getRefCount();
- if (count == 0) {
- cylinderCache.remove(key);
- }
- }
+ cylinderCache.invalidateMesh(key);
}
}
synchronized void dispose() {
// just clearing references to them
@@ -141,39 +178,35 @@
}
// for testing purpose
synchronized void printStats() {
if (boxCache != null) {
- System.out.println("BoxCache size: " + boxCache.size());
+ boxCache.printState("BoxCache");
}
if (sphereCache != null) {
- System.out.println("SphereCache size: " + sphereCache.size());
+ sphereCache.printState("SphereCache");
}
if (cylinderCache != null) {
- System.out.println("CylinderCache size: " + cylinderCache.size());
+ cylinderCache.printState("CylinderCache");
}
}
private final static class BoxCacheLoader {
// lazy & thread-safe instantiation
- private static final HashMap<Integer, TriangleMesh>
- INSTANCE = new HashMap<Integer, TriangleMesh>(INITAL_CAPACITY, LOAD_FACTOR);
+ private static final TriangleMeshCache INSTANCE = new TriangleMeshCache();
}
private final static class SphereCacheLoader {
// lazy & thread-safe instantiation
- private static final HashMap<Integer, TriangleMesh>
- INSTANCE = new HashMap<Integer, TriangleMesh>(INITAL_CAPACITY, LOAD_FACTOR);
+ private static final TriangleMeshCache INSTANCE = new TriangleMeshCache();
}
private final static class CylinderCacheLoader {
// lazy & thread-safe instantiation
- private static final HashMap<Integer, TriangleMesh>
- INSTANCE = new HashMap<Integer, TriangleMesh>(INITAL_CAPACITY, LOAD_FACTOR);
+ private static final TriangleMeshCache INSTANCE = new TriangleMeshCache();
}
-
};
< prev index next >