* 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. 34
      engine/src/core/com/jme3/shader/ShaderKey.java

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

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

Loading…
Cancel
Save