1a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk/*
2a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Copyright (C) 2011 The Android Open Source Project
3a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk *
4a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License");
5a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * you may not use this file except in compliance with the License.
6a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * You may obtain a copy of the License at
7a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk *
8a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk *      http://www.apache.org/licenses/LICENSE-2.0
9a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk *
10a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Unless required by applicable law or agreed to in writing, software
11a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS,
12a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * See the License for the specific language governing permissions and
14a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * limitations under the License.
15a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk */
16a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
17a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukpackage com.android.scenegraph;
18a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
19a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.lang.Math;
20a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.ArrayList;
214fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukimport java.util.HashMap;
22a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
230c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchoukimport com.android.scenegraph.SceneManager;
244fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukimport com.android.scenegraph.Transform;
254fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
264fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukimport android.renderscript.Element;
27a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.Matrix4f;
28a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.ProgramFragment;
29a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.ProgramStore;
30a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.ProgramVertex;
314fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukimport android.renderscript.RenderScriptGL;
32a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.util.Log;
33a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
34a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk/**
35a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * @hide
36a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk */
37dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchoukpublic abstract class ShaderParam extends SceneGraphBase {
38dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk
39dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String cameraPos        = "cameraPos";
40dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String cameraDir        = "cameraDir";
41dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk
42dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String lightColor       = "lightColor";
43dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String lightPos         = "lightPos";
44dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String lightDir         = "lightDir";
45dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk
46dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String view             = "view";
47dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String proj             = "proj";
48dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String viewProj         = "viewProj";
49dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String model            = "model";
50dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String modelView        = "modelView";
51dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    static final String modelViewProj    = "modelViewProj";
52dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk
535c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk    static final long sMaxTimeStamp = 0xffffffffL;
545c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk
550c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk    ScriptField_ShaderParamData_s.Item mData;
560c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk    ScriptField_ShaderParamData_s mField;
57dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk
58a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    String mParamName;
590c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk    Camera mCamera;
600c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk
610c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk    static ScriptField_ShaderParam_s fillInParams(Element constantElem,
620c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk                                                  HashMap<String, ShaderParam> sourceParams,
630c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk                                                  Transform transform) {
640c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        RenderScriptGL rs = SceneManager.getRS();
650c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        ArrayList<ScriptField_ShaderParam_s.Item> paramList;
660c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        paramList = new ArrayList<ScriptField_ShaderParam_s.Item>();
67a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
684fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        int subElemCount = constantElem.getSubElementCount();
694fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        for (int i = 0; i < subElemCount; i ++) {
704fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            String inputName = constantElem.getSubElementName(i);
714fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            int offset = constantElem.getSubElementOffsetBytes(i);
724fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
734fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            ShaderParam matchingParam = sourceParams.get(inputName);
744fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            Element subElem = constantElem.getSubElement(i);
754fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            // Make one if it's not there
764fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            if (matchingParam == null) {
774fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk                if (subElem.getDataType() == Element.DataType.FLOAT_32) {
78c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk                    matchingParam = new Float4Param(inputName, 0.5f, 0.5f, 0.5f, 0.5f);
794fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk                } else if (subElem.getDataType() == Element.DataType.MATRIX_4X4) {
804fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk                    TransformParam trParam = new TransformParam(inputName);
814fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk                    trParam.setTransform(transform);
824fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk                    matchingParam = trParam;
834fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk                }
844fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            }
850c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            ScriptField_ShaderParam_s.Item paramRS = new ScriptField_ShaderParam_s.Item();
860c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            paramRS.bufferOffset = offset;
870c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            paramRS.transformTimestamp = 0;
885c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk            paramRS.dataTimestamp = 0;
890c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            paramRS.data = matchingParam.getRSData().getAllocation();
905c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk            if (subElem.getDataType() == Element.DataType.FLOAT_32) {
915c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk                paramRS.float_vecSize = subElem.getVectorSize();
925c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk            }
930c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk
940c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            paramList.add(paramRS);
950c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        }
960c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk
970c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        ScriptField_ShaderParam_s rsParams = null;
980c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        int paramCount = paramList.size();
990c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        if (paramCount != 0) {
1000c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            rsParams = new ScriptField_ShaderParam_s(rs, paramCount);
1010c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            for (int i = 0; i < paramCount; i++) {
1020c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk                rsParams.set(paramList.get(i), i, false);
1030c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            }
1040c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            rsParams.copyAll();
1054fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        }
1060c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        return rsParams;
1074fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    }
1084fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
109a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public ShaderParam(String name) {
110a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        mParamName = name;
1110c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        mData = new ScriptField_ShaderParamData_s.Item();
112a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
113a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
114a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    public String getParamName() {
115a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk        return mParamName;
116a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk    }
117dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk
1180c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk    public void setCamera(Camera c) {
1190c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        mCamera = c;
1200c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        if (mField != null) {
1210c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            mData.camera = mCamera.getRSData().getAllocation();
1220c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            mField.set_camera(0, mData.camera, true);
1230c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        }
124dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    }
125dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk
1265c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk    protected void incTimestamp() {
1275c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk        if (mField != null) {
1285c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk            mData.timestamp ++;
1295c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk            mData.timestamp %= sMaxTimeStamp;
1305c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk            mField.set_timestamp(0, mData.timestamp, true);
1315c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk        }
1325c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk    }
1335c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk
1340c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk    abstract void initLocalData();
135dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk
1360c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk    public ScriptField_ShaderParamData_s getRSData() {
1370c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        if (mField != null) {
1380c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            return mField;
139dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk        }
140dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk
1410c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        RenderScriptGL rs = SceneManager.getRS();
1420c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        mField = new ScriptField_ShaderParamData_s(rs, 1);
1430c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk
144452889a29671e63114dc2ab873597bdc5701f97bAlex Sakhartchouk        if (mParamName != null) {
1450c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            mData.paramName = SceneManager.getCachedAlloc(mParamName);
1460c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            if (mData.paramName == null) {
1470c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk                mData.paramName = SceneManager.getStringAsAllocation(rs, mParamName);
1480c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk                SceneManager.cacheAlloc(mParamName, mData.paramName);
149452889a29671e63114dc2ab873597bdc5701f97bAlex Sakhartchouk            }
150452889a29671e63114dc2ab873597bdc5701f97bAlex Sakhartchouk        }
1510c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        initLocalData();
1525c15b765fecca6b0ba2760d04c86798ff980fd53Alex Sakhartchouk        mData.timestamp = 1;
1530c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk
1540c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        mField.set(mData, 0, true);
1550c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk        return mField;
156dd1da451159578d865230ceada3e1f0058e3c18eAlex Sakhartchouk    }
157a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk}
158a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
159a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
160a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
161a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
162a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk
163