/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.renderscript;


/**
 * @hide
 * @deprecated in API 16
 * <p>The RenderScript fragment program, also known as fragment shader is responsible
 * for manipulating pixel data in a user defined way. It's constructed from a GLSL
 * shader string containing the program body, textures inputs, and a Type object
 * that describes the constants used by the program. Similar to the vertex programs,
 * when an allocation with constant input values is bound to the shader, its values
 * are sent to the graphics program automatically.</p>
 * <p> The values inside the allocation are not explicitly tracked. If they change between two draw
 * calls using the same program object, the runtime needs to be notified of that
 * change by calling rsgAllocationSyncAll so it could send the new values to hardware.
 * Communication between the vertex and fragment programs is handled internally in the
 * GLSL code. For example, if the fragment program is expecting a varying input called
 * varTex0, the GLSL code inside the program vertex must provide it.
 * </p>
 *
 **/
public class ProgramFragment extends Program {
    ProgramFragment(long id, RenderScript rs) {
        super(id, rs);
    }

    /**
     * @deprecated in API 16
     */
    public static class Builder extends BaseProgramBuilder {
        /**
         * @deprecated in API 16
         * Create a builder object.
         *
         * @param rs Context to which the program will belong.
         */
        public Builder(RenderScript rs) {
            super(rs);
        }

        /**
         * @deprecated in API 16
         * Creates ProgramFragment from the current state of the builder
         *
         * @return  ProgramFragment
         */
        public ProgramFragment create() {
            mRS.validate();
            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
            String[] texNames = new String[mTextureCount];
            int idx = 0;

            for (int i=0; i < mInputCount; i++) {
                tmp[idx++] = ProgramParam.INPUT.mID;
                tmp[idx++] = (int)mInputs[i].getID(mRS);
            }
            for (int i=0; i < mOutputCount; i++) {
                tmp[idx++] = ProgramParam.OUTPUT.mID;
                tmp[idx++] = (int)mOutputs[i].getID(mRS);
            }
            for (int i=0; i < mConstantCount; i++) {
                tmp[idx++] = ProgramParam.CONSTANT.mID;
                tmp[idx++] = (int)mConstants[i].getID(mRS);
            }
            for (int i=0; i < mTextureCount; i++) {
                tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
                tmp[idx++] = (int)mTextureTypes[i].mID;
                texNames[i] = mTextureNames[i];
            }

            long id = mRS.nProgramFragmentCreate(mShader, texNames, tmp);
            ProgramFragment pf = new ProgramFragment(id, mRS);
            initProgram(pf);
            return pf;
        }
    }
}



