From 3ccb91691cf754c2c16e61710a49c2ea74cb9f30 Mon Sep 17 00:00:00 2001 From: wixoa Date: Wed, 27 Dec 2023 14:41:46 -0500 Subject: [PATCH] Avoid allocating shaders when values are default (#1570) * Avoid allocating shaders when values are default * Update some outdated comments --- OpenDream.sln.DotSettings | 1 + OpenDreamClient/Rendering/DreamPlane.cs | 2 +- OpenDreamClient/Rendering/DreamViewOverlay.cs | 24 ++++++++++++------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/OpenDream.sln.DotSettings b/OpenDream.sln.DotSettings index 4c33ccfb25..854dfd7752 100644 --- a/OpenDream.sln.DotSettings +++ b/OpenDream.sln.DotSettings @@ -48,6 +48,7 @@ True True True + True True True True diff --git a/OpenDreamClient/Rendering/DreamPlane.cs b/OpenDreamClient/Rendering/DreamPlane.cs index 4953727a90..fe728efd69 100644 --- a/OpenDreamClient/Rendering/DreamPlane.cs +++ b/OpenDreamClient/Rendering/DreamPlane.cs @@ -55,7 +55,7 @@ public void Draw(DreamViewOverlay overlay, DrawingHandleWorld handle) { if (_temporaryRenderTarget != null) { // Draw again, but with the color applied handle.RenderInRenderTarget(_temporaryRenderTarget, () => { - handle.UseShader(overlay.GetBlendAndColorShader(Master, blendModeOverride: BlendMode.Overlay)); + handle.UseShader(overlay.GetBlendAndColorShader(Master, useOverlayMode: true)); handle.SetTransform(overlay.CreateRenderTargetFlipMatrix(_temporaryRenderTarget.Size, Vector2.Zero)); handle.DrawTextureRect(_mainRenderTarget.Texture, new Box2(Vector2.Zero, _mainRenderTarget.Size)); handle.SetTransform(Matrix3.Identity); diff --git a/OpenDreamClient/Rendering/DreamViewOverlay.cs b/OpenDreamClient/Rendering/DreamViewOverlay.cs index e24977df9a..d26993c042 100644 --- a/OpenDreamClient/Rendering/DreamViewOverlay.cs +++ b/OpenDreamClient/Rendering/DreamViewOverlay.cs @@ -87,8 +87,8 @@ public DreamViewOverlay(TransformSystem transformSystem, EntityLookupSystem look _blockColorInstance = _protoManager.Index("blockcolor").InstanceUnique(); _colorInstance = _protoManager.Index("color").InstanceUnique(); _blendModeInstances = new(6) { - {BlendMode.Default, _protoManager.Index("blend_overlay").InstanceUnique()}, //BLEND_DEFAULT - {BlendMode.Overlay, _protoManager.Index("blend_overlay").InstanceUnique()}, //BLEND_OVERLAY (same as BLEND_DEFAULT) + {BlendMode.Default, _protoManager.Index("blend_overlay").InstanceUnique()}, //BLEND_DEFAULT (Same as BLEND_OVERLAY when there's no parent) + {BlendMode.Overlay, _protoManager.Index("blend_overlay").InstanceUnique()}, //BLEND_OVERLAY {BlendMode.Add, _protoManager.Index("blend_add").InstanceUnique()}, //BLEND_ADD {BlendMode.Subtract, _protoManager.Index("blend_subtract").InstanceUnique()}, //BLEND_SUBTRACT {BlendMode.Multiply, _protoManager.Index("blend_multiply").InstanceUnique()}, //BLEND_MULTIPLY @@ -379,16 +379,23 @@ private void ClearRenderTarget(IRenderTexture target, DrawingHandleWorld handle, handle.RenderInRenderTarget(target, () => {}, clearColor); } - public ShaderInstance GetBlendAndColorShader(RendererMetaData iconMetaData, Color? colorOverride = null, BlendMode? blendModeOverride = null) { - Color rgba = colorOverride ?? iconMetaData.ColorToApply.WithAlpha(iconMetaData.AlphaToApply); + public ShaderInstance? GetBlendAndColorShader(RendererMetaData iconMetaData, bool ignoreColor = false, bool useOverlayMode = false) { + BlendMode blendMode = useOverlayMode ? BlendMode.Overlay : iconMetaData.BlendMode; ColorMatrix colorMatrix; - if (colorOverride != null || iconMetaData.ColorMatrixToApply.Equals(ColorMatrix.Identity)) - colorMatrix = new ColorMatrix(rgba); + if (ignoreColor) + colorMatrix = ColorMatrix.Identity; + else if (iconMetaData.ColorMatrixToApply.Equals(ColorMatrix.Identity)) + colorMatrix = new ColorMatrix(iconMetaData.ColorToApply.WithAlpha(iconMetaData.AlphaToApply)); else colorMatrix = iconMetaData.ColorMatrixToApply; - if (!_blendModeInstances.TryGetValue(blendModeOverride ?? iconMetaData.BlendMode, out var blendAndColor)) + // We can use no shader if everything is default + if (!iconMetaData.IsPlaneMaster && blendMode is BlendMode.Default or BlendMode.Overlay && + colorMatrix.Equals(ColorMatrix.Identity)) + return null; + + if (!_blendModeInstances.TryGetValue(blendMode, out var blendAndColor)) blendAndColor = _blendModeInstances[BlendMode.Default]; blendAndColor = blendAndColor.Duplicate(); @@ -548,8 +555,7 @@ public ShaderInstance GetBlendAndColorShader(RendererMetaData iconMetaData, Colo //then we return the Action that draws the actual icon with filters applied iconDrawAction = renderTargetSize => { //note we apply the color *before* the filters, so we use override here - handle.UseShader(GetBlendAndColorShader(iconMetaData, colorOverride: Color.White)); - + handle.UseShader(GetBlendAndColorShader(iconMetaData, ignoreColor: true)); handle.SetTransform(CreateRenderTargetFlipMatrix(renderTargetSize, pixelPosition - frame.Size / 2)); handle.DrawTextureRect(pong.Texture, new Box2(Vector2.Zero, pong.Size)); handle.UseShader(null);