#ifndef GPU_IPC_SERVICE_GPU_CHANNEL_H_
#define GPU_IPC_SERVICE_GPU_CHANNEL_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <optional>
#include <string>
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process_handle.h"
#include "base/task/single_thread_task_runner.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/command_buffer/common/context_result.h"
#include "gpu/command_buffer/service/isolation_key_provider.h"
#include "gpu/ipc/common/gpu_channel.mojom.h"
#include "gpu/ipc/common/gpu_disk_cache_type.h"
#include "gpu/ipc/service/command_buffer_stub.h"
#include "gpu/ipc/service/gpu_ipc_service_export.h"
#include "gpu/ipc/service/shared_image_stub.h"
#include "ipc/ipc_sync_channel.h"
#include "mojo/public/cpp/bindings/generic_pending_associated_receiver.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_extra_info.h"
#include "ui/gfx/native_ui_types.h"
#include "ui/gl/gl_share_group.h"
#include "ui/gl/gpu_preference.h"
#include "arkweb/build/features/features.h"
namespace base {
class WaitableEvent;
}
namespace gpu {
class DCOMPTexture;
class FenceSyncReleaseDelegate;
class GpuChannelManager;
class GpuChannelMessageFilter;
class Scheduler;
class SharedImageStub;
class SyncPointManager;
class GpuChannelExt;
class GPU_IPC_SERVICE_EXPORT GpuChannel : public IPC::Listener,
public IsolationKeyProvider {
public:
friend class GpuChannelExt;
GpuChannel(const GpuChannel&) = delete;
GpuChannel& operator=(const GpuChannel&) = delete;
~GpuChannel() override;
virtual gpu::GpuChannelExt* AsGpuChannelExt() {
return nullptr;
}
static std::unique_ptr<GpuChannel> Create(
GpuChannelManager* gpu_channel_manager,
const base::UnguessableToken& channel_token,
Scheduler* scheduler,
SyncPointManager* sync_point_manager,
scoped_refptr<gl::GLShareGroup> share_group,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
int32_t client_id,
uint64_t client_tracing_id,
bool is_gpu_host,
bool enable_extra_handles_validation,
const gfx::GpuExtraInfo& gpu_extra_info);
void Init(mojo::MessagePipeHandle channel_handle,
base::WaitableEvent* shutdown_event);
base::WeakPtr<GpuChannel> AsWeakPtr();
GpuChannelManager* gpu_channel_manager() const {
return gpu_channel_manager_;
}
Scheduler* scheduler() const { return scheduler_; }
SyncPointManager* sync_point_manager() const { return sync_point_manager_; }
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner() const {
return task_runner_;
}
void set_client_pid(base::ProcessId pid) { client_pid_ = pid; }
base::ProcessId client_pid() const { return client_pid_; }
int client_id() const { return client_id_; }
uint64_t client_tracing_id() const { return client_tracing_id_; }
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner() const {
return io_task_runner_;
}
bool is_gpu_host() const { return is_gpu_host_; }
bool enable_extra_handles_validation() const {
return enable_extra_handles_validation_;
}
void OnChannelError() override;
void GetIsolationKey(const blink::WebGPUExecutionContextToken& token,
GetIsolationKeyCallback cb) override;
void OnCommandBufferScheduled(CommandBufferStub* stub);
void OnCommandBufferDescheduled(CommandBufferStub* stub);
gl::GLShareGroup* share_group() const { return share_group_.get(); }
CommandBufferStub* LookupCommandBuffer(int32_t route_id);
bool HasActiveStatefulContext() const;
void MarkAllContextsLost();
bool AddRoute(int32_t route_id, SequenceId sequence_id);
void RemoveRoute(int32_t route_id);
std::optional<gpu::GpuDiskCacheHandle> GetCacheHandleForType(
gpu::GpuDiskCacheType type);
void RegisterCacheHandle(const gpu::GpuDiskCacheHandle& handle);
void CacheBlob(gpu::GpuDiskCacheType type,
const std::string& key,
const std::string& shader);
uint64_t GetMemoryUsage() const;
void ExecuteDeferredRequest(mojom::DeferredRequestParamsPtr params,
FenceSyncReleaseDelegate* release_delegate);
void PerformImmediateCleanup();
void WaitForTokenInRange(
int32_t routing_id,
int32_t start,
int32_t end,
mojom::GpuChannel::WaitForTokenInRangeCallback callback);
void WaitForGetOffsetInRange(
int32_t routing_id,
uint32_t set_get_buffer_count,
int32_t start,
int32_t end,
mojom::GpuChannel::WaitForGetOffsetInRangeCallback callback);
mojom::GpuChannel& GetGpuChannelForTesting();
#if BUILDFLAG(IS_ANDROID)
const CommandBufferStub* GetOneStub() const;
#endif
#if BUILDFLAG(IS_WIN)
bool CreateDCOMPTexture(
int32_t route_id,
mojo::PendingAssociatedReceiver<mojom::DCOMPTexture> receiver);
void DestroyDCOMPTexture(int32_t route_id);
bool RegisterOverlayStateObserver(
mojo::PendingRemote<gpu::mojom::OverlayStateObserver>
promotion_hint_observer,
const gpu::Mailbox& mailbox);
#endif
SharedImageStub* shared_image_stub() const {
return shared_image_stub_.get();
}
void CreateCommandBuffer(
mojom::CreateCommandBufferParamsPtr init_params,
int32_t routing_id,
base::UnsafeSharedMemoryRegion shared_state_shm,
mojo::PendingAssociatedReceiver<mojom::CommandBuffer> receiver,
mojo::PendingAssociatedRemote<mojom::CommandBufferClient> client,
mojom::GpuChannel::CreateCommandBufferCallback callback);
void DestroyCommandBuffer(int32_t routing_id);
#if BUILDFLAG(IS_FUCHSIA)
void RegisterSysmemBufferCollection(mojo::PlatformHandle service_handle,
mojo::PlatformHandle sysmem_token,
const viz::SharedImageFormat& format,
gfx::BufferUsage usage,
bool register_with_image_pipe);
#endif
private:
GpuChannel(GpuChannelManager* gpu_channel_manager,
const base::UnguessableToken& channel_token,
Scheduler* scheduler,
SyncPointManager* sync_point_manager,
scoped_refptr<gl::GLShareGroup> share_group,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
int32_t client_id,
uint64_t client_tracing_id,
bool is_gpu_host,
bool enable_extra_handles_validation,
const gfx::GpuExtraInfo& gpu_extra_info);
void OnDestroyCommandBuffer(int32_t route_id);
bool CreateSharedImageStub(const gfx::GpuExtraInfo& gpu_extra_info);
std::unique_ptr<IPC::SyncChannel> sync_channel_;
base::ProcessId client_pid_ = base::kNullProcessId;
base::flat_map<int32_t, std::unique_ptr<CommandBufferStub>> stubs_;
base::flat_map<int32_t, SequenceId> stream_sequences_;
base::flat_map<gpu::GpuDiskCacheType, gpu::GpuDiskCacheHandle> caches_;
const raw_ptr<GpuChannelManager> gpu_channel_manager_;
const raw_ptr<Scheduler> scheduler_;
const raw_ptr<SyncPointManager> sync_point_manager_;
const int32_t client_id_;
const uint64_t client_tracing_id_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
scoped_refptr<gl::GLShareGroup> share_group_;
std::unique_ptr<SharedImageStub> shared_image_stub_;
const bool is_gpu_host_;
const bool enable_extra_handles_validation_;
#if BUILDFLAG(IS_WIN)
base::flat_map<int32_t, scoped_refptr<DCOMPTexture>> dcomp_textures_;
#endif
const scoped_refptr<GpuChannelMessageFilter> filter_;
base::WeakPtrFactory<GpuChannel> weak_factory_{this};
};
}
#endif