[go: nahoru, domu]

blob: 8ef587af39dbf972d92169c7efa34cdce806b3bb [file] [log] [blame]
Avi Drissman05dfbc822022-09-13 21:25:341// Copyright 2019 The Chromium Authors
Weiliang Chen7cf2b5322020-01-23 02:04:172// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Kevin Haslett927f2342022-08-02 20:10:585#include "gpu/command_buffer/service/shared_image_interface_in_process.h"
Weiliang Chen7cf2b5322020-01-23 02:04:176
Avi Drissman93a273d2023-01-11 00:38:277#include "base/functional/bind.h"
Keishi Hattori0e45c022021-11-27 09:25:528#include "base/memory/raw_ptr.h"
David Sanders10242c12022-03-17 07:36:449#include "base/synchronization/waitable_event.h"
Xiaohan Wangfa22d3e2022-01-15 02:02:4310#include "build/build_config.h"
Mingjing Zhang65eedcc2023-10-24 15:12:4211#include "gpu/command_buffer/client/client_shared_image.h"
Weiliang Chen7cf2b5322020-01-23 02:04:1712#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
kylecharbee4cd42022-07-15 15:22:0813#include "gpu/command_buffer/common/shared_image_usage.h"
Weiliang Chen7cf2b5322020-01-23 02:04:1714#include "gpu/command_buffer/common/sync_token.h"
Kevin Haslett927f2342022-08-02 20:10:5815#include "gpu/command_buffer/service/command_buffer_task_executor.h"
16#include "gpu/command_buffer/service/display_compositor_memory_and_task_controller_on_gpu.h"
17#include "gpu/command_buffer/service/gpu_command_buffer_memory_tracker.h"
Peter McNeeleyd9ea4112023-05-08 15:33:4318#include "gpu/command_buffer/service/gr_shader_cache.h"
Saifuddin Hitawala81cbd382022-07-20 19:14:5319#include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
Kevin Haslett927f2342022-08-02 20:10:5820#include "gpu/command_buffer/service/single_task_sequence.h"
Weiliang Chen7cf2b5322020-01-23 02:04:1721#include "gpu/command_buffer/service/sync_point_manager.h"
Kevin Haslett927f2342022-08-02 20:10:5822#include "gpu/config/gpu_driver_bug_workarounds.h"
23#include "gpu/config/gpu_feature_info.h"
24#include "gpu/config/gpu_preferences.h"
Vikas Sonic6b087a2023-05-18 21:22:1025#include "gpu/ipc/common/gpu_client_ids.h"
Peter McNeeleyd9ea4112023-05-08 15:33:4326#include "third_party/abseil-cpp/absl/types/optional.h"
Weiliang Chen7cf2b5322020-01-23 02:04:1727#include "ui/gl/gl_context.h"
28
29namespace gpu {
Weiliang Chen25ebb7a2020-10-28 00:16:0530
Piotr Bialecki0296b22c2021-11-16 21:25:2431struct SharedImageInterfaceInProcess::SetUpOnGpuParams {
32 const GpuPreferences gpu_preferences;
33 const GpuDriverBugWorkarounds gpu_workarounds;
34 const GpuFeatureInfo gpu_feature_info;
Keishi Hattori0e45c022021-11-27 09:25:5235 const raw_ptr<gpu::SharedContextState> context_state;
Keishi Hattori0e45c022021-11-27 09:25:5236 const raw_ptr<SharedImageManager> shared_image_manager;
Piotr Bialecki0296b22c2021-11-16 21:25:2437 const bool is_for_display_compositor;
38
39 SetUpOnGpuParams(const GpuPreferences& gpu_preferences,
40 const GpuDriverBugWorkarounds& gpu_workarounds,
41 const GpuFeatureInfo& gpu_feature_info,
42 gpu::SharedContextState* context_state,
Piotr Bialecki0296b22c2021-11-16 21:25:2443 SharedImageManager* shared_image_manager,
Piotr Bialecki0296b22c2021-11-16 21:25:2444 bool is_for_display_compositor)
45 : gpu_preferences(gpu_preferences),
46 gpu_workarounds(gpu_workarounds),
47 gpu_feature_info(gpu_feature_info),
48 context_state(context_state),
Piotr Bialecki0296b22c2021-11-16 21:25:2449 shared_image_manager(shared_image_manager),
Piotr Bialecki0296b22c2021-11-16 21:25:2450 is_for_display_compositor(is_for_display_compositor) {}
51
52 ~SetUpOnGpuParams() = default;
53
54 SetUpOnGpuParams(const SetUpOnGpuParams& other) = delete;
55 SetUpOnGpuParams& operator=(const SetUpOnGpuParams& other) = delete;
56};
57
Weiliang Chen7cf2b5322020-01-23 02:04:1758SharedImageInterfaceInProcess::SharedImageInterfaceInProcess(
Weiliang Chen25ebb7a2020-10-28 00:16:0559 SingleTaskSequence* task_sequence,
kylechar0155a062022-09-01 22:09:4960 DisplayCompositorMemoryAndTaskControllerOnGpu* display_controller)
Piotr Bialecki0296b22c2021-11-16 21:25:2461 : SharedImageInterfaceInProcess(
62 task_sequence,
63 display_controller->sync_point_manager(),
64 display_controller->gpu_preferences(),
65 display_controller->gpu_driver_bug_workarounds(),
66 display_controller->gpu_feature_info(),
67 display_controller->shared_context_state(),
Piotr Bialecki0296b22c2021-11-16 21:25:2468 display_controller->shared_image_manager(),
kylechar0155a062022-09-01 22:09:4969 /*is_for_display_compositor=*/true) {}
Piotr Bialecki0296b22c2021-11-16 21:25:2470
71SharedImageInterfaceInProcess::SharedImageInterfaceInProcess(
72 SingleTaskSequence* task_sequence,
73 SyncPointManager* sync_point_manager,
74 const GpuPreferences& gpu_preferences,
75 const GpuDriverBugWorkarounds& gpu_workarounds,
76 const GpuFeatureInfo& gpu_feature_info,
77 gpu::SharedContextState* context_state,
Piotr Bialecki0296b22c2021-11-16 21:25:2478 SharedImageManager* shared_image_manager,
kylechar0155a062022-09-01 22:09:4979 bool is_for_display_compositor)
Weiliang Chen25ebb7a2020-10-28 00:16:0580 : task_sequence_(task_sequence),
Piotr Bialecki0296b22c2021-11-16 21:25:2481 command_buffer_id_(
82 DisplayCompositorMemoryAndTaskControllerOnGpu::NextCommandBufferId()),
Piotr Bialecki0296b22c2021-11-16 21:25:2483 shared_image_manager_(shared_image_manager),
84 sync_point_manager_(sync_point_manager) {
Weiliang Chen7cf2b5322020-01-23 02:04:1785 DETACH_FROM_SEQUENCE(gpu_sequence_checker_);
86 task_sequence_->ScheduleTask(
kylechar0155a062022-09-01 22:09:4987 base::BindOnce(
88 &SharedImageInterfaceInProcess::SetUpOnGpu, base::Unretained(this),
89 std::make_unique<SetUpOnGpuParams>(
90 gpu_preferences, gpu_workarounds, gpu_feature_info, context_state,
Vasiliy Telezhnikov9b1a7df2022-12-16 21:09:1291 shared_image_manager, is_for_display_compositor)),
Weiliang Chen7cf2b5322020-01-23 02:04:1792 {});
93}
94
95SharedImageInterfaceInProcess::~SharedImageInterfaceInProcess() {
96 base::WaitableEvent completion(
97 base::WaitableEvent::ResetPolicy::MANUAL,
98 base::WaitableEvent::InitialState::NOT_SIGNALED);
99
100 task_sequence_->ScheduleTask(
101 base::BindOnce(&SharedImageInterfaceInProcess::DestroyOnGpu,
102 base::Unretained(this), &completion),
103 {});
104 completion.Wait();
105}
Mingjing Zhang5915cc72023-09-27 15:13:46106
107const SharedImageCapabilities&
108SharedImageInterfaceInProcess::GetCapabilities() {
109 base::WaitableEvent completion(
110 base::WaitableEvent::ResetPolicy::MANUAL,
111 base::WaitableEvent::InitialState::NOT_SIGNALED);
112
113 if (!shared_image_capabilities_) {
114 shared_image_capabilities_ = std::make_unique<SharedImageCapabilities>();
115 task_sequence_->ScheduleTask(
116 base::BindOnce(&SharedImageInterfaceInProcess::GetCapabilitiesOnGpu,
117 base::Unretained(this), &completion,
118 shared_image_capabilities_.get()),
119 {});
120 completion.Wait();
121 }
122 return *shared_image_capabilities_;
123}
124
125void SharedImageInterfaceInProcess::GetCapabilitiesOnGpu(
126 base::WaitableEvent* completion,
127 SharedImageCapabilities* out_capabilities) {
128 if (!LazyCreateSharedImageFactory()) {
129 return;
130 }
131
132 DCHECK(shared_image_factory_);
133 *out_capabilities = shared_image_factory_->MakeCapabilities();
134 completion->Signal();
135}
136
Weiliang Chen7cf2b5322020-01-23 02:04:17137void SharedImageInterfaceInProcess::SetUpOnGpu(
Piotr Bialecki0296b22c2021-11-16 21:25:24138 std::unique_ptr<SetUpOnGpuParams> params) {
Weiliang Chen7cf2b5322020-01-23 02:04:17139 DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
Keishi Hattori0e45c022021-11-27 09:25:52140 context_state_ = params->context_state.get();
Weiliang Chen7cf2b5322020-01-23 02:04:17141
Weiliang Chen7cf2b5322020-01-23 02:04:17142 create_factory_ = base::BindOnce(
kylechar5436fb52022-07-04 20:56:00143 [](std::unique_ptr<SetUpOnGpuParams> params) {
Weiliang Chen7cf2b5322020-01-23 02:04:17144 auto shared_image_factory = std::make_unique<SharedImageFactory>(
Piotr Bialecki0296b22c2021-11-16 21:25:24145 params->gpu_preferences, params->gpu_workarounds,
146 params->gpu_feature_info, params->context_state,
Vasiliy Telezhnikov9b1a7df2022-12-16 21:09:12147 params->shared_image_manager,
kylechar0155a062022-09-01 22:09:49148 params->context_state->memory_tracker(),
149 params->is_for_display_compositor);
Weiliang Chen7cf2b5322020-01-23 02:04:17150 return shared_image_factory;
151 },
Piotr Bialecki0296b22c2021-11-16 21:25:24152 std::move(params));
Weiliang Chen7cf2b5322020-01-23 02:04:17153
154 // Make the SharedImageInterface use the same sequence as the command buffer,
155 // it's necessary for WebView because of the blocking behavior.
156 // TODO(piman): see if it's worth using a different sequence for non-WebView.
157 sync_point_client_state_ = sync_point_manager_->CreateSyncPointClientState(
158 CommandBufferNamespace::IN_PROCESS, command_buffer_id_,
159 task_sequence_->GetSequenceId());
160}
161
162void SharedImageInterfaceInProcess::DestroyOnGpu(
163 base::WaitableEvent* completion) {
164 bool have_context = MakeContextCurrent();
Peng Huang50103652020-09-29 13:50:44165 if (shared_image_factory_) {
Weiliang Chen7cf2b5322020-01-23 02:04:17166 shared_image_factory_->DestroyAllSharedImages(have_context);
Peng Huang50103652020-09-29 13:50:44167 shared_image_factory_ = nullptr;
168 }
Weiliang Chen7cf2b5322020-01-23 02:04:17169
170 if (sync_point_client_state_) {
171 sync_point_client_state_->Destroy();
172 sync_point_client_state_ = nullptr;
173 }
Peng Huang38b4905f2021-06-18 21:20:09174
175 context_state_ = nullptr;
Weiliang Chen7cf2b5322020-01-23 02:04:17176 completion->Signal();
177}
178
Peng Huangca587f992020-06-05 17:19:28179bool SharedImageInterfaceInProcess::MakeContextCurrent(bool needs_gl) {
Weiliang Chen7cf2b5322020-01-23 02:04:17180 if (!context_state_)
181 return false;
182
183 if (context_state_->context_lost())
184 return false;
185
186 // |shared_image_factory_| never writes to the surface, so skip unnecessary
187 // MakeCurrent to improve performance. https://crbug.com/457431
188 auto* context = context_state_->real_context();
Jonathan Backerbaf79d92020-06-01 21:30:30189 if (context->IsCurrent(nullptr))
Peng Huangca587f992020-06-05 17:19:28190 return !context_state_->CheckResetStatus(needs_gl);
191 return context_state_->MakeCurrent(/*surface=*/nullptr, needs_gl);
Weiliang Chen7cf2b5322020-01-23 02:04:17192}
193
Saifuddin Hitawalaad61a0a52021-08-11 12:18:35194bool SharedImageInterfaceInProcess::LazyCreateSharedImageFactory() {
Weiliang Chen7cf2b5322020-01-23 02:04:17195 if (shared_image_factory_)
Saifuddin Hitawalaad61a0a52021-08-11 12:18:35196 return true;
Weiliang Chen7cf2b5322020-01-23 02:04:17197
Peng Huangca587f992020-06-05 17:19:28198 // Some shared image backing factories will use GL in ctor, so we need GL even
199 // if chrome is using non-GL backing.
200 if (!MakeContextCurrent(/*needs_gl=*/true))
Saifuddin Hitawalaad61a0a52021-08-11 12:18:35201 return false;
Peng Huangca587f992020-06-05 17:19:28202
kylechar5436fb52022-07-04 20:56:00203 shared_image_factory_ = std::move(create_factory_).Run();
Saifuddin Hitawalaad61a0a52021-08-11 12:18:35204 return true;
Weiliang Chen7cf2b5322020-01-23 02:04:17205}
206
Mingjing Zhangdeb52562023-11-01 13:57:07207scoped_refptr<ClientSharedImage>
208SharedImageInterfaceInProcess::CreateSharedImage(
Colin Blundella679a472023-02-13 09:05:27209 viz::SharedImageFormat format,
210 const gfx::Size& size,
211 const gfx::ColorSpace& color_space,
212 GrSurfaceOrigin surface_origin,
213 SkAlphaType alpha_type,
214 uint32_t usage,
Rafael Cintronde3d9b82023-04-19 20:19:28215 base::StringPiece debug_label,
Colin Blundella679a472023-02-13 09:05:27216 gpu::SurfaceHandle surface_handle) {
kylecharbee4cd42022-07-15 15:22:08217 DCHECK(gpu::IsValidClientUsage(usage));
Weiliang Chen7cf2b5322020-01-23 02:04:17218 auto mailbox = Mailbox::GenerateForSharedImage();
219 {
220 base::AutoLock lock(lock_);
221 // Note: we enqueue the task under the lock to guarantee monotonicity of
222 // the release ids as seen by the service. Unretained is safe because
223 // SharedImageInterfaceInProcess synchronizes with the GPU thread at
224 // destruction time, cancelling tasks, before |this| is destroyed.
225 ScheduleGpuTask(
226 base::BindOnce(
227 &SharedImageInterfaceInProcess::CreateSharedImageOnGpuThread,
Colin Blundella679a472023-02-13 09:05:27228 base::Unretained(this), mailbox, format, surface_handle, size,
Nathan Zabriskie659c2742020-07-16 03:49:32229 color_space, surface_origin, alpha_type, usage,
Rafael Cintronde3d9b82023-04-19 20:19:28230 std::string(debug_label),
Nathan Zabriskie659c2742020-07-16 03:49:32231 MakeSyncToken(next_fence_sync_release_++)),
Weiliang Chen7cf2b5322020-01-23 02:04:17232 {});
233 }
Mingjing Zhangdeb52562023-11-01 13:57:07234 return base::MakeRefCounted<ClientSharedImage>(mailbox);
Weiliang Chen7cf2b5322020-01-23 02:04:17235}
236
237void SharedImageInterfaceInProcess::CreateSharedImageOnGpuThread(
238 const Mailbox& mailbox,
Colin Blundell79b4f1d82023-02-10 09:31:39239 viz::SharedImageFormat format,
Paulo Warrenfad0b112020-03-03 21:40:26240 gpu::SurfaceHandle surface_handle,
Weiliang Chen7cf2b5322020-01-23 02:04:17241 const gfx::Size& size,
242 const gfx::ColorSpace& color_space,
Nathan Zabriskie659c2742020-07-16 03:49:32243 GrSurfaceOrigin surface_origin,
244 SkAlphaType alpha_type,
Weiliang Chen7cf2b5322020-01-23 02:04:17245 uint32_t usage,
Rafael Cintronde3d9b82023-04-19 20:19:28246 std::string debug_label,
Weiliang Chen7cf2b5322020-01-23 02:04:17247 const SyncToken& sync_token) {
248 DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
Saifuddin Hitawalaad61a0a52021-08-11 12:18:35249 if (!LazyCreateSharedImageFactory())
250 return;
251
Weiliang Chen7cf2b5322020-01-23 02:04:17252 if (!MakeContextCurrent())
253 return;
254
Saifuddin Hitawalaad61a0a52021-08-11 12:18:35255 DCHECK(shared_image_factory_);
Paulo Warrenfad0b112020-03-03 21:40:26256 if (!shared_image_factory_->CreateSharedImage(
Colin Blundell79b4f1d82023-02-10 09:31:39257 mailbox, format, size, color_space, surface_origin, alpha_type,
Rafael Cintronde3d9b82023-04-19 20:19:28258 surface_handle, usage, std::string(debug_label))) {
kylechar0155a062022-09-01 22:09:49259 context_state_->MarkContextLost();
Weiliang Chen7cf2b5322020-01-23 02:04:17260 return;
261 }
Weiliang Chen7cf2b5322020-01-23 02:04:17262 sync_point_client_state_->ReleaseFenceSync(sync_token.release_count());
263}
264
Mingjing Zhang65eedcc2023-10-24 15:12:42265scoped_refptr<ClientSharedImage>
266SharedImageInterfaceInProcess::CreateSharedImage(
Colin Blundella679a472023-02-13 09:05:27267 viz::SharedImageFormat format,
268 const gfx::Size& size,
269 const gfx::ColorSpace& color_space,
270 GrSurfaceOrigin surface_origin,
271 SkAlphaType alpha_type,
272 uint32_t usage,
Rafael Cintronde3d9b82023-04-19 20:19:28273 base::StringPiece debug_label,
Colin Blundella679a472023-02-13 09:05:27274 base::span<const uint8_t> pixel_data) {
kylecharbee4cd42022-07-15 15:22:08275 DCHECK(gpu::IsValidClientUsage(usage));
Weiliang Chen7cf2b5322020-01-23 02:04:17276 auto mailbox = Mailbox::GenerateForSharedImage();
277 std::vector<uint8_t> pixel_data_copy(pixel_data.begin(), pixel_data.end());
278 {
279 base::AutoLock lock(lock_);
280 // Note: we enqueue the task under the lock to guarantee monotonicity of
281 // the release ids as seen by the service. Unretained is safe because
282 // InProcessCommandBuffer synchronizes with the GPU thread at destruction
283 // time, cancelling tasks, before |this| is destroyed.
Rafael Cintronde3d9b82023-04-19 20:19:28284 ScheduleGpuTask(base::BindOnce(&SharedImageInterfaceInProcess::
285 CreateSharedImageWithDataOnGpuThread,
286 base::Unretained(this), mailbox, format,
287 size, color_space, surface_origin,
288 alpha_type, usage, std::string(debug_label),
289 MakeSyncToken(next_fence_sync_release_++),
290 std::move(pixel_data_copy)),
291 {});
Weiliang Chen7cf2b5322020-01-23 02:04:17292 }
Mingjing Zhang65eedcc2023-10-24 15:12:42293 return base::MakeRefCounted<ClientSharedImage>(mailbox);
Weiliang Chen7cf2b5322020-01-23 02:04:17294}
295
296void SharedImageInterfaceInProcess::CreateSharedImageWithDataOnGpuThread(
297 const Mailbox& mailbox,
Colin Blundell79b4f1d82023-02-10 09:31:39298 viz::SharedImageFormat format,
Weiliang Chen7cf2b5322020-01-23 02:04:17299 const gfx::Size& size,
300 const gfx::ColorSpace& color_space,
Nathan Zabriskie659c2742020-07-16 03:49:32301 GrSurfaceOrigin surface_origin,
302 SkAlphaType alpha_type,
Weiliang Chen7cf2b5322020-01-23 02:04:17303 uint32_t usage,
Rafael Cintronde3d9b82023-04-19 20:19:28304 std::string debug_label,
Weiliang Chen7cf2b5322020-01-23 02:04:17305 const SyncToken& sync_token,
306 std::vector<uint8_t> pixel_data) {
307 DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
Saifuddin Hitawalaad61a0a52021-08-11 12:18:35308 if (!LazyCreateSharedImageFactory())
309 return;
310
Weiliang Chen7cf2b5322020-01-23 02:04:17311 if (!MakeContextCurrent())
312 return;
313
Saifuddin Hitawalaad61a0a52021-08-11 12:18:35314 DCHECK(shared_image_factory_);
Weiliang Chen7cf2b5322020-01-23 02:04:17315 if (!shared_image_factory_->CreateSharedImage(
Colin Blundell79b4f1d82023-02-10 09:31:39316 mailbox, format, size, color_space, surface_origin, alpha_type, usage,
Rafael Cintronde3d9b82023-04-19 20:19:28317 std::move(debug_label), pixel_data)) {
kylechar0155a062022-09-01 22:09:49318 context_state_->MarkContextLost();
Weiliang Chen7cf2b5322020-01-23 02:04:17319 return;
320 }
Weiliang Chen7cf2b5322020-01-23 02:04:17321 sync_point_client_state_->ReleaseFenceSync(sync_token.release_count());
322}
323
Mingjing Zhang3f1265c2023-10-26 02:16:55324scoped_refptr<ClientSharedImage>
325SharedImageInterfaceInProcess::CreateSharedImage(
kylechar7205de12022-12-07 18:43:48326 viz::SharedImageFormat format,
327 const gfx::Size& size,
328 const gfx::ColorSpace& color_space,
329 GrSurfaceOrigin surface_origin,
330 SkAlphaType alpha_type,
331 uint32_t usage,
Rafael Cintronde3d9b82023-04-19 20:19:28332 base::StringPiece debug_label,
Colin Blundell7204dc62023-09-20 09:21:42333 SurfaceHandle surface_handle,
334 gfx::BufferUsage buffer_usage) {
335 DCHECK(gpu::IsValidClientUsage(usage));
336 auto mailbox = Mailbox::GenerateForSharedImage();
337 {
338 base::AutoLock lock(lock_);
339 // Note: we enqueue the task under the lock to guarantee monotonicity of
340 // the release ids as seen by the service. Unretained is safe because
341 // InProcessCommandBuffer synchronizes with the GPU thread at destruction
342 // time, cancelling tasks, before |this| is destroyed.
343 ScheduleGpuTask(
344 base::BindOnce(&SharedImageInterfaceInProcess::
345 CreateSharedImageWithBufferUsageOnGpuThread,
346 base::Unretained(this), mailbox, format, size,
347 color_space, surface_origin, alpha_type, usage,
348 std::string(debug_label), surface_handle, buffer_usage,
349 MakeSyncToken(next_fence_sync_release_++)),
350 {});
351 }
Mingjing Zhang3f1265c2023-10-26 02:16:55352 return base::MakeRefCounted<ClientSharedImage>(mailbox);
Colin Blundell7204dc62023-09-20 09:21:42353}
354
355void SharedImageInterfaceInProcess::CreateSharedImageWithBufferUsageOnGpuThread(
356 const Mailbox& mailbox,
357 viz::SharedImageFormat format,
358 const gfx::Size& size,
359 const gfx::ColorSpace& color_space,
360 GrSurfaceOrigin surface_origin,
361 SkAlphaType alpha_type,
362 uint32_t usage,
363 std::string debug_label,
364 SurfaceHandle surface_handle,
365 gfx::BufferUsage buffer_usage,
366 const SyncToken& sync_token) {
367 DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
368 if (!LazyCreateSharedImageFactory()) {
369 return;
370 }
371
372 if (!MakeContextCurrent()) {
373 return;
374 }
375
376 DCHECK(shared_image_factory_);
Vikas Soni034fa472023-10-03 16:07:42377
378 // Note that SharedImageInterfaceInProcess implementation here uses
379 // SharedImageFactory::CreateSharedImage() to create a shared image backed by
380 // native buffer/shared memory in GPU process. This is different
381 // implementation and code path compared to ClientSharedImage implementation
382 // which creates native buffer/shared memory on IO thread and then creates a
383 // mailbox from it on GPU thread.
Colin Blundell7204dc62023-09-20 09:21:42384 if (!shared_image_factory_->CreateSharedImage(
385 mailbox, format, size, color_space, surface_origin, alpha_type,
386 surface_handle, usage, std::move(debug_label), buffer_usage)) {
387 context_state_->MarkContextLost();
388 return;
389 }
390 sync_point_client_state_->ReleaseFenceSync(sync_token.release_count());
391}
392
Colin Blundell5eb24ad22023-10-23 08:23:33393gfx::GpuMemoryBuffer* SharedImageInterfaceInProcess::GetGpuMemoryBuffer(
Colin Blundellc1a9b3fd2023-09-28 16:00:19394 const Mailbox& mailbox) {
395 {
396 base::AutoLock lock(lock_);
Colin Blundell5eb24ad22023-10-23 08:23:33397 auto it = gpu_memory_buffers_.find(mailbox);
398 if (it != gpu_memory_buffers_.end()) {
399 return it->second.get();
Colin Blundellc1a9b3fd2023-09-28 16:00:19400 }
401 }
402
Colin Blundell7204dc62023-09-20 09:21:42403 base::WaitableEvent completion(
404 base::WaitableEvent::ResetPolicy::MANUAL,
405 base::WaitableEvent::InitialState::NOT_SIGNALED);
406
407 gfx::GpuMemoryBufferHandle handle;
408 viz::SharedImageFormat format;
409 gfx::Size size;
410 gfx::BufferUsage buffer_usage;
411
Colin Blundell7204dc62023-09-20 09:21:42412 task_sequence_->ScheduleTask(
Colin Blundellc1a9b3fd2023-09-28 16:00:19413 base::BindOnce(&SharedImageInterfaceInProcess::
414 GetGpuMemoryBufferHandleInfoOnGpuThread,
Colin Blundell7204dc62023-09-20 09:21:42415 base::Unretained(this), mailbox, &handle, &format, &size,
416 &buffer_usage, &completion),
417 {});
418 completion.Wait();
Colin Blundell5eb24ad22023-10-23 08:23:33419 auto gpu_memory_buffer =
420 SharedImageInterface::CreateGpuMemoryBufferForUseByScopedMapping(
421 GpuMemoryBufferHandleInfo(std::move(handle), format, size,
422 buffer_usage));
423 auto* raw_gpu_memory_buffer = gpu_memory_buffer.get();
Colin Blundellc1a9b3fd2023-09-28 16:00:19424 {
425 base::AutoLock lock(lock_);
Colin Blundell5eb24ad22023-10-23 08:23:33426 gpu_memory_buffers_[mailbox] = std::move(gpu_memory_buffer);
Colin Blundellc1a9b3fd2023-09-28 16:00:19427 }
Colin Blundell7204dc62023-09-20 09:21:42428
Colin Blundell5eb24ad22023-10-23 08:23:33429 return raw_gpu_memory_buffer;
Colin Blundellc1a9b3fd2023-09-28 16:00:19430}
431
432std::unique_ptr<SharedImageInterface::ScopedMapping>
433SharedImageInterfaceInProcess::MapSharedImage(const Mailbox& mailbox) {
Colin Blundell5eb24ad22023-10-23 08:23:33434 auto* gpu_memory_buffer = GetGpuMemoryBuffer(mailbox);
435 if (!gpu_memory_buffer) {
Colin Blundellc1a9b3fd2023-09-28 16:00:19436 LOG(ERROR) << "Buffer is null.";
Colin Blundell7204dc62023-09-20 09:21:42437 return nullptr;
438 }
439
Colin Blundell04855822023-09-29 09:37:22440 auto scoped_mapping =
Colin Blundell5eb24ad22023-10-23 08:23:33441 SharedImageInterface::ScopedMapping::Create(gpu_memory_buffer);
Colin Blundell7204dc62023-09-20 09:21:42442
443 if (!scoped_mapping) {
444 LOG(ERROR) << "Unable to create ScopedMapping.";
445 }
446
447 return scoped_mapping;
448}
449
Colin Blundellc1a9b3fd2023-09-28 16:00:19450void SharedImageInterfaceInProcess::GetGpuMemoryBufferHandleInfoOnGpuThread(
Colin Blundell7204dc62023-09-20 09:21:42451 const Mailbox& mailbox,
452 gfx::GpuMemoryBufferHandle* handle,
453 viz::SharedImageFormat* format,
454 gfx::Size* size,
455 gfx::BufferUsage* buffer_usage,
456 base::WaitableEvent* completion) {
457 base::ScopedClosureRunner completion_runner(base::BindOnce(
458 [](base::WaitableEvent* completion) { completion->Signal(); },
459 completion));
460
461 DCHECK(shared_image_factory_);
462
463 if (!mailbox.IsSharedImage()) {
464 LOG(ERROR) << "SharedImageInterfaceInProcess: Trying to access a "
465 "SharedImage with a "
466 "non-SharedImage mailbox.";
467 return;
468 }
469
470 // Note that we are not making |context_state_| current here as of now since
471 // it is not needed to get the handle from the backings. Make context current
472 // if we find that it is required.
473 if (!shared_image_factory_->GetGpuMemoryBufferHandleInfo(
474 mailbox, *handle, *format, *size, *buffer_usage)) {
475 LOG(ERROR)
476 << "SharedImageInterfaceInProcess: Unable to get GpuMemoryBufferHandle";
477 }
478}
479
Mingjing Zhang02453562023-10-30 20:28:31480scoped_refptr<ClientSharedImage>
481SharedImageInterfaceInProcess::CreateSharedImage(
Colin Blundell7204dc62023-09-20 09:21:42482 viz::SharedImageFormat format,
483 const gfx::Size& size,
484 const gfx::ColorSpace& color_space,
485 GrSurfaceOrigin surface_origin,
486 SkAlphaType alpha_type,
487 uint32_t usage,
488 base::StringPiece debug_label,
kylechar7205de12022-12-07 18:43:48489 gfx::GpuMemoryBufferHandle buffer_handle) {
Saifuddin Hitawala43427272023-05-29 17:18:47490 DCHECK(gpu::IsValidClientUsage(usage));
491
Saifuddin Hitawalae1682302023-07-06 15:32:33492#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
493 CHECK(!format.PrefersExternalSampler());
494#endif
495
Saifuddin Hitawala43427272023-05-29 17:18:47496 auto mailbox = Mailbox::GenerateForSharedImage();
497 {
498 base::AutoLock lock(lock_);
499 SyncToken sync_token = MakeSyncToken(next_fence_sync_release_++);
500 // Note: we enqueue the task under the lock to guarantee monotonicity of
501 // the release ids as seen by the service. Unretained is safe because
502 // InProcessCommandBuffer synchronizes with the GPU thread at destruction
503 // time, cancelling tasks, before |this| is destroyed.
504 ScheduleGpuTask(base::BindOnce(&SharedImageInterfaceInProcess::
505 CreateSharedImageWithBufferOnGpuThread,
506 base::Unretained(this), mailbox, format,
507 size, color_space, surface_origin,
508 alpha_type, usage, std::move(buffer_handle),
509 std::string(debug_label), sync_token),
510 {});
511 }
512
Mingjing Zhang02453562023-10-30 20:28:31513 return base::MakeRefCounted<ClientSharedImage>(mailbox);
Saifuddin Hitawala43427272023-05-29 17:18:47514}
515
516void SharedImageInterfaceInProcess::CreateSharedImageWithBufferOnGpuThread(
517 const Mailbox& mailbox,
518 viz::SharedImageFormat format,
519 const gfx::Size& size,
520 const gfx::ColorSpace& color_space,
521 GrSurfaceOrigin surface_origin,
522 SkAlphaType alpha_type,
523 uint32_t usage,
524 gfx::GpuMemoryBufferHandle buffer_handle,
525 std::string debug_label,
526 const SyncToken& sync_token) {
527 DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
528 if (!LazyCreateSharedImageFactory()) {
529 return;
530 }
531
532 if (!MakeContextCurrent()) {
533 return;
534 }
535
536 DCHECK(shared_image_factory_);
537 if (!shared_image_factory_->CreateSharedImage(
538 mailbox, format, size, color_space, surface_origin, alpha_type, usage,
539 std::move(debug_label), std::move(buffer_handle))) {
540 context_state_->MarkContextLost();
541 return;
542 }
543 sync_point_client_state_->ReleaseFenceSync(sync_token.release_count());
kylechar7205de12022-12-07 18:43:48544}
545
Mingjing Zhang2f5591472023-11-06 18:49:07546scoped_refptr<ClientSharedImage>
547SharedImageInterfaceInProcess::CreateSharedImage(
Weiliang Chen7cf2b5322020-01-23 02:04:17548 gfx::GpuMemoryBuffer* gpu_memory_buffer,
549 GpuMemoryBufferManager* gpu_memory_buffer_manager,
Christopher Cameron2adb77f2021-04-27 17:59:39550 gfx::BufferPlane plane,
Weiliang Chen7cf2b5322020-01-23 02:04:17551 const gfx::ColorSpace& color_space,
Nathan Zabriskie659c2742020-07-16 03:49:32552 GrSurfaceOrigin surface_origin,
553 SkAlphaType alpha_type,
Rafael Cintronde3d9b82023-04-19 20:19:28554 uint32_t usage,
555 base::StringPiece debug_label) {
kylecharbee4cd42022-07-15 15:22:08556 DCHECK(gpu::IsValidClientUsage(usage));
Weiliang Chen7cf2b5322020-01-23 02:04:17557 // TODO(piman): DCHECK GMB format support.
558 DCHECK(IsImageSizeValidForGpuMemoryBufferFormat(
Sunny Sachanandani8b1c6a42021-09-18 00:38:21559 gpu_memory_buffer->GetSize(), gpu_memory_buffer->GetFormat()));
Christopher Cameron2adb77f2021-04-27 17:59:39560 DCHECK(IsPlaneValidForGpuMemoryBufferFormat(plane,
561 gpu_memory_buffer->GetFormat()));
Weiliang Chen7cf2b5322020-01-23 02:04:17562
563 auto mailbox = Mailbox::GenerateForSharedImage();
564 gfx::GpuMemoryBufferHandle handle = gpu_memory_buffer->CloneHandle();
Weiliang Chen7cf2b5322020-01-23 02:04:17565 {
566 base::AutoLock lock(lock_);
kylechar2fde6782023-01-04 17:22:42567 SyncToken sync_token = MakeSyncToken(next_fence_sync_release_++);
Weiliang Chen7cf2b5322020-01-23 02:04:17568 // Note: we enqueue the task under the lock to guarantee monotonicity of
569 // the release ids as seen by the service. Unretained is safe because
570 // InProcessCommandBuffer synchronizes with the GPU thread at destruction
571 // time, cancelling tasks, before |this| is destroyed.
572 ScheduleGpuTask(
573 base::BindOnce(
574 &SharedImageInterfaceInProcess::CreateGMBSharedImageOnGpuThread,
575 base::Unretained(this), mailbox, std::move(handle),
Christopher Cameron2adb77f2021-04-27 17:59:39576 gpu_memory_buffer->GetFormat(), plane, gpu_memory_buffer->GetSize(),
Rafael Cintronde3d9b82023-04-19 20:19:28577 color_space, surface_origin, alpha_type, usage,
578 std::string(debug_label), sync_token),
Weiliang Chen7cf2b5322020-01-23 02:04:17579 {});
580 }
kylechar2fde6782023-01-04 17:22:42581
Mingjing Zhang2f5591472023-11-06 18:49:07582 return base::MakeRefCounted<ClientSharedImage>(mailbox);
Weiliang Chen7cf2b5322020-01-23 02:04:17583}
584
585void SharedImageInterfaceInProcess::CreateGMBSharedImageOnGpuThread(
586 const Mailbox& mailbox,
587 gfx::GpuMemoryBufferHandle handle,
588 gfx::BufferFormat format,
Christopher Cameron2adb77f2021-04-27 17:59:39589 gfx::BufferPlane plane,
Weiliang Chen7cf2b5322020-01-23 02:04:17590 const gfx::Size& size,
591 const gfx::ColorSpace& color_space,
Nathan Zabriskie659c2742020-07-16 03:49:32592 GrSurfaceOrigin surface_origin,
593 SkAlphaType alpha_type,
Weiliang Chen7cf2b5322020-01-23 02:04:17594 uint32_t usage,
Rafael Cintronde3d9b82023-04-19 20:19:28595 std::string debug_label,
Weiliang Chen7cf2b5322020-01-23 02:04:17596 const SyncToken& sync_token) {
597 DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
Saifuddin Hitawalaad61a0a52021-08-11 12:18:35598 if (!LazyCreateSharedImageFactory())
599 return;
600
Weiliang Chen7cf2b5322020-01-23 02:04:17601 if (!MakeContextCurrent())
602 return;
603
Saifuddin Hitawalaad61a0a52021-08-11 12:18:35604 DCHECK(shared_image_factory_);
Weiliang Chen7cf2b5322020-01-23 02:04:17605 if (!shared_image_factory_->CreateSharedImage(
kylechar06177642023-01-12 18:03:19606 mailbox, std::move(handle), format, plane, size, color_space,
Rafael Cintronde3d9b82023-04-19 20:19:28607 surface_origin, alpha_type, usage, std::move(debug_label))) {
kylechar0155a062022-09-01 22:09:49608 context_state_->MarkContextLost();
Weiliang Chen7cf2b5322020-01-23 02:04:17609 return;
610 }
Weiliang Chen7cf2b5322020-01-23 02:04:17611 sync_point_client_state_->ReleaseFenceSync(sync_token.release_count());
612}
613
614SharedImageInterface::SwapChainMailboxes
615SharedImageInterfaceInProcess::CreateSwapChain(
Colin Blundell680c1e52023-02-24 10:25:12616 viz::SharedImageFormat format,
Weiliang Chen7cf2b5322020-01-23 02:04:17617 const gfx::Size& size,
618 const gfx::ColorSpace& color_space,
Nathan Zabriskie659c2742020-07-16 03:49:32619 GrSurfaceOrigin surface_origin,
620 SkAlphaType alpha_type,
Weiliang Chen7cf2b5322020-01-23 02:04:17621 uint32_t usage) {
622 NOTREACHED();
623 return {};
624}
625
626void SharedImageInterfaceInProcess::PresentSwapChain(
627 const SyncToken& sync_token,
628 const Mailbox& mailbox) {
629 NOTREACHED();
630}
631
Xiaohan Wangfa22d3e2022-01-15 02:02:43632#if BUILDFLAG(IS_FUCHSIA)
Weiliang Chen7cf2b5322020-01-23 02:04:17633void SharedImageInterfaceInProcess::RegisterSysmemBufferCollection(
Sergey Ulanov7f507a0f2022-10-28 19:11:13634 zx::eventpair service_handle,
635 zx::channel sysmem_token,
Sergey Ulanov28068562020-06-09 23:28:07636 gfx::BufferFormat format,
Emircan Uysaler23c657d2020-09-30 16:28:09637 gfx::BufferUsage usage,
638 bool register_with_image_pipe) {
Weiliang Chen7cf2b5322020-01-23 02:04:17639 NOTREACHED();
640}
Xiaohan Wangfa22d3e2022-01-15 02:02:43641#endif // BUILDFLAG(IS_FUCHSIA)
Weiliang Chen7cf2b5322020-01-23 02:04:17642
643void SharedImageInterfaceInProcess::UpdateSharedImage(
644 const SyncToken& sync_token,
645 const Mailbox& mailbox) {
646 UpdateSharedImage(sync_token, nullptr, mailbox);
647}
648
649void SharedImageInterfaceInProcess::UpdateSharedImage(
650 const SyncToken& sync_token,
651 std::unique_ptr<gfx::GpuFence> acquire_fence,
652 const Mailbox& mailbox) {
653 DCHECK(!acquire_fence);
654 base::AutoLock lock(lock_);
655 // Note: we enqueue the task under the lock to guarantee monotonicity of
656 // the release ids as seen by the service. Unretained is safe because
657 // InProcessCommandBuffer synchronizes with the GPU thread at destruction
658 // time, cancelling tasks, before |this| is destroyed.
659 ScheduleGpuTask(
660 base::BindOnce(
661 &SharedImageInterfaceInProcess::UpdateSharedImageOnGpuThread,
662 base::Unretained(this), mailbox,
663 MakeSyncToken(next_fence_sync_release_++)),
664 {sync_token});
665}
666
667void SharedImageInterfaceInProcess::UpdateSharedImageOnGpuThread(
668 const Mailbox& mailbox,
669 const SyncToken& sync_token) {
670 DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
671 if (!MakeContextCurrent())
672 return;
673
674 if (!shared_image_factory_ ||
675 !shared_image_factory_->UpdateSharedImage(mailbox)) {
kylechar0155a062022-09-01 22:09:49676 context_state_->MarkContextLost();
Weiliang Chen7cf2b5322020-01-23 02:04:17677 return;
678 }
Weiliang Chen7cf2b5322020-01-23 02:04:17679 sync_point_client_state_->ReleaseFenceSync(sync_token.release_count());
680}
681
682void SharedImageInterfaceInProcess::DestroySharedImage(
683 const SyncToken& sync_token,
684 const Mailbox& mailbox) {
685 // Use sync token dependency to ensure that the destroy task does not run
686 // before sync token is released.
687 ScheduleGpuTask(
688 base::BindOnce(
689 &SharedImageInterfaceInProcess::DestroySharedImageOnGpuThread,
690 base::Unretained(this), mailbox),
691 {sync_token});
692}
693
Mingjing Zhang6b7036f2023-11-03 15:38:42694void SharedImageInterfaceInProcess::DestroySharedImage(
695 const SyncToken& sync_token,
696 scoped_refptr<ClientSharedImage> client_shared_image) {
697 CHECK(client_shared_image->HasOneRef());
698 DestroySharedImage(sync_token, client_shared_image->mailbox());
699}
700
Weiliang Chen7cf2b5322020-01-23 02:04:17701void SharedImageInterfaceInProcess::DestroySharedImageOnGpuThread(
702 const Mailbox& mailbox) {
703 DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
704 if (!MakeContextCurrent())
705 return;
706
707 if (!shared_image_factory_ ||
708 !shared_image_factory_->DestroySharedImage(mailbox)) {
kylechar0155a062022-09-01 22:09:49709 context_state_->MarkContextLost();
Weiliang Chen7cf2b5322020-01-23 02:04:17710 }
Colin Blundellc1a9b3fd2023-09-28 16:00:19711
712 {
713 base::AutoLock lock(lock_);
Colin Blundell5eb24ad22023-10-23 08:23:33714 gpu_memory_buffers_.erase(mailbox);
Colin Blundellc1a9b3fd2023-09-28 16:00:19715 }
Weiliang Chen7cf2b5322020-01-23 02:04:17716}
717
Vikas Soni08dfc582020-06-09 21:29:57718void SharedImageInterfaceInProcess::WaitSyncTokenOnGpuThread(
719 const SyncToken& sync_token) {
720 DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
721 if (!MakeContextCurrent())
722 return;
723
Vikas Soni08dfc582020-06-09 21:29:57724 sync_point_client_state_->ReleaseFenceSync(sync_token.release_count());
725}
726
Weiliang Chen7cf2b5322020-01-23 02:04:17727SyncToken SharedImageInterfaceInProcess::GenUnverifiedSyncToken() {
728 base::AutoLock lock(lock_);
729 return MakeSyncToken(next_fence_sync_release_ - 1);
730}
731
732SyncToken SharedImageInterfaceInProcess::GenVerifiedSyncToken() {
733 base::AutoLock lock(lock_);
734 SyncToken sync_token = MakeSyncToken(next_fence_sync_release_ - 1);
735 sync_token.SetVerifyFlush();
736 return sync_token;
737}
738
Vikas Soni08dfc582020-06-09 21:29:57739void SharedImageInterfaceInProcess::WaitSyncToken(const SyncToken& sync_token) {
740 base::AutoLock lock(lock_);
741
742 ScheduleGpuTask(
743 base::BindOnce(&SharedImageInterfaceInProcess::WaitSyncTokenOnGpuThread,
744 base::Unretained(this),
745 MakeSyncToken(next_fence_sync_release_++)),
746 {sync_token});
747}
748
Weiliang Chen7cf2b5322020-01-23 02:04:17749void SharedImageInterfaceInProcess::Flush() {
750 // No need to flush in this implementation.
751}
752
753scoped_refptr<gfx::NativePixmap> SharedImageInterfaceInProcess::GetNativePixmap(
754 const gpu::Mailbox& mailbox) {
755 DCHECK(shared_image_manager_->is_thread_safe());
756 return shared_image_manager_->GetNativePixmap(mailbox);
757}
758
Weiliang Chen7cf2b5322020-01-23 02:04:17759void SharedImageInterfaceInProcess::ScheduleGpuTask(
760 base::OnceClosure task,
761 std::vector<SyncToken> sync_token_fences) {
kylechar0155a062022-09-01 22:09:49762 task_sequence_->ScheduleTask(std::move(task), std::move(sync_token_fences));
Weiliang Chen7cf2b5322020-01-23 02:04:17763}
764
Vasiliy Telezhnikov67468c92023-03-08 16:43:46765void SharedImageInterfaceInProcess::AddReferenceToSharedImage(
766 const SyncToken& sync_token,
767 const Mailbox& mailbox,
768 uint32_t usage) {
769 // Secondary references are required only by client processes, so it shouldn't
770 // be reachable here.
771 NOTREACHED();
772}
773
Weiliang Chen7cf2b5322020-01-23 02:04:17774} // namespace gpu