private void UpdateRenderScale() { if (!scaleRenderViewport) { renderViewportScaleSetting.currentValue = defaultRenderViewportScaleLevel; renderScaleSetting.currentValue = defaultRenderViewportScaleLevel; SetRenderScale(1.0f, 1.0f); return; } // Rendering in low resolution means adaptive quality needs to scale back the render scale target to free up gpu cycles bool renderInLowResolution = VRTK_SDK_Bridge.ShouldAppRenderWithLowResources(); // Thresholds float allowedSingleFrameDurationInMilliseconds = renderInLowResolution ? singleFrameDurationInMilliseconds * 0.75f : singleFrameDurationInMilliseconds; float lowThresholdInMilliseconds = 0.7f * allowedSingleFrameDurationInMilliseconds; float extrapolationThresholdInMilliseconds = 0.85f * allowedSingleFrameDurationInMilliseconds; float highThresholdInMilliseconds = 0.9f * allowedSingleFrameDurationInMilliseconds; int newRenderViewportScaleLevel = renderViewportScaleSetting.currentValue; // Rapidly reduce render viewport scale level if cost of last 1 or 3 frames, or the predicted next frame's cost are expensive if (timing.WasFrameTimingBad( 1, highThresholdInMilliseconds, renderViewportScaleSetting.lastChangeFrameCount, renderViewportScaleSetting.decreaseFrameCost) || timing.WasFrameTimingBad( 3, highThresholdInMilliseconds, renderViewportScaleSetting.lastChangeFrameCount, renderViewportScaleSetting.decreaseFrameCost) || timing.WillFrameTimingBeBad( extrapolationThresholdInMilliseconds, highThresholdInMilliseconds, renderViewportScaleSetting.lastChangeFrameCount, renderViewportScaleSetting.decreaseFrameCost)) { // Always drop 2 levels except when dropping from level 2 (level 0 is for reprojection) newRenderViewportScaleLevel = ClampRenderScaleLevel(renderViewportScaleSetting.currentValue == 2 ? 1 : renderViewportScaleSetting.currentValue - 2); } // Rapidly increase render viewport scale level if last 12 frames are cheap else if (timing.WasFrameTimingGood( 12, lowThresholdInMilliseconds, renderViewportScaleSetting.lastChangeFrameCount - renderViewportScaleSetting.increaseFrameCost, renderViewportScaleSetting.increaseFrameCost)) { newRenderViewportScaleLevel = ClampRenderScaleLevel(renderViewportScaleSetting.currentValue + 2); } // Slowly increase render viewport scale level if last 6 frames are cheap else if (timing.WasFrameTimingGood( 6, lowThresholdInMilliseconds, renderViewportScaleSetting.lastChangeFrameCount, renderViewportScaleSetting.increaseFrameCost)) { // Only increase by 1 level to prevent frame drops caused by adjusting newRenderViewportScaleLevel = ClampRenderScaleLevel(renderViewportScaleSetting.currentValue + 1); } // Apply and remember when render viewport scale level changed if (newRenderViewportScaleLevel != renderViewportScaleSetting.currentValue) { if (renderViewportScaleSetting.currentValue >= renderScaleSetting.currentValue && newRenderViewportScaleLevel < renderScaleSetting.currentValue) { lastRenderViewportScaleLevelBelowRenderScaleLevelFrameCount = Time.frameCount; } renderViewportScaleSetting.currentValue = newRenderViewportScaleLevel; } // Ignore frame timings if overriding if (overrideRenderViewportScale) { renderViewportScaleSetting.currentValue = overrideRenderViewportScaleLevel; } // Force on interleaved reprojection for level 0 which is just a replica of level 1 with reprojection enabled float additionalViewportScale = 1.0f; if (!hmdDisplayIsOnDesktop) { if (renderViewportScaleSetting.currentValue == 0) { if (interleavedReprojectionEnabled && timing.GetFrameTiming(0) < singleFrameDurationInMilliseconds * 0.85f) { interleavedReprojectionEnabled = false; } else if (timing.GetFrameTiming(0) > singleFrameDurationInMilliseconds * 0.925f) { interleavedReprojectionEnabled = true; } } else { interleavedReprojectionEnabled = false; } VRTK_SDK_Bridge.ForceInterleavedReprojectionOn(interleavedReprojectionEnabled); } // Not running in direct mode! Interleaved reprojection not supported, so scale down the viewport some more else if (renderViewportScaleSetting.currentValue == 0) { additionalViewportScale = 0.8f; } int newRenderScaleLevel = renderScaleSetting.currentValue; int levelInBetween = (renderViewportScaleSetting.currentValue - renderScaleSetting.currentValue) / 2; // Increase render scale level to the level in between if (renderScaleSetting.currentValue < renderViewportScaleSetting.currentValue && Time.frameCount >= renderScaleSetting.lastChangeFrameCount + renderScaleSetting.increaseFrameCost) { newRenderScaleLevel = ClampRenderScaleLevel(renderScaleSetting.currentValue + Mathf.Max(1, levelInBetween)); } // Decrease render scale level else if (renderScaleSetting.currentValue > renderViewportScaleSetting.currentValue && Time.frameCount >= renderScaleSetting.lastChangeFrameCount + renderScaleSetting.decreaseFrameCost && Time.frameCount >= lastRenderViewportScaleLevelBelowRenderScaleLevelFrameCount + renderViewportScaleSetting.increaseFrameCost) { // Slowly decrease render scale level to level in between if last 6 frames are cheap, otherwise rapidly newRenderScaleLevel = timing.WasFrameTimingGood(6, lowThresholdInMilliseconds, 0, 0) ? ClampRenderScaleLevel(renderScaleSetting.currentValue + Mathf.Min(-1, levelInBetween)) : renderViewportScaleSetting.currentValue; } // Apply and remember when render scale level changed renderScaleSetting.currentValue = newRenderScaleLevel; if (!scaleRenderTargetResolution) { renderScaleSetting.currentValue = allRenderScales.Count - 1; } float newRenderScale = allRenderScales[renderScaleSetting.currentValue]; float newRenderViewportScale = allRenderScales[Mathf.Min(renderViewportScaleSetting.currentValue, renderScaleSetting.currentValue)] / newRenderScale * additionalViewportScale; SetRenderScale(newRenderScale, newRenderViewportScale); }
private void UpdateRenderScale() { if (!active) { SetRenderScale(1.0f, 1.0f); return; } // Add latest timing to ring buffer frameTimeRingBufferIndex = (frameTimeRingBufferIndex + 1) % frameTimeRingBuffer.Length; frameTimeRingBuffer[frameTimeRingBufferIndex] = UnityEngine.XR.XRStats.gpuTimeLastFrame; // Rendering in low resolution means adaptive quality needs to scale back the render scale target to free up gpu cycles bool renderInLowResolution = VRTK_SDK_Bridge.ShouldAppRenderWithLowResources(); // Thresholds float thresholdModifier = renderInLowResolution ? singleFrameDurationInMilliseconds * 0.75f : singleFrameDurationInMilliseconds; float lowThresholdInMilliseconds = 0.7f * thresholdModifier; float extrapolationThresholdInMilliseconds = 0.85f * thresholdModifier; float highThresholdInMilliseconds = 0.9f * thresholdModifier; // Get latest 3 frames float frameMinus0 = frameTimeRingBuffer[(frameTimeRingBufferIndex - 0 + frameTimeRingBuffer.Length) % frameTimeRingBuffer.Length]; float frameMinus1 = frameTimeRingBuffer[(frameTimeRingBufferIndex - 1 + frameTimeRingBuffer.Length) % frameTimeRingBuffer.Length]; float frameMinus2 = frameTimeRingBuffer[(frameTimeRingBufferIndex - 2 + frameTimeRingBuffer.Length) % frameTimeRingBuffer.Length]; int previousLevel = currentRenderScaleLevel; // Always drop 2 levels except when dropping from level 2 int dropTargetLevel = previousLevel == 2 ? 1 : previousLevel - 2; int newLevel = Mathf.Clamp(dropTargetLevel, 0, allRenderScales.Count - 1); // Ignore frame timings if overriding if (overrideRenderScale) { currentRenderScaleLevel = overrideRenderScaleLevel; } // Rapidly reduce quality 2 levels if last frame was critical else if (Time.frameCount >= lastRenderScaleChangeFrameCount + 2 + 1 && frameMinus0 > highThresholdInMilliseconds && newLevel != previousLevel) { currentRenderScaleLevel = newLevel; lastRenderScaleChangeFrameCount = Time.frameCount; } // Rapidly reduce quality 2 levels if last 3 frames are expensive else if (Time.frameCount >= lastRenderScaleChangeFrameCount + 2 + 3 && frameMinus0 > highThresholdInMilliseconds && frameMinus1 > highThresholdInMilliseconds && frameMinus2 > highThresholdInMilliseconds && newLevel != previousLevel) { currentRenderScaleLevel = newLevel; lastRenderScaleChangeFrameCount = Time.frameCount; } // Predict next frame's cost using linear extrapolation: max(frame-1 to frame+1, frame-2 to frame+1) else if (Time.frameCount >= lastRenderScaleChangeFrameCount + 2 + 2 && frameMinus0 > extrapolationThresholdInMilliseconds) { float frameDelta = frameMinus0 - frameMinus1; // Use frame-2 if it's available if (Time.frameCount >= lastRenderScaleChangeFrameCount + 2 + 3) { float frameDelta2 = (frameMinus0 - frameMinus2) * 0.5f; frameDelta = Mathf.Max(frameDelta, frameDelta2); } if (frameMinus0 + frameDelta > highThresholdInMilliseconds && newLevel != previousLevel) { currentRenderScaleLevel = newLevel; lastRenderScaleChangeFrameCount = Time.frameCount; } } else { // Increase quality 1 level if last 3 frames are cheap newLevel = Mathf.Clamp(previousLevel + 1, 0, allRenderScales.Count - 1); if (Time.frameCount >= lastRenderScaleChangeFrameCount + 2 + 3 && frameMinus0 < lowThresholdInMilliseconds && frameMinus1 < lowThresholdInMilliseconds && frameMinus2 < lowThresholdInMilliseconds && newLevel != previousLevel) { currentRenderScaleLevel = newLevel; lastRenderScaleChangeFrameCount = Time.frameCount; } } // Force on interleaved reprojection for level 0 which is just a replica of level 1 with reprojection enabled float additionalViewportScale = 1.0f; if (!hmdDisplayIsOnDesktop) { if (currentRenderScaleLevel == 0) { if (interleavedReprojectionEnabled && frameMinus0 < singleFrameDurationInMilliseconds * 0.85f) { interleavedReprojectionEnabled = false; } else if (frameMinus0 > singleFrameDurationInMilliseconds * 0.925f) { interleavedReprojectionEnabled = true; } } else { interleavedReprojectionEnabled = false; } VRTK_SDK_Bridge.ForceInterleavedReprojectionOn(interleavedReprojectionEnabled); } // Not running in direct mode! Interleaved reprojection not supported, so scale down the viewport else if (currentRenderScaleLevel == 0) { additionalViewportScale = 0.8f; } float newRenderScale = allRenderScales[allRenderScales.Count - 1]; float newRenderViewportScale = allRenderScales[currentRenderScaleLevel] / newRenderScale * additionalViewportScale; SetRenderScale(newRenderScale, newRenderViewportScale); }
// Token: 0x06001B91 RID: 7057 RVA: 0x00090340 File Offset: 0x0008E540 private void UpdateRenderScale() { if (this.allRenderScales.Count == 0) { return; } if (!this.scaleRenderViewport) { this.renderViewportScaleSetting.currentValue = this.defaultRenderViewportScaleLevel; this.renderScaleSetting.currentValue = this.defaultRenderViewportScaleLevel; VRTK_AdaptiveQuality.SetRenderScale(1f, 1f); return; } float num = VRTK_SDK_Bridge.ShouldAppRenderWithLowResources() ? (this.singleFrameDurationInMilliseconds * 0.75f) : this.singleFrameDurationInMilliseconds; float thresholdInMilliseconds = 0.7f * num; float extrapolationThresholdInMilliseconds = 0.85f * num; float thresholdInMilliseconds2 = 0.9f * num; int num2 = this.renderViewportScaleSetting.currentValue; if (this.timing.WasFrameTimingBad(1, thresholdInMilliseconds2, this.renderViewportScaleSetting.lastChangeFrameCount, this.renderViewportScaleSetting.decreaseFrameCost) || this.timing.WasFrameTimingBad(3, thresholdInMilliseconds2, this.renderViewportScaleSetting.lastChangeFrameCount, this.renderViewportScaleSetting.decreaseFrameCost) || this.timing.WillFrameTimingBeBad(extrapolationThresholdInMilliseconds, thresholdInMilliseconds2, this.renderViewportScaleSetting.lastChangeFrameCount, this.renderViewportScaleSetting.decreaseFrameCost)) { num2 = this.ClampRenderScaleLevel((this.renderViewportScaleSetting.currentValue == 2) ? 1 : (this.renderViewportScaleSetting.currentValue - 2)); } else if (this.timing.WasFrameTimingGood(12, thresholdInMilliseconds, this.renderViewportScaleSetting.lastChangeFrameCount - this.renderViewportScaleSetting.increaseFrameCost, this.renderViewportScaleSetting.increaseFrameCost)) { num2 = this.ClampRenderScaleLevel(this.renderViewportScaleSetting.currentValue + 2); } else if (this.timing.WasFrameTimingGood(6, thresholdInMilliseconds, this.renderViewportScaleSetting.lastChangeFrameCount, this.renderViewportScaleSetting.increaseFrameCost)) { num2 = this.ClampRenderScaleLevel(this.renderViewportScaleSetting.currentValue + 1); } if (num2 != this.renderViewportScaleSetting.currentValue) { if (this.renderViewportScaleSetting.currentValue >= this.renderScaleSetting.currentValue && num2 < this.renderScaleSetting.currentValue) { this.lastRenderViewportScaleLevelBelowRenderScaleLevelFrameCount = Time.frameCount; } this.renderViewportScaleSetting.currentValue = num2; } if (this.overrideRenderViewportScale) { this.renderViewportScaleSetting.currentValue = this.overrideRenderViewportScaleLevel; } float num3 = 1f; if (!this.hmdDisplayIsOnDesktop) { if (this.renderViewportScaleSetting.currentValue == 0) { if (this.interleavedReprojectionEnabled && this.timing.GetFrameTiming(0) < this.singleFrameDurationInMilliseconds * 0.85f) { this.interleavedReprojectionEnabled = false; } else if (this.timing.GetFrameTiming(0) > this.singleFrameDurationInMilliseconds * 0.925f) { this.interleavedReprojectionEnabled = true; } } else { this.interleavedReprojectionEnabled = false; } VRTK_SDK_Bridge.ForceInterleavedReprojectionOn(this.interleavedReprojectionEnabled); } else if (this.renderViewportScaleSetting.currentValue == 0) { num3 = 0.8f; } int currentValue = this.renderScaleSetting.currentValue; int b = (this.renderViewportScaleSetting.currentValue - this.renderScaleSetting.currentValue) / 2; if (this.renderScaleSetting.currentValue < this.renderViewportScaleSetting.currentValue && Time.frameCount >= this.renderScaleSetting.lastChangeFrameCount + this.renderScaleSetting.increaseFrameCost) { currentValue = this.ClampRenderScaleLevel(this.renderScaleSetting.currentValue + Mathf.Max(1, b)); } else if (this.renderScaleSetting.currentValue > this.renderViewportScaleSetting.currentValue && Time.frameCount >= this.renderScaleSetting.lastChangeFrameCount + this.renderScaleSetting.decreaseFrameCost && Time.frameCount >= this.lastRenderViewportScaleLevelBelowRenderScaleLevelFrameCount + this.renderViewportScaleSetting.increaseFrameCost) { currentValue = (this.timing.WasFrameTimingGood(6, thresholdInMilliseconds, 0, 0) ? this.ClampRenderScaleLevel(this.renderScaleSetting.currentValue + Mathf.Min(-1, b)) : this.renderViewportScaleSetting.currentValue); } this.renderScaleSetting.currentValue = currentValue; if (!this.scaleRenderTargetResolution) { this.renderScaleSetting.currentValue = this.allRenderScales.Count - 1; } float num4 = this.allRenderScales[this.renderScaleSetting.currentValue]; float renderViewportScale = this.allRenderScales[Mathf.Min(this.renderViewportScaleSetting.currentValue, this.renderScaleSetting.currentValue)] / num4 * num3; VRTK_AdaptiveQuality.SetRenderScale(num4, renderViewportScale); }