* Some optimizations for defines and shader key. Computing "compiled" define list isn't necessary to execute a lookup against asset manager. Allows faster changes in defines.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9771 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Sha..rd 12 years ago
parent 1a12437436
commit 8efd28da76
  1. 67
      engine/src/core/com/jme3/shader/DefineList.java
  2. 40
      engine/src/core/com/jme3/shader/ShaderKey.java

@ -35,13 +35,15 @@ package com.jme3.shader;
import com.jme3.export.*; import com.jme3.export.*;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
public class DefineList implements Savable { public class DefineList implements Savable, Cloneable {
private final SortedMap<String, String> defines = new TreeMap<String, String>(); private static final String ONE = "1";
private TreeMap<String, String> defines = new TreeMap<String, String>();
private String compiled = null; private String compiled = null;
private int cachedHashCode = 0;
public void write(JmeExporter ex) throws IOException{ public void write(JmeExporter ex) throws IOException{
OutputCapsule oc = ex.getCapsule(this); OutputCapsule oc = ex.getCapsule(this);
@ -73,46 +75,66 @@ public class DefineList implements Savable {
public void clear() { public void clear() {
defines.clear(); defines.clear();
compiled = ""; compiled = "";
cachedHashCode = 0;
} }
public String get(String key){ public String get(String key){
return defines.get(key); return defines.get(key);
} }
@Override
public DefineList clone() {
try {
DefineList clone = (DefineList) super.clone();
clone.cachedHashCode = 0;
clone.compiled = null;
clone.defines = (TreeMap<String, String>) defines.clone();
return clone;
} catch (CloneNotSupportedException ex) {
throw new AssertionError();
}
}
public boolean set(String key, VarType type, Object val){ public boolean set(String key, VarType type, Object val){
if (val == null){ if (val == null){
defines.remove(key); defines.remove(key);
compiled = null; compiled = null;
cachedHashCode = 0;
return true; return true;
} }
switch (type){ switch (type){
case Boolean: case Boolean:
if ( ((Boolean) val).booleanValue() ) { if (((Boolean) val).booleanValue()) {
// same literal, != should work // same literal, != will work
if (defines.put(key, "1") != "1") { if (defines.put(key, ONE) != ONE) {
compiled = null; compiled = null;
cachedHashCode = 0;
return true; return true;
} }
} else if (defines.containsKey(key)) { } else if (defines.containsKey(key)) {
defines.remove(key); defines.remove(key);
compiled = null; compiled = null;
cachedHashCode = 0;
return true; return true;
} }
break; break;
case Float: case Float:
case Int: case Int:
String original = defines.put(key, val.toString()); String newValue = val.toString();
String original = defines.put(key, newValue);
if (!val.equals(original)) { if (!val.equals(original)) {
compiled = null; compiled = null;
cachedHashCode = 0;
return true; return true;
} }
break; break;
default: default:
// same literal, != should work // same literal, != will work
if (defines.put(key, "1") != "1") { if (defines.put(key, ONE) != ONE) {
compiled = null; compiled = null;
cachedHashCode = 0;
return true; return true;
} }
break; break;
@ -124,17 +146,18 @@ public class DefineList implements Savable {
public boolean remove(String key){ public boolean remove(String key){
if (defines.remove(key) != null) { if (defines.remove(key) != null) {
compiled = null; compiled = null;
cachedHashCode = 0;
return true; return true;
} }
return false; return false;
} }
public void addFrom(DefineList other){ public void addFrom(DefineList other){
if (other == null) if (other == null) {
return; return;
}
compiled = null; compiled = null;
cachedHashCode = 0;
defines.putAll(other.defines); defines.putAll(other.defines);
} }
@ -150,15 +173,29 @@ public class DefineList implements Savable {
return compiled; return compiled;
} }
@Override
public boolean equals(Object obj) {
final DefineList other = (DefineList) obj;
return defines.equals(other.defines);
}
@Override
public int hashCode() {
if (cachedHashCode == 0) {
cachedHashCode = defines.hashCode();
}
return cachedHashCode;
}
@Override @Override
public String toString(){ public String toString(){
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
int i = 0; int i = 0;
for (Map.Entry<String, String> entry : defines.entrySet()) { for (Map.Entry<String, String> entry : defines.entrySet()) {
sb.append(entry.getKey()); sb.append(entry.getKey()).append("=").append(entry.getValue());
if (i != defines.size() - 1) if (i != defines.size() - 1) {
sb.append(", "); sb.append(", ");
}
i++; i++;
} }
return sb.toString(); return sb.toString();

@ -45,6 +45,7 @@ public class ShaderKey extends AssetKey<Shader> {
protected DefineList defines; protected DefineList defines;
protected String vertLanguage; protected String vertLanguage;
protected String fragLanguage; protected String fragLanguage;
protected int cachedHashedCode = 0;
public ShaderKey(){ public ShaderKey(){
} }
@ -57,6 +58,14 @@ public class ShaderKey extends AssetKey<Shader> {
this.fragLanguage = fragLanguage; this.fragLanguage = fragLanguage;
} }
@Override
public ShaderKey clone() {
ShaderKey clone = (ShaderKey) super.clone();
clone.cachedHashedCode = 0;
clone.defines = defines.clone();
return clone;
}
@Override @Override
public String toString(){ public String toString(){
return "V="+name + " F=" + fragName + (defines != null ? defines : ""); return "V="+name + " F=" + fragName + (defines != null ? defines : "");
@ -64,32 +73,29 @@ public class ShaderKey extends AssetKey<Shader> {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj == null){
return false;
}
if (getClass() != obj.getClass()){
return false;
}
final ShaderKey other = (ShaderKey) obj; final ShaderKey other = (ShaderKey) obj;
if (name.equals(other.name) && fragName.equals(other.fragName)){ if (name.equals(other.name) && fragName.equals(other.fragName)){
if (defines != null && other.defines != null) if (defines != null && other.defines != null) {
return defines.getCompiled().equals(other.defines.getCompiled()); return defines.equals(other.defines);
else if (defines != null || other.defines != null) } else if (defines != null || other.defines != null) {
return false; return false;
else } else {
return true; return true;
}
} }
return false; return false;
} }
@Override @Override
public int hashCode() { public int hashCode() {
int hash = 7; if (cachedHashedCode == 0) {
hash = 41 * hash + name.hashCode(); int hash = 7;
hash = 41 * hash + fragName.hashCode(); hash = 41 * hash + name.hashCode();
hash = 41 * hash + (defines != null ? defines.getCompiled().hashCode() : 0); hash = 41 * hash + fragName.hashCode();
return hash; hash = 41 * hash + (defines != null ? defines.hashCode() : 0);
cachedHashedCode = hash;
}
return cachedHashedCode;
} }
public DefineList getDefines() { public DefineList getDefines() {
@ -126,6 +132,7 @@ public class ShaderKey extends AssetKey<Shader> {
OutputCapsule oc = ex.getCapsule(this); OutputCapsule oc = ex.getCapsule(this);
oc.write(fragName, "fragment_name", null); oc.write(fragName, "fragment_name", null);
oc.write(vertLanguage, "language", null); oc.write(vertLanguage, "language", null);
oc.write(fragLanguage, "frag_language", null);
} }
@Override @Override
@ -134,6 +141,7 @@ public class ShaderKey extends AssetKey<Shader> {
InputCapsule ic = im.getCapsule(this); InputCapsule ic = im.getCapsule(this);
fragName = ic.readString("fragment_name", null); fragName = ic.readString("fragment_name", null);
vertLanguage = ic.readString("language", null); vertLanguage = ic.readString("language", null);
fragLanguage = ic.readString("frag_language", null);
} }
} }

Loading…
Cancel
Save