// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
/**
 * @class   vtkWebGPURenderPipelineCache
 * @brief   Class to create and retrieve render pipelines based on a given key.
 *
 * vtkWebGPURenderPipelineCache is meant to reduce the cost of creating render
 * pipelines by caching `wgpu::RenderPipeline` instances that are similar.
 * This class generates a unique hash for a given `wgpu::RenderPipelineDescriptor`
 * and a shader source string.
 *
 * The key is built from certain properties. It is guaranteed that the combination
 * of a collection of properties result in a unique pipeline. Here are the properties
 * which are used to generate a hash.
 * 1. Shader source string
 * 2. Culling mode
 * 3. Topology
 *
 * The hash is generated by stringifying the properties and generating a hash using
 * md5sum.
 *
 * @sa
 * vtkWebGPURenderer, vtkWebGPURenderWindow, vtkWebGPUPolyDataMapper
 */

#ifndef vtkWebGPURenderPipelineCache_h
#define vtkWebGPURenderPipelineCache_h

#include "vtkObject.h"

#include "vtkRenderingWebGPUModule.h" // for export macro
#include "vtk_wgpu.h"                 // for webgpu

VTK_ABI_NAMESPACE_BEGIN

class vtkWebGPURenderer;
class vtkWebGPURenderWindow;
class vtkWindow;

class VTKRENDERINGWEBGPU_EXPORT vtkWebGPURenderPipelineCache : public vtkObject
{
public:
  static vtkWebGPURenderPipelineCache* New();
  vtkTypeMacro(vtkWebGPURenderPipelineCache, vtkObject);
  void PrintSelf(ostream& os, vtkIndent indent) override;

  /**
   * Reset the pipeline cache.
   */
  void ReleaseGraphicsResources(vtkWindow* w);

  /**
   * Get a render pipeline associated with the given hash.
   */
  wgpu::RenderPipeline GetRenderPipeline(const std::string& key);

  /**
   * Get a unique hash for the given combination of render pipeline descriptor and shader source.
   */
  std::string GetPipelineKey(wgpu::RenderPipelineDescriptor* descriptor, const char* shaderSource);

  /**
   * Create a render pipeline for the given combination of render pipeline descriptor and shader
   * source.
   */
  void CreateRenderPipeline(wgpu::RenderPipelineDescriptor* descriptor,
    vtkWebGPURenderer* wgpuRenderer, const char* shaderSource);

  void CreateRenderPipeline(wgpu::RenderPipelineDescriptor* descriptor,
    vtkWebGPURenderWindow* wgpuRenderWindow, const char* shaderSource);

  /**
   * Destroy the render pipeline associated with the given hash.
   */
  void DestroyRenderPipeline(const std::string& key);

protected:
  vtkWebGPURenderPipelineCache();
  ~vtkWebGPURenderPipelineCache() override;

private:
  vtkWebGPURenderPipelineCache(const vtkWebGPURenderPipelineCache&) = delete;
  void operator=(const vtkWebGPURenderPipelineCache&) = delete;

  class vtkInternals;
  std::unique_ptr<vtkInternals> Internals;
};

VTK_ABI_NAMESPACE_END
#endif
