Repository: microsoft/terminal (language: cpp)

Issue:
Don't constantly repaint if a pixel shader doesn't reference `time`

![image](https://user-images.githubusercontent.com/18356694/187975473-e71e870a-9390-4353-834c-343e8b03ed24.png)
![image](https://user-images.githubusercontent.com/18356694/187975497-30509c32-0aca-4aa9-92dc-3df49e7a9d7e.png)


> technically it could be `time` ,`Time`, `tiempo` or anything, right? in the shader, its just the 0th float in `PixelShaderSettings` yea?

> right we'd use it by index instead of name




Discussion / hints:
I figured I'd take a crack at this for Atlas today

Fix patch:
diff --git a/src/renderer/atlas/AtlasEngine.cpp b/src/renderer/atlas/AtlasEngine.cpp
index 948cd6b5a33..e33ac4fae22 100644
--- a/src/renderer/atlas/AtlasEngine.cpp
+++ b/src/renderer/atlas/AtlasEngine.cpp
@@ -696,9 +696,30 @@ void AtlasEngine::_createResources()
                 /* ppCode      */ blob.addressof(),
                 /* ppErrorMsgs */ error.addressof());
 
+            // Unless we can determine otherwise, assume this shader requires evaluation every frame
+            _r.requiresContinuousRedraw = true;
+
             if (SUCCEEDED(hr))
             {
                 THROW_IF_FAILED(_r.device->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, _r.customPixelShader.put()));
+
+                // Try to determine whether the shader uses the Time variable
+                wil::com_ptr<ID3D11ShaderReflection> reflector;
+                if (SUCCEEDED_LOG(D3DReflect(blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(reflector.put()))))
+                {
+                    if (ID3D11ShaderReflectionConstantBuffer* constantBufferReflector = reflector->GetConstantBufferByIndex(0)) // shader buffer
+                    {
+                        if (ID3D11ShaderReflectionVariable* variableReflector = constantBufferReflector->GetVariableByIndex(0)) // time
+                        {
+                            D3D11_SHADER_VARIABLE_DESC variableDescriptor;
+                            if (SUCCEEDED_LOG(variableReflector->GetDesc(&variableDescriptor)))
+                            {
+                                // only if time is used
+                                _r.requiresContinuousRedraw = WI_IsFlagSet(variableDescriptor.uFlags, D3D_SVF_USED);
+                            }
+                        }
+                    }
+                }
             }
             else
             {
@@ -710,18 +731,17 @@ void AtlasEngine::_createResources()
                 {
                     LOG_HR(hr);
                 }
-
                 if (_api.warningCallback)
                 {
                     _api.warningCallback(D2DERR_SHADER_COMPILE_FAILED);
                 }
             }
-
-            _r.requiresContinuousRedraw = true;
         }
         else if (_api.useRetroTerminalEffect)
         {
             THROW_IF_FAILED(_r.device->CreatePixelShader(&custom_shader_ps[0], sizeof(custom_shader_ps), nullptr, _r.customPixelShader.put()));
+            // We know the built-in retro shader doesn't require continuous redraw.
+            _r.requiresContinuousRedraw = false;
         }
 
         if (_r.customPixelShader)


Test patch: