1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gpu/command_buffer/service/external_semaphore_pool.h"
#include "build/build_config.h"
#include "components/viz/common/gpu/vulkan_context_provider.h"
#include "gpu/command_buffer/service/shared_context_state.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_fence_helper.h"
#include "gpu/vulkan/vulkan_implementation.h"
#include "ui/gl/gl_context.h"
namespace gpu {
namespace {
#if BUILDFLAG(IS_FUCHSIA)
// On Fuchsia semaphores are passed to scenic as zx::event. Scenic doesn't reset
// them after waiting, so they would have to be reset explicitly to be reused.
// OTOH new semaphores are cheap, so reuse doesn't provide significant benefits.
constexpr size_t kMaxSemaphoresInPool = 0;
#else
constexpr size_t kMaxSemaphoresInPool = 16;
#endif
} // namespace
ExternalSemaphorePool::ExternalSemaphorePool(
SharedContextState* shared_context_state)
: shared_context_state_(shared_context_state) {}
ExternalSemaphorePool::~ExternalSemaphorePool() = default;
ExternalSemaphore ExternalSemaphorePool::GetOrCreateSemaphore() {
if (!semaphores_.empty()) {
auto semaphore = std::move(semaphores_.front());
semaphores_.pop_front();
return semaphore;
}
return ExternalSemaphore::Create(
shared_context_state_->vk_context_provider());
}
void ExternalSemaphorePool::ReturnSemaphore(ExternalSemaphore semaphore) {
DCHECK(semaphore);
if (semaphores_.size() < kMaxSemaphoresInPool)
semaphores_.push_back(std::move(semaphore));
}
void ExternalSemaphorePool::ReturnSemaphores(
std::vector<ExternalSemaphore> semaphores) {
DCHECK_LE(semaphores_.size(), kMaxSemaphoresInPool);
while (!semaphores.empty() && semaphores_.size() < kMaxSemaphoresInPool) {
auto& semaphore = semaphores.back();
DCHECK(semaphore);
semaphores_.emplace_back(std::move(semaphore));
semaphores.pop_back();
}
if (semaphores.empty())
return;
// Need a GL context current for releasing semaphores.
if (!gl::GLContext::GetCurrent())
shared_context_state_->MakeCurrent(/*surface=*/nullptr, /*needs_gl=*/true);
}
void ExternalSemaphorePool::ReturnSemaphoresWithFenceHelper(
std::vector<ExternalSemaphore> semaphores) {
#if DCHECK_IS_ON()
for (auto& semaphore : semaphores)
DCHECK(semaphore);
#endif
if (semaphores.empty())
return;
auto* fence_helper = shared_context_state_->vk_context_provider()
->GetDeviceQueue()
->GetFenceHelper();
fence_helper->EnqueueCleanupTaskForSubmittedWork(base::BindOnce(
[](base::WeakPtr<ExternalSemaphorePool> pool,
std::vector<ExternalSemaphore> semaphores,
VulkanDeviceQueue* device_queue, bool device_lost) {
if (pool)
pool->ReturnSemaphores(std::move(semaphores));
},
weak_ptr_factory_.GetWeakPtr(), std::move(semaphores)));
}
} // namespace gpu
|