/// <summary>
        /// Initializes a new instance of the <see cref="StreamingManager"/> class.
        /// </summary>
        /// <param name="services">The servicies registry.</param>
        /// <remarks>
        /// The GameSystem expects the following services to be registered: <see cref="T:Stride.Games.IGame" /> and <see cref="T:Stride.Core.Serialization.Contents.IContentManager" />.
        /// </remarks>
        public StreamingManager([NotNull] IServiceRegistry services)
            : base(services)
        {
            services.AddService(this);
            services.AddService <IStreamingManager>(this);
            services.AddService <ITexturesStreamingProvider>(this);

            ContentStreaming = new ContentStreamingService();

            Enabled         = true;
            EnabledChanged += OnEnabledChanged;
        }
Example #2
0
        private static void DeserializeTexture(ContentManager contentManager, Texture texture, ref ImageDescription imageDescription, ref ContentStorageHeader storageHeader)
        {
            using (var content = new ContentStreamingService())
            {
                // Get content storage container
                var storage = content.GetStorage(ref storageHeader);
                if (storage is null)
                {
                    throw new ContentStreamingException("Missing content storage.");
                }
                storage.LockChunks();

                // Cache data
                var  fileProvider      = contentManager.FileProvider;
                var  format            = imageDescription.Format;
                bool isBlockCompressed =
                    (format >= PixelFormat.BC1_Typeless && format <= PixelFormat.BC5_SNorm) ||
                    (format >= PixelFormat.BC6H_Typeless && format <= PixelFormat.BC7_UNorm_SRgb);
                var dataBoxes    = new DataBox[imageDescription.MipLevels * imageDescription.ArraySize];
                int dataBoxIndex = 0;

                // Get data boxes data
                for (int arrayIndex = 0; arrayIndex < imageDescription.ArraySize; arrayIndex++)
                {
                    for (int mipIndex = 0; mipIndex < imageDescription.MipLevels; mipIndex++)
                    {
                        int mipWidth  = imageDescription.Width >> mipIndex;
                        int mipHeight = imageDescription.Height >> mipIndex;
                        if (isBlockCompressed && ((mipWidth % 4) != 0 || (mipHeight % 4) != 0))
                        {
                            mipWidth  = unchecked ((int)(((uint)(mipWidth + 3)) & ~3U));
                            mipHeight = unchecked ((int)(((uint)(mipHeight + 3)) & ~3U));
                        }

                        int rowPitch, slicePitch;
                        int widthPacked;
                        int heightPacked;
                        Image.ComputePitch(format, mipWidth, mipHeight, out rowPitch, out slicePitch, out widthPacked, out heightPacked);

                        var chunk = storage.GetChunk(mipIndex);
                        if (chunk == null || chunk.Size != slicePitch * imageDescription.ArraySize)
                        {
                            throw new ContentStreamingException("Data chunk is missing or has invalid size.", storage);
                        }
                        var data = chunk.GetData(fileProvider);
                        if (!chunk.IsLoaded)
                        {
                            throw new ContentStreamingException("Data chunk is not loaded.", storage);
                        }

                        dataBoxes[dataBoxIndex].DataPointer = data + slicePitch * arrayIndex;
                        dataBoxes[dataBoxIndex].RowPitch    = rowPitch;
                        dataBoxes[dataBoxIndex].SlicePitch  = slicePitch;
                        dataBoxIndex++;
                    }
                }

                // Initialize texture
                texture.InitializeFrom(imageDescription, new TextureViewDescription(), dataBoxes);

                storage.UnlockChunks();
            }
        }
Example #3
0
        private static void DeserializeImage(ContentManager contentManager, Image obj, ref ImageDescription imageDescription, ref ContentStorageHeader storageHeader)
        {
            using (var content = new ContentStreamingService())
            {
                // Get content storage container
                var storage = content.GetStorage(ref storageHeader);
                if (storage == null)
                {
                    throw new ContentStreamingException("Missing content storage.");
                }
                storage.LockChunks();

                // Cache data
                var  fileProvider      = contentManager.FileProvider;
                var  format            = imageDescription.Format;
                bool isBlockCompressed =
                    (format >= PixelFormat.BC1_Typeless && format <= PixelFormat.BC5_SNorm) ||
                    (format >= PixelFormat.BC6H_Typeless && format <= PixelFormat.BC7_UNorm_SRgb);

                // Calculate total size
                int size = 0;
                for (int mipIndex = 0; mipIndex < imageDescription.MipLevels; mipIndex++)
                {
                    int mipWidth  = Math.Max(1, imageDescription.Width >> mipIndex);
                    int mipHeight = Math.Max(1, imageDescription.Height >> mipIndex);
                    if (isBlockCompressed && ((mipWidth % 4) != 0 || (mipHeight % 4) != 0))
                    {
                        mipWidth  = unchecked ((int)(((uint)(mipWidth + 3)) & ~(uint)3));
                        mipHeight = unchecked ((int)(((uint)(mipHeight + 3)) & ~(uint)3));
                    }

                    int rowPitch, slicePitch;
                    int widthPacked;
                    int heightPacked;
                    Image.ComputePitch(format, mipWidth, mipHeight, out rowPitch, out slicePitch, out widthPacked, out heightPacked);

                    size += slicePitch;
                }
                size *= imageDescription.ArraySize;

                // Preload chunks
                for (int mipIndex = 0; mipIndex < imageDescription.MipLevels; mipIndex++)
                {
                    storage.GetChunk(mipIndex)?.GetData(fileProvider);
                }

                // Allocate buffer for image data
                var buffer = Utilities.AllocateMemory(size);

                try
                {
                    // Load image data to the buffer
                    var bufferPtr = buffer;
                    for (int arrayIndex = 0; arrayIndex < imageDescription.ArraySize; arrayIndex++)
                    {
                        for (int mipIndex = 0; mipIndex < imageDescription.MipLevels; mipIndex++)
                        {
                            int mipWidth  = Math.Max(1, imageDescription.Width >> mipIndex);
                            int mipHeight = Math.Max(1, imageDescription.Height >> mipIndex);
                            if (isBlockCompressed && ((mipWidth % 4) != 0 || (mipHeight % 4) != 0))
                            {
                                mipWidth  = unchecked ((int)(((uint)(mipWidth + 3)) & ~(uint)3));
                                mipHeight = unchecked ((int)(((uint)(mipHeight + 3)) & ~(uint)3));
                            }

                            int rowPitch, slicePitch;
                            int widthPacked;
                            int heightPacked;
                            Image.ComputePitch(format, mipWidth, mipHeight, out rowPitch, out slicePitch, out widthPacked, out heightPacked);
                            var chunk = storage.GetChunk(mipIndex);
                            if (chunk == null || chunk.Size != slicePitch * imageDescription.ArraySize)
                            {
                                throw new ContentStreamingException("Data chunk is missing or has invalid size.", storage);
                            }
                            var data = chunk.GetData(fileProvider);
                            if (!chunk.IsLoaded)
                            {
                                throw new ContentStreamingException("Data chunk is not loaded.", storage);
                            }

                            Utilities.CopyMemory(bufferPtr, data, chunk.Size);
                            bufferPtr += chunk.Size;
                        }
                    }

                    // Initialize image
                    var image = new Image(imageDescription, buffer, 0, null, true);
                    obj.InitializeFrom(image);
                }
                catch
                {
                    // Free memory in case of error
                    Utilities.FreeMemory(buffer);

                    throw;
                }

                storage.UnlockChunks();
            }
        }