From c3f96385adb80eb5eee9a3a772a1f64659a016fd Mon Sep 17 00:00:00 2001
From: "David C. Lonie" <david.lonie@kitware.com>
Date: Tue, 20 Sep 2016 11:20:57 -0400
Subject: [PATCH] Add a vtkFXAAOptions class for storing FXAA config.

This will simplify the API for vtkRenderer, vtkSynchronizedRenderer, etc.
---
 Rendering/Core/CMakeLists.txt                 |   1 +
 Rendering/Core/vtkFXAAOptions.cxx             |  86 +++++++++
 Rendering/Core/vtkFXAAOptions.h               | 172 ++++++++++++++++++
 Rendering/Core/vtkRenderer.cxx                |  16 +-
 Rendering/Core/vtkRenderer.h                  |  32 +---
 .../OpenGL2/Testing/Cxx/TestFXAAFilter.cxx    |   1 +
 Rendering/OpenGL2/vtkOpenGLFXAAFilter.cxx     |  65 ++++++-
 Rendering/OpenGL2/vtkOpenGLFXAAFilter.h       | 120 ++----------
 Rendering/OpenGL2/vtkOpenGLRenderer.cxx       |  19 +-
 9 files changed, 354 insertions(+), 158 deletions(-)
 create mode 100644 Rendering/Core/vtkFXAAOptions.cxx
 create mode 100644 Rendering/Core/vtkFXAAOptions.h

