14fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk/*
24fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk * Copyright (C) 2011 The Android Open Source Project
34fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk *
44fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License");
54fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk * you may not use this file except in compliance with the License.
64fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk * You may obtain a copy of the License at
74fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk *
84fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk *      http://www.apache.org/licenses/LICENSE-2.0
94fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk *
104fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk * Unless required by applicable law or agreed to in writing, software
114fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS,
124fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk * See the License for the specific language governing permissions and
144fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk * limitations under the License.
154fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk */
164fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
174fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukpackage com.android.scenegraph;
184fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
194fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukimport java.lang.Math;
204fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukimport java.util.ArrayList;
214fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
225de922962a2fa06267f3ad26f75e3a8083af906cAlex Sakhartchoukimport com.android.scenegraph.TextureBase;
235de922962a2fa06267f3ad26f75e3a8083af906cAlex Sakhartchouk
244fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukimport android.content.res.Resources;
254fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukimport android.renderscript.*;
264fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukimport android.renderscript.ProgramFragment.Builder;
274fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukimport android.util.Log;
284fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
294fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk/**
304fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk * @hide
314fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk */
324fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchoukpublic class FragmentShader extends Shader {
334fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    ProgramFragment mProgram;
344fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    ScriptField_FragmentShader_s mField;
354fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
364fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    public static class Builder {
374fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
384fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        FragmentShader mShader;
394fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        ProgramFragment.Builder mBuilder;
404fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
414fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        public Builder(RenderScriptGL rs) {
424fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            mShader = new FragmentShader();
434fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            mBuilder = new ProgramFragment.Builder(rs);
444fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        }
454fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
464fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        public Builder setShader(Resources resources, int resourceID) {
474fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            mBuilder.setShader(resources, resourceID);
484fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            return this;
494fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        }
504fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
51c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        public Builder setShader(String code) {
52c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            mBuilder.setShader(code);
53c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk            return this;
54c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk        }
55c71343acc469db7ec351db2344032801e0e1b30aAlex Sakhartchouk
564fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        public Builder setObjectConst(Type type) {
574fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            mShader.mPerObjConstants = type;
584fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            return this;
594fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        }
604fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
614fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        public Builder setShaderConst(Type type) {
624fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            mShader.mPerShaderConstants = type;
634fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            return this;
644fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        }
654fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
6699b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk        public Builder addShaderTexture(Program.TextureType texType, String name) {
6799b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            mShader.mShaderTextureNames.add(name);
6899b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            mShader.mShaderTextureTypes.add(texType);
6999b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            return this;
7099b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk        }
7199b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk
724fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        public Builder addTexture(Program.TextureType texType, String name) {
734fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            mShader.mTextureNames.add(name);
7499b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            mShader.mTextureTypes.add(texType);
754fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            return this;
764fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        }
774fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
78d4cb9c587c23e3c24d928b0ac1a4de5679846f93Alex Sakhartchouk        public FragmentShader create() {
794fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            if (mShader.mPerShaderConstants != null) {
804fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk                mBuilder.addConstant(mShader.mPerShaderConstants);
814fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            }
824fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            if (mShader.mPerObjConstants != null) {
834fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk                mBuilder.addConstant(mShader.mPerObjConstants);
844fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            }
8599b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            for (int i = 0; i < mShader.mTextureTypes.size(); i ++) {
869cc290038ca3ee06ed34d172bbd139ea13bafd1bAlex Sakhartchouk                mBuilder.addTexture(mShader.mTextureTypes.get(i),
879cc290038ca3ee06ed34d172bbd139ea13bafd1bAlex Sakhartchouk                                    mShader.mTextureNames.get(i));
8899b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            }
8999b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            for (int i = 0; i < mShader.mShaderTextureTypes.size(); i ++) {
909cc290038ca3ee06ed34d172bbd139ea13bafd1bAlex Sakhartchouk                mBuilder.addTexture(mShader.mShaderTextureTypes.get(i),
919cc290038ca3ee06ed34d172bbd139ea13bafd1bAlex Sakhartchouk                                    mShader.mShaderTextureNames.get(i));
9299b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            }
9399b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk
944fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            mShader.mProgram = mBuilder.create();
954fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            return mShader;
964fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        }
974fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    }
984fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
99d4cb9c587c23e3c24d928b0ac1a4de5679846f93Alex Sakhartchouk    public ProgramFragment getProgram() {
100d4cb9c587c23e3c24d928b0ac1a4de5679846f93Alex Sakhartchouk        return mProgram;
101d4cb9c587c23e3c24d928b0ac1a4de5679846f93Alex Sakhartchouk    }
102d4cb9c587c23e3c24d928b0ac1a4de5679846f93Alex Sakhartchouk
103e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk    ScriptField_ShaderParam_s getTextureParams() {
104e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        RenderScriptGL rs = SceneManager.getRS();
105e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        Resources res = SceneManager.getRes();
106e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        if (rs == null || res == null) {
107e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk            return null;
108e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        }
109e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
110e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        ArrayList<ScriptField_ShaderParam_s.Item> paramList;
111e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        paramList = new ArrayList<ScriptField_ShaderParam_s.Item>();
112e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
11399b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk        int shaderTextureStart = mTextureTypes.size();
11499b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk        for (int i = 0; i < mShaderTextureNames.size(); i ++) {
11599b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            ShaderParam sp = mSourceParams.get(mShaderTextureNames.get(i));
11699b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            if (sp != null && sp instanceof TextureParam) {
11799b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk                TextureParam p = (TextureParam)sp;
118e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk                ScriptField_ShaderParam_s.Item paramRS = new ScriptField_ShaderParam_s.Item();
119e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk                paramRS.bufferOffset = shaderTextureStart + i;
120e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk                paramRS.transformTimestamp = 0;
121e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk                paramRS.dataTimestamp = 0;
122e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk                paramRS.data = p.getRSData().getAllocation();
123e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk                paramList.add(paramRS);
124e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk            }
125e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        }
126e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
127e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        ScriptField_ShaderParam_s rsParams = null;
128e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        int paramCount = paramList.size();
129e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        if (paramCount != 0) {
130e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk            rsParams = new ScriptField_ShaderParam_s(rs, paramCount);
131e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk            for (int i = 0; i < paramCount; i++) {
132e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk                rsParams.set(paramList.get(i), i, false);
13399b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk            }
134e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk            rsParams.copyAll();
13599b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk        }
136e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        return rsParams;
13799b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk    }
13899b93819f12f18b8559f702d7a303c31fe05205aAlex Sakhartchouk
139e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk    ScriptField_FragmentShader_s getRSData() {
1404fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        if (mField != null) {
1414fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            return mField;
1424fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        }
1434fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
144e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        RenderScriptGL rs = SceneManager.getRS();
145e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        Resources res = SceneManager.getRes();
146e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        if (rs == null || res == null) {
147e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk            return null;
148e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        }
149e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk
1504fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        ScriptField_FragmentShader_s.Item item = new ScriptField_FragmentShader_s.Item();
1514fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        item.program = mProgram;
1524fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
153e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        ScriptField_ShaderParam_s texParams = getTextureParams();
154e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        if (texParams != null) {
155e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk            item.shaderTextureParams = texParams.getAllocation();
156e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk        }
157e8bb420a687598be9801e7ff4a0d114fa72ac5bcAlex Sakhartchouk
158e93db17a143ff560f92d94b68ce1e76f79db7902Alex Sakhartchouk        linkConstants(rs);
1594fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        if (mPerShaderConstants != null) {
1604fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            item.shaderConst = mConstantBuffer;
1610c9523357f48a26c8214ccff0b0d95c6927ac0d3Alex Sakhartchouk            item.shaderConstParams = mConstantBufferParams.getAllocation();
1624fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            mProgram.bindConstants(item.shaderConst, 0);
1634fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        }
1644fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
1654fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        item.objectConstIndex = -1;
1664fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        if (mPerObjConstants != null) {
1674fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk            item.objectConstIndex = mPerShaderConstants != null ? 1 : 0;
1684fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        }
1694fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk
1704fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        mField = new ScriptField_FragmentShader_s(rs, 1);
1714fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        mField.set(item, 0, true);
1724fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk        return mField;
1734fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk    }
1744fd35d8f49dbed174828da60b70c37e7a77a0d13Alex Sakhartchouk}
175