Renderable.java revision be5bdeb9471c4a04905edd34e6d3560315293427
1/* 2 * Copyright (C) 2011 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 17package com.android.scenegraph; 18 19import java.lang.Math; 20import java.util.ArrayList; 21import java.util.HashMap; 22import java.util.Iterator; 23 24import com.android.scenegraph.Float4Param; 25import com.android.scenegraph.ShaderParam; 26import com.android.scenegraph.TransformParam; 27 28import android.content.res.Resources; 29import android.renderscript.Allocation; 30import android.renderscript.Element; 31import android.renderscript.Element.DataType; 32import android.renderscript.Matrix4f; 33import android.renderscript.Mesh; 34import android.renderscript.ProgramFragment; 35import android.renderscript.ProgramStore; 36import android.renderscript.ProgramVertex; 37import android.renderscript.RenderScriptGL; 38import android.util.Log; 39 40/** 41 * @hide 42 */ 43public class Renderable extends RenderableBase { 44 Allocation mVertexConstants; 45 Allocation mVertexParams; 46 Allocation mFragmentConstants; 47 Allocation mFragmentParams; 48 ArrayList<Allocation> mFragmentTextures; 49 50 HashMap<String, ShaderParam> mSourceParams; 51 52 ArrayList<ShaderParam> mVertexParamList; 53 ArrayList<ShaderParam> mFragmentParamList; 54 55 Mesh mMesh; 56 int mMeshIndex; 57 58 int mCullType; 59 60 RenderState mRenderState; 61 62 Transform mTransform; 63 64 String mMeshName; 65 String mMeshIndexName; 66 67 public String mMaterialName; 68 69 // quick hack to prototype 70 int sceneIndex; 71 72 ScriptField_Renderable_s mRsField; 73 ScriptField_Renderable_s.Item mRsFieldItem; 74 75 public Renderable() { 76 mSourceParams = new HashMap<String, ShaderParam>(); 77 mVertexParamList = new ArrayList<ShaderParam>(); 78 mFragmentParamList = new ArrayList<ShaderParam>(); 79 } 80 81 public void setCullType(int cull) { 82 mCullType = cull; 83 } 84 85 public void setRenderState(RenderState renderState) { 86 mRenderState = renderState; 87 } 88 89 public void setMesh(Mesh mesh) { 90 mMesh = mesh; 91 } 92 93 public void setMesh(String mesh, String indexName) { 94 mMeshName = mesh; 95 mMeshIndexName = indexName; 96 } 97 98 public void setMaterialName(String name) { 99 mMaterialName = name; 100 } 101 102 public void setTransform(Transform t) { 103 mTransform = t; 104 } 105 106 public void appendSourceParams(ShaderParam p) { 107 mSourceParams.put(p.getParamName(), p); 108 } 109 110 public void resolveMeshData(Mesh mMesh) { 111 mMesh = mMesh; 112 if (mMesh == null) { 113 Log.v("DRAWABLE: ", "*** NO MESH *** " + mMeshName); 114 return; 115 } 116 int subIndexCount = mMesh.getPrimitiveCount(); 117 if (subIndexCount == 1 || mMeshIndexName == null) { 118 mMeshIndex = 0; 119 } else { 120 for (int i = 0; i < subIndexCount; i ++) { 121 if (mMesh.getIndexSetAllocation(i).getName().equals(mMeshIndexName)) { 122 mMeshIndex = i; 123 break; 124 } 125 } 126 } 127 128 mRsFieldItem.mesh = mMesh; 129 mRsFieldItem.meshIndex = mMeshIndex; 130 131 mRsField.set(mRsFieldItem, 0, true); 132 } 133 134 void updateTextures(RenderScriptGL rs, Resources res) { 135 Iterator<ShaderParam> allParamsIter = mSourceParams.values().iterator(); 136 int paramIndex = 0; 137 while (allParamsIter.hasNext()) { 138 ShaderParam sp = allParamsIter.next(); 139 if (sp instanceof TextureParam) { 140 TextureParam p = (TextureParam)sp; 141 mRsFieldItem.pf_textures[paramIndex++] = p.getTexture().getRsData(rs, res); 142 } 143 } 144 ProgramFragment pf = mRenderState.mFragment; 145 mRsFieldItem.pf_num_textures = pf != null ? Math.min(pf.getTextureCount(), paramIndex) : 0; 146 mRsField.set(mRsFieldItem, 0, true); 147 } 148 149 void updateTextures(RenderScriptGL rs, Allocation a, int slot) { 150 getRsFieldItem(rs, null); 151 mRsFieldItem.pf_textures[slot] = a; 152 } 153 154 void setVisible(RenderScriptGL rs, boolean vis) { 155 getRsField(rs, null); 156 mRsFieldItem.cullType = vis ? 0 : 2; 157 mRsField.set(mRsFieldItem, 0, true); 158 } 159 160 ShaderParam findParamByName(String name) { 161 return mSourceParams.get(name); 162 } 163 164 void fillInParams(Element constantElem, ArrayList<ShaderParam> paramList) { 165 int subElemCount = constantElem.getSubElementCount(); 166 for (int i = 0; i < subElemCount; i ++) { 167 String inputName = constantElem.getSubElementName(i); 168 int offset = constantElem.getSubElementOffsetBytes(i); 169 ShaderParam matchingParam = findParamByName(inputName); 170 // Make one if it's not there 171 if (matchingParam == null) { 172 Element subElem = constantElem.getSubElement(i); 173 if (subElem.getDataType() == Element.DataType.FLOAT_32) { 174 Float4Param fParam = new Float4Param(inputName); 175 fParam.setVecSize(subElem.getVectorSize()); 176 matchingParam = fParam; 177 } else if (subElem.getDataType() == Element.DataType.MATRIX_4X4) { 178 TransformParam trParam = new TransformParam(inputName); 179 trParam.setTransform(mTransform); 180 matchingParam = trParam; 181 } 182 } 183 matchingParam.setOffset(offset); 184 paramList.add(matchingParam); 185 } 186 } 187 188 void linkConstants() { 189 // Assign all the fragment params 190 if (mFragmentConstants != null) { 191 Element fragmentConst = mFragmentConstants.getType().getElement(); 192 fillInParams(fragmentConst, mFragmentParamList); 193 } 194 195 // Assign all the vertex params 196 if (mVertexConstants != null) { 197 Element vertexConst = mVertexConstants.getType().getElement(); 198 fillInParams(vertexConst, mVertexParamList); 199 } 200 } 201 202 ScriptField_Renderable_s getRsField(RenderScriptGL rs, Resources res) { 203 if (mRsField != null) { 204 return mRsField; 205 } 206 getRsFieldItem(rs, res); 207 208 mRsField = new ScriptField_Renderable_s(rs, 1); 209 mRsField.set(mRsFieldItem, 0, true); 210 211 return mRsField; 212 } 213 214 void getRsFieldItem(RenderScriptGL rs, Resources res) { 215 if (mRsFieldItem != null) { 216 return; 217 } 218 219 ProgramVertex pv = mRenderState.mVertex; 220 if (pv != null && pv.getConstantCount() > 0) { 221 mVertexConstants = Allocation.createTyped(rs, pv.getConstant(0)); 222 } 223 ProgramFragment pf = mRenderState.mFragment; 224 if (pf != null && pf.getConstantCount() > 0) { 225 mFragmentConstants = Allocation.createTyped(rs, pf.getConstant(0)); 226 } 227 228 // Very important step that links available inputs and the constants vertex and 229 // fragment shader request 230 linkConstants(); 231 232 ScriptField_ShaderParam_s pvParams = null, pfParams = null; 233 int paramCount = mVertexParamList.size(); 234 if (paramCount != 0) { 235 pvParams = new ScriptField_ShaderParam_s(rs, paramCount); 236 for (int i = 0; i < paramCount; i++) { 237 pvParams.set(mVertexParamList.get(i).getRSData(rs), i, false); 238 } 239 pvParams.copyAll(); 240 } 241 242 paramCount = mFragmentParamList.size(); 243 if (paramCount != 0) { 244 pfParams = new ScriptField_ShaderParam_s(rs, paramCount); 245 for (int i = 0; i < paramCount; i++) { 246 pfParams.set(mFragmentParamList.get(i).getRSData(rs), i, false); 247 } 248 pfParams.copyAll(); 249 } 250 251 mRsFieldItem = new ScriptField_Renderable_s.Item(); 252 mRsFieldItem.mesh = mMesh; 253 mRsFieldItem.meshIndex = mMeshIndex; 254 mRsFieldItem.pv_const = mVertexConstants; 255 mRsFieldItem.pv_constParams = pvParams != null ? pvParams.getAllocation() : null; 256 mRsFieldItem.pf_const = mFragmentConstants; 257 mRsFieldItem.pf_constParams = pfParams != null ? pfParams.getAllocation() : null; 258 if (mTransform != null) { 259 mRsFieldItem.transformMatrix = mTransform.getRSData(rs).getAllocation(); 260 } 261 mRsFieldItem.name = getStringAsAllocation(rs, getName()); 262 mRsFieldItem.render_state = mRenderState.getRSData(rs).getAllocation(); 263 mRsFieldItem.bVolInitialized = 0; 264 mRsFieldItem.cullType = mCullType; 265 } 266} 267 268 269 270 271 272