Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 1 | // Copyright 2019 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/shared_image_interface_in_process.h" |
| 6 | |
| 7 | #include "base/bind.h" |
| 8 | #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" |
| 9 | #include "gpu/command_buffer/common/sync_token.h" |
| 10 | #include "gpu/command_buffer/service/mailbox_manager.h" |
| 11 | #include "gpu/command_buffer/service/shared_image_factory.h" |
| 12 | #include "gpu/command_buffer/service/sync_point_manager.h" |
| 13 | #include "gpu/ipc/command_buffer_task_executor.h" |
| 14 | #include "gpu/ipc/common/gpu_client_ids.h" |
| 15 | #include "gpu/ipc/single_task_sequence.h" |
| 16 | #include "ui/gl/gl_context.h" |
| 17 | |
| 18 | namespace gpu { |
| 19 | SharedImageInterfaceInProcess::SharedImageInterfaceInProcess( |
| 20 | CommandBufferTaskExecutor* task_executor, |
| 21 | SingleTaskSequence* single_task_sequence, |
| 22 | CommandBufferId command_buffer_id, |
| 23 | MailboxManager* mailbox_manager, |
| 24 | ImageFactory* image_factory, |
| 25 | MemoryTracker* memory_tracker, |
| 26 | std::unique_ptr<CommandBufferHelper> command_buffer_helper) |
| 27 | : task_sequence_(single_task_sequence), |
| 28 | command_buffer_id_(command_buffer_id), |
| 29 | command_buffer_helper_(std::move(command_buffer_helper)), |
| 30 | shared_image_manager_(task_executor->shared_image_manager()), |
| 31 | mailbox_manager_(mailbox_manager), |
| 32 | sync_point_manager_(task_executor->sync_point_manager()) { |
| 33 | DETACH_FROM_SEQUENCE(gpu_sequence_checker_); |
| 34 | task_sequence_->ScheduleTask( |
| 35 | base::BindOnce(&SharedImageInterfaceInProcess::SetUpOnGpu, |
| 36 | base::Unretained(this), task_executor, image_factory, |
| 37 | memory_tracker), |
| 38 | {}); |
| 39 | } |
| 40 | |
| 41 | SharedImageInterfaceInProcess::~SharedImageInterfaceInProcess() { |
| 42 | base::WaitableEvent completion( |
| 43 | base::WaitableEvent::ResetPolicy::MANUAL, |
| 44 | base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 45 | |
| 46 | task_sequence_->ScheduleTask( |
| 47 | base::BindOnce(&SharedImageInterfaceInProcess::DestroyOnGpu, |
| 48 | base::Unretained(this), &completion), |
| 49 | {}); |
| 50 | completion.Wait(); |
| 51 | } |
| 52 | |
| 53 | void SharedImageInterfaceInProcess::SetUpOnGpu( |
| 54 | CommandBufferTaskExecutor* task_executor, |
| 55 | ImageFactory* image_factory, |
| 56 | MemoryTracker* memory_tracker) { |
| 57 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 58 | |
| 59 | context_state_ = task_executor->GetSharedContextState().get(); |
| 60 | create_factory_ = base::BindOnce( |
| 61 | [](CommandBufferTaskExecutor* task_executor, ImageFactory* image_factory, |
| 62 | MemoryTracker* memory_tracker, MailboxManager* mailbox_manager, |
| 63 | bool enable_wrapped_sk_image) { |
| 64 | auto shared_image_factory = std::make_unique<SharedImageFactory>( |
| 65 | task_executor->gpu_preferences(), |
| 66 | GpuDriverBugWorkarounds(task_executor->gpu_feature_info() |
| 67 | .enabled_gpu_driver_bug_workarounds), |
| 68 | task_executor->gpu_feature_info(), |
| 69 | task_executor->GetSharedContextState().get(), mailbox_manager, |
| 70 | task_executor->shared_image_manager(), image_factory, |
| 71 | memory_tracker, enable_wrapped_sk_image); |
| 72 | return shared_image_factory; |
| 73 | }, |
| 74 | task_executor, image_factory, memory_tracker, mailbox_manager_); |
| 75 | |
| 76 | // Make the SharedImageInterface use the same sequence as the command buffer, |
| 77 | // it's necessary for WebView because of the blocking behavior. |
| 78 | // TODO(piman): see if it's worth using a different sequence for non-WebView. |
| 79 | sync_point_client_state_ = sync_point_manager_->CreateSyncPointClientState( |
| 80 | CommandBufferNamespace::IN_PROCESS, command_buffer_id_, |
| 81 | task_sequence_->GetSequenceId()); |
| 82 | } |
| 83 | |
| 84 | void SharedImageInterfaceInProcess::DestroyOnGpu( |
| 85 | base::WaitableEvent* completion) { |
| 86 | bool have_context = MakeContextCurrent(); |
| 87 | if (shared_image_factory_) |
| 88 | shared_image_factory_->DestroyAllSharedImages(have_context); |
| 89 | |
| 90 | if (sync_point_client_state_) { |
| 91 | sync_point_client_state_->Destroy(); |
| 92 | sync_point_client_state_ = nullptr; |
| 93 | } |
| 94 | completion->Signal(); |
| 95 | } |
| 96 | |
Peng Huang | ca587f99 | 2020-06-05 17:19:28 | [diff] [blame] | 97 | bool SharedImageInterfaceInProcess::MakeContextCurrent(bool needs_gl) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 98 | if (!context_state_) |
| 99 | return false; |
| 100 | |
| 101 | if (context_state_->context_lost()) |
| 102 | return false; |
| 103 | |
| 104 | // |shared_image_factory_| never writes to the surface, so skip unnecessary |
| 105 | // MakeCurrent to improve performance. https://crbug.com/457431 |
| 106 | auto* context = context_state_->real_context(); |
Jonathan Backer | baf79d9 | 2020-06-01 21:30:30 | [diff] [blame] | 107 | if (context->IsCurrent(nullptr)) |
Peng Huang | ca587f99 | 2020-06-05 17:19:28 | [diff] [blame] | 108 | return !context_state_->CheckResetStatus(needs_gl); |
| 109 | return context_state_->MakeCurrent(/*surface=*/nullptr, needs_gl); |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | void SharedImageInterfaceInProcess::LazyCreateSharedImageFactory() { |
| 113 | // This function is always called right after we call MakeContextCurrent(). |
| 114 | if (shared_image_factory_) |
| 115 | return; |
| 116 | |
Peng Huang | ca587f99 | 2020-06-05 17:19:28 | [diff] [blame] | 117 | // Some shared image backing factories will use GL in ctor, so we need GL even |
| 118 | // if chrome is using non-GL backing. |
| 119 | if (!MakeContextCurrent(/*needs_gl=*/true)) |
| 120 | return; |
| 121 | |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 122 | // We need WrappedSkImage to support creating a SharedImage with pixel data |
| 123 | // when GL is unavailable. This is used in various unit tests. |
| 124 | const bool enable_wrapped_sk_image = |
| 125 | command_buffer_helper_ && command_buffer_helper_->EnableWrappedSkImage(); |
| 126 | shared_image_factory_ = |
| 127 | std::move(create_factory_).Run(enable_wrapped_sk_image); |
| 128 | } |
| 129 | |
| 130 | Mailbox SharedImageInterfaceInProcess::CreateSharedImage( |
| 131 | viz::ResourceFormat format, |
| 132 | const gfx::Size& size, |
| 133 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 134 | GrSurfaceOrigin surface_origin, |
| 135 | SkAlphaType alpha_type, |
Paulo Warren | fad0b11 | 2020-03-03 21:40:26 | [diff] [blame] | 136 | uint32_t usage, |
| 137 | gpu::SurfaceHandle surface_handle) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 138 | auto mailbox = Mailbox::GenerateForSharedImage(); |
| 139 | { |
| 140 | base::AutoLock lock(lock_); |
| 141 | // Note: we enqueue the task under the lock to guarantee monotonicity of |
| 142 | // the release ids as seen by the service. Unretained is safe because |
| 143 | // SharedImageInterfaceInProcess synchronizes with the GPU thread at |
| 144 | // destruction time, cancelling tasks, before |this| is destroyed. |
| 145 | ScheduleGpuTask( |
| 146 | base::BindOnce( |
| 147 | &SharedImageInterfaceInProcess::CreateSharedImageOnGpuThread, |
Paulo Warren | fad0b11 | 2020-03-03 21:40:26 | [diff] [blame] | 148 | base::Unretained(this), mailbox, format, surface_handle, size, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 149 | color_space, surface_origin, alpha_type, usage, |
| 150 | MakeSyncToken(next_fence_sync_release_++)), |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 151 | {}); |
| 152 | } |
| 153 | return mailbox; |
| 154 | } |
| 155 | |
| 156 | void SharedImageInterfaceInProcess::CreateSharedImageOnGpuThread( |
| 157 | const Mailbox& mailbox, |
| 158 | viz::ResourceFormat format, |
Paulo Warren | fad0b11 | 2020-03-03 21:40:26 | [diff] [blame] | 159 | gpu::SurfaceHandle surface_handle, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 160 | const gfx::Size& size, |
| 161 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 162 | GrSurfaceOrigin surface_origin, |
| 163 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 164 | uint32_t usage, |
| 165 | const SyncToken& sync_token) { |
| 166 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 167 | if (!MakeContextCurrent()) |
| 168 | return; |
| 169 | |
| 170 | LazyCreateSharedImageFactory(); |
| 171 | |
Paulo Warren | fad0b11 | 2020-03-03 21:40:26 | [diff] [blame] | 172 | if (!shared_image_factory_->CreateSharedImage( |
Nathan Zabriskie | eed7e6c | 2020-07-18 01:34:42 | [diff] [blame^] | 173 | mailbox, format, size, color_space, surface_origin, alpha_type, |
| 174 | surface_handle, usage)) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 175 | // Signal errors by losing the command buffer. |
| 176 | command_buffer_helper_->SetError(); |
| 177 | return; |
| 178 | } |
| 179 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 180 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 181 | } |
| 182 | |
| 183 | Mailbox SharedImageInterfaceInProcess::CreateSharedImage( |
| 184 | viz::ResourceFormat format, |
| 185 | const gfx::Size& size, |
| 186 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 187 | GrSurfaceOrigin surface_origin, |
| 188 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 189 | uint32_t usage, |
| 190 | base::span<const uint8_t> pixel_data) { |
| 191 | auto mailbox = Mailbox::GenerateForSharedImage(); |
| 192 | std::vector<uint8_t> pixel_data_copy(pixel_data.begin(), pixel_data.end()); |
| 193 | { |
| 194 | base::AutoLock lock(lock_); |
| 195 | // Note: we enqueue the task under the lock to guarantee monotonicity of |
| 196 | // the release ids as seen by the service. Unretained is safe because |
| 197 | // InProcessCommandBuffer synchronizes with the GPU thread at destruction |
| 198 | // time, cancelling tasks, before |this| is destroyed. |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 199 | ScheduleGpuTask( |
| 200 | base::BindOnce(&SharedImageInterfaceInProcess:: |
| 201 | CreateSharedImageWithDataOnGpuThread, |
| 202 | base::Unretained(this), mailbox, format, size, |
| 203 | color_space, surface_origin, alpha_type, usage, |
| 204 | MakeSyncToken(next_fence_sync_release_++), |
| 205 | std::move(pixel_data_copy)), |
| 206 | {}); |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 207 | } |
| 208 | return mailbox; |
| 209 | } |
| 210 | |
| 211 | void SharedImageInterfaceInProcess::CreateSharedImageWithDataOnGpuThread( |
| 212 | const Mailbox& mailbox, |
| 213 | viz::ResourceFormat format, |
| 214 | const gfx::Size& size, |
| 215 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 216 | GrSurfaceOrigin surface_origin, |
| 217 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 218 | uint32_t usage, |
| 219 | const SyncToken& sync_token, |
| 220 | std::vector<uint8_t> pixel_data) { |
| 221 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 222 | if (!MakeContextCurrent()) |
| 223 | return; |
| 224 | |
| 225 | LazyCreateSharedImageFactory(); |
| 226 | |
| 227 | if (!shared_image_factory_->CreateSharedImage( |
Nathan Zabriskie | eed7e6c | 2020-07-18 01:34:42 | [diff] [blame^] | 228 | mailbox, format, size, color_space, surface_origin, alpha_type, usage, |
| 229 | pixel_data)) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 230 | // Signal errors by losing the command buffer. |
| 231 | command_buffer_helper_->SetError(); |
| 232 | return; |
| 233 | } |
| 234 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 235 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 236 | } |
| 237 | |
| 238 | Mailbox SharedImageInterfaceInProcess::CreateSharedImage( |
| 239 | gfx::GpuMemoryBuffer* gpu_memory_buffer, |
| 240 | GpuMemoryBufferManager* gpu_memory_buffer_manager, |
| 241 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 242 | GrSurfaceOrigin surface_origin, |
| 243 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 244 | uint32_t usage) { |
| 245 | DCHECK(gpu_memory_buffer->GetType() == gfx::NATIVE_PIXMAP || |
| 246 | gpu_memory_buffer->GetType() == gfx::ANDROID_HARDWARE_BUFFER || |
| 247 | gpu_memory_buffer_manager); |
| 248 | |
| 249 | // TODO(piman): DCHECK GMB format support. |
| 250 | DCHECK(IsImageSizeValidForGpuMemoryBufferFormat( |
| 251 | gpu_memory_buffer->GetSize(), gpu_memory_buffer->GetFormat())); |
| 252 | |
| 253 | auto mailbox = Mailbox::GenerateForSharedImage(); |
| 254 | gfx::GpuMemoryBufferHandle handle = gpu_memory_buffer->CloneHandle(); |
| 255 | bool requires_sync_token = handle.type == gfx::IO_SURFACE_BUFFER; |
| 256 | SyncToken sync_token; |
| 257 | { |
| 258 | base::AutoLock lock(lock_); |
| 259 | sync_token = MakeSyncToken(next_fence_sync_release_++); |
| 260 | // Note: we enqueue the task under the lock to guarantee monotonicity of |
| 261 | // the release ids as seen by the service. Unretained is safe because |
| 262 | // InProcessCommandBuffer synchronizes with the GPU thread at destruction |
| 263 | // time, cancelling tasks, before |this| is destroyed. |
| 264 | ScheduleGpuTask( |
| 265 | base::BindOnce( |
| 266 | &SharedImageInterfaceInProcess::CreateGMBSharedImageOnGpuThread, |
| 267 | base::Unretained(this), mailbox, std::move(handle), |
| 268 | gpu_memory_buffer->GetFormat(), gpu_memory_buffer->GetSize(), |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 269 | color_space, surface_origin, alpha_type, usage, sync_token), |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 270 | {}); |
| 271 | } |
| 272 | if (requires_sync_token) { |
| 273 | sync_token.SetVerifyFlush(); |
| 274 | gpu_memory_buffer_manager->SetDestructionSyncToken(gpu_memory_buffer, |
| 275 | sync_token); |
| 276 | } |
| 277 | return mailbox; |
| 278 | } |
| 279 | |
| 280 | void SharedImageInterfaceInProcess::CreateGMBSharedImageOnGpuThread( |
| 281 | const Mailbox& mailbox, |
| 282 | gfx::GpuMemoryBufferHandle handle, |
| 283 | gfx::BufferFormat format, |
| 284 | const gfx::Size& size, |
| 285 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 286 | GrSurfaceOrigin surface_origin, |
| 287 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 288 | uint32_t usage, |
| 289 | const SyncToken& sync_token) { |
| 290 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 291 | if (!MakeContextCurrent()) |
| 292 | return; |
| 293 | |
| 294 | LazyCreateSharedImageFactory(); |
| 295 | |
| 296 | // TODO(piman): add support for SurfaceHandle (for backbuffers for ozone/drm). |
| 297 | SurfaceHandle surface_handle = kNullSurfaceHandle; |
| 298 | if (!shared_image_factory_->CreateSharedImage( |
| 299 | mailbox, kInProcessCommandBufferClientId, std::move(handle), format, |
Nathan Zabriskie | eed7e6c | 2020-07-18 01:34:42 | [diff] [blame^] | 300 | surface_handle, size, color_space, surface_origin, alpha_type, |
| 301 | usage)) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 302 | // Signal errors by losing the command buffer. |
| 303 | // Signal errors by losing the command buffer. |
| 304 | command_buffer_helper_->SetError(); |
| 305 | return; |
| 306 | } |
| 307 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 308 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 309 | } |
| 310 | |
| 311 | SharedImageInterface::SwapChainMailboxes |
| 312 | SharedImageInterfaceInProcess::CreateSwapChain( |
| 313 | viz::ResourceFormat format, |
| 314 | const gfx::Size& size, |
| 315 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 316 | GrSurfaceOrigin surface_origin, |
| 317 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 318 | uint32_t usage) { |
| 319 | NOTREACHED(); |
| 320 | return {}; |
| 321 | } |
| 322 | |
| 323 | void SharedImageInterfaceInProcess::PresentSwapChain( |
| 324 | const SyncToken& sync_token, |
| 325 | const Mailbox& mailbox) { |
| 326 | NOTREACHED(); |
| 327 | } |
| 328 | |
| 329 | #if defined(OS_FUCHSIA) |
| 330 | void SharedImageInterfaceInProcess::RegisterSysmemBufferCollection( |
| 331 | gfx::SysmemBufferCollectionId id, |
Sergey Ulanov | 2806856 | 2020-06-09 23:28:07 | [diff] [blame] | 332 | zx::channel token, |
| 333 | gfx::BufferFormat format, |
| 334 | gfx::BufferUsage usage) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 335 | NOTREACHED(); |
| 336 | } |
| 337 | void SharedImageInterfaceInProcess::ReleaseSysmemBufferCollection( |
| 338 | gfx::SysmemBufferCollectionId id) { |
| 339 | NOTREACHED(); |
| 340 | } |
| 341 | #endif // defined(OS_FUCHSIA) |
| 342 | |
| 343 | void SharedImageInterfaceInProcess::UpdateSharedImage( |
| 344 | const SyncToken& sync_token, |
| 345 | const Mailbox& mailbox) { |
| 346 | UpdateSharedImage(sync_token, nullptr, mailbox); |
| 347 | } |
| 348 | |
| 349 | void SharedImageInterfaceInProcess::UpdateSharedImage( |
| 350 | const SyncToken& sync_token, |
| 351 | std::unique_ptr<gfx::GpuFence> acquire_fence, |
| 352 | const Mailbox& mailbox) { |
| 353 | DCHECK(!acquire_fence); |
| 354 | base::AutoLock lock(lock_); |
| 355 | // Note: we enqueue the task under the lock to guarantee monotonicity of |
| 356 | // the release ids as seen by the service. Unretained is safe because |
| 357 | // InProcessCommandBuffer synchronizes with the GPU thread at destruction |
| 358 | // time, cancelling tasks, before |this| is destroyed. |
| 359 | ScheduleGpuTask( |
| 360 | base::BindOnce( |
| 361 | &SharedImageInterfaceInProcess::UpdateSharedImageOnGpuThread, |
| 362 | base::Unretained(this), mailbox, |
| 363 | MakeSyncToken(next_fence_sync_release_++)), |
| 364 | {sync_token}); |
| 365 | } |
| 366 | |
| 367 | void SharedImageInterfaceInProcess::UpdateSharedImageOnGpuThread( |
| 368 | const Mailbox& mailbox, |
| 369 | const SyncToken& sync_token) { |
| 370 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 371 | if (!MakeContextCurrent()) |
| 372 | return; |
| 373 | |
| 374 | if (!shared_image_factory_ || |
| 375 | !shared_image_factory_->UpdateSharedImage(mailbox)) { |
| 376 | // Signal errors by losing the command buffer. |
| 377 | command_buffer_helper_->SetError(); |
| 378 | return; |
| 379 | } |
| 380 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 381 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 382 | } |
| 383 | |
| 384 | void SharedImageInterfaceInProcess::DestroySharedImage( |
| 385 | const SyncToken& sync_token, |
| 386 | const Mailbox& mailbox) { |
| 387 | // Use sync token dependency to ensure that the destroy task does not run |
| 388 | // before sync token is released. |
| 389 | ScheduleGpuTask( |
| 390 | base::BindOnce( |
| 391 | &SharedImageInterfaceInProcess::DestroySharedImageOnGpuThread, |
| 392 | base::Unretained(this), mailbox), |
| 393 | {sync_token}); |
| 394 | } |
| 395 | |
| 396 | void SharedImageInterfaceInProcess::DestroySharedImageOnGpuThread( |
| 397 | const Mailbox& mailbox) { |
| 398 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 399 | if (!MakeContextCurrent()) |
| 400 | return; |
| 401 | |
| 402 | if (!shared_image_factory_ || |
| 403 | !shared_image_factory_->DestroySharedImage(mailbox)) { |
| 404 | // Signal errors by losing the command buffer. |
| 405 | command_buffer_helper_->SetError(); |
| 406 | } |
| 407 | } |
| 408 | |
Vikas Soni | 08dfc58 | 2020-06-09 21:29:57 | [diff] [blame] | 409 | void SharedImageInterfaceInProcess::WaitSyncTokenOnGpuThread( |
| 410 | const SyncToken& sync_token) { |
| 411 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 412 | if (!MakeContextCurrent()) |
| 413 | return; |
| 414 | |
| 415 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 416 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 417 | } |
| 418 | |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 419 | SyncToken SharedImageInterfaceInProcess::GenUnverifiedSyncToken() { |
| 420 | base::AutoLock lock(lock_); |
| 421 | return MakeSyncToken(next_fence_sync_release_ - 1); |
| 422 | } |
| 423 | |
| 424 | SyncToken SharedImageInterfaceInProcess::GenVerifiedSyncToken() { |
| 425 | base::AutoLock lock(lock_); |
| 426 | SyncToken sync_token = MakeSyncToken(next_fence_sync_release_ - 1); |
| 427 | sync_token.SetVerifyFlush(); |
| 428 | return sync_token; |
| 429 | } |
| 430 | |
Vikas Soni | 08dfc58 | 2020-06-09 21:29:57 | [diff] [blame] | 431 | void SharedImageInterfaceInProcess::WaitSyncToken(const SyncToken& sync_token) { |
| 432 | base::AutoLock lock(lock_); |
| 433 | |
| 434 | ScheduleGpuTask( |
| 435 | base::BindOnce(&SharedImageInterfaceInProcess::WaitSyncTokenOnGpuThread, |
| 436 | base::Unretained(this), |
| 437 | MakeSyncToken(next_fence_sync_release_++)), |
| 438 | {sync_token}); |
| 439 | } |
| 440 | |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 441 | void SharedImageInterfaceInProcess::Flush() { |
| 442 | // No need to flush in this implementation. |
| 443 | } |
| 444 | |
| 445 | scoped_refptr<gfx::NativePixmap> SharedImageInterfaceInProcess::GetNativePixmap( |
| 446 | const gpu::Mailbox& mailbox) { |
| 447 | DCHECK(shared_image_manager_->is_thread_safe()); |
| 448 | return shared_image_manager_->GetNativePixmap(mailbox); |
| 449 | } |
| 450 | |
| 451 | void SharedImageInterfaceInProcess::WrapTaskWithGpuUrl(base::OnceClosure task) { |
| 452 | if (command_buffer_helper_) { |
| 453 | command_buffer_helper_->WrapTaskWithGpuCheck(std::move(task)); |
| 454 | } else { |
| 455 | std::move(task).Run(); |
| 456 | } |
| 457 | } |
| 458 | |
| 459 | void SharedImageInterfaceInProcess::ScheduleGpuTask( |
| 460 | base::OnceClosure task, |
| 461 | std::vector<SyncToken> sync_token_fences) { |
| 462 | base::OnceClosure gpu_task = |
| 463 | base::BindOnce(&SharedImageInterfaceInProcess::WrapTaskWithGpuUrl, |
| 464 | base::Unretained(this), std::move(task)); |
| 465 | |
| 466 | task_sequence_->ScheduleTask(std::move(gpu_task), |
| 467 | std::move(sync_token_fences)); |
| 468 | } |
| 469 | |
| 470 | } // namespace gpu |