ProgramVertexFixedFunction.java revision b4d7bb6872f523b4318144202e119766ed9054ed
1b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk/*
2b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk * Copyright (C) 2008 The Android Open Source Project
3b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk *
4b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License");
5b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk * you may not use this file except in compliance with the License.
6b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk * You may obtain a copy of the License at
7b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk *
8b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk *      http://www.apache.org/licenses/LICENSE-2.0
9b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk *
10b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk * Unless required by applicable law or agreed to in writing, software
11b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS,
12b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk * See the License for the specific language governing permissions and
14b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk * limitations under the License.
15b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk */
16b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
17b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchoukpackage android.renderscript;
18b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
19b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
20b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchoukimport android.graphics.Matrix;
21b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchoukimport android.util.Config;
22b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchoukimport android.util.Log;
23b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
24b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
25b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk/**
26b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk * @hide
27b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk *
28b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk **/
29b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchoukpublic class ProgramVertexFixedFunction extends ProgramVertex {
30b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
31b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    ProgramVertexFixedFunction(int id, RenderScript rs) {
32b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        super(id, rs);
33b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    }
34b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
35b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    public void bindConstants(Constants va) {
36b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        mRS.validate();
37b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        bindConstants(va.getAllocation(), 0);
38b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    }
39b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
40b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    static class InternalBuilder extends BaseProgramBuilder {
41b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public InternalBuilder(RenderScript rs) {
42b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            super(rs);
43b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
44b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
45b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public InternalBuilder addInput(Element e) throws IllegalStateException {
46b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            // Should check for consistant and non-conflicting names...
47b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            if(mInputCount >= MAX_INPUT) {
48b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                throw new RSIllegalArgumentException("Max input count exceeded.");
49b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            }
50b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            if (e.isComplex()) {
51b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                throw new RSIllegalArgumentException("Complex elements not allowed.");
52b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            }
53b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mInputs[mInputCount++] = e;
54b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            return this;
55b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
56b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
57b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public ProgramVertexFixedFunction create() {
58b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mRS.validate();
59b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
60b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            int idx = 0;
61b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
62b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            for (int i=0; i < mInputCount; i++) {
63b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                tmp[idx++] = ProgramParam.INPUT.mID;
64b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                tmp[idx++] = mInputs[i].getID();
65b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            }
66b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            for (int i=0; i < mOutputCount; i++) {
67b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                tmp[idx++] = ProgramParam.OUTPUT.mID;
68b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                tmp[idx++] = mOutputs[i].getID();
69b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            }
70b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            for (int i=0; i < mConstantCount; i++) {
71b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                tmp[idx++] = ProgramParam.CONSTANT.mID;
72b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                tmp[idx++] = mConstants[i].getID();
73b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            }
74b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            for (int i=0; i < mTextureCount; i++) {
75b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
76b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                tmp[idx++] = mTextureTypes[i].mID;
77b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            }
78b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
79b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            int id = mRS.nProgramVertexCreate(mShader, tmp);
80b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            ProgramVertexFixedFunction pv = new ProgramVertexFixedFunction(id, mRS);
81b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            initProgram(pv);
82b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            return pv;
83b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
84b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    }
85b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
86b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    public static class Builder {
87b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        boolean mTextureMatrixEnable;
88b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        String mShader;
89b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        RenderScript mRS;
90b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
91b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public Builder(RenderScript rs) {
92b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mRS = rs;
93b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
94b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
95b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public Builder setTextureMatrixEnable(boolean enable) {
96b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mTextureMatrixEnable = enable;
97b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            return this;
98b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
99b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        static Type getConstantInputType(RenderScript rs) {
100b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            Element.Builder b = new Element.Builder(rs);
101b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            b.add(Element.MATRIX4X4(rs), "MV");
102b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            b.add(Element.MATRIX4X4(rs), "P");
103b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            b.add(Element.MATRIX4X4(rs), "TexMatrix");
104b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            b.add(Element.MATRIX4X4(rs), "MVP");
105b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
106b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            Type.Builder typeBuilder = new Type.Builder(rs, b.create());
107b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            typeBuilder.setX(1);
108b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            return typeBuilder.create();
109b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
110b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
111b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        private void buildShaderString() {
112b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
113b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mShader  = "//rs_shader_internal\n";
114b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mShader += "varying vec4 varColor;\n";
115b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mShader += "varying vec2 varTex0;\n";
116b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
117b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mShader += "void main() {\n";
118b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mShader += "  gl_Position = UNI_MVP * ATTRIB_position;\n";
119b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mShader += "  gl_PointSize = 1.0;\n";
120b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
121b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mShader += "  varColor = ATTRIB_color;\n";
122b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            if (mTextureMatrixEnable) {
123b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                mShader += "  varTex0 = (UNI_TexMatrix * vec4(ATTRIB_texture0, 0.0, 1.0)).xy;\n";
124b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            } else {
125b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                mShader += "  varTex0 = ATTRIB_texture0;\n";
126b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            }
127b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mShader += "}\n";
128b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
129b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
130b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public ProgramVertexFixedFunction create() {
131b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            buildShaderString();
132b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
133b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            InternalBuilder sb = new InternalBuilder(mRS);
134b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            sb.setShader(mShader);
135b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            sb.addConstant(getConstantInputType(mRS));
136b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
137b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            Element.Builder b = new Element.Builder(mRS);
138b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            b.add(Element.F32_4(mRS), "position");
139b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            b.add(Element.F32_4(mRS), "color");
140b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            b.add(Element.F32_3(mRS), "normal");
141b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            b.add(Element.F32_2(mRS), "texture0");
142b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            sb.addInput(b.create());
143b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
144b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            return sb.create();
145b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
146b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    }
147b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
148b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    public static class Constants {
149b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        static final int MODELVIEW_OFFSET = 0;
150b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        static final int PROJECTION_OFFSET = 16;
151b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        static final int TEXTURE_OFFSET = 32;
152b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
153b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        Matrix4f mModel;
154b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        Matrix4f mProjection;
155b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        Matrix4f mTexture;
156b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
157b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        Allocation mAlloc;
158b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        Allocation getAllocation() {
159b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            return mAlloc;
160b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
161b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        private FieldPacker mIOBuffer;
162b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
163b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public Constants(RenderScript rs) {
164b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            Type constInputType = ProgramVertexFixedFunction.Builder.getConstantInputType(rs);
165b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mAlloc = Allocation.createTyped(rs, constInputType);
166b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            int bufferSize = constInputType.getElement().getSizeBytes()*
167b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                             constInputType.getCount();
168b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mIOBuffer = new FieldPacker(bufferSize);
169b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mModel = new Matrix4f();
170b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mProjection = new Matrix4f();
171b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mTexture = new Matrix4f();
172b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            setModelview(new Matrix4f());
173b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            setProjection(new Matrix4f());
174b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            setTexture(new Matrix4f());
175b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
176b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
177b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public void destroy() {
178b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mAlloc.destroy();
179b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mAlloc = null;
180b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
181b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
182b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        private void addToBuffer(int offset, Matrix4f m) {
183b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mIOBuffer.reset(offset);
184b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            for(int i = 0; i < 16; i ++) {
185b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk                mIOBuffer.addF32(m.mMat[i]);
186b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            }
187b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mAlloc.copyFrom(mIOBuffer.getData());
188b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
189b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
190b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public void setModelview(Matrix4f m) {
191b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mModel.load(m);
192b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            addToBuffer(MODELVIEW_OFFSET*4, m);
193b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
194b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
195b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public void setProjection(Matrix4f m) {
196b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mProjection.load(m);
197b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            addToBuffer(PROJECTION_OFFSET*4, m);
198b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
199b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk
200b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        public void setTexture(Matrix4f m) {
201b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            mTexture.load(m);
202b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk            addToBuffer(TEXTURE_OFFSET*4, m);
203b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk        }
204b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk    }
205b4d7bb6872f523b4318144202e119766ed9054edAlex Sakhartchouk}
206