text: /*
   * Copyright 2013 Google Inc.
   *
   * Use of this source code is governed by a BSD-style license that can be
   * found in the LICENSE file.
   */
  
  #ifndef GrTypesPriv_DEFINED
  #define GrTypesPriv_DEFINED
  
  #include "GrTypes.h"
  #include "SkTArray.h"
  
  /**
   * Types of shader-language-specific boxed variables we can create. (Currently only GrGLShaderVars,
   * but should be applicable to other shader languages.)
   */
  enum GrSLType {
      kVoid_GrSLType,
      kFloat_GrSLType,
      kVec2f_GrSLType,
      kVec3f_GrSLType,
      kVec4f_GrSLType,
      kMat33f_GrSLType,
      kMat44f_GrSLType,
      kSampler2D_GrSLType,
  
      kLast_GrSLType = kSampler2D_GrSLType
  };
  static const int kGrSLTypeCount = kLast_GrSLType + 1;
  
  /**
   * Gets the vector size of the SLType. Returns -1 for void, matrices, and samplers.
   */
  static inline int GrSLTypeVectorCount(GrSLType type) {
      GrAssert(type >= 0 && type < static_cast<GrSLType>(kGrSLTypeCount));
      static const int kCounts[] = { -1, 1, 2, 3, 4, -1, -1, -1 };
      return kCounts[type];
  
      GR_STATIC_ASSERT(0 == kVoid_GrSLType);
      GR_STATIC_ASSERT(1 == kFloat_GrSLType);
      GR_STATIC_ASSERT(2 == kVec2f_GrSLType);
      GR_STATIC_ASSERT(3 == kVec3f_GrSLType);
      GR_STATIC_ASSERT(4 == kVec4f_GrSLType);
      GR_STATIC_ASSERT(5 == kMat33f_GrSLType);
      GR_STATIC_ASSERT(6 == kMat44f_GrSLType);
      GR_STATIC_ASSERT(7 == kSampler2D_GrSLType);
      GR_STATIC_ASSERT(GR_ARRAY_COUNT(kCounts) == kGrSLTypeCount);
  }
  
  /** Return the type enum for a vector of floats of length n (1..4),
   e.g. 1 -> kFloat_GrSLType, 2 -> kVec2_GrSLType, ... */
  static inline GrSLType GrSLFloatVectorType(int count) {
      GrAssert(count > 0 && count <= 4);
      return (GrSLType)(count);
  
      GR_STATIC_ASSERT(kFloat_GrSLType == 1);
      GR_STATIC_ASSERT(kVec2f_GrSLType == 2);
      GR_STATIC_ASSERT(kVec3f_GrSLType == 3);
      GR_STATIC_ASSERT(kVec4f_GrSLType == 4);
  }
  
  /**
   * Types used to describe format of vertices in arrays.
    */
  enum GrVertexAttribType {
      kFloat_GrVertexAttribType = 0,
      kVec2f_GrVertexAttribType,
      kVec3f_GrVertexAttribType,
      kVec4f_GrVertexAttribType,
      kVec4ub_GrVertexAttribType,   // vector of 4 unsigned bytes, e.g. colors
  
      kLast_GrVertexAttribType = kVec4ub_GrVertexAttribType
  };
  static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
  
  /**
   * Returns the vector size of the type.
   */
  static inline int GrVertexAttribTypeVectorCount(GrVertexAttribType type) {
      GrAssert(type >= 0 && type < kGrVertexAttribTypeCount);
      static const int kCounts[] = { 1, 2, 3, 4, 4 };
      return kCounts[type];
  
      GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
      GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
      GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
      GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
      GR_STATIC_ASSERT(4 == kVec4ub_GrVertexAttribType);
      GR_STATIC_ASSERT(GR_ARRAY_COUNT(kCounts) == kGrVertexAttribTypeCount);
  }
  
  /**
   * Returns the size of the attrib type in bytes.
   */
  static inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
      GrAssert(type >= 0 && type < kGrVertexAttribTypeCount);
      static const size_t kSizes[] = {
          sizeof(float),          // kFloat_GrVertexAttribType
          2*sizeof(float),        // kVec2f_GrVertexAttribType
          3*sizeof(float),        // kVec3f_GrVertexAttribType
          4*sizeof(float),        // kVec4f_GrVertexAttribType
          4*sizeof(char)          // kVec4ub_GrVertexAttribType
      };
      return kSizes[type];
  
      GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
      GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
      GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
      GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
      GR_STATIC_ASSERT(4 == kVec4ub_GrVertexAttribType);
      GR_STATIC_ASSERT(GR_ARRAY_COUNT(kSizes) == kGrVertexAttribTypeCount);
  }
  
  /**
   * Semantic bindings for vertex attributes. kEffect means that the attribute is input to a GrEffect.
   * Each binding other than kEffect may not appear more than once in the current set of attributes.
   * kPosition must be appear for exactly one attribute.
   */
  enum GrVertexAttribBinding {
      kPosition_GrVertexAttribBinding,    // required, must have vector count of 2
      kLocalCoord_GrVertexAttribBinding,  // must have vector count of 2
      kColor_GrVertexAttribBinding,       // must have vector count of 4
      kCoverage_GrVertexAttribBinding,    // must have vector count of 4
  
      kLastFixedFunction_GrVertexAttribBinding = kCoverage_GrVertexAttribBinding,
  
      kEffect_GrVertexAttribBinding,      // vector length must agree with
                                          // GrEffect::vertexAttribType() for each effect input to
                                          // which the attribute is mapped by GrDrawState::setEffect()
      kLast_GrVertexAttribBinding = kEffect_GrVertexAttribBinding
  };
  
  static const int kGrVertexAttribBindingCnt = kLast_GrVertexAttribBinding + 1;
  static const int kGrFixedFunctionVertexAttribBindingCnt =
      kLastFixedFunction_GrVertexAttribBinding + 1;
  
  static inline int GrFixedFunctionVertexAttribVectorCount(GrVertexAttribBinding binding) {
      GrAssert(binding >= 0 && binding < kGrFixedFunctionVertexAttribBindingCnt);
      static const int kVecCounts[] = { 2, 2, 4, 4 };
  
      return kVecCounts[binding];
  
      GR_STATIC_ASSERT(0 == kPosition_GrVertexAttribBinding);
      GR_STATIC_ASSERT(1 == kLocalCoord_GrVertexAttribBinding);
      GR_STATIC_ASSERT(2 == kColor_GrVertexAttribBinding);
      GR_STATIC_ASSERT(3 == kCoverage_GrVertexAttribBinding);
      GR_STATIC_ASSERT(kGrFixedFunctionVertexAttribBindingCnt == SK_ARRAY_COUNT(kVecCounts));
  }
  
  struct GrVertexAttrib {
      inline void set(GrVertexAttribType type, size_t offset, GrVertexAttribBinding binding) {
          fType = type;
          fOffset = offset;
          fBinding = binding;
      }
      bool operator==(const GrVertexAttrib& other) const {
          return fType == other.fType && fOffset == other.fOffset && fBinding == other.fBinding;
      };
      bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
  
      GrVertexAttribType      fType;
      size_t                  fOffset;
      GrVertexAttribBinding   fBinding;
  };
  
  template <int N> class GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
  
  #endif
  