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); } }