| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef GPU_COMMAND_BUFFER_SERVICE_GRAPHITE_CACHE_CONTROLLER_H_ |
| #define GPU_COMMAND_BUFFER_SERVICE_GRAPHITE_CACHE_CONTROLLER_H_ |
| |
| #include "base/cancelable_callback.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/sequence_checker.h" |
| #include "gpu/gpu_gles2_export.h" |
| |
| namespace skgpu::graphite { |
| class Recorder; |
| } // namespace skgpu::graphite |
| |
| namespace gpu { |
| class DawnContextProvider; |
| class GraphiteSharedContext; |
| |
| namespace raster { |
| // GraphiteCacheController is not thread-safe; it can be created on any thread, |
| // but it must be destroyed on the same thread that ScheduleCleanup is called. |
| class GPU_GLES2_EXPORT GraphiteCacheController final |
| : public base::RefCounted<GraphiteCacheController> { |
| public: |
| // |context| and |dawn_context_provider| are optional e.g. Viz thread |
| // GraphiteCacheController won't cleanup the Graphite context or |
| // DawnContextProvider which live on GPU main thread. |
| explicit GraphiteCacheController( |
| skgpu::graphite::Recorder* recorder, |
| bool can_handle_context_resources = false, |
| DawnContextProvider* dawn_context_provider = nullptr); |
| |
| GraphiteCacheController(const GraphiteCacheController&) = delete; |
| GraphiteCacheController& operator=(const GraphiteCacheController&) = delete; |
| |
| // Schedule cleanup for the graphite cache; the cleanup will be performed |
| // after ScheduleCleanup() is not called for a while after going idle. |
| void ScheduleCleanup(); |
| |
| base::WeakPtr<GraphiteCacheController> AsWeakPtr() { |
| return weak_ptr_factory_.GetWeakPtr(); |
| } |
| |
| // Cleans up all Skia-owned scratch resources. |
| void CleanUpScratchResources(); |
| |
| // Cleans up all resources. |
| void CleanUpAllResources(); |
| |
| private: |
| friend class base::RefCounted<GraphiteCacheController>; |
| ~GraphiteCacheController(); |
| |
| // If the controller is only for a recorder, aka for viz thread recorer, then |
| // it operates in local mode where it only considers if current controller is |
| // idle. If the controller is for recorder+context then it operates in global |
| // mode where it waits for all global controllers to be idle. |
| bool UseGlobalIdleId() const; |
| uint32_t GetIdleId() const; |
| |
| void ScheduleCleanUpAllResources(uint32_t idle_id); |
| void MaybeCleanUpAllResources(uint32_t posted_idle_id); |
| void CleanUpAllResourcesImpl(); |
| GraphiteSharedContext* GetGraphiteSharedContext(); |
| |
| const raw_ptr<skgpu::graphite::Recorder> recorder_; |
| const raw_ptr<DawnContextProvider> dawn_context_provider_; |
| |
| uint32_t local_idle_id_ = 0; |
| base::CancelableOnceClosure idle_cleanup_cb_; |
| |
| // If multiple DawnContextProviders share the same graphite::Context, only one |
| // controller is responsible for cleaning up the graphite context resources. |
| // TODO(crbug.com/407874799): Fix the issue that dawn cleanup won't happen if |
| // no work is done on CrGpuMain to call into ScheduleCleanup() and start the |
| // timer. |
| const bool can_handle_context_resources_; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| base::WeakPtrFactory<GraphiteCacheController> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace raster |
| } // namespace gpu |
| |
| #endif // GPU_COMMAND_BUFFER_SERVICE_GRAPHITE_CACHE_CONTROLLER_H_ |