diff --git a/Rendering/Core/CMakeLists.txt b/Rendering/Core/CMakeLists.txt
index 94d47140f6e..12adb2550a8 100644
--- a/Rendering/Core/CMakeLists.txt
+++ b/Rendering/Core/CMakeLists.txt
@@ -25,6 +25,7 @@ set(Module_SRCS
   vtkFollower.cxx
   vtkFrameBufferObjectBase.cxx
   vtkFrustumCoverageCuller.cxx
+  vtkFXAAOptions.cxx
   vtkGenericRenderWindowInteractor.cxx
   vtkGenericVertexAttributeMapping.cxx
   vtkGlyph3DMapper.cxx
diff --git a/Rendering/Core/vtkFXAAOptions.cxx b/Rendering/Core/vtkFXAAOptions.cxx
new file mode 100644
index 00000000000..cbc42752626
--- /dev/null
+++ b/Rendering/Core/vtkFXAAOptions.cxx
@@ -0,0 +1,86 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkFXAAOptions.cxx
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkFXAAOptions.h"
+
+#include "vtkObjectFactory.h"
+
+vtkStandardNewMacro(vtkFXAAOptions)
+
+//------------------------------------------------------------------------------
+void vtkFXAAOptions::PrintSelf(std::ostream &os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+
+  os << indent << "RelativeContrastThreshold: "
+     << this->RelativeContrastThreshold << "\n";
+  os << indent << "HardContrastThreshold: "
+     << this->HardContrastThreshold << "\n";
+  os << indent << "SubpixelBlendLimit: " <<
+        this->SubpixelBlendLimit << "\n";
+  os << indent << "SubpixelContrastThreshold: "
+     << this->SubpixelContrastThreshold << "\n";
+  os << indent << "EndpointSearchIterations: "
+     << this->EndpointSearchIterations << "\n";
+  os << indent << "UseHighQualityEndpoints: "
+     << this->UseHighQualityEndpoints << "\n";
+
+  os << indent << "DebugOptionValue: ";
+  switch (this->DebugOptionValue)
+    {
+    default:
+    case vtkFXAAOptions::FXAA_NO_DEBUG:
+      os << "FXAA_NO_DEBUG\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_SUBPIXEL_ALIASING:
+      os << "FXAA_DEBUG_SUBPIXEL_ALIASING\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_EDGE_DIRECTION:
+      os << "FXAA_DEBUG_EDGE_DIRECTION\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_EDGE_NUM_STEPS:
+      os << "FXAA_DEBUG_EDGE_NUM_STEPS\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_EDGE_DISTANCE:
+      os << "FXAA_DEBUG_EDGE_DISTANCE\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_EDGE_SAMPLE_OFFSET:
+      os << "FXAA_DEBUG_EDGE_SAMPLE_OFFSET\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_ONLY_SUBPIX_AA:
+      os << "FXAA_DEBUG_ONLY_SUBPIX_AA\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_ONLY_EDGE_AA:
+      os << "FXAA_DEBUG_ONLY_EDGE_AA\n";
+      break;
+    }
+}
+
+//------------------------------------------------------------------------------
+vtkFXAAOptions::vtkFXAAOptions()
+  : RelativeContrastThreshold(1.f/8.f),
+    HardContrastThreshold(1.f/16.f),
+    SubpixelBlendLimit(3.f/4.f),
+    SubpixelContrastThreshold(1.f/4.f),
+    EndpointSearchIterations(12),
+    UseHighQualityEndpoints(true),
+    DebugOptionValue(vtkFXAAOptions::FXAA_NO_DEBUG)
+{
+}
+
+//------------------------------------------------------------------------------
+vtkFXAAOptions::~vtkFXAAOptions()
+{
+}
diff --git a/Rendering/Core/vtkFXAAOptions.h b/Rendering/Core/vtkFXAAOptions.h
new file mode 100644
index 00000000000..65137485a06
--- /dev/null
+++ b/Rendering/Core/vtkFXAAOptions.h
@@ -0,0 +1,172 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkFXAAOptions.h
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// .NAME vtkFXAAOptions - Configuration for FXAA implementations.
+//
+// .SECTION Description
+// This class encapsulates the settings for vtkOpenGLFXAAFilter.
+
+#ifndef vtkFXAAOptions_h
+#define vtkFXAAOptions_h
+
+#include "vtkRenderingCoreModule.h" // For export macro
+#include "vtkObject.h"
+
+class VTKRENDERINGCORE_EXPORT vtkFXAAOptions: public vtkObject
+{
+public:
+  // Description:
+  // Debugging options that affect the output color buffer. See
+  // vtkFXAAFilterFS.glsl for details.
+  enum DebugOption
+  {
+    FXAA_NO_DEBUG = 0,
+    FXAA_DEBUG_SUBPIXEL_ALIASING,
+    FXAA_DEBUG_EDGE_DIRECTION,
+    FXAA_DEBUG_EDGE_NUM_STEPS,
+    FXAA_DEBUG_EDGE_DISTANCE,
+    FXAA_DEBUG_EDGE_SAMPLE_OFFSET,
+    FXAA_DEBUG_ONLY_SUBPIX_AA,
+    FXAA_DEBUG_ONLY_EDGE_AA
+  };
+
+  static vtkFXAAOptions* New();
+  vtkTypeMacro(vtkFXAAOptions, vtkObject)
+  virtual void PrintSelf(ostream &os, vtkIndent indent);
+
+  // Description:
+  // Threshold for applying FXAA to a pixel, relative to the maximum luminosity
+  // of its 4 immediate neighbors.
+  //
+  // The luminosity of the current pixel and it's NSWE neighbors is computed.
+  // The maximum luminosity and luminosity range (contrast) of all 5 pixels is
+  // found. If the contrast is less than RelativeContrastThreshold * maxLum,
+  // the pixel is not considered aliased and will not be affected by FXAA.
+  //
+  // Suggested settings:
+  // - 1/3: Too little
+  // - 1/4: Low quality
+  // - 1/8: High quality (default)
+  // - 1/16: Overkill
+  vtkSetClampMacro(RelativeContrastThreshold, float, 0.f, 1.f)
+  vtkGetMacro(RelativeContrastThreshold, float)
+
+  // Description:
+  // Similar to RelativeContrastThreshold, but not scaled by the maximum
+  // luminosity.
+  //
+  // If the contrast of the current pixel and it's 4 immediate NSWE neighbors is
+  // less than HardContrastThreshold, the pixel is not considered aliased and
+  // will not be affected by FXAA.
+  //
+  // Suggested settings:
+  // - 1/32: Visible limit
+  // - 1/16: High quality (default)
+  // - 1/12: Upper limit (start of visible unfiltered edges)
+  vtkSetClampMacro(HardContrastThreshold, float, 0.f, 1.f)
+  vtkGetMacro(HardContrastThreshold, float)
+
+  // Description:
+  // Subpixel aliasing is corrected by applying a lowpass filter to the current
+  // pixel. This is implemented by blending an average of the 3x3 neighborhood
+  // around the pixel into the final result. The amount of blending is
+  // determined by comparing the detected amount of subpixel aliasing to the
+  // total contrasting of the CNSWE pixels:
+  //
+  // SubpixelBlending = abs(lumC - lumAveNSWE) / (lumMaxCNSWE - lumMinCNSWE)
+  //
+  // This parameter sets an upper limit to the amount of subpixel blending to
+  // prevent the image from simply getting blurred.
+  //
+  // Suggested settings:
+  // - 1/2: Low amount of blending.
+  // - 3/4: Medium amount of blending (default)
+  // - 7/8: High amount of blending.
+  // - 1: Maximum amount of blending.
+  vtkSetClampMacro(SubpixelBlendLimit, float, 0.f, 1.f)
+  vtkGetMacro(SubpixelBlendLimit, float)
+
+  // Description:
+  // Minimum amount of subpixel aliasing required for subpixel antialiasing to
+  // be applied.
+  //
+  // Subpixel aliasing is corrected by applying a lowpass filter to the current
+  // pixel. This is implemented by blending an average of the 3x3 neighborhood
+  // around the pixel into the final result. The amount of blending is
+  // determined by comparing the detected amount of subpixel aliasing to the
+  // total contrasting of the CNSWE pixels:
+  //
+  // SubpixelBlending = abs(lumC - lumAveNSWE) / (lumMaxCNSWE - lumMinCNSWE)
+  //
+  // If SubpixelBlending is less than this threshold, no lowpass blending will
+  // occur.
+  //
+  // Suggested settings:
+  // - 1/2: Low subpixel aliasing removal
+  // - 1/3: Medium subpixel aliasing removal
+  // - 1/4: Default subpixel aliasing removal
+  // - 1/8: High subpixel aliasing removal
+  // - 0: Complete subpixel aliasing removal
+  vtkSetClampMacro(SubpixelContrastThreshold, float, 0.f, 1.f)
+  vtkGetMacro(SubpixelContrastThreshold, float)
+
+  // Description:
+  // Use an improved edge endpoint detection algorithm.
+  //
+  // If true, a modified edge endpoint detection algorithm is used that requires
+  // more texture lookups, but will properly detect aliased single-pixel lines.
+  //
+  // If false, the edge endpoint algorithm proposed by NVIDIA will by used. This
+  // algorithm is faster (fewer lookups), but will fail to detect endpoints of
+  // single pixel edge steps.
+  //
+  // Default setting is true.
+  vtkSetMacro(UseHighQualityEndpoints, bool)
+  vtkGetMacro(UseHighQualityEndpoints, bool)
+  vtkBooleanMacro(UseHighQualityEndpoints, bool)
+
+  // Description:
+  // Set the number of iterations for the endpoint search algorithm. Increasing
+  // this value will increase runtime, but also properly detect longer edges.
+  // The current implementation steps one pixel in both the positive and
+  // negative directions per iteration. The default value is 12, which will
+  // resolve endpoints of edges < 25 pixels long (2 * 12 + 1).
+  vtkSetClampMacro(EndpointSearchIterations, int, 0, VTK_INT_MAX)
+  vtkGetMacro(EndpointSearchIterations, int)
+
+  // Description:
+  // Debugging options that affect the output color buffer. See
+  // vtkFXAAFilterFS.glsl for details. Only one may be active at a time.
+  vtkSetMacro(DebugOptionValue, DebugOption)
+  vtkGetMacro(DebugOptionValue, DebugOption)
+
+protected:
+  vtkFXAAOptions();
+  ~vtkFXAAOptions();
+
+  float RelativeContrastThreshold;
+  float HardContrastThreshold;
+  float SubpixelBlendLimit;
+  float SubpixelContrastThreshold;
+  int EndpointSearchIterations;
+  bool UseHighQualityEndpoints;
+  DebugOption DebugOptionValue;
+
+private:
+  vtkFXAAOptions(const vtkFXAAOptions&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkFXAAOptions&) VTK_DELETE_FUNCTION;
+};
+
+#endif // vtkFXAAOptions_h
diff --git a/Rendering/Core/vtkRenderer.cxx b/Rendering/Core/vtkRenderer.cxx
index b8a5bfdd38d..b65d5c92b55 100644
--- a/Rendering/Core/vtkRenderer.cxx
+++ b/Rendering/Core/vtkRenderer.cxx
@@ -22,6 +22,7 @@
 #include "vtkCullerCollection.h"
 #include "vtkCuller.h"
 #include "vtkFrustumCoverageCuller.h"
+#include "vtkFXAAOptions.h"
 #include "vtkObjectFactory.h"
 #include "vtkHardwareSelector.h"
 #include "vtkInformation.h"
@@ -44,6 +45,7 @@ vtkCxxSetObjectMacro(vtkRenderer, Information, vtkInformation);
 vtkCxxSetObjectMacro(vtkRenderer, Delegate, vtkRendererDelegate);
 vtkCxxSetObjectMacro(vtkRenderer, BackgroundTexture, vtkTexture);
 vtkCxxSetObjectMacro(vtkRenderer, Pass, vtkRenderPass);
+vtkCxxSetObjectMacro(vtkRenderer, FXAAOptions, vtkFXAAOptions);
 
 //----------------------------------------------------------------------------
 // Return NULL if no override is supplied.
@@ -118,13 +120,7 @@ vtkRenderer::vtkRenderer()
   this->GL2PSSpecialPropCollection = NULL;
 
   this->UseFXAA = false;
-  this->FXAARelativeContrastThreshold = 1.f / 8.f;
-  this->FXAAHardContrastThreshold = 1.f / 16.f;
-  this->FXAASubpixelBlendLimit = 3.f / 4.f;
-  this->FXAASubpixelContrastThreshold = 1.f / 4.f;
-  this->FXAAEndpointSearchIterations = 12;
-  this->FXAAUseHighQualityEndpoints = true;
-  this->FXAADebugOption = 0;
+  this->FXAAOptions = vtkFXAAOptions::New();
 
   this->UseShadows = 0;
 
@@ -175,6 +171,12 @@ vtkRenderer::~vtkRenderer()
   this->Cullers->Delete();
   this->Cullers = NULL;
 
+  if (this->FXAAOptions != NULL)
+    {
+    this->FXAAOptions->Delete();
+    this->FXAAOptions = NULL;
+    }
+
   if(this->Delegate!=0)
     {
     this->Delegate->UnRegister(this);
diff --git a/Rendering/Core/vtkRenderer.h b/Rendering/Core/vtkRenderer.h
index 0809201dddf..33484bd44f1 100644
--- a/Rendering/Core/vtkRenderer.h
+++ b/Rendering/Core/vtkRenderer.h
@@ -35,6 +35,7 @@
 #include "vtkVolumeCollection.h" // Needed for access in inline members
 #include "vtkActorCollection.h" // Needed for access in inline members
 
+class vtkFXAAOptions;
 class vtkRenderWindow;
 class vtkVolume;
 class vtkCuller;
@@ -535,23 +536,9 @@ public:
   vtkBooleanMacro(UseFXAA, bool)
 
   // Description:
-  // Tuning parameters for FXAA. See vtkOpenGLFXAAFilter.h for documentation
-  // and suggested values.
-  vtkSetClampMacro(FXAARelativeContrastThreshold, float, 0.f, 1.f)
-  vtkGetMacro(FXAARelativeContrastThreshold, float)
-  vtkSetClampMacro(FXAAHardContrastThreshold, float, 0.f, 1.f)
-  vtkGetMacro(FXAAHardContrastThreshold, float)
-  vtkSetClampMacro(FXAASubpixelBlendLimit, float, 0.f, 1.f)
-  vtkGetMacro(FXAASubpixelBlendLimit, float)
-  vtkSetClampMacro(FXAASubpixelContrastThreshold, float, 0.f, 1.f)
-  vtkGetMacro(FXAASubpixelContrastThreshold, float)
-  vtkSetClampMacro(FXAAEndpointSearchIterations, int, 0, VTK_INT_MAX)
-  vtkGetMacro(FXAAEndpointSearchIterations, int)
-  vtkSetMacro(FXAAUseHighQualityEndpoints, bool)
-  vtkGetMacro(FXAAUseHighQualityEndpoints, bool)
-  vtkBooleanMacro(FXAAUseHighQualityEndpoints, bool)
-  vtkSetMacro(FXAADebugOption, int)
-  vtkGetMacro(FXAADebugOption, int)
+  // The configuration object for FXAA antialiasing.
+  vtkGetObjectMacro(FXAAOptions, vtkFXAAOptions)
+  virtual void SetFXAAOptions(vtkFXAAOptions*);
 
   // Description:
   // Turn on/off rendering of shadows if supported
@@ -722,15 +709,8 @@ protected:
   bool UseFXAA;
 
   // Description:
-  // Parameters for FXAA. See vtkOpenGLFXAAFilter.h for documentation and
-  // suggested values.
-  float FXAARelativeContrastThreshold;
-  float FXAAHardContrastThreshold;
-  float FXAASubpixelBlendLimit;
-  float FXAASubpixelContrastThreshold;
-  int FXAAEndpointSearchIterations;
-  bool FXAAUseHighQualityEndpoints;
-  int FXAADebugOption;
+  // Holds the FXAA configuration.
+  vtkFXAAOptions *FXAAOptions;
 
   // Description:
   // If this flag is on and the rendering engine supports it render shadows
diff --git a/Rendering/OpenGL2/Testing/Cxx/TestFXAAFilter.cxx b/Rendering/OpenGL2/Testing/Cxx/TestFXAAFilter.cxx
index d85866df083..034985e4219 100644
--- a/Rendering/OpenGL2/Testing/Cxx/TestFXAAFilter.cxx
+++ b/Rendering/OpenGL2/Testing/Cxx/TestFXAAFilter.cxx
@@ -21,6 +21,7 @@
 #include "vtkConeSource.h"
 #include "vtkCylinderSource.h"
 #include "vtkDiskSource.h"
+#include "vtkFXAAOptions.h"
 #include "vtkLineSource.h"
 #include "vtkNew.h"
 #include "vtkOpenGLRenderer.h"
diff --git a/Rendering/OpenGL2/vtkOpenGLFXAAFilter.cxx b/Rendering/OpenGL2/vtkOpenGLFXAAFilter.cxx
index 89e5be7a4b9..c2d77dd2752 100644
--- a/Rendering/OpenGL2/vtkOpenGLFXAAFilter.cxx
+++ b/Rendering/OpenGL2/vtkOpenGLFXAAFilter.cxx
@@ -17,6 +17,7 @@
 
 #include "vtk_glew.h"
 
+#include "vtkFXAAOptions.h"
 #include "vtkObjectFactory.h"
 #include "vtkOpenGLBufferObject.h"
 #include "vtkOpenGLError.h"
@@ -45,6 +46,49 @@ vtkStandardNewMacro(vtkOpenGLFXAAFilter)
 void vtkOpenGLFXAAFilter::PrintSelf(std::ostream &os, vtkIndent indent)
 {
   this->Superclass::PrintSelf(os, indent);
+
+  os << indent << "RelativeContrastThreshold: "
+     << this->RelativeContrastThreshold << "\n";
+  os << indent << "HardContrastThreshold: "
+     << this->HardContrastThreshold << "\n";
+  os << indent << "SubpixelBlendLimit: " <<
+        this->SubpixelBlendLimit << "\n";
+  os << indent << "SubpixelContrastThreshold: "
+     << this->SubpixelContrastThreshold << "\n";
+  os << indent << "EndpointSearchIterations: "
+     << this->EndpointSearchIterations << "\n";
+  os << indent << "UseHighQualityEndpoints: "
+     << this->UseHighQualityEndpoints << "\n";
+
+  os << indent << "DebugOptionValue: ";
+  switch (this->DebugOptionValue)
+    {
+    default:
+    case vtkFXAAOptions::FXAA_NO_DEBUG:
+      os << "FXAA_NO_DEBUG\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_SUBPIXEL_ALIASING:
+      os << "FXAA_DEBUG_SUBPIXEL_ALIASING\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_EDGE_DIRECTION:
+      os << "FXAA_DEBUG_EDGE_DIRECTION\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_EDGE_NUM_STEPS:
+      os << "FXAA_DEBUG_EDGE_NUM_STEPS\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_EDGE_DISTANCE:
+      os << "FXAA_DEBUG_EDGE_DISTANCE\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_EDGE_SAMPLE_OFFSET:
+      os << "FXAA_DEBUG_EDGE_SAMPLE_OFFSET\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_ONLY_SUBPIX_AA:
+      os << "FXAA_DEBUG_ONLY_SUBPIX_AA\n";
+      break;
+    case vtkFXAAOptions::FXAA_DEBUG_ONLY_EDGE_AA:
+      os << "FXAA_DEBUG_ONLY_EDGE_AA\n";
+      break;
+    }
 }
 
 //------------------------------------------------------------------------------
@@ -78,6 +122,20 @@ void vtkOpenGLFXAAFilter::ReleaseGraphicsResources()
   this->FreeGLObjects();
 }
 
+//------------------------------------------------------------------------------
+void vtkOpenGLFXAAFilter::UpdateConfiguration(vtkFXAAOptions *opts)
+{
+  // Use the setters -- some of these options will trigger a shader rebuild
+  // when they change, and the setters hold the logic for determining this.
+  this->SetRelativeContrastThreshold(opts->GetRelativeContrastThreshold());
+  this->SetHardContrastThreshold(opts->GetHardContrastThreshold());
+  this->SetSubpixelBlendLimit(opts->GetSubpixelBlendLimit());
+  this->SetSubpixelContrastThreshold(opts->GetSubpixelContrastThreshold());
+  this->SetEndpointSearchIterations(opts->GetEndpointSearchIterations());
+  this->SetUseHighQualityEndpoints(opts->GetUseHighQualityEndpoints());
+  this->SetDebugOptionValue(opts->GetDebugOptionValue());
+}
+
 //------------------------------------------------------------------------------
 void vtkOpenGLFXAAFilter::SetUseHighQualityEndpoints(bool val)
 {
@@ -90,7 +148,7 @@ void vtkOpenGLFXAAFilter::SetUseHighQualityEndpoints(bool val)
 }
 
 //------------------------------------------------------------------------------
-void vtkOpenGLFXAAFilter::SetDebugOptionValue(DebugOption opt)
+void vtkOpenGLFXAAFilter::SetDebugOptionValue(vtkFXAAOptions::DebugOption opt)
 {
   if (this->DebugOptionValue != opt)
     {
@@ -116,6 +174,7 @@ vtkOpenGLFXAAFilter::vtkOpenGLFXAAFilter()
     SubpixelContrastThreshold(1.f/4.f),
     EndpointSearchIterations(12),
     UseHighQualityEndpoints(true),
+    DebugOptionValue(vtkFXAAOptions::FXAA_NO_DEBUG),
     NeedToRebuildShader(true),
     Renderer(NULL),
     Input(NULL),
@@ -298,7 +357,7 @@ void vtkOpenGLFXAAFilter::SubstituteFragmentShader(std::string &fragShader)
     }
 
 #define DEBUG_OPT_CASE(optName) \
-  case optName: \
+  case vtkFXAAOptions::optName: \
     vtkShaderProgram::Substitute(fragShader, "//VTK::DebugOptions::Def", \
                                  "#define " #optName); \
     break
@@ -307,7 +366,7 @@ void vtkOpenGLFXAAFilter::SubstituteFragmentShader(std::string &fragShader)
   switch (this->DebugOptionValue)
     {
     default:
-    case FXAA_NO_DEBUG:
+    case vtkFXAAOptions::FXAA_NO_DEBUG:
       break;
     DEBUG_OPT_CASE(FXAA_DEBUG_SUBPIXEL_ALIASING);
     DEBUG_OPT_CASE(FXAA_DEBUG_EDGE_DIRECTION);
diff --git a/Rendering/OpenGL2/vtkOpenGLFXAAFilter.h b/Rendering/OpenGL2/vtkOpenGLFXAAFilter.h
index 3ca4db0e6e3..2e917cff5a1 100644
--- a/Rendering/OpenGL2/vtkOpenGLFXAAFilter.h
+++ b/Rendering/OpenGL2/vtkOpenGLFXAAFilter.h
@@ -39,7 +39,9 @@
 
 #include "vtkRenderingOpenGL2Module.h" // For export macro
 #include "vtkObject.h"
+#include "vtkFXAAOptions.h" // For DebugOptions enum
 
+class vtkFXAAOptions;
 class vtkOpenGLBufferObject;
 class vtkOpenGLVertexArrayObject;
 class vtkOpenGLRenderer;
@@ -62,125 +64,29 @@ public:
   void ReleaseGraphicsResources();
 
   // Description:
-  // Threshold for applying FXAA to a pixel, relative to the maximum luminosity
-  // of its 4 immediate neighbors.
-  //
-  // The luminosity of the current pixel and it's NSWE neighbors is computed.
-  // The maximum luminosity and luminosity range (contrast) of all 5 pixels is
-  // found. If the contrast is less than RelativeContrastThreshold * maxLum,
-  // the pixel is not considered aliased and will not be affected by FXAA.
-  //
-  // Suggested settings:
-  // - 1/3: Too little
-  // - 1/4: Low quality
-  // - 1/8: High quality (default)
-  // - 1/16: Overkill
-  vtkSetClampMacro(RelativeContrastThreshold, float, 0.f, 1.f)
-  vtkGetMacro(RelativeContrastThreshold, float)
+  // Copy the configuration values from @a opts into this filter. Note that
+  // this copies the configuration values from opts -- it does not save the
+  // @a opts pointer.
+  void UpdateConfiguration(vtkFXAAOptions *opts);
 
   // Description:
-  // Similar to RelativeContrastThreshold, but not scaled by the maximum
-  // luminosity.
-  //
-  // If the contrast of the current pixel and it's 4 immediate NSWE neighbors is
-  // less than HardContrastThreshold, the pixel is not considered aliased and
-  // will not be affected by FXAA.
-  //
-  // Suggested settings:
-  // - 1/32: Visible limit
-  // - 1/16: High quality (default)
-  // - 1/12: Upper limit (start of visible unfiltered edges)
+  // Parameter for tuning the FXAA implementation. See vtkFXAAOptions for
+  // details and suggested values.
+  vtkSetClampMacro(RelativeContrastThreshold, float, 0.f, 1.f)
+  vtkGetMacro(RelativeContrastThreshold, float)
   vtkSetClampMacro(HardContrastThreshold, float, 0.f, 1.f)
   vtkGetMacro(HardContrastThreshold, float)
-
-  // Description:
-  // Subpixel aliasing is corrected by applying a lowpass filter to the current
-  // pixel. This is implemented by blending an average of the 3x3 neighborhood
-  // around the pixel into the final result. The amount of blending is
-  // determined by comparing the detected amount of subpixel aliasing to the
-  // total contrasting of the CNSWE pixels:
-  //
-  // SubpixelBlending = abs(lumC - lumAveNSWE) / (lumMaxCNSWE - lumMinCNSWE)
-  //
-  // This parameter sets an upper limit to the amount of subpixel blending to
-  // prevent the image from simply getting blurred.
-  //
-  // Suggested settings:
-  // - 1/2: Low amount of blending.
-  // - 3/4: Medium amount of blending (default)
-  // - 7/8: High amount of blending.
-  // - 1: Maximum amount of blending.
   vtkSetClampMacro(SubpixelBlendLimit, float, 0.f, 1.f)
   vtkGetMacro(SubpixelBlendLimit, float)
-
-  // Description:
-  // Minimum amount of subpixel aliasing required for subpixel antialiasing to
-  // be applied.
-  //
-  // Subpixel aliasing is corrected by applying a lowpass filter to the current
-  // pixel. This is implemented by blending an average of the 3x3 neighborhood
-  // around the pixel into the final result. The amount of blending is
-  // determined by comparing the detected amount of subpixel aliasing to the
-  // total contrasting of the CNSWE pixels:
-  //
-  // SubpixelBlending = abs(lumC - lumAveNSWE) / (lumMaxCNSWE - lumMinCNSWE)
-  //
-  // If SubpixelBlending is less than this threshold, no lowpass blending will
-  // occur.
-  //
-  // Suggested settings:
-  // - 1/2: Low subpixel aliasing removal
-  // - 1/3: Medium subpixel aliasing removal
-  // - 1/4: Default subpixel aliasing removal
-  // - 1/8: High subpixel aliasing removal
-  // - 0: Complete subpixel aliasing removal
   vtkSetClampMacro(SubpixelContrastThreshold, float, 0.f, 1.f)
   vtkGetMacro(SubpixelContrastThreshold, float)
-
-  // Description:
-  // Use an improved edge endpoint detection algorithm.
-  //
-  // If true, a modified edge endpoint detection algorithm is used that requires
-  // more texture lookups, but will properly detect aliased single-pixel lines.
-  //
-  // If false, the edge endpoint algorithm proposed by NVIDIA will by used. This
-  // algorithm is faster (fewer lookups), but will fail to detect endpoints of
-  // single pixel edge steps.
-  //
-  // Default setting is true.
   virtual void SetUseHighQualityEndpoints(bool val);
   vtkGetMacro(UseHighQualityEndpoints, bool)
   vtkBooleanMacro(UseHighQualityEndpoints, bool)
-
-  // Description:
-  // Set the number of iterations for the endpoint search algorithm. Increasing
-  // this value will increase runtime, but also properly detect longer edges.
-  // The current implementation steps one pixel in both the positive and
-  // negative directions per iteration. The default value is 12, which will
-  // resolve endpoints of edges < 25 pixels long (2 * 12 + 1).
   vtkSetClampMacro(EndpointSearchIterations, int, 0, VTK_INT_MAX)
   vtkGetMacro(EndpointSearchIterations, int)
-
-  // Description:
-  // Debugging options that affect the output color buffer. See
-  // vtkFXAAFilterFS.glsl for details.
-  enum DebugOption
-  {
-    FXAA_NO_DEBUG = 0,
-    FXAA_DEBUG_SUBPIXEL_ALIASING,
-    FXAA_DEBUG_EDGE_DIRECTION,
-    FXAA_DEBUG_EDGE_NUM_STEPS,
-    FXAA_DEBUG_EDGE_DISTANCE,
-    FXAA_DEBUG_EDGE_SAMPLE_OFFSET,
-    FXAA_DEBUG_ONLY_SUBPIX_AA,
-    FXAA_DEBUG_ONLY_EDGE_AA
-  };
-
-  // Description:
-  // Debugging options that affect the output color buffer. See
-  // vtkFXAAFilterFS.glsl for details. Only one may be active at a time.
-  virtual void SetDebugOptionValue(DebugOption opt);
-  vtkGetMacro(DebugOptionValue, DebugOption)
+  virtual void SetDebugOptionValue(vtkFXAAOptions::DebugOption opt);
+  vtkGetMacro(DebugOptionValue, vtkFXAAOptions::DebugOption)
 
 protected:
   vtkOpenGLFXAAFilter();
@@ -221,7 +127,7 @@ protected:
   int EndpointSearchIterations;
 
   bool UseHighQualityEndpoints;
-  DebugOption DebugOptionValue;
+  vtkFXAAOptions::DebugOption DebugOptionValue;
 
   // Set to true when the shader definitions change so we know when to rebuild.
   bool NeedToRebuildShader;
diff --git a/Rendering/OpenGL2/vtkOpenGLRenderer.cxx b/Rendering/OpenGL2/vtkOpenGLRenderer.cxx
index 7671dcaf2e7..caf14797af6 100644
--- a/Rendering/OpenGL2/vtkOpenGLRenderer.cxx
+++ b/Rendering/OpenGL2/vtkOpenGLRenderer.cxx
@@ -238,21 +238,10 @@ int vtkOpenGLRenderer::UpdateGeometry()
       {
       this->FXAAFilter = vtkOpenGLFXAAFilter::New();
       }
-
-    this->FXAAFilter->SetRelativeContrastThreshold(
-          this->FXAARelativeContrastThreshold);
-    this->FXAAFilter->SetHardContrastThreshold(
-          this->FXAAHardContrastThreshold);
-    this->FXAAFilter->SetSubpixelBlendLimit(
-          this->FXAASubpixelBlendLimit);
-    this->FXAAFilter->SetSubpixelContrastThreshold(
-          this->FXAASubpixelContrastThreshold);
-    this->FXAAFilter->SetEndpointSearchIterations(
-          this->FXAAEndpointSearchIterations);
-    this->FXAAFilter->SetUseHighQualityEndpoints(
-          this->FXAAUseHighQualityEndpoints);
-    this->FXAAFilter->SetDebugOptionValue(
-          static_cast<vtkOpenGLFXAAFilter::DebugOption>(this->FXAADebugOption));
+    if (this->FXAAOptions)
+      {
+      this->FXAAFilter->UpdateConfiguration(this->FXAAOptions);
+      }
 
     this->FXAAFilter->Execute(this);
     }
-- 
GitLab