Exemple #1
0
        private void Update(StreamableResource resource, ref DateTime now)
        {
            Debug.Assert(resource != null && resource.CanBeUpdated, $"resource[{resource}] != null && resource.CanBeUpdated[{resource?.CanBeUpdated}]");

            var options       = resource.StreamingOptions ?? StreamingOptions.Default;
            var isUnderBudget = AllocatedMemory < TargetedMemoryBudget;

            // Calculate target quality for that asset
            StreamingQuality targetQuality = StreamingQuality.Mininum;

            if (isUnderBudget || resource.LastTimeUsed > 0 || options.KeepLoaded)
            {
                var lastUsageTimespan = new TimeSpan((frameIndex - resource.LastTimeUsed) * ManagerUpdatesInterval.Ticks);
                if (isUnderBudget || lastUsageTimespan <= ResourceLiveTimeout || options.KeepLoaded)
                {
                    targetQuality = StreamingQuality.Maximum;
#if USE_TEST_MANUAL_QUALITY
                    targetQuality = (testQuality / 100.0f); // apply quality scale for testing
#endif
                    // TODO: here we should apply resources group master scale (based on game settings quality level and memory level)
                }
            }
            targetQuality.Normalize();

            // Calculate target residency level (discrete value)
            var currentResidency   = resource.CurrentResidency;
            var allocatedResidency = resource.AllocatedResidency;
            var targetResidency    = resource.CalculateTargetResidency(targetQuality);
            Debug.Assert(allocatedResidency >= currentResidency && allocatedResidency >= 0, $"allocatedResidency[{allocatedResidency}] >= currentResidency[{currentResidency }] && allocatedResidency[{allocatedResidency }] >= 0");

            // Update target residency smoothing
            // TODO: use move quality samples and use max or avg value - make that input it smooth - or use PID
            //resource.QualitySamples.Add(targetResidency);
            //targetResidency = resource.QualitySamples.Maximum();

            // Assign last update time
            resource.LastUpdate = now;

            // Check if a target residency level has been changed
            if (targetResidency != resource.TargetResidency)
            {
                // Register change
                resource.TargetResidency       = targetResidency;
                resource.TargetResidencyChange = now;
            }

            // Check if need to change resource current residency
            if (targetResidency != currentResidency)
            {
                // Calculate residency level to stream in (resources may want to incease/decrease it's quality in steps rather than at once)
                var requestedResidency = resource.CalculateRequestedResidency(targetResidency);
                if (options.ForceHighestQuality)
                {
                    requestedResidency = targetResidency;
                }

                // Create streaming task (resource type specific)
                StreamAsync(resource, requestedResidency);
            }
        }