/// <summary> /// Initializes a new instance of the <see cref="AssetCloner" /> struct. /// </summary> /// <param name="value">The value to clone.</param> /// <param name="flags">Cloning flags</param> private AssetCloner(object value, AssetClonerFlags flags) { this.flags = flags; invariantObjects = null; // Clone only if value is not a value type if (value != null && !value.GetType().IsValueType) { invariantObjects = new List<object>(); // TODO: keepOnlySealedOverride is currently ignored // TODO Clone is not supporting SourceCodeAsset (The SourceCodeAsset.Text won't be cloned) var stream = new MemoryStream(); var writer = new BinarySerializationWriter(stream); writer.Context.SerializerSelector = ClonerSelector; var refFlag = (flags & AssetClonerFlags.ReferenceAsNull) != 0 ? ContentSerializerContext.AttachedReferenceSerialization.AsNull : ContentSerializerContext.AttachedReferenceSerialization.AsSerializableVersion; writer.Context.Set(InvariantObjectListProperty, invariantObjects); writer.Context.Set(ContentSerializerContext.SerializeAttachedReferenceProperty, refFlag); writer.SerializeExtended(value, ArchiveMode.Serialize); writer.Flush(); // Retrieve back object references objectReferences = writer.Context.Get(MemberSerializer.ObjectSerializeReferences); streamOrValueType = stream; } else { streamOrValueType = value; objectReferences = null; } }
protected override void ComputeParameterHash(Stream stream) { base.ComputeParameterHash(stream); var writer = new BinarySerializationWriter(stream); writer.Write(commandId); }
protected override void ComputeParameterHash(BinarySerializationWriter writer) { base.ComputeParameterHash(writer); writer.Write(SourcePath); writer.Write(Location); }
protected override void ComputeParameterHash(BinarySerializationWriter writer) { base.ComputeParameterHash(writer); // Regenerate new shaders if magic header changed uint effectbyteCodeMagicNumber = EffectBytecode.MagicHeader; writer.Serialize(ref effectbyteCodeMagicNumber, ArchiveMode.Serialize); }
protected override void ComputeParameterHash(BinarySerializationWriter writer) { base.ComputeParameterHash(writer); uint effectbyteCodeMagicNumber = EffectBytecode.MagicHeader; writer.Serialize(ref effectbyteCodeMagicNumber, ArchiveMode.Serialize); writer.Serialize(ref effectName, ArchiveMode.Serialize); writer.Serialize(ref compilerParameters, ArchiveMode.Serialize); }
protected override void ComputeParameterHash(Stream stream) { base.ComputeParameterHash(stream); var writer = new BinarySerializationWriter(stream); writer.Write(SourcePath); writer.Write(Location); }
private static byte[] EncodeObject(object obj) { var memoryStream = new MemoryStream(); var writer = new BinarySerializationWriter(memoryStream); writer.Context.SerializerSelector = SerializerSelector.AssetWithReuse; writer.Context.Set(ContentSerializerContext.SerializeAttachedReferenceProperty, ContentSerializerContext.AttachedReferenceSerialization.AsSerializableVersion); writer.SerializeExtended(ref obj, ArchiveMode.Serialize); return memoryStream.ToArray(); }
/// <summary> /// Initializes a new instance of the <see cref="AssetCloner" /> struct. /// </summary> /// <param name="value">The value to clone.</param> /// <param name="flags">Cloning flags</param> private AssetCloner(object value, AssetClonerFlags flags) { this.flags = flags; invariantObjects = null; objectReferences = null; // Clone only if value is not a value type if (value != null && !value.GetType().IsValueType) { invariantObjects = new List<object>(); // TODO: keepOnlySealedOverride is currently ignored // TODO Clone is not supporting SourceCodeAsset (The SourceCodeAsset.Text won't be cloned) var stream = new MemoryStream(); var writer = new BinarySerializationWriter(stream); writer.Context.SerializerSelector = ClonerSelector; var refFlag = (flags & AssetClonerFlags.ReferenceAsNull) != 0 ? ContentSerializerContext.AttachedReferenceSerialization.AsNull : ContentSerializerContext.AttachedReferenceSerialization.AsSerializableVersion; writer.Context.Set(InvariantObjectListProperty, invariantObjects); writer.Context.Set(ContentSerializerContext.SerializeAttachedReferenceProperty, refFlag); writer.SerializeExtended(value, ArchiveMode.Serialize); writer.Flush(); // Retrieve back all object references that were discovered while serializing // They will be used layer by OnObjectDeserialized when cloning ShadowObject datas var objectRefs = writer.Context.Get(MemberSerializer.ObjectSerializeReferences); if (objectRefs != null) { // Remap object references to a simple array objectReferences = new object[objectRefs.Count]; foreach (var objRef in objectRefs) { objectReferences[objRef.Value] = objRef.Key; } } streamOrValueType = stream; } else { streamOrValueType = value; } }
public void NotifyEffectUsed(EffectCompileRequest effectCompileRequest) { Task.Run(async () => { // Silently fails if connection already failed previously var socketMessageLayerTask = GetOrCreateConnection(); if (socketMessageLayerTask.IsFaulted) return; // Send any effect request remotely (should fail if not connected) var socketMessageLayer = await socketMessageLayerTask; var memoryStream = new MemoryStream(); var binaryWriter = new BinarySerializationWriter(memoryStream); binaryWriter.Context.SerializerSelector = SerializerSelector.AssetWithReuse; binaryWriter.SerializeExtended(effectCompileRequest, ArchiveMode.Serialize, null); await socketMessageLayer.Send(new RemoteEffectCompilerEffectRequested { Request = memoryStream.ToArray() }); }); }
public static async Task UnpackAPK() { // get the apk last update time var packageManager = PlatformAndroid.Context.PackageManager; var packageInfo = packageManager.GetPackageInfo(PlatformAndroid.Context.PackageName, PackageInfoFlags.Activities); var lastUpdateTime = packageInfo.LastUpdateTime; var sourceDir = PlatformAndroid.Context.ApplicationInfo.SourceDir; // evaluate if asset data should be extracted from apk file var shouldExtractAssets = true; if (ApplicationTemporary.FileExists(LastExtractedApkFileName)) { Int64 extractedLastUpdateTime = 0; using (var file = ApplicationTemporary.OpenStream(LastExtractedApkFileName, VirtualFileMode.Open, VirtualFileAccess.Read)) { var binaryReader = new BinarySerializationReader(file); binaryReader.Serialize(ref extractedLastUpdateTime, ArchiveMode.Deserialize); } shouldExtractAssets = extractedLastUpdateTime != lastUpdateTime; } // Copy assets if (shouldExtractAssets) { var assets = PlatformAndroid.Context.Assets; // Make sure assets exists var logger = GlobalLogger.GetLogger("VFS"); CopyFileOrDirectory(logger, sourceDir, "assets/data/", string.Empty); // update value of extracted last update time using (var stream = ApplicationTemporary.OpenStream(LastExtractedApkFileName, VirtualFileMode.Create, VirtualFileAccess.Write, VirtualFileShare.None)) { var binaryWriter = new BinarySerializationWriter(stream); binaryWriter.Write(lastUpdateTime); } } }
public static void SaveFromMemory(PixelBuffer[] pixelBuffers, int count, ImageDescription description, System.IO.Stream imageStream) { var stream = new BinarySerializationWriter(imageStream); // Write magic code stream.Write(MagicCode); // Write image header imageDescriptionSerializer.Serialize(ref description, ArchiveMode.Serialize, stream); // Write total size int totalSize = 0; foreach (var pixelBuffer in pixelBuffers) totalSize += pixelBuffer.BufferStride; stream.Write(totalSize); // Write buffers contiguously foreach (var pixelBuffer in pixelBuffers) { stream.Serialize(pixelBuffer.DataPointer, pixelBuffer.BufferStride); } }
protected override void ComputeParameterHash(Stream stream) { base.ComputeParameterHash(stream); // Really necesary? (need system for identical blob reuse) var writer = new BinarySerializationWriter(stream); writer.Write(InputUrl); writer.Write(OutputUrl); writer.Write(Width); writer.Write(Height); writer.Write(IsAbsolute); writer.Write(Format); writer.Write(GenerateMipmaps); }
protected override void ComputeParameterHash(BinarySerializationWriter writer) { base.ComputeParameterHash(writer); writer.Write(commandId); }
protected override void ComputeParameterHash(BinarySerializationWriter writer) { writer.Write(Source); writer.Write(OutputUrl); }
private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId, DatabaseFileProvider database, string compiledUrl) { // Open the database for writing var log = new LoggerResult(); // Note: this compiler is expected to not be async and directly write stuff in localLogger var compiledShader = base.Compile(mixinTree, effectParameters, compilerParameters).WaitForResult(); compiledShader.CompilationLog.CopyTo(log); // If there are any errors, return immediately if (log.HasErrors) { lock (compilingShaders) { compilingShaders.Remove(mixinObjectId); } return new EffectBytecodeCompilerResult(null, log); } // Compute the bytecodeId var newBytecodeId = compiledShader.Bytecode.ComputeId(); // Check if we really need to store the bytecode lock (bytecodes) { // Using custom serialization to the database to store an object with a custom id // TODO: Check if we really need to write the bytecode everytime even if id is not changed var memoryStream = new MemoryStream(); compiledShader.Bytecode.WriteTo(memoryStream); // Write current cache at the end (not part of the pure bytecode, but we use this as meta info) var writer = new BinarySerializationWriter(memoryStream); writer.Write(CurrentCache); memoryStream.Position = 0; database.ObjectDatabase.Write(memoryStream, newBytecodeId, true); database.ContentIndexMap[compiledUrl] = newBytecodeId; // Save bytecode Id to the database cache as well memoryStream.SetLength(0); memoryStream.Write((byte[])newBytecodeId, 0, ObjectId.HashSize); memoryStream.Position = 0; database.ObjectDatabase.Write(memoryStream, mixinObjectId, true); if (!bytecodes.ContainsKey(newBytecodeId)) { log.Verbose("New effect compiled #{0} [{1}] (db: {2})\r\n{3}", effectCompileCount, mixinObjectId, newBytecodeId, compilerParameters?.ToStringPermutationsDetailed()); Interlocked.Increment(ref effectCompileCount); // Replace or add new bytecode bytecodes[newBytecodeId] = new KeyValuePair<EffectBytecode, EffectBytecodeCacheLoadSource>(compiledShader.Bytecode, EffectBytecodeCacheLoadSource.JustCompiled); } } lock (compilingShaders) { compilingShaders.Remove(mixinObjectId); } return compiledShader; }
protected override void ComputeParameterHash(BinarySerializationWriter writer) { base.ComputeParameterHash(writer); writer.SerializeExtended(this, ArchiveMode.Serialize); }
/// <inheritdoc/> public CompilationResult Compile(string shaderSource, string entryPoint, string profile, string sourceFileName = "unknown") { string realShaderSource; if (profile == "glsl") { // Compile directly as GLSL realShaderSource = shaderSource; } else { // Convert HLSL to GLSL PipelineStage stage; var profileParts = profile.Split('_'); switch (profileParts[0]) { case "vs": stage = PipelineStage.Vertex; break; case "ps": stage = PipelineStage.Pixel; break; case "gs": case "hs": case "ds": case "cs": throw new NotImplementedException("This shader stage can't be converted to OpenGL."); default: throw new NotSupportedException("Unknown shader profile."); } // Convert from HLSL to GLSL // Note that for now we parse from shader as a string, but we could simply clone effectPass.Shader to avoid multiple parsing. var glslConvertor = new ShaderConverter(isOpenGLES); var glslShader = glslConvertor.Convert(shaderSource, entryPoint, stage); // Add std140 layout foreach (var constantBuffer in glslShader.Declarations.OfType<ConstantBuffer>()) { constantBuffer.Qualifiers |= new LayoutQualifier(new LayoutKeyValue("std140")); } // Output the result var glslShaderWriter = new HlslToGlslWriter(); if (isOpenGLES) { glslShaderWriter.TrimFloatSuffix = true; glslShaderWriter.GenerateUniformBlocks = false; foreach (var variable in glslShader.Declarations.OfType<Variable>()) { if (variable.Qualifiers.Contains(ParameterQualifier.In)) { variable.Qualifiers.Values.Remove(ParameterQualifier.In); // "in" becomes "attribute" in VS, "varying" in other stages variable.Qualifiers.Values.Add( stage == PipelineStage.Vertex ? global::SiliconStudio.Shaders.Ast.Glsl.ParameterQualifier.Attribute : global::SiliconStudio.Shaders.Ast.Glsl.ParameterQualifier.Varying); } if (variable.Qualifiers.Contains(ParameterQualifier.Out)) { variable.Qualifiers.Values.Remove(ParameterQualifier.Out); variable.Qualifiers.Values.Add(global::SiliconStudio.Shaders.Ast.Glsl.ParameterQualifier.Varying); } } } // Write shader glslShaderWriter.Visit(glslShader); // Build shader source var glslShaderCode = new StringBuilder(); // Append some header depending on target if (!isOpenGLES) { glslShaderCode .AppendLine("#version 420") .AppendLine(); if (stage == PipelineStage.Pixel) glslShaderCode .AppendLine("out vec4 gl_FragData[1];") .AppendLine(); } if (isOpenGLES) { if (stage == PipelineStage.Pixel) glslShaderCode .AppendLine("precision mediump float;") .AppendLine(); } glslShaderCode.Append(glslShaderWriter.Text); realShaderSource = glslShaderCode.ToString(); } var shaderBytecodeData = new OpenGLShaderBytecodeData { IsBinary = false, EntryPoint = entryPoint, Profile = profile, Source = realShaderSource, }; // Encode shader source to a byte array (no universal StageBytecode format for OpenGL) var memoryStream = new MemoryStream(); var binarySerializationWriter = new BinarySerializationWriter(memoryStream); shaderBytecodeData.Serialize(binarySerializationWriter, ArchiveMode.Serialize); return new CompilationResult(new ShaderBytecode(memoryStream.ToArray()), false, null); }
/// <summary> /// Writes an object instance to the specified stream. /// </summary> /// <typeparam name="T">Type of the object to write</typeparam> /// <param name="stream">The stream to write the object instance to.</param> /// <param name="value">The value to write.</param> public static void Write <T>([NotNull] Stream stream, T value) { var writer = new BinarySerializationWriter(stream); writer.Write(value); }
protected override void ComputeAssemblyHash(BinarySerializationWriter writer) { writer.Write(DataSerializer.BinaryFormatVersion); writer.Write(EffectBytecode.MagicHeader); }
public void Test() { var prefab = new PrefabAsset(); var modelComponent = new ModelComponent(); var entity = new Entity() { modelComponent }; prefab.Hierarchy.Entities.Add(entity); prefab.Hierarchy.RootEntities.Add(entity.Id); var material1 = new MaterialNull(); IdentifiableHelper.SetId(material1, new Guid("39E2B226-8752-4678-8E93-76FFBFBA337B")); var material2 = new MaterialNull(); IdentifiableHelper.SetId(material2, new Guid("CC4F1B31-FBB7-4360-A3E7-060BDFDA0695")); modelComponent.Materials.Add(material1); modelComponent.Materials.Add(material2); Action<PrefabAsset> checkPrefab = (newPrefab) => { var previousEntityDesign = newPrefab.Hierarchy.Entities.FirstOrDefault(); Assert.NotNull(previousEntityDesign); var previousEntity = previousEntityDesign.Entity; var component = previousEntity.Get<ModelComponent>(); Assert.NotNull(component); Assert.AreEqual(2, component.Materials.Count); var newMaterial1 = component.Materials[0]; Assert.AreEqual(IdentifiableHelper.GetId(material1), IdentifiableHelper.GetId(newMaterial1)); var newMaterial2 = component.Materials[1]; Assert.AreEqual(IdentifiableHelper.GetId(material2), IdentifiableHelper.GetId(newMaterial2)); }; // Test yaml serialization { using (var stream = new MemoryStream()) { AssetSerializer.Save(stream, prefab); stream.Position = 0; var serializedVersion = Encoding.UTF8.GetString(stream.ToArray()); Console.WriteLine(serializedVersion); stream.Position = 0; var newPrefab = (PrefabAsset)AssetSerializer.Load(stream, "myentity"); checkPrefab(newPrefab); } } // Test cloning var newPrefabClone = (PrefabAsset)AssetCloner.Clone(prefab); checkPrefab(newPrefabClone); // Test runtime serialization (runtime serialization is removing MaterialNull and replacing it by a null) { var stream = new MemoryStream(); var writer = new BinarySerializationWriter(stream) { Context = { SerializerSelector = SerializerSelector.AssetWithReuse } }; writer.SerializeExtended(entity, ArchiveMode.Serialize); writer.Flush(); stream.Position = 0; var reader = new BinarySerializationReader(stream) { Context = { SerializerSelector = SerializerSelector.AssetWithReuse } }; Entity newEntity = null; reader.SerializeExtended(ref newEntity, ArchiveMode.Deserialize); Assert.NotNull(newEntity); var component = newEntity.Get<ModelComponent>(); Assert.NotNull(component); Assert.AreEqual(2, component.Materials.Count); Assert.Null(component.Materials[0]); Assert.Null(component.Materials[1]); } }
protected override void ComputeParameterHash(BinarySerializationWriter writer) { // force execution of the command with a new GUID var newGuid = Guid.NewGuid(); writer.Serialize(ref newGuid, ArchiveMode.Serialize); }
public void ComputeCommandHash(Stream stream, IPrepareContext prepareContext) { var writer = new BinarySerializationWriter(stream); writer.Context.SerializerSelector = SerializerSelector.AssetWithReuse; writer.Write(CommandCacheVersion); // Compute assembly hash ComputeAssemblyHash(writer); // Compute parameters hash ComputeParameterHash(writer); // Compute static input files hash (parameter dependent) ComputeInputFilesHash(writer, prepareContext); }
protected virtual void ComputeParameterHash(BinarySerializationWriter writer) { // Do nothing by default }
/// <summary> /// Writes this <see cref="EffectBytecode" /> to a stream with its magic number. /// </summary> /// <param name="stream">The stream.</param> /// <exception cref="System.ArgumentNullException">stream</exception> public void WriteTo(Stream stream) { if (stream == null) throw new ArgumentNullException("stream"); var writer = new BinarySerializationWriter(stream); writer.Write(MagicHeader); writer.Write(this); }
protected void ComputeInputFilesHash(BinarySerializationWriter writer, IPrepareContext prepareContext) { var inputFiles = GetInputFiles(); if (inputFiles == null) return; foreach (var inputFile in inputFiles) { var hash = prepareContext.ComputeInputHash(inputFile.Type, inputFile.Path); if (hash == ObjectId.Empty) { writer.NativeStream.WriteByte(0); } else { writer.NativeStream.Write((byte[])hash, 0, ObjectId.HashSize); } } }
public void TestShaderParametersSerialization() { // Test serialization var shaderParameters = new ShaderMixinParameters("Test"); shaderParameters.Set(PropertyInt, 5); var subShaderParameters = new ShaderMixinParameters("Sub"); subShaderParameters.Set(PropertyInt, 6); shaderParameters.Set(PropertySub, subShaderParameters); var subShaderParametersArray = new ShaderMixinParameters[1]; var subShaderParametersArray1 = new ShaderMixinParameters("InArray1"); subShaderParametersArray[0] = subShaderParametersArray1; subShaderParametersArray1.Set(PropertyInt, 7); shaderParameters.Set(PropertySubs, subShaderParametersArray); var memoryStream = new MemoryStream(); var writer = new BinarySerializationWriter(memoryStream); writer.Write(shaderParameters); writer.Flush(); memoryStream.Position = 0; var reader = new BinarySerializationReader(memoryStream); var shaderParametersReloaded = reader.Read<ShaderMixinParameters>(); // They should be strictly equal Assert.That(shaderParametersReloaded.IsSubsetOf(shaderParameters), Is.True); Assert.That(shaderParameters.IsSubsetOf(shaderParametersReloaded), Is.True); // Test subset // Check that by removing one key from the original parameters, the reloaded version is // no longer a subset subShaderParametersArray1.Remove(PropertyInt); Assert.That(shaderParametersReloaded.IsSubsetOf(shaderParameters), Is.False); }
protected virtual void ComputeAssemblyHash(BinarySerializationWriter writer) { // Use binary format version (bumping it forces everything to be reevaluated) writer.Write(DataSerializer.BinaryFormatVersion); // Gets the hash of the assembly of the command writer.Write(AssemblyHash.ComputeAssemblyHash(GetType().Assembly)); }
private ObjectId GetHashId() { // This methods use the stream that is already filled-up by the standard binary serialization of the object // Here we add ids and overrides metadata informations to the stream in order to calculate an accurate id var stream = streamOrValueType as MemoryStream; if (stream != null) { // ------------------------------------------------------ // Un-comment the following code to debug the ObjectId of the serialized version without taking into account overrides // ------------------------------------------------------ //var savedPosition = stream.Position; //stream.Position = 0; //var intermediateHashId = ObjectId.FromBytes(stream.ToArray()); //stream.Position = savedPosition; var writer = new BinarySerializationWriter(stream); Dictionary<string, OverrideType> overrides = null; List<string> orderedNames = null; foreach (var objectRef in objectReferences) { //// If the object is actually a reference to another asset, we can skip it as their won't be any overrides //if (AttachedReferenceManager.GetAttachedReference(objectRef) != null) //{ // continue; //} // Else gets the id if there are any (including shadows that are not part of the standard serialization) var shadowObject = ShadowObject.GetOrCreate(objectRef); if (shadowObject.IsIdentifiable) { // Get the shadow id (may be a non-shadow, so we may duplicate it in the stream (e.g Entity) // but it should not be a big deal var id = shadowObject.GetId(objectRef); writer.Write(id); } // Dump all members with overrides informations foreach (var item in shadowObject) { if (item.Key.Item2 == Override.OverrideKey) { // Use the member name to ensure a stable id var memberName = ((IMemberDescriptor)item.Key.Item1).Name; // Only creates the overrides dictionary if needed if (overrides == null) { overrides = new Dictionary<string, OverrideType>(); } overrides.Add(memberName, (OverrideType)item.Value); } } // Write any overrides information to the stream if (overrides != null) { // Collect names and order them by alphabetical order in order to make sure that we will get a stable id // (Dictionary doesn't ensure order) if (orderedNames == null) { orderedNames = new List<string>(); } orderedNames.Clear(); foreach (var entry in overrides) { orderedNames.Add(entry.Key); } orderedNames.Sort(); // Write all overrides for the current object reference foreach (var name in orderedNames) { writer.Write(name); // Write the override as an int writer.Write((int)overrides[name]); } // Clear overrides for next entry overrides.Clear(); } } writer.Flush(); stream.Position = 0; return ObjectId.FromBytes(stream.ToArray()); } return ObjectId.Empty; }