content: /*
   * 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;
  
  import android.annotation.UnsupportedAppUsage;
  
  
  /**
   * @hide
   * <p>ProgramStore contains a set of parameters that control how
   * the graphics hardware handles writes to the framebuffer.
   * It could be used to:</p>
   * <ul>
   *   <li>enable/disable depth testing</li>
   *   <li>specify wheather depth writes are performed</li>
   *   <li>setup various blending modes for use in effects like
   *     transparency</li>
   *   <li>define write masks for color components written into the
   *     framebuffer</li>
   *  </ul>
   *
   **/
  public class ProgramStore extends BaseObj {
      /**
      * Specifies the function used to determine whether a fragment
      * will be drawn during the depth testing stage in the rendering
      * pipeline by comparing its value with that already in the depth
      * buffer. DepthFunc is only valid when depth buffer is present
      * and depth testing is enabled
      */
      public enum DepthFunc {
  
          /**
          * Always drawn
          */
          @UnsupportedAppUsage
          ALWAYS (0),
          /**
          * Drawn if the incoming depth value is less than that in the
          * depth buffer
          */
          @UnsupportedAppUsage
          LESS (1),
          /**
          * Drawn if the incoming depth value is less or equal to that in
          * the depth buffer
          */
          LESS_OR_EQUAL (2),
          /**
          * Drawn if the incoming depth value is greater than that in the
          * depth buffer
          */
          GREATER (3),
          /**
          * Drawn if the incoming depth value is greater or equal to that
          * in the depth buffer
          */
          GREATER_OR_EQUAL (4),
          /**
          * Drawn if the incoming depth value is equal to that in the
          * depth buffer
          */
          EQUAL (5),
          /**
          * Drawn if the incoming depth value is not equal to that in the
          * depth buffer
          */
          NOT_EQUAL (6);
  
          int mID;
          DepthFunc(int id) {
              mID = id;
          }
      }
  
      /**
      * Specifies the functions used to combine incoming pixels with
      * those already in the frame buffer.
      *
      * BlendSrcFunc describes how the coefficient used to scale the
      * source pixels during the blending operation is computed
      *
      */
      public enum BlendSrcFunc {
          ZERO (0),
          @UnsupportedAppUsage
          ONE (1),
          DST_COLOR (2),
          ONE_MINUS_DST_COLOR (3),
          @UnsupportedAppUsage
          SRC_ALPHA (4),
          ONE_MINUS_SRC_ALPHA (5),
          DST_ALPHA (6),
          ONE_MINUS_DST_ALPHA (7),
          SRC_ALPHA_SATURATE (8);
  
          int mID;
          BlendSrcFunc(int id) {
              mID = id;
          }
      }
  
      /**
      * Specifies the functions used to combine incoming pixels with
      * those already in the frame buffer.
      *
      * BlendDstFunc describes how the coefficient used to scale the
      * pixels already in the framebuffer is computed during the
      * blending operation
      *
      */
      public enum BlendDstFunc {
          @UnsupportedAppUsage
          ZERO (0),
          @UnsupportedAppUsage
          ONE (1),
          SRC_COLOR (2),
          ONE_MINUS_SRC_COLOR (3),
          SRC_ALPHA (4),
          @UnsupportedAppUsage
          ONE_MINUS_SRC_ALPHA (5),
          DST_ALPHA (6),
          ONE_MINUS_DST_ALPHA (7);
  
          int mID;
          BlendDstFunc(int id) {
              mID = id;
          }
      }
  
      DepthFunc mDepthFunc;
      boolean mDepthMask;
      boolean mColorMaskR;
      boolean mColorMaskG;
      boolean mColorMaskB;
      boolean mColorMaskA;
      BlendSrcFunc mBlendSrc;
      BlendDstFunc mBlendDst;
      boolean mDither;
  
      ProgramStore(long id, RenderScript rs) {
          super(id, rs);
      }
  
      /**
      * Returns the function used to test writing into the depth
      * buffer
      * @return depth function
      */
      public DepthFunc getDepthFunc() {
          return mDepthFunc;
      }
  
      /**
      * Queries whether writes are enabled into the depth buffer
      * @return depth mask
      */
      public boolean isDepthMaskEnabled() {
          return mDepthMask;
      }
  
      /**
      * Queries whether red channel is written
      * @return red color channel mask
      */
      public boolean isColorMaskRedEnabled() {
          return mColorMaskR;
      }
  
      /**
      * Queries whether green channel is written
      * @return green color channel mask
      */
      public boolean isColorMaskGreenEnabled() {
          return mColorMaskG;
      }
  
      /**
      * Queries whether blue channel is written
      * @return blue color channel mask
      */
      public boolean isColorMaskBlueEnabled() {
          return mColorMaskB;
      }
  
      /**
      * Queries whether alpha channel is written
      * @return alpha channel mask
      */
      public boolean isColorMaskAlphaEnabled() {
          return mColorMaskA;
      }
  
      /**
      * Specifies how the source blending factor is computed
      * @return source blend function
      */
      public BlendSrcFunc getBlendSrcFunc() {
          return mBlendSrc;
      }
  
      /**
      * Specifies how the destination blending factor is computed
      * @return destination blend function
      */
      public BlendDstFunc getBlendDstFunc() {
          return mBlendDst;
      }
  
      /**
      * Specifies whether colors are dithered before writing into the
      * framebuffer
      * @return whether dither is enabled
      */
      public boolean isDitherEnabled() {
          return mDither;
      }
  
      /**
      * Returns a pre-defined program store object with the following
      * characteristics:
      *  - incoming pixels are drawn if their depth value is less than
      *    the stored value in the depth buffer. If the pixel is
      *    drawn, its value is also stored in the depth buffer
      *  - incoming pixels override the value stored in the color
      *    buffer if it passes the depth test
      *
      *  @param rs Context to which the program will belong.
      **/
      public static ProgramStore BLEND_NONE_DEPTH_TEST(RenderScript rs) {
          if(rs.mProgramStore_BLEND_NONE_DEPTH_TEST == null) {
              ProgramStore.Builder builder = new ProgramStore.Builder(rs);
              builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
              builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
              builder.setDitherEnabled(false);
              builder.setDepthMaskEnabled(true);
              rs.mProgramStore_BLEND_NONE_DEPTH_TEST = builder.create();
          }
          return rs.mProgramStore_BLEND_NONE_DEPTH_TEST;
      }
      /**
      * Returns a pre-defined program store object with the following
      * characteristics:
      *  - incoming pixels always pass the depth test and their value
      *    is not stored in the depth buffer
      *  - incoming pixels override the value stored in the color
      *    buffer
      *
      *  @param rs Context to which the program will belong.
      **/
      public static ProgramStore BLEND_NONE_DEPTH_NONE(RenderScript rs) {
          if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH == null) {
              ProgramStore.Builder builder = new ProgramStore.Builder(rs);
              builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
              builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
              builder.setDitherEnabled(false);
              builder.setDepthMaskEnabled(false);
              rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH = builder.create();
          }
          return rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
      }
      /**
      * Returns a pre-defined program store object with the following
      * characteristics:
      *  - incoming pixels are drawn if their depth value is less than
      *    the stored value in the depth buffer. If the pixel is
      *    drawn, its value is also stored in the depth buffer
      *  - if the incoming (Source) pixel passes depth test, its value
      *    is combined with the stored color (Dest) using the
      *    following formula
      *  Final.RGB = Source.RGB * Source.A + Dest.RGB * (1 - Source.A)
      *
      *  @param rs Context to which the program will belong.
      **/
      public static ProgramStore BLEND_ALPHA_DEPTH_TEST(RenderScript rs) {
          if(rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST == null) {
              ProgramStore.Builder builder = new ProgramStore.Builder(rs);
              builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
              builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
              builder.setDitherEnabled(false);
              builder.setDepthMaskEnabled(true);
              rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST = builder.create();
          }
          return rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST;
      }
      /**
      * Returns a pre-defined program store object with the following
      * characteristics:
      *  - incoming pixels always pass the depth test and their value
      *    is not stored in the depth buffer
      *  - incoming pixel's value is combined with the stored color
      *    (Dest) using the following formula
      *  Final.RGB = Source.RGB * Source.A + Dest.RGB * (1 - Source.A)
      *
      *  @param rs Context to which the program will belong.
      **/
      @UnsupportedAppUsage
      public static ProgramStore BLEND_ALPHA_DEPTH_NONE(RenderScript rs) {
          if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH == null) {
              ProgramStore.Builder builder = new ProgramStore.Builder(rs);
              builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
              builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
              builder.setDitherEnabled(false);
              builder.setDepthMaskEnabled(false);
              rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH = builder.create();
          }
          return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
      }
  
      /**
      * Builder class for ProgramStore object. If the builder is left
      * empty, the equivalent of BLEND_NONE_DEPTH_NONE would be
      * returned
      */
      public static class Builder {
          RenderScript mRS;
          DepthFunc mDepthFunc;
          boolean mDepthMask;
          boolean mColorMaskR;
          boolean mColorMaskG;
          boolean mColorMaskB;
          boolean mColorMaskA;
          BlendSrcFunc mBlendSrc;
          BlendDstFunc mBlendDst;
          boolean mDither;
  
          @UnsupportedAppUsage
          public Builder(RenderScript rs) {
              mRS = rs;
              mDepthFunc = DepthFunc.ALWAYS;
              mDepthMask = false;
              mColorMaskR = true;
              mColorMaskG = true;
              mColorMaskB = true;
              mColorMaskA = true;
              mBlendSrc = BlendSrcFunc.ONE;
              mBlendDst = BlendDstFunc.ZERO;
          }
  
          /**
          * Specifies the depth testing behavior
          *
          * @param func function used for depth testing
          *
          * @return this
          */
          @UnsupportedAppUsage
          public Builder setDepthFunc(DepthFunc func) {
              mDepthFunc = func;
              return this;
          }
  
          /**
          * Enables writes into the depth buffer
          *
          * @param enable specifies whether depth writes are
          *         enabled or disabled
          *
          * @return this
          */
          @UnsupportedAppUsage
          public Builder setDepthMaskEnabled(boolean enable) {
              mDepthMask = enable;
              return this;
          }
  
          /**
          * Enables writes into the color buffer
          *
          * @param r specifies whether red channel is written
          * @param g specifies whether green channel is written
          * @param b specifies whether blue channel is written
          * @param a specifies whether alpha channel is written
          *
          * @return this
          */
          public Builder setColorMaskEnabled(boolean r, boolean g, boolean b, boolean a) {
              mColorMaskR = r;
              mColorMaskG = g;
              mColorMaskB = b;
              mColorMaskA = a;
              return this;
          }
  
          /**
          * Specifies how incoming pixels are combined with the pixels
          * stored in the framebuffer
          *
          * @param src specifies how the source blending factor is
          *            computed
          * @param dst specifies how the destination blending factor is
          *            computed
          *
          * @return this
          */
          @UnsupportedAppUsage
          public Builder setBlendFunc(BlendSrcFunc src, BlendDstFunc dst) {
              mBlendSrc = src;
              mBlendDst = dst;
              return this;
          }
  
          /**
          * Enables dithering
          *
          * @param enable specifies whether dithering is enabled or
          *               disabled
          *
          * @return this
          */
          @UnsupportedAppUsage
          public Builder setDitherEnabled(boolean enable) {
              mDither = enable;
              return this;
          }
  
          /**
          * Creates a program store from the current state of the builder
          */
          @UnsupportedAppUsage
          public ProgramStore create() {
              mRS.validate();
              long id = mRS.nProgramStoreCreate(mColorMaskR, mColorMaskG, mColorMaskB, mColorMaskA,
                                               mDepthMask, mDither,
                                               mBlendSrc.mID, mBlendDst.mID, mDepthFunc.mID);
              ProgramStore programStore = new ProgramStore(id, mRS);
              programStore.mDepthFunc = mDepthFunc;
              programStore.mDepthMask = mDepthMask;
              programStore.mColorMaskR = mColorMaskR;
              programStore.mColorMaskG = mColorMaskG;
              programStore.mColorMaskB = mColorMaskB;
              programStore.mColorMaskA = mColorMaskA;
              programStore.mBlendSrc = mBlendSrc;
              programStore.mBlendDst = mBlendDst;
              programStore.mDither = mDither;
              return programStore;
          }
      }
  
  }
  
  
  
  
  