text: // Copyright 2016 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef COMPONENTS_VIZ_COMMON_GPU_VULKAN_IN_PROCESS_CONTEXT_PROVIDER_H_
  #define COMPONENTS_VIZ_COMMON_GPU_VULKAN_IN_PROCESS_CONTEXT_PROVIDER_H_
  
  #include <memory>
  #include <vector>
  
  #include "base/memory/memory_pressure_listener.h"
  #include "base/time/time.h"
  #include "components/viz/common/gpu/vulkan_context_provider.h"
  #include "components/viz/common/viz_vulkan_context_provider_export.h"
  #include "gpu/vulkan/buildflags.h"
  #include "third_party/skia/include/gpu/GrContextOptions.h"
  
  #if BUILDFLAG(ENABLE_VULKAN)
  #include "third_party/skia/include/gpu/vk/GrVkBackendContext.h"
  #endif
  
  namespace gpu {
  class VulkanImplementation;
  class VulkanDeviceQueue;
  struct GPUInfo;
  }
  
  namespace viz {
  
  class VIZ_VULKAN_CONTEXT_PROVIDER_EXPORT VulkanInProcessContextProvider
      : public VulkanContextProvider {
   public:
    // if |sync_cpu_memory_limit| is set and greater than zero,
    // |cooldown_duration_at_memory_pressure_critical| is the duration of applying
    // zero sync cpu memory limit after CRITICAL memory pressure signal is
    // received. 15s is default to sync with memory monitor cycles.
    static scoped_refptr<VulkanInProcessContextProvider> Create(
        gpu::VulkanImplementation* vulkan_implementation,
        uint32_t heap_memory_limit = 0,
        uint32_t sync_cpu_memory_limit = 0,
        const gpu::GPUInfo* gpu_info = nullptr,
        base::TimeDelta cooldown_duration_at_memory_pressure_critical =
            base::TimeDelta::FromSeconds(15));
  
    void Destroy();
  
    // VulkanContextProvider implementation
    bool InitializeGrContext(const GrContextOptions& context_options) override;
    gpu::VulkanImplementation* GetVulkanImplementation() override;
    gpu::VulkanDeviceQueue* GetDeviceQueue() override;
    GrDirectContext* GetGrContext() override;
    GrVkSecondaryCBDrawContext* GetGrSecondaryCBDrawContext() override;
    void EnqueueSecondaryCBSemaphores(
        std::vector<VkSemaphore> semaphores) override;
    void EnqueueSecondaryCBPostSubmitTask(base::OnceClosure closure) override;
    absl::optional<uint32_t> GetSyncCpuMemoryLimit() const override;
  
   private:
    friend class VulkanInProcessContextProviderTest;
  
    VulkanInProcessContextProvider(
        gpu::VulkanImplementation* vulkan_implementation,
        uint32_t heap_memory_limit,
        uint32_t sync_cpu_memory_limit,
        base::TimeDelta cooldown_duration_at_memory_pressure_critical);
    ~VulkanInProcessContextProvider() override;
  
    bool Initialize(const gpu::GPUInfo* gpu_info);
  
    // Memory pressure handler, called by |memory_pressure_listener_|.
    void OnMemoryPressure(
        base::MemoryPressureListener::MemoryPressureLevel level);
  
  #if BUILDFLAG(ENABLE_VULKAN)
    sk_sp<GrDirectContext> gr_context_;
    gpu::VulkanImplementation* vulkan_implementation_;
    std::unique_ptr<gpu::VulkanDeviceQueue> device_queue_;
    const uint32_t heap_memory_limit_;
    const uint32_t sync_cpu_memory_limit_;
    const base::TimeDelta cooldown_duration_at_memory_pressure_critical_;
    base::TimeTicks critical_memory_pressure_expiration_time_;
  #endif
  
    std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
  
    DISALLOW_COPY_AND_ASSIGN(VulkanInProcessContextProvider);
  };
  
  }  // namespace viz
  
  #endif  // COMPONENTS_VIZ_COMMON_GPU_VULKAN_IN_PROCESS_CONTEXT_PROVIDER_H_
  