/// <summary> /// Adds the shader source registered manually. /// </summary> /// <param name="type">The type.</param> /// <param name="sourceCode">The source code.</param> /// <param name="sourcePath">The source path.</param> public void AddShaderSource(string type, string sourceCode, string sourcePath) { lock (locker) { var shaderSource = new ShaderSourceWithHash() { Source = sourceCode, Path = sourcePath }; shaderSource.Hash = ObjectId.FromBytes(Encoding.UTF8.GetBytes(shaderSource.Source)); loadedShaderSources[type] = shaderSource; classNameToPath[type] = sourcePath; } }
/// <summary> /// Loads the shader source with the specified type name. /// </summary> /// <param name="type">The typeName.</param> /// <returns>ShaderSourceWithHash.</returns> /// <exception cref="System.IO.FileNotFoundException">If the file was not found</exception> public ShaderSourceWithHash LoadShaderSource(string type) { lock (locker) { // Load file ShaderSourceWithHash shaderSource; if (!loadedShaderSources.TryGetValue(type, out shaderSource)) { var sourceUrl = FindFilePath(type); if (sourceUrl != null) { shaderSource = new ShaderSourceWithHash(); if (!UrlToFilePath.TryGetValue(sourceUrl, out shaderSource.Path)) { shaderSource.Path = sourceUrl; } // On Windows, Always try to load first from the original URL in order to get the latest version if (Platform.IsWindowsDesktop) { // TODO: the "/path" is hardcoded, used in ImportStreamCommand and EffectSystem. Find a place to share this correctly. var pathUrl = sourceUrl + "/path"; if (FileExists(pathUrl)) { using (var fileStream = OpenStream(pathUrl)) { string shaderSourcePath; using (var sr = new StreamReader(fileStream, Encoding.UTF8)) shaderSourcePath = sr.ReadToEnd(); if (File.Exists(shaderSourcePath)) { // Replace path with a local path shaderSource.Path = Path.Combine(Environment.CurrentDirectory, shaderSourcePath); // Optimization: It currently reads the source file twice shaderSource.Hash = ObjectId.FromBytes(File.ReadAllBytes(shaderSourcePath)); using (var sourceStream = File.Open(shaderSourcePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (var sr = new StreamReader(sourceStream)) shaderSource.Source = sr.ReadToEnd(); } } } } } if (shaderSource.Source == null) { using (var sourceStream = OpenStream(sourceUrl)) { var databaseStream = sourceStream as IDatabaseStream; var fileStream = sourceStream as FileStream; if (databaseStream != null || fileStream != null) { using (var sr = new StreamReader(sourceStream)) shaderSource.Source = sr.ReadToEnd(); if (databaseStream != null) { shaderSource.Hash = databaseStream.ObjectId; } else { shaderSource.Hash = ObjectId.FromBytes(File.ReadAllBytes(sourceUrl)); } } else { throw new Exception(string.Format("Unsupported Stream type to load shader [{0}.pdxsl]", type)); } } } loadedShaderSources[type] = shaderSource; } else { throw new FileNotFoundException(string.Format("Unable to find shader [{0}]", type), string.Format("{0}.pdxsl", type)); } } return(shaderSource); } }
/// <summary> /// Loads the shader source with the specified type name. /// </summary> /// <param name="type">The typeName.</param> /// <returns>ShaderSourceWithHash.</returns> /// <exception cref="System.IO.FileNotFoundException">If the file was not found</exception> public ShaderSourceWithHash LoadShaderSource(string type) { lock (locker) { // Load file ShaderSourceWithHash shaderSource; if (!loadedShaderSources.TryGetValue(type, out shaderSource)) { var sourceUrl = FindFilePath(type); if (sourceUrl != null) { shaderSource = new ShaderSourceWithHash(); if (!UrlToFilePath.TryGetValue(sourceUrl, out shaderSource.Path)) { shaderSource.Path = sourceUrl; } // On Windows, Always try to load first from the original URL in order to get the latest version if (Platform.IsWindowsDesktop) { // TODO: the "/path" is hardcoded, used in ImportStreamCommand and EffectSystem. Find a place to share this correctly. var pathUrl = sourceUrl + "/path"; if (FileExists(pathUrl)) { using (var fileStream = OpenStream(pathUrl)) { string shaderSourcePath; using (var sr = new StreamReader(fileStream, Encoding.UTF8)) shaderSourcePath = sr.ReadToEnd(); if (File.Exists(shaderSourcePath)) { // Replace path with a local path shaderSource.Path = Path.Combine(Environment.CurrentDirectory, shaderSourcePath); // Optimization: It currently reads the source file twice shaderSource.Hash = ObjectId.FromBytes(File.ReadAllBytes(shaderSourcePath)); using (var sourceStream = File.Open(shaderSourcePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (var sr = new StreamReader(sourceStream)) shaderSource.Source = sr.ReadToEnd(); } } } } } if (shaderSource.Source == null) { using (var sourceStream = OpenStream(sourceUrl)) { var databaseStream = sourceStream as IDatabaseStream; var fileStream = sourceStream as FileStream; if (databaseStream != null || fileStream != null) { using (var sr = new StreamReader(sourceStream)) shaderSource.Source = sr.ReadToEnd(); if (databaseStream != null) shaderSource.Hash = databaseStream.ObjectId; else shaderSource.Hash = ObjectId.FromBytes(File.ReadAllBytes(sourceUrl)); } else { throw new Exception(string.Format("Unsupported Stream type to load shader [{0}.xksl]", type)); } } } loadedShaderSources[type] = shaderSource; } else { throw new FileNotFoundException(string.Format("Unable to find shader [{0}]", type), string.Format("{0}.xksl", type)); } } return shaderSource; } }
/// <summary> /// Loads the shader source with the specified type name. /// </summary> /// <param name="type">The typeName.</param> /// <returns>ShaderSourceWithHash.</returns> /// <exception cref="System.IO.FileNotFoundException">If the file was not found</exception> public ShaderSourceWithHash LoadShaderSource(string type) { lock (locker) { // Load file ShaderSourceWithHash shaderSource; if (!loadedShaderSources.TryGetValue(type, out shaderSource)) { var sourceUrl = FindFilePath(type); if (sourceUrl != null) { shaderSource = new ShaderSourceWithHash(); if (!UrlToFilePath.TryGetValue(sourceUrl, out shaderSource.Path)) { shaderSource.Path = sourceUrl; } // On Windows, Always try to load first from the original URL in order to get the latest version if (Platform.IsWindowsDesktop) { // TODO: the "/path" is hardcoded, used in ImportStreamCommand and EffectSystem. Find a place to share this correctly. var pathUrl = sourceUrl + "/path"; if (FileExists(pathUrl)) { using (var fileStream = OpenStream(pathUrl)) { string shaderSourcePath; using (var sr = new StreamReader(fileStream, Encoding.UTF8)) shaderSourcePath = sr.ReadToEnd(); if (File.Exists(shaderSourcePath)) { byte[] fileData = null; for (int tries = 10; tries >= 0; --tries) { try { fileData = File.ReadAllBytes(shaderSourcePath); break; } catch (IOException) { // Try again } } if (fileData != null) { // Replace path with a local path shaderSource.Path = Path.Combine(PlatformFolders.ApplicationBinaryDirectory, shaderSourcePath); shaderSource.Hash = ObjectId.FromBytes(fileData); // Note: we can't use Encoding.UTF8.GetString directly because there might be the UTF8 BOM at the beginning of the file using (StreamReader reader = new StreamReader(new MemoryStream(fileData), Encoding.UTF8)) shaderSource.Source = reader.ReadToEnd(); } } } } } if (shaderSource.Source == null) { using (var sourceStream = OpenStream(sourceUrl)) { var databaseStream = sourceStream as IDatabaseStream; using (var sr = new StreamReader(sourceStream)) { shaderSource.Source = sr.ReadToEnd(); if (databaseStream == null) { sourceStream.Position = 0; var data = new byte[sourceStream.Length]; sourceStream.Read(data, 0, (int)sourceStream.Length); shaderSource.Hash = ObjectId.FromBytes(data); } else { shaderSource.Hash = databaseStream.ObjectId; } } } } loadedShaderSources[type] = shaderSource; } else { throw new FileNotFoundException($"Unable to find shader [{type}]", $"{type}.xksl"); } } return(shaderSource); } }
/// <summary> /// Loads the shader source with the specified type name. /// </summary> /// <param name="type">The typeName.</param> /// <param name="modifiedShaders">The list of modified shaders.</param> /// <returns>ShaderSourceWithHash.</returns> /// <exception cref="System.IO.FileNotFoundException">If the file was not found</exception> public ShaderSourceWithHash LoadShaderSource(string type, HashSet <string> modifiedShaders = null) { lock (locker) { // Load file ShaderSourceWithHash shaderSource; if (!loadedShaderSources.TryGetValue(type, out shaderSource)) { var sourceUrl = FindFilePath(type); if (sourceUrl != null) { shaderSource = new ShaderSourceWithHash(); if (modifiedShaders != null && modifiedShaders.Contains(sourceUrl)) { using (var fileStream = AssetManager.FileProvider.OpenStream(sourceUrl + "/path", VirtualFileMode.Open, VirtualFileAccess.Read, VirtualFileShare.Read)) { string shaderSourcePath; using (var sr = new StreamReader(fileStream, Encoding.UTF8)) shaderSourcePath = sr.ReadToEnd(); try { using (var sourceStream = File.Open(shaderSourcePath, FileMode.Open, FileAccess.Read)) { using (var sr = new StreamReader(sourceStream)) shaderSource.Source = sr.ReadToEnd(); } } catch (FileNotFoundException) { throw new FileNotFoundException(string.Format("Unable to find shader [{0}] on disk", type), string.Format("{0}.pdxsl", type)); } } } else { using (var fileStream = AssetManager.FileProvider.OpenStream(sourceUrl, VirtualFileMode.Open, VirtualFileAccess.Read, VirtualFileShare.Read)) { using (var sr = new StreamReader(fileStream)) shaderSource.Source = sr.ReadToEnd(); var databaseStream = fileStream as IDatabaseStream; if (databaseStream != null) { shaderSource.Hash = databaseStream.ObjectId; } } } // If the file was loaded from the database, use the ObjectId returned by the database, otherwise compute it directly if (shaderSource.Hash == ObjectId.Empty) { shaderSource.Hash = ObjectId.FromBytes(Encoding.UTF8.GetBytes(shaderSource.Source)); } // Convert URL to absolute file path // TODO can we handle path differently? Current code is just a hack UrlToFilePath.TryGetValue(sourceUrl, out shaderSource.Path); // If Path is null, set it to type at least to be able to have more information if (shaderSource.Path == null) { shaderSource.Path = type; } loadedShaderSources[type] = shaderSource; } else { throw new FileNotFoundException(string.Format("Unable to find shader [{0}]", type), string.Format("{0}.pdxsl", type)); } } return(shaderSource); } }
/// <summary> /// Loads the shader source with the specified type name. /// </summary> /// <param name="type">The typeName.</param> /// <returns>ShaderSourceWithHash.</returns> /// <exception cref="System.IO.FileNotFoundException">If the file was not found</exception> public ShaderSourceWithHash LoadShaderSource(string type) { lock (locker) { // Load file ShaderSourceWithHash shaderSource; if (!loadedShaderSources.TryGetValue(type, out shaderSource)) { var sourceUrl = FindFilePath(type); if (sourceUrl != null) { shaderSource = new ShaderSourceWithHash(); if (!UrlToFilePath.TryGetValue(sourceUrl, out shaderSource.Path)) { shaderSource.Path = sourceUrl; } // On Windows, Always try to load first from the original URL in order to get the latest version #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP if (Platform.IsWindowsDesktop) { // TODO: the "/path" is hardcoded, used in ImportStreamCommand and EffectSystem. Find a place to share this correctly. var pathUrl = sourceUrl + "/path"; if (FileExists(pathUrl)) { using (var fileStream = OpenStream(pathUrl)) { string shaderSourcePath; using (var sr = new StreamReader(fileStream, Encoding.UTF8)) shaderSourcePath = sr.ReadToEnd(); if (File.Exists(shaderSourcePath)) { // Replace path with a local path shaderSource.Path = Path.Combine(Directory.GetCurrentDirectory(), shaderSourcePath); // Optimization: It currently reads the source file twice shaderSource.Hash = ObjectId.FromBytes(File.ReadAllBytes(shaderSourcePath)); using (var sourceStream = File.Open(shaderSourcePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (var sr = new StreamReader(sourceStream)) shaderSource.Source = sr.ReadToEnd(); } } } } } #endif if (shaderSource.Source == null) { using (var sourceStream = OpenStream(sourceUrl)) { var databaseStream = sourceStream as IDatabaseStream; using (var sr = new StreamReader(sourceStream)) { shaderSource.Source = sr.ReadToEnd(); if (databaseStream == null) { sourceStream.Position = 0; var data = new byte[sourceStream.Length]; sourceStream.Read(data, 0, (int)sourceStream.Length); shaderSource.Hash = ObjectId.FromBytes(data); } else { shaderSource.Hash = databaseStream.ObjectId; } } } } loadedShaderSources[type] = shaderSource; } else { throw new FileNotFoundException($"Unable to find shader [{type}]", $"{type}.xksl"); } } return(shaderSource); } }