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