1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "gpu/ipc/service/webgpu_command_buffer_stub.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/macros.h"
11 #include "base/memory/unsafe_shared_memory_region.h"
12 #include "base/trace_event/trace_event.h"
13 #include "build/build_config.h"
14 #include "gpu/command_buffer/common/constants.h"
15 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
16 #include "gpu/command_buffer/common/mailbox.h"
17 #include "gpu/command_buffer/service/gl_context_virtual.h"
18 #include "gpu/command_buffer/service/gl_state_restorer_impl.h"
19 #include "gpu/command_buffer/service/image_manager.h"
20 #include "gpu/command_buffer/service/logger.h"
21 #include "gpu/command_buffer/service/mailbox_manager.h"
22 #include "gpu/command_buffer/service/memory_tracking.h"
23 #include "gpu/command_buffer/service/service_utils.h"
24 #include "gpu/command_buffer/service/sync_point_manager.h"
25 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
26 #include "gpu/command_buffer/service/webgpu_decoder.h"
27 #include "gpu/config/gpu_crash_keys.h"
28 #include "gpu/ipc/common/gpu_messages.h"
29 #include "gpu/ipc/service/gpu_channel.h"
30 #include "gpu/ipc/service/gpu_channel_manager.h"
31 #include "gpu/ipc/service/gpu_channel_manager_delegate.h"
32 #include "gpu/ipc/service/gpu_memory_buffer_factory.h"
33 #include "gpu/ipc/service/gpu_watchdog_thread.h"
34 #include "ui/gl/gl_bindings.h"
35 #include "ui/gl/gl_context.h"
36 #include "ui/gl/gl_image.h"
37 #include "ui/gl/gl_implementation.h"
38 #include "ui/gl/gl_switches.h"
39 #include "ui/gl/gl_workarounds.h"
40 #include "ui/gl/init/gl_factory.h"
41 
42 #if defined(OS_WIN)
43 #include "base/win/win_util.h"
44 #endif
45 
46 #if defined(OS_ANDROID)
47 #include "gpu/ipc/service/stream_texture_android.h"
48 #endif
49 
50 namespace gpu {
51 
WebGPUCommandBufferStub(GpuChannel * channel,const GPUCreateCommandBufferConfig & init_params,CommandBufferId command_buffer_id,SequenceId sequence_id,int32_t stream_id,int32_t route_id)52 WebGPUCommandBufferStub::WebGPUCommandBufferStub(
53     GpuChannel* channel,
54     const GPUCreateCommandBufferConfig& init_params,
55     CommandBufferId command_buffer_id,
56     SequenceId sequence_id,
57     int32_t stream_id,
58     int32_t route_id)
59     : CommandBufferStub(channel,
60                         init_params,
61                         command_buffer_id,
62                         sequence_id,
63                         stream_id,
64                         route_id) {}
65 
~WebGPUCommandBufferStub()66 WebGPUCommandBufferStub::~WebGPUCommandBufferStub() {}
67 
Initialize(CommandBufferStub * share_command_buffer_stub,const GPUCreateCommandBufferConfig & init_params,base::UnsafeSharedMemoryRegion shared_state_shm)68 gpu::ContextResult WebGPUCommandBufferStub::Initialize(
69     CommandBufferStub* share_command_buffer_stub,
70     const GPUCreateCommandBufferConfig& init_params,
71     base::UnsafeSharedMemoryRegion shared_state_shm) {
72 #if defined(OS_FUCHSIA)
73   // TODO(crbug.com/707031): Implement this.
74   NOTIMPLEMENTED();
75   LOG(ERROR) << "ContextResult::kFatalFailure: no fuchsia support";
76   return gpu::ContextResult::kFatalFailure;
77 #else
78   TRACE_EVENT0("gpu", "WebGPUBufferStub::Initialize");
79   UpdateActiveUrl();
80 
81   GpuChannelManager* manager = channel_->gpu_channel_manager();
82   DCHECK(manager);
83 
84   if (share_command_buffer_stub) {
85     LOG(ERROR) << "Using a share group is not supported with WebGPUDecoder";
86     return ContextResult::kFatalFailure;
87   }
88 
89   if (surface_handle_ != kNullSurfaceHandle) {
90     LOG(ERROR) << "ContextResult::kFatalFailure: "
91                   "WebGPUInterface clients must render offscreen.";
92     return ContextResult::kFatalFailure;
93   }
94 
95   if (init_params.attribs.context_type != CONTEXT_TYPE_WEBGPU) {
96     LOG(ERROR) << "ContextResult::kFatalFailure: Incompatible creation attribs "
97                   "used with WebGPUDecoder";
98     return ContextResult::kFatalFailure;
99   }
100 
101   share_group_ = manager->share_group();
102   use_virtualized_gl_context_ = false;
103 
104   memory_tracker_ = CreateMemoryTracker(init_params);
105 
106   command_buffer_ =
107       std::make_unique<CommandBufferService>(this, memory_tracker_.get());
108   std::unique_ptr<webgpu::WebGPUDecoder> decoder(webgpu::WebGPUDecoder::Create(
109       this, command_buffer_.get(), manager->shared_image_manager(),
110       memory_tracker_.get(), manager->outputter()));
111 
112   sync_point_client_state_ =
113       channel_->sync_point_manager()->CreateSyncPointClientState(
114           CommandBufferNamespace::GPU_IO, command_buffer_id_, sequence_id_);
115 
116   ContextResult result = decoder->Initialize();
117   if (result != gpu::ContextResult::kSuccess) {
118     DLOG(ERROR) << "Failed to initialize decoder.";
119     return result;
120   }
121 
122   if (manager->gpu_preferences().enable_gpu_service_logging) {
123     decoder->SetLogCommands(true);
124   }
125   set_decoder_context(std::move(decoder));
126 
127   const size_t kSharedStateSize = sizeof(CommandBufferSharedState);
128   base::WritableSharedMemoryMapping shared_state_mapping =
129       shared_state_shm.MapAt(0, kSharedStateSize);
130   if (!shared_state_mapping.IsValid()) {
131     LOG(ERROR) << "ContextResult::kFatalFailure: "
132                   "Failed to map shared state buffer.";
133     return gpu::ContextResult::kFatalFailure;
134   }
135   command_buffer_->SetSharedStateBuffer(MakeBackingFromSharedMemory(
136       std::move(shared_state_shm), std::move(shared_state_mapping)));
137 
138   if (!active_url_.is_empty())
139     manager->delegate()->DidCreateOffscreenContext(active_url_.url());
140 
141   manager->delegate()->DidCreateContextSuccessfully();
142   initialized_ = true;
143   return gpu::ContextResult::kSuccess;
144 #endif  // defined(OS_FUCHSIA)
145 }
146 
GetMemoryTracker() const147 MemoryTracker* WebGPUCommandBufferStub::GetMemoryTracker() const {
148   return memory_tracker_.get();
149 }
150 
HandleMessage(const IPC::Message & message)151 bool WebGPUCommandBufferStub::HandleMessage(const IPC::Message& message) {
152   return false;
153 }
154 
OnSwapBuffers(uint64_t swap_id,uint32_t flags)155 void WebGPUCommandBufferStub::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {}
156 
157 }  // namespace gpu
158