Scene.java revision 684267525b349eb12f4e31d88061c51115678dec
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.regex.Matcher; 23import java.util.regex.Pattern; 24 25import android.renderscript.RenderScriptGL; 26import android.renderscript.Mesh; 27import android.renderscript.*; 28import android.content.res.Resources; 29import android.util.Log; 30import android.os.AsyncTask; 31 32/** 33 * @hide 34 */ 35public class Scene extends SceneGraphBase { 36 private static String TIMER_TAG = "TIMER"; 37 38 private class ImageLoaderTask extends AsyncTask<String, Void, Boolean> { 39 protected Boolean doInBackground(String... names) { 40 long start = System.currentTimeMillis(); 41 for (int i = 0; i < mRenderables.size(); i ++) { 42 Renderable dI = (Renderable)mRenderables.get(i); 43 dI.updateTextures(mRS, mRes); 44 } 45 long end = System.currentTimeMillis(); 46 Log.v(TIMER_TAG, "Texture init time: " + (end - start)); 47 return new Boolean(true); 48 } 49 50 protected void onPostExecute(Boolean result) { 51 } 52 } 53 54 CompoundTransform mRootTransforms; 55 HashMap<String, Transform> mTransformMap; 56 ArrayList<RenderPass> mRenderPasses; 57 ArrayList<LightBase> mLights; 58 ArrayList<Camera> mCameras; 59 ArrayList<RenderableBase> mRenderables; 60 HashMap<String, RenderableBase> mRenderableMap; 61 ArrayList<Texture2D> mTextures; 62 63 HashMap<String, ArrayList<Renderable> > mRenderableMeshMap; 64 65 // RS Specific stuff 66 ScriptField_SgTransform mTransformRSData; 67 68 RenderScriptGL mRS; 69 Resources mRes; 70 71 ScriptField_RenderPass_s mRenderPassAlloc; 72 73 public Scene() { 74 mRenderPasses = new ArrayList<RenderPass>(); 75 mLights = new ArrayList<LightBase>(); 76 mCameras = new ArrayList<Camera>(); 77 mRenderables = new ArrayList<RenderableBase>(); 78 mRenderableMap = new HashMap<String, RenderableBase>(); 79 mRenderableMeshMap = new HashMap<String, ArrayList<Renderable> >(); 80 mTextures = new ArrayList<Texture2D>(); 81 mRootTransforms = new CompoundTransform(); 82 mRootTransforms.setName("_scene_root_"); 83 mTransformMap = new HashMap<String, Transform>(); 84 } 85 86 public void appendTransform(Transform t) { 87 mRootTransforms.appendChild(t); 88 } 89 90 // temporary 91 public void addToTransformMap(Transform t) { 92 mTransformMap.put(t.getName(), t); 93 } 94 95 public Transform getTransformByName(String name) { 96 return mTransformMap.get(name); 97 } 98 99 public void appendRenderPass(RenderPass p) { 100 mRenderPasses.add(p); 101 } 102 103 public void clearRenderPasses() { 104 mRenderPasses.clear(); 105 } 106 107 public void appendLight(LightBase l) { 108 mLights.add(l); 109 } 110 111 public void appendCamera(Camera c) { 112 mCameras.add(c); 113 } 114 115 public ArrayList<Camera> getCameras() { 116 return mCameras; 117 } 118 119 public void appendRenderable(RenderableBase d) { 120 mRenderables.add(d); 121 mRenderableMap.put(d.getName(), d); 122 } 123 124 public ArrayList<RenderableBase> getRenderables() { 125 return mRenderables; 126 } 127 128 public RenderableBase getRenderableByName(String name) { 129 return mRenderableMap.get(name); 130 } 131 132 public void appendTextures(Texture2D tex) { 133 mTextures.add(tex); 134 } 135 136 public void assignRenderStateToMaterial(RenderState renderState, String regex) { 137 Pattern pattern = Pattern.compile(regex); 138 int numRenderables = mRenderables.size(); 139 for (int i = 0; i < numRenderables; i ++) { 140 Renderable shape = (Renderable)mRenderables.get(i); 141 Matcher m = pattern.matcher(shape.mMaterialName); 142 if (m.find()) { 143 shape.setRenderState(renderState); 144 } 145 } 146 } 147 148 public void assignRenderState(RenderState renderState) { 149 int numRenderables = mRenderables.size(); 150 for (int i = 0; i < numRenderables; i ++) { 151 Renderable shape = (Renderable)mRenderables.get(i); 152 shape.setRenderState(renderState); 153 } 154 } 155 156 public void meshLoaded(Mesh m) { 157 ArrayList<Renderable> entries = mRenderableMeshMap.get(m.getName()); 158 int numEntries = entries.size(); 159 for (int i = 0; i < numEntries; i++) { 160 Renderable d = entries.get(i); 161 d.resolveMeshData(m); 162 //mRenderablesField.set(d.getRsField(mRS, mRes), d.sceneIndex, true); 163 } 164 } 165 166 void addToMeshMap(Renderable d) { 167 ArrayList<Renderable> entries = mRenderableMeshMap.get(d.mMeshName); 168 if (entries == null) { 169 entries = new ArrayList<Renderable>(); 170 mRenderableMeshMap.put(d.mMeshName, entries); 171 } 172 entries.add(d); 173 } 174 175 public void destroyRS(SceneManager sceneManager) { 176 mTransformRSData = null; 177 sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData); 178 sceneManager.mRenderLoop.set_gRenderableObjects(null); 179 mRenderPassAlloc = null; 180 sceneManager.mRenderLoop.set_gRenderPasses(null); 181 sceneManager.mRenderLoop.bind_gFrontToBack(null); 182 sceneManager.mRenderLoop.bind_gBackToFront(null); 183 sceneManager.mRenderLoop.set_gCameras(null); 184 185 mTransformMap = null; 186 mRenderPasses = null; 187 mLights = null; 188 mCameras = null; 189 mRenderables = null; 190 mRenderableMap = null; 191 mTextures = null; 192 mRenderableMeshMap = null; 193 mRootTransforms = null; 194 } 195 196 public void initRenderPassRS(RenderScriptGL rs, SceneManager sceneManager) { 197 if (mRenderPasses.size() != 0) { 198 mRenderPassAlloc = new ScriptField_RenderPass_s(mRS, mRenderPasses.size()); 199 for (int i = 0; i < mRenderPasses.size(); i ++) { 200 mRenderPassAlloc.set(mRenderPasses.get(i).getRsField(mRS, mRes), i, false); 201 } 202 mRenderPassAlloc.copyAll(); 203 sceneManager.mRenderLoop.set_gRenderPasses(mRenderPassAlloc.getAllocation()); 204 } 205 } 206 207 public void initRS(RenderScriptGL rs, Resources res, SceneManager sceneManager) { 208 mRS = rs; 209 long start = System.currentTimeMillis(); 210 mTransformRSData = mRootTransforms.getRSData(rs); 211 long end = System.currentTimeMillis(); 212 Log.v(TIMER_TAG, "Transform init time: " + (end - start)); 213 214 start = System.currentTimeMillis(); 215 216 sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData); 217 end = System.currentTimeMillis(); 218 Log.v(TIMER_TAG, "Script init time: " + (end - start)); 219 220 start = System.currentTimeMillis(); 221 Allocation drawableData = Allocation.createSized(rs, 222 Element.ALLOCATION(rs), 223 mRenderables.size()); 224 Allocation[] drawableAllocs = new Allocation[mRenderables.size()]; 225 for (int i = 0; i < mRenderables.size(); i ++) { 226 Renderable dI = (Renderable)mRenderables.get(i); 227 dI.sceneIndex = i; 228 addToMeshMap(dI); 229 drawableAllocs[i] = dI.getRsField(rs, res).getAllocation(); 230 } 231 drawableData.copyFrom(drawableAllocs); 232 sceneManager.mRenderLoop.set_gRenderableObjects(drawableData); 233 234 initRenderPassRS(rs, sceneManager); 235 236 new ImageLoaderTask().execute(); 237 238 end = System.currentTimeMillis(); 239 Log.v(TIMER_TAG, "Renderable init time: " + (end - start)); 240 241 Allocation opaqueBuffer = Allocation.createSized(rs, Element.U32(rs), mRenderables.size()); 242 Allocation transparentBuffer = Allocation.createSized(rs, 243 Element.U32(rs), mRenderables.size()); 244 245 sceneManager.mRenderLoop.bind_gFrontToBack(opaqueBuffer); 246 sceneManager.mRenderLoop.bind_gBackToFront(transparentBuffer); 247 248 Allocation cameraData = Allocation.createSized(rs, Element.ALLOCATION(rs), mCameras.size()); 249 Allocation[] cameraAllocs = new Allocation[mCameras.size()]; 250 for (int i = 0; i < mCameras.size(); i ++) { 251 cameraAllocs[i] = mCameras.get(i).getRSData(rs).getAllocation(); 252 } 253 cameraData.copyFrom(cameraAllocs); 254 sceneManager.mRenderLoop.set_gCameras(cameraData); 255 } 256} 257 258 259 260 261