/* static */ ProgramProfileOGL
ProgramProfileOGL::GetProfileFor(gl::ShaderProgramType aType,
                                 MaskType aMask)
{
  NS_ASSERTION(ProgramExists(aType, aMask), "Invalid program type.");
  ProgramProfileOGL result;

  switch (aType) {
  case gl::RGBALayerProgramType:
    if (aMask == Mask3d) {
      result.mVertexShaderString = sLayerMask3DVS;
      result.mFragmentShaderString = sRGBATextureLayerMask3DFS;
    } else if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sRGBATextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sRGBATextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case gl::RGBALayerExternalProgramType:
    if (aMask == Mask3d) {
      result.mVertexShaderString = sLayerMask3DVS;
      result.mFragmentShaderString = sRGBATextureLayerExternalMask3DFS;
    } else if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sRGBATextureLayerExternalMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sRGBATextureLayerExternalFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mUniforms.AppendElement(Argument("uTextureTransform"));
    result.mHasTextureTransform = true;
    result.mTextureCount = 1;
    break;
  case gl::BGRALayerProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sBGRATextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sBGRATextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case gl::RGBXLayerProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sRGBXTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sRGBXTextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case gl::BGRXLayerProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sBGRXTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sBGRXTextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case gl::RGBARectLayerProgramType:
    if (aMask == Mask3d) {
      result.mVertexShaderString = sLayerMask3DVS;
      result.mFragmentShaderString = sRGBARectTextureLayerMask3DFS;
    } else if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sRGBARectTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sRGBARectTextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case gl::RGBAExternalLayerProgramType:
    if (aMask == Mask3d) {
      result.mVertexShaderString = sLayerMask3DVS;
      result.mFragmentShaderString = sRGBAExternalTextureLayerMask3DFS;
    } else if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sRGBAExternalTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sRGBAExternalTextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case gl::ColorLayerProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sSolidColorLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sSolidColorLayerFS;
    }
    AddCommonArgs(result);
    result.mUniforms.AppendElement(Argument("uRenderColor"));
    break;
  case gl::YCbCrLayerProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sYCbCrTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sYCbCrTextureLayerFS;
    }
    AddCommonArgs(result);
    result.mUniforms.AppendElement(Argument("uLayerOpacity"));
    result.mUniforms.AppendElement(Argument("uYTexture"));
    result.mUniforms.AppendElement(Argument("uCbTexture"));
    result.mUniforms.AppendElement(Argument("uCrTexture"));
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 3;
    break;
  case gl::ComponentAlphaPass1ProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sComponentPassMask1FS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sComponentPass1FS;
    }
    AddCommonArgs(result);
    result.mUniforms.AppendElement(Argument("uLayerOpacity"));
    result.mUniforms.AppendElement(Argument("uBlackTexture"));
    result.mUniforms.AppendElement(Argument("uWhiteTexture"));
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 2;
    break;
  case gl::ComponentAlphaPass2ProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sComponentPassMask2FS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sComponentPass2FS;
    }
    AddCommonArgs(result);
    result.mUniforms.AppendElement(Argument("uLayerOpacity"));
    result.mUniforms.AppendElement(Argument("uBlackTexture"));
    result.mUniforms.AppendElement(Argument("uWhiteTexture"));
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 2;
    break;
  case gl::Copy2DProgramType:
    NS_ASSERTION(!aMask, "Program does not have masked variant.");
    result.mVertexShaderString = sCopyVS;
    result.mFragmentShaderString = sCopy2DFS;
    result.mUniforms.AppendElement(Argument("uTexture"));
    result.mAttributes.AppendElement(Argument("aVertexCoord"));
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 1;
    break;
  case gl::Copy2DRectProgramType:
    NS_ASSERTION(!aMask, "Program does not have masked variant.");
    result.mVertexShaderString = sCopyVS;
    result.mFragmentShaderString = sCopy2DRectFS;
    result.mUniforms.AppendElement(Argument("uTexture"));
    result.mAttributes.AppendElement(Argument("aVertexCoord"));
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 1;
    break;
  default:
    NS_NOTREACHED("Unknown shader program type.");
  }

  if (aMask > MaskNone) {
    result.mUniforms.AppendElement(Argument("uMaskTexture"));
    result.mUniforms.AppendElement(Argument("uMaskQuadTransform"));
    result.mTextureCount += 1;
  }

  return result;
}
/* static */ ProgramProfileOGL
ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
                                 MaskType aMask)
{
  NS_ASSERTION(ProgramExists(aType, aMask), "Invalid program type.");
  ProgramProfileOGL result;

  AddUniforms(result);

  switch (aType) {
  case RGBALayerProgramType:
    if (aMask == Mask3d) {
      result.mVertexShaderString = sLayerMask3DVS;
      result.mFragmentShaderString = sRGBATextureLayerMask3DFS;
    } else if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sRGBATextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sRGBATextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case BGRALayerProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sBGRATextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sBGRATextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case RGBXLayerProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sRGBXTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sRGBXTextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case BGRXLayerProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sBGRXTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sBGRXTextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case RGBARectLayerProgramType:
    if (aMask == Mask3d) {
      result.mVertexShaderString = sLayerMask3DVS;
      result.mFragmentShaderString = sRGBARectTextureLayerMask3DFS;
    } else if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sRGBARectTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sRGBARectTextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case RGBXRectLayerProgramType:
    if (aMask == Mask3d) {
      result.mVertexShaderString = sLayerMask3DVS;
      result.mFragmentShaderString = sRGBXRectTextureLayerMask3DFS;
    } else if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sRGBXRectTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sRGBXRectTextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case BGRARectLayerProgramType:
    MOZ_ASSERT(aMask == MaskNone, "BGRARectLayerProgramType can't handle masks.");
    result.mVertexShaderString = sLayerVS;
    result.mFragmentShaderString = sBGRARectTextureLayerFS;
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case RGBAExternalLayerProgramType:
    if (aMask == Mask3d) {
      result.mVertexShaderString = sLayerMask3DVS;
      result.mFragmentShaderString = sRGBAExternalTextureLayerMask3DFS;
    } else if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sRGBAExternalTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sRGBAExternalTextureLayerFS;
    }
    AddCommonArgs(result);
    AddCommonTextureArgs(result);
    result.mTextureCount = 1;
    break;
  case ColorLayerProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sSolidColorLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sSolidColorLayerFS;
    }
    AddCommonArgs(result);
    break;
  case YCbCrLayerProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sYCbCrTextureLayerMaskFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sYCbCrTextureLayerFS;
    }
    AddCommonArgs(result);
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 3;
    break;
  case ComponentAlphaPass1ProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sComponentPassMask1FS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sComponentPass1FS;
    }
    AddCommonArgs(result);
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 2;
    break;
  case ComponentAlphaPass1RGBProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sComponentPassMask1RGBFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sComponentPass1RGBFS;
    }
    AddCommonArgs(result);
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 2;
    break;
  case ComponentAlphaPass2ProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sComponentPassMask2FS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sComponentPass2FS;
    }
    AddCommonArgs(result);
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 2;
    break;
  case ComponentAlphaPass2RGBProgramType:
    if (aMask == Mask2d) {
      result.mVertexShaderString = sLayerMaskVS;
      result.mFragmentShaderString = sComponentPassMask2RGBFS;
    } else {
      result.mVertexShaderString = sLayerVS;
      result.mFragmentShaderString = sComponentPass2RGBFS;
    }
    AddCommonArgs(result);
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 2;
    break;
  case Copy2DProgramType:
    NS_ASSERTION(!aMask, "Program does not have masked variant.");
    result.mVertexShaderString = sCopyVS;
    result.mFragmentShaderString = sCopy2DFS;
    result.mAttributes.AppendElement(Argument("aVertexCoord"));
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 1;
    break;
  case Copy2DRectProgramType:
    NS_ASSERTION(!aMask, "Program does not have masked variant.");
    result.mVertexShaderString = sCopyVS;
    result.mFragmentShaderString = sCopy2DRectFS;
    result.mAttributes.AppendElement(Argument("aVertexCoord"));
    result.mAttributes.AppendElement(Argument("aTexCoord"));
    result.mTextureCount = 1;
    break;
  default:
    NS_NOTREACHED("Unknown shader program type.");
  }

  if (aMask > MaskNone) {
    result.mTextureCount += 1;
  }

  return result;
}