1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.renderscript; 18 19 import android.content.res.Resources; 20 import android.util.Log; 21 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.util.Map.Entry; 25 import java.util.HashMap; 26 27 import java.lang.reflect.Field; 28 import java.lang.reflect.Modifier; 29 30 /** 31 * @hide 32 **/ 33 public class ScriptC extends Script { 34 private static final String TAG = "ScriptC"; 35 36 ScriptC(int id, RenderScript rs) { 37 super(id, rs); 38 } 39 40 public static class Builder extends Script.Builder { 41 byte[] mProgram; 42 int mProgramLength; 43 HashMap<String,Integer> mIntDefines = new HashMap(); 44 HashMap<String,Float> mFloatDefines = new HashMap(); 45 46 public Builder(RenderScript rs) { 47 super(rs); 48 } 49 50 public void setScript(String s) { 51 try { 52 mProgram = s.getBytes("UTF-8"); 53 mProgramLength = mProgram.length; 54 } catch (java.io.UnsupportedEncodingException e) { 55 throw new RuntimeException(e); 56 } 57 } 58 59 public void setScript(Resources resources, int id) { 60 InputStream is = resources.openRawResource(id); 61 try { 62 try { 63 setScript(is); 64 } finally { 65 is.close(); 66 } 67 } catch(IOException e) { 68 throw new Resources.NotFoundException(); 69 } 70 } 71 72 public void setScript(InputStream is) throws IOException { 73 byte[] buf = new byte[1024]; 74 int currentPos = 0; 75 while(true) { 76 int bytesLeft = buf.length - currentPos; 77 if (bytesLeft == 0) { 78 byte[] buf2 = new byte[buf.length * 2]; 79 System.arraycopy(buf, 0, buf2, 0, buf.length); 80 buf = buf2; 81 bytesLeft = buf.length - currentPos; 82 } 83 int bytesRead = is.read(buf, currentPos, bytesLeft); 84 if (bytesRead <= 0) { 85 break; 86 } 87 currentPos += bytesRead; 88 } 89 mProgram = buf; 90 mProgramLength = currentPos; 91 } 92 93 static synchronized ScriptC internalCreate(Builder b) { 94 b.mRS.nScriptCBegin(); 95 b.transferCreate(); 96 97 for (Entry<String,Integer> e: b.mIntDefines.entrySet()) { 98 b.mRS.nScriptCAddDefineI32(e.getKey(), e.getValue().intValue()); 99 } 100 for (Entry<String,Float> e: b.mFloatDefines.entrySet()) { 101 b.mRS.nScriptCAddDefineF(e.getKey(), e.getValue().floatValue()); 102 } 103 104 b.mRS.nScriptCSetScript(b.mProgram, 0, b.mProgramLength); 105 106 int id = b.mRS.nScriptCCreate(); 107 ScriptC obj = new ScriptC(id, b.mRS); 108 b.transferObject(obj); 109 110 return obj; 111 } 112 113 public void addDefine(String name, int value) { 114 mIntDefines.put(name, value); 115 } 116 117 public void addDefine(String name, float value) { 118 mFloatDefines.put(name, value); 119 } 120 121 /** 122 * Takes the all public static final fields for a class, and adds defines 123 * for them, using the name of the field as the name of the define. 124 */ 125 public void addDefines(Class cl) { 126 addDefines(cl.getFields(), (Modifier.STATIC | Modifier.FINAL | Modifier.PUBLIC), null); 127 } 128 129 /** 130 * Takes the all public fields for an object, and adds defines 131 * for them, using the name of the field as the name of the define. 132 */ 133 public void addDefines(Object o) { 134 addDefines(o.getClass().getFields(), Modifier.PUBLIC, o); 135 } 136 137 void addDefines(Field[] fields, int mask, Object o) { 138 for (Field f: fields) { 139 try { 140 if ((f.getModifiers() & mask) == mask) { 141 Class t = f.getType(); 142 if (t == int.class) { 143 mIntDefines.put(f.getName(), f.getInt(o)); 144 } 145 else if (t == float.class) { 146 mFloatDefines.put(f.getName(), f.getFloat(o)); 147 } 148 } 149 } catch (IllegalAccessException ex) { 150 // TODO: Do we want this log? 151 Log.d(TAG, "addDefines skipping field " + f.getName()); 152 } 153 } 154 } 155 156 public ScriptC create() { 157 return internalCreate(this); 158 } 159 } 160 } 161 162