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(); |
Peng Huang | 5010365 | 2020-09-29 13:50:44 | [diff] [blame] | 87 | if (shared_image_factory_) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 88 | shared_image_factory_->DestroyAllSharedImages(have_context); |
Peng Huang | 5010365 | 2020-09-29 13:50:44 | [diff] [blame] | 89 | shared_image_factory_ = nullptr; |
| 90 | } |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 91 | |
| 92 | if (sync_point_client_state_) { |
| 93 | sync_point_client_state_->Destroy(); |
| 94 | sync_point_client_state_ = nullptr; |
| 95 | } |
| 96 | completion->Signal(); |
| 97 | } |
| 98 | |
Peng Huang | ca587f99 | 2020-06-05 17:19:28 | [diff] [blame] | 99 | bool SharedImageInterfaceInProcess::MakeContextCurrent(bool needs_gl) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 100 | if (!context_state_) |
| 101 | return false; |
| 102 | |
| 103 | if (context_state_->context_lost()) |
| 104 | return false; |
| 105 | |
| 106 | // |shared_image_factory_| never writes to the surface, so skip unnecessary |
| 107 | // MakeCurrent to improve performance. https://crbug.com/457431 |
| 108 | auto* context = context_state_->real_context(); |
Jonathan Backer | baf79d9 | 2020-06-01 21:30:30 | [diff] [blame] | 109 | if (context->IsCurrent(nullptr)) |
Peng Huang | ca587f99 | 2020-06-05 17:19:28 | [diff] [blame] | 110 | return !context_state_->CheckResetStatus(needs_gl); |
| 111 | return context_state_->MakeCurrent(/*surface=*/nullptr, needs_gl); |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 112 | } |
| 113 | |
| 114 | void SharedImageInterfaceInProcess::LazyCreateSharedImageFactory() { |
| 115 | // This function is always called right after we call MakeContextCurrent(). |
| 116 | if (shared_image_factory_) |
| 117 | return; |
| 118 | |
Peng Huang | ca587f99 | 2020-06-05 17:19:28 | [diff] [blame] | 119 | // Some shared image backing factories will use GL in ctor, so we need GL even |
| 120 | // if chrome is using non-GL backing. |
| 121 | if (!MakeContextCurrent(/*needs_gl=*/true)) |
| 122 | return; |
| 123 | |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 124 | // We need WrappedSkImage to support creating a SharedImage with pixel data |
| 125 | // when GL is unavailable. This is used in various unit tests. |
| 126 | const bool enable_wrapped_sk_image = |
| 127 | command_buffer_helper_ && command_buffer_helper_->EnableWrappedSkImage(); |
| 128 | shared_image_factory_ = |
| 129 | std::move(create_factory_).Run(enable_wrapped_sk_image); |
| 130 | } |
| 131 | |
| 132 | Mailbox SharedImageInterfaceInProcess::CreateSharedImage( |
| 133 | viz::ResourceFormat format, |
| 134 | const gfx::Size& size, |
| 135 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 136 | GrSurfaceOrigin surface_origin, |
| 137 | SkAlphaType alpha_type, |
Paulo Warren | fad0b11 | 2020-03-03 21:40:26 | [diff] [blame] | 138 | uint32_t usage, |
| 139 | gpu::SurfaceHandle surface_handle) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 140 | auto mailbox = Mailbox::GenerateForSharedImage(); |
| 141 | { |
| 142 | base::AutoLock lock(lock_); |
| 143 | // Note: we enqueue the task under the lock to guarantee monotonicity of |
| 144 | // the release ids as seen by the service. Unretained is safe because |
| 145 | // SharedImageInterfaceInProcess synchronizes with the GPU thread at |
| 146 | // destruction time, cancelling tasks, before |this| is destroyed. |
| 147 | ScheduleGpuTask( |
| 148 | base::BindOnce( |
| 149 | &SharedImageInterfaceInProcess::CreateSharedImageOnGpuThread, |
Paulo Warren | fad0b11 | 2020-03-03 21:40:26 | [diff] [blame] | 150 | base::Unretained(this), mailbox, format, surface_handle, size, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 151 | color_space, surface_origin, alpha_type, usage, |
| 152 | MakeSyncToken(next_fence_sync_release_++)), |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 153 | {}); |
| 154 | } |
| 155 | return mailbox; |
| 156 | } |
| 157 | |
| 158 | void SharedImageInterfaceInProcess::CreateSharedImageOnGpuThread( |
| 159 | const Mailbox& mailbox, |
| 160 | viz::ResourceFormat format, |
Paulo Warren | fad0b11 | 2020-03-03 21:40:26 | [diff] [blame] | 161 | gpu::SurfaceHandle surface_handle, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 162 | const gfx::Size& size, |
| 163 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 164 | GrSurfaceOrigin surface_origin, |
| 165 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 166 | uint32_t usage, |
| 167 | const SyncToken& sync_token) { |
| 168 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 169 | if (!MakeContextCurrent()) |
| 170 | return; |
| 171 | |
| 172 | LazyCreateSharedImageFactory(); |
| 173 | |
Paulo Warren | fad0b11 | 2020-03-03 21:40:26 | [diff] [blame] | 174 | if (!shared_image_factory_->CreateSharedImage( |
Nathan Zabriskie | eed7e6c | 2020-07-18 01:34:42 | [diff] [blame] | 175 | mailbox, format, size, color_space, surface_origin, alpha_type, |
| 176 | surface_handle, usage)) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 177 | // Signal errors by losing the command buffer. |
| 178 | command_buffer_helper_->SetError(); |
| 179 | return; |
| 180 | } |
| 181 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 182 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 183 | } |
| 184 | |
| 185 | Mailbox SharedImageInterfaceInProcess::CreateSharedImage( |
| 186 | viz::ResourceFormat format, |
| 187 | const gfx::Size& size, |
| 188 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 189 | GrSurfaceOrigin surface_origin, |
| 190 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 191 | uint32_t usage, |
| 192 | base::span<const uint8_t> pixel_data) { |
| 193 | auto mailbox = Mailbox::GenerateForSharedImage(); |
| 194 | std::vector<uint8_t> pixel_data_copy(pixel_data.begin(), pixel_data.end()); |
| 195 | { |
| 196 | base::AutoLock lock(lock_); |
| 197 | // Note: we enqueue the task under the lock to guarantee monotonicity of |
| 198 | // the release ids as seen by the service. Unretained is safe because |
| 199 | // InProcessCommandBuffer synchronizes with the GPU thread at destruction |
| 200 | // time, cancelling tasks, before |this| is destroyed. |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 201 | ScheduleGpuTask( |
| 202 | base::BindOnce(&SharedImageInterfaceInProcess:: |
| 203 | CreateSharedImageWithDataOnGpuThread, |
| 204 | base::Unretained(this), mailbox, format, size, |
| 205 | color_space, surface_origin, alpha_type, usage, |
| 206 | MakeSyncToken(next_fence_sync_release_++), |
| 207 | std::move(pixel_data_copy)), |
| 208 | {}); |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 209 | } |
| 210 | return mailbox; |
| 211 | } |
| 212 | |
| 213 | void SharedImageInterfaceInProcess::CreateSharedImageWithDataOnGpuThread( |
| 214 | const Mailbox& mailbox, |
| 215 | viz::ResourceFormat format, |
| 216 | const gfx::Size& size, |
| 217 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 218 | GrSurfaceOrigin surface_origin, |
| 219 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 220 | uint32_t usage, |
| 221 | const SyncToken& sync_token, |
| 222 | std::vector<uint8_t> pixel_data) { |
| 223 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 224 | if (!MakeContextCurrent()) |
| 225 | return; |
| 226 | |
| 227 | LazyCreateSharedImageFactory(); |
| 228 | |
| 229 | if (!shared_image_factory_->CreateSharedImage( |
Nathan Zabriskie | eed7e6c | 2020-07-18 01:34:42 | [diff] [blame] | 230 | mailbox, format, size, color_space, surface_origin, alpha_type, usage, |
| 231 | pixel_data)) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 232 | // Signal errors by losing the command buffer. |
| 233 | command_buffer_helper_->SetError(); |
| 234 | return; |
| 235 | } |
| 236 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 237 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 238 | } |
| 239 | |
| 240 | Mailbox SharedImageInterfaceInProcess::CreateSharedImage( |
| 241 | gfx::GpuMemoryBuffer* gpu_memory_buffer, |
| 242 | GpuMemoryBufferManager* gpu_memory_buffer_manager, |
| 243 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 244 | GrSurfaceOrigin surface_origin, |
| 245 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 246 | uint32_t usage) { |
| 247 | DCHECK(gpu_memory_buffer->GetType() == gfx::NATIVE_PIXMAP || |
| 248 | gpu_memory_buffer->GetType() == gfx::ANDROID_HARDWARE_BUFFER || |
| 249 | gpu_memory_buffer_manager); |
| 250 | |
| 251 | // TODO(piman): DCHECK GMB format support. |
| 252 | DCHECK(IsImageSizeValidForGpuMemoryBufferFormat( |
| 253 | gpu_memory_buffer->GetSize(), gpu_memory_buffer->GetFormat())); |
| 254 | |
| 255 | auto mailbox = Mailbox::GenerateForSharedImage(); |
| 256 | gfx::GpuMemoryBufferHandle handle = gpu_memory_buffer->CloneHandle(); |
| 257 | bool requires_sync_token = handle.type == gfx::IO_SURFACE_BUFFER; |
| 258 | SyncToken sync_token; |
| 259 | { |
| 260 | base::AutoLock lock(lock_); |
| 261 | sync_token = MakeSyncToken(next_fence_sync_release_++); |
| 262 | // Note: we enqueue the task under the lock to guarantee monotonicity of |
| 263 | // the release ids as seen by the service. Unretained is safe because |
| 264 | // InProcessCommandBuffer synchronizes with the GPU thread at destruction |
| 265 | // time, cancelling tasks, before |this| is destroyed. |
| 266 | ScheduleGpuTask( |
| 267 | base::BindOnce( |
| 268 | &SharedImageInterfaceInProcess::CreateGMBSharedImageOnGpuThread, |
| 269 | base::Unretained(this), mailbox, std::move(handle), |
| 270 | gpu_memory_buffer->GetFormat(), gpu_memory_buffer->GetSize(), |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 271 | color_space, surface_origin, alpha_type, usage, sync_token), |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 272 | {}); |
| 273 | } |
| 274 | if (requires_sync_token) { |
| 275 | sync_token.SetVerifyFlush(); |
| 276 | gpu_memory_buffer_manager->SetDestructionSyncToken(gpu_memory_buffer, |
| 277 | sync_token); |
| 278 | } |
| 279 | return mailbox; |
| 280 | } |
| 281 | |
| 282 | void SharedImageInterfaceInProcess::CreateGMBSharedImageOnGpuThread( |
| 283 | const Mailbox& mailbox, |
| 284 | gfx::GpuMemoryBufferHandle handle, |
| 285 | gfx::BufferFormat format, |
| 286 | const gfx::Size& size, |
| 287 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 288 | GrSurfaceOrigin surface_origin, |
| 289 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 290 | uint32_t usage, |
| 291 | const SyncToken& sync_token) { |
| 292 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 293 | if (!MakeContextCurrent()) |
| 294 | return; |
| 295 | |
| 296 | LazyCreateSharedImageFactory(); |
| 297 | |
| 298 | // TODO(piman): add support for SurfaceHandle (for backbuffers for ozone/drm). |
| 299 | SurfaceHandle surface_handle = kNullSurfaceHandle; |
| 300 | if (!shared_image_factory_->CreateSharedImage( |
kylechar | 90f620c | 2020-08-18 17:08:41 | [diff] [blame] | 301 | mailbox, kDisplayCompositorClientId, std::move(handle), format, |
Nathan Zabriskie | eed7e6c | 2020-07-18 01:34:42 | [diff] [blame] | 302 | surface_handle, size, color_space, surface_origin, alpha_type, |
| 303 | usage)) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 304 | // Signal errors by losing the command buffer. |
| 305 | // Signal errors by losing the command buffer. |
| 306 | command_buffer_helper_->SetError(); |
| 307 | return; |
| 308 | } |
| 309 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 310 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 311 | } |
| 312 | |
Vikas Soni | 16c01bb | 2020-08-07 12:11:20 | [diff] [blame] | 313 | #if defined(OS_ANDROID) |
| 314 | Mailbox SharedImageInterfaceInProcess::CreateSharedImageWithAHB( |
| 315 | const Mailbox& in_mailbox, |
| 316 | uint32_t usage, |
| 317 | const SyncToken& sync_token) { |
| 318 | auto out_mailbox = Mailbox::GenerateForSharedImage(); |
| 319 | { |
| 320 | base::AutoLock lock(lock_); |
| 321 | // Note: we enqueue the task under the lock to guarantee monotonicity of |
| 322 | // the release ids as seen by the service. Unretained is safe because |
| 323 | // SharedImageInterfaceInProcess synchronizes with the GPU thread at |
| 324 | // destruction time, cancelling tasks, before |this| is destroyed. |
| 325 | ScheduleGpuTask( |
| 326 | base::BindOnce( |
| 327 | &SharedImageInterfaceInProcess::CreateSharedImageWithAHBOnGpuThread, |
| 328 | base::Unretained(this), out_mailbox, in_mailbox, usage, |
| 329 | MakeSyncToken(next_fence_sync_release_++)), |
| 330 | {sync_token}); |
| 331 | } |
| 332 | return out_mailbox; |
| 333 | } |
| 334 | |
| 335 | void SharedImageInterfaceInProcess::CreateSharedImageWithAHBOnGpuThread( |
| 336 | const Mailbox& out_mailbox, |
| 337 | const Mailbox& in_mailbox, |
| 338 | uint32_t usage, |
| 339 | const SyncToken& sync_token) { |
| 340 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 341 | if (!MakeContextCurrent()) |
| 342 | return; |
| 343 | |
| 344 | if (!shared_image_factory_ || |
| 345 | !shared_image_factory_->CreateSharedImageWithAHB(out_mailbox, in_mailbox, |
| 346 | usage)) { |
| 347 | // Signal errors by losing the command buffer. |
| 348 | command_buffer_helper_->SetError(); |
| 349 | return; |
| 350 | } |
| 351 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 352 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 353 | } |
| 354 | #endif |
| 355 | |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 356 | SharedImageInterface::SwapChainMailboxes |
| 357 | SharedImageInterfaceInProcess::CreateSwapChain( |
| 358 | viz::ResourceFormat format, |
| 359 | const gfx::Size& size, |
| 360 | const gfx::ColorSpace& color_space, |
Nathan Zabriskie | 659c274 | 2020-07-16 03:49:32 | [diff] [blame] | 361 | GrSurfaceOrigin surface_origin, |
| 362 | SkAlphaType alpha_type, |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 363 | uint32_t usage) { |
| 364 | NOTREACHED(); |
| 365 | return {}; |
| 366 | } |
| 367 | |
| 368 | void SharedImageInterfaceInProcess::PresentSwapChain( |
| 369 | const SyncToken& sync_token, |
| 370 | const Mailbox& mailbox) { |
| 371 | NOTREACHED(); |
| 372 | } |
| 373 | |
| 374 | #if defined(OS_FUCHSIA) |
| 375 | void SharedImageInterfaceInProcess::RegisterSysmemBufferCollection( |
| 376 | gfx::SysmemBufferCollectionId id, |
Sergey Ulanov | 2806856 | 2020-06-09 23:28:07 | [diff] [blame] | 377 | zx::channel token, |
| 378 | gfx::BufferFormat format, |
Emircan Uysaler | 23c657d | 2020-09-30 16:28:09 | [diff] [blame] | 379 | gfx::BufferUsage usage, |
| 380 | bool register_with_image_pipe) { |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 381 | NOTREACHED(); |
| 382 | } |
| 383 | void SharedImageInterfaceInProcess::ReleaseSysmemBufferCollection( |
| 384 | gfx::SysmemBufferCollectionId id) { |
| 385 | NOTREACHED(); |
| 386 | } |
| 387 | #endif // defined(OS_FUCHSIA) |
| 388 | |
| 389 | void SharedImageInterfaceInProcess::UpdateSharedImage( |
| 390 | const SyncToken& sync_token, |
| 391 | const Mailbox& mailbox) { |
| 392 | UpdateSharedImage(sync_token, nullptr, mailbox); |
| 393 | } |
| 394 | |
| 395 | void SharedImageInterfaceInProcess::UpdateSharedImage( |
| 396 | const SyncToken& sync_token, |
| 397 | std::unique_ptr<gfx::GpuFence> acquire_fence, |
| 398 | const Mailbox& mailbox) { |
| 399 | DCHECK(!acquire_fence); |
| 400 | base::AutoLock lock(lock_); |
| 401 | // Note: we enqueue the task under the lock to guarantee monotonicity of |
| 402 | // the release ids as seen by the service. Unretained is safe because |
| 403 | // InProcessCommandBuffer synchronizes with the GPU thread at destruction |
| 404 | // time, cancelling tasks, before |this| is destroyed. |
| 405 | ScheduleGpuTask( |
| 406 | base::BindOnce( |
| 407 | &SharedImageInterfaceInProcess::UpdateSharedImageOnGpuThread, |
| 408 | base::Unretained(this), mailbox, |
| 409 | MakeSyncToken(next_fence_sync_release_++)), |
| 410 | {sync_token}); |
| 411 | } |
| 412 | |
| 413 | void SharedImageInterfaceInProcess::UpdateSharedImageOnGpuThread( |
| 414 | const Mailbox& mailbox, |
| 415 | const SyncToken& sync_token) { |
| 416 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 417 | if (!MakeContextCurrent()) |
| 418 | return; |
| 419 | |
| 420 | if (!shared_image_factory_ || |
| 421 | !shared_image_factory_->UpdateSharedImage(mailbox)) { |
| 422 | // Signal errors by losing the command buffer. |
| 423 | command_buffer_helper_->SetError(); |
| 424 | return; |
| 425 | } |
| 426 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 427 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 428 | } |
| 429 | |
| 430 | void SharedImageInterfaceInProcess::DestroySharedImage( |
| 431 | const SyncToken& sync_token, |
| 432 | const Mailbox& mailbox) { |
| 433 | // Use sync token dependency to ensure that the destroy task does not run |
| 434 | // before sync token is released. |
| 435 | ScheduleGpuTask( |
| 436 | base::BindOnce( |
| 437 | &SharedImageInterfaceInProcess::DestroySharedImageOnGpuThread, |
| 438 | base::Unretained(this), mailbox), |
| 439 | {sync_token}); |
| 440 | } |
| 441 | |
| 442 | void SharedImageInterfaceInProcess::DestroySharedImageOnGpuThread( |
| 443 | const Mailbox& mailbox) { |
| 444 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 445 | if (!MakeContextCurrent()) |
| 446 | return; |
| 447 | |
| 448 | if (!shared_image_factory_ || |
| 449 | !shared_image_factory_->DestroySharedImage(mailbox)) { |
| 450 | // Signal errors by losing the command buffer. |
| 451 | command_buffer_helper_->SetError(); |
| 452 | } |
| 453 | } |
| 454 | |
Vikas Soni | 08dfc58 | 2020-06-09 21:29:57 | [diff] [blame] | 455 | void SharedImageInterfaceInProcess::WaitSyncTokenOnGpuThread( |
| 456 | const SyncToken& sync_token) { |
| 457 | DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); |
| 458 | if (!MakeContextCurrent()) |
| 459 | return; |
| 460 | |
| 461 | mailbox_manager_->PushTextureUpdates(sync_token); |
| 462 | sync_point_client_state_->ReleaseFenceSync(sync_token.release_count()); |
| 463 | } |
| 464 | |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 465 | SyncToken SharedImageInterfaceInProcess::GenUnverifiedSyncToken() { |
| 466 | base::AutoLock lock(lock_); |
| 467 | return MakeSyncToken(next_fence_sync_release_ - 1); |
| 468 | } |
| 469 | |
| 470 | SyncToken SharedImageInterfaceInProcess::GenVerifiedSyncToken() { |
| 471 | base::AutoLock lock(lock_); |
| 472 | SyncToken sync_token = MakeSyncToken(next_fence_sync_release_ - 1); |
| 473 | sync_token.SetVerifyFlush(); |
| 474 | return sync_token; |
| 475 | } |
| 476 | |
Vikas Soni | 08dfc58 | 2020-06-09 21:29:57 | [diff] [blame] | 477 | void SharedImageInterfaceInProcess::WaitSyncToken(const SyncToken& sync_token) { |
| 478 | base::AutoLock lock(lock_); |
| 479 | |
| 480 | ScheduleGpuTask( |
| 481 | base::BindOnce(&SharedImageInterfaceInProcess::WaitSyncTokenOnGpuThread, |
| 482 | base::Unretained(this), |
| 483 | MakeSyncToken(next_fence_sync_release_++)), |
| 484 | {sync_token}); |
| 485 | } |
| 486 | |
Weiliang Chen | 7cf2b532 | 2020-01-23 02:04:17 | [diff] [blame] | 487 | void SharedImageInterfaceInProcess::Flush() { |
| 488 | // No need to flush in this implementation. |
| 489 | } |
| 490 | |
| 491 | scoped_refptr<gfx::NativePixmap> SharedImageInterfaceInProcess::GetNativePixmap( |
| 492 | const gpu::Mailbox& mailbox) { |
| 493 | DCHECK(shared_image_manager_->is_thread_safe()); |
| 494 | return shared_image_manager_->GetNativePixmap(mailbox); |
| 495 | } |
| 496 | |
| 497 | void SharedImageInterfaceInProcess::WrapTaskWithGpuUrl(base::OnceClosure task) { |
| 498 | if (command_buffer_helper_) { |
| 499 | command_buffer_helper_->WrapTaskWithGpuCheck(std::move(task)); |
| 500 | } else { |
| 501 | std::move(task).Run(); |
| 502 | } |
| 503 | } |
| 504 | |
| 505 | void SharedImageInterfaceInProcess::ScheduleGpuTask( |
| 506 | base::OnceClosure task, |
| 507 | std::vector<SyncToken> sync_token_fences) { |
| 508 | base::OnceClosure gpu_task = |
| 509 | base::BindOnce(&SharedImageInterfaceInProcess::WrapTaskWithGpuUrl, |
| 510 | base::Unretained(this), std::move(task)); |
| 511 | |
| 512 | task_sequence_->ScheduleTask(std::move(gpu_task), |
| 513 | std::move(sync_token_fences)); |
| 514 | } |
| 515 | |
| 516 | } // namespace gpu |