Commit 3c9db653 authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

vulkan: add branch prediction hints

Bug: None
Change-Id: I72116c939a055ad8458d9163d1279d21fd10cde3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2333315
Auto-Submit: Peng Huang <penghuang@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: default avatarVasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795518}
parent 1f9a9579
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
#include <utility> #include <utility>
#include "base/compiler_specific.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/threading/scoped_blocking_call.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "components/viz/common/gpu/vulkan_context_provider.h" #include "components/viz/common/gpu/vulkan_context_provider.h"
#include "gpu/command_buffer/service/memory_tracking.h" #include "gpu/command_buffer/service/memory_tracking.h"
...@@ -31,7 +33,7 @@ std::unique_ptr<SkiaOutputDeviceVulkan> SkiaOutputDeviceVulkan::Create( ...@@ -31,7 +33,7 @@ std::unique_ptr<SkiaOutputDeviceVulkan> SkiaOutputDeviceVulkan::Create(
auto output_device = std::make_unique<SkiaOutputDeviceVulkan>( auto output_device = std::make_unique<SkiaOutputDeviceVulkan>(
util::PassKey<SkiaOutputDeviceVulkan>(), context_provider, surface_handle, util::PassKey<SkiaOutputDeviceVulkan>(), context_provider, surface_handle,
memory_tracker, did_swap_buffer_complete_callback); memory_tracker, did_swap_buffer_complete_callback);
if (!output_device->Initialize()) if (UNLIKELY(!output_device->Initialize()))
return nullptr; return nullptr;
return output_device; return output_device;
} }
...@@ -48,22 +50,27 @@ SkiaOutputDeviceVulkan::SkiaOutputDeviceVulkan( ...@@ -48,22 +50,27 @@ SkiaOutputDeviceVulkan::SkiaOutputDeviceVulkan(
SkiaOutputDeviceVulkan::~SkiaOutputDeviceVulkan() { SkiaOutputDeviceVulkan::~SkiaOutputDeviceVulkan() {
DCHECK(!scoped_write_); DCHECK(!scoped_write_);
for (auto it = sk_surface_size_pairs_.begin();
it != sk_surface_size_pairs_.end(); ++it) { for (const auto& sk_surface_size_pair : sk_surface_size_pairs_) {
memory_type_tracker_->TrackMemFree(it->bytes_allocated); memory_type_tracker_->TrackMemFree(sk_surface_size_pair.bytes_allocated);
} }
sk_surface_size_pairs_.clear(); sk_surface_size_pairs_.clear();
if (!vulkan_surface_) if (UNLIKELY(!vulkan_surface_))
return; return;
vkQueueWaitIdle(context_provider_->GetDeviceQueue()->GetVulkanQueue()); {
base::ScopedBlockingCall scoped_blocking_call(
FROM_HERE, base::BlockingType::MAY_BLOCK);
vkQueueWaitIdle(context_provider_->GetDeviceQueue()->GetVulkanQueue());
}
vulkan_surface_->Destroy(); vulkan_surface_->Destroy();
} }
#if defined(OS_WIN) #if defined(OS_WIN)
gpu::SurfaceHandle SkiaOutputDeviceVulkan::GetChildSurfaceHandle() { gpu::SurfaceHandle SkiaOutputDeviceVulkan::GetChildSurfaceHandle() {
if (vulkan_surface_->accelerated_widget() != surface_handle_) if (LIKELY(vulkan_surface_->accelerated_widget() != surface_handle_))
return vulkan_surface_->accelerated_widget(); return vulkan_surface_->accelerated_widget();
return gpu::kNullSurfaceHandle; return gpu::kNullSurfaceHandle;
} }
...@@ -76,14 +83,14 @@ bool SkiaOutputDeviceVulkan::Reshape(const gfx::Size& size, ...@@ -76,14 +83,14 @@ bool SkiaOutputDeviceVulkan::Reshape(const gfx::Size& size,
gfx::OverlayTransform transform) { gfx::OverlayTransform transform) {
DCHECK(!scoped_write_); DCHECK(!scoped_write_);
if (!vulkan_surface_) if (UNLIKELY(!vulkan_surface_))
return false; return false;
return RecreateSwapChain(size, color_space.ToSkColorSpace(), transform); return RecreateSwapChain(size, color_space.ToSkColorSpace(), transform);
} }
void SkiaOutputDeviceVulkan::PreGrContextSubmit() { void SkiaOutputDeviceVulkan::PreGrContextSubmit() {
if (scoped_write_) { if (LIKELY(scoped_write_)) {
auto& sk_surface = auto& sk_surface =
sk_surface_size_pairs_[scoped_write_->image_index()].sk_surface; sk_surface_size_pairs_[scoped_write_->image_index()].sk_surface;
DCHECK(sk_surface); DCHECK(sk_surface);
...@@ -116,14 +123,15 @@ void SkiaOutputDeviceVulkan::PostSubBuffer( ...@@ -116,14 +123,15 @@ void SkiaOutputDeviceVulkan::PostSubBuffer(
StartSwapBuffers(std::move(feedback)); StartSwapBuffers(std::move(feedback));
if (is_new_swap_chain_ && rect == gfx::Rect(vulkan_surface_->image_size())) { if (UNLIKELY(is_new_swap_chain_ &&
rect == gfx::Rect(vulkan_surface_->image_size()))) {
is_new_swap_chain_ = false; is_new_swap_chain_ = false;
} }
if (!is_new_swap_chain_) { if (LIKELY(!is_new_swap_chain_)) {
auto image_index = vulkan_surface_->swap_chain()->current_image_index(); auto image_index = vulkan_surface_->swap_chain()->current_image_index();
for (size_t i = 0; i < damage_of_images_.size(); ++i) { for (size_t i = 0; i < damage_of_images_.size(); ++i) {
if (i == image_index) { if (UNLIKELY(i == image_index)) {
damage_of_images_[i] = gfx::Rect(); damage_of_images_[i] = gfx::Rect();
} else { } else {
damage_of_images_[i].Union(rect); damage_of_images_[i].Union(rect);
...@@ -131,7 +139,7 @@ void SkiaOutputDeviceVulkan::PostSubBuffer( ...@@ -131,7 +139,7 @@ void SkiaOutputDeviceVulkan::PostSubBuffer(
} }
} }
if (!rect.IsEmpty()) { if (LIKELY(!rect.IsEmpty())) {
// If the swapchain is new created, but rect doesn't cover the whole buffer, // If the swapchain is new created, but rect doesn't cover the whole buffer,
// we will still present it even it causes a artifact in this frame and // we will still present it even it causes a artifact in this frame and
// recovered when the next frame is presented. We do that because the old // recovered when the next frame is presented. We do that because the old
...@@ -154,18 +162,21 @@ SkSurface* SkiaOutputDeviceVulkan::BeginPaint( ...@@ -154,18 +162,21 @@ SkSurface* SkiaOutputDeviceVulkan::BeginPaint(
DCHECK(!scoped_write_); DCHECK(!scoped_write_);
scoped_write_.emplace(vulkan_surface_->swap_chain()); scoped_write_.emplace(vulkan_surface_->swap_chain());
if (!scoped_write_->success()) { if (UNLIKELY(!scoped_write_->success())) {
scoped_write_.reset(); scoped_write_.reset();
if (vulkan_surface_->swap_chain()->state() != VK_ERROR_SURFACE_LOST_KHR) if (UNLIKELY(vulkan_surface_->swap_chain()->state() !=
VK_ERROR_SURFACE_LOST_KHR))
return nullptr; return nullptr;
auto result = RecreateSwapChain(vulkan_surface_->image_size(), color_space_,
vulkan_surface_->transform());
// If vulkan surface is lost, we will try to recreate swap chain. // If vulkan surface is lost, we will try to recreate swap chain.
if (!RecreateSwapChain(vulkan_surface_->image_size(), color_space_, if (UNLIKELY(!result)) {
vulkan_surface_->transform())) {
LOG(DFATAL) << "Failed to recreate vulkan swap chain."; LOG(DFATAL) << "Failed to recreate vulkan swap chain.";
return nullptr; return nullptr;
} }
scoped_write_.emplace(vulkan_surface_->swap_chain()); scoped_write_.emplace(vulkan_surface_->swap_chain());
if (!scoped_write_->success()) { if (UNLIKELY(!scoped_write_->success())) {
scoped_write_.reset(); scoped_write_.reset();
return nullptr; return nullptr;
} }
...@@ -174,7 +185,7 @@ SkSurface* SkiaOutputDeviceVulkan::BeginPaint( ...@@ -174,7 +185,7 @@ SkSurface* SkiaOutputDeviceVulkan::BeginPaint(
auto& sk_surface = auto& sk_surface =
sk_surface_size_pairs_[scoped_write_->image_index()].sk_surface; sk_surface_size_pairs_[scoped_write_->image_index()].sk_surface;
if (!sk_surface) { if (UNLIKELY(!sk_surface)) {
SkSurfaceProps surface_props = SkSurfaceProps surface_props =
SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType); SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
const auto surface_format = vulkan_surface_->surface_format().format; const auto surface_format = vulkan_surface_->surface_format().format;
...@@ -213,15 +224,16 @@ SkSurface* SkiaOutputDeviceVulkan::BeginPaint( ...@@ -213,15 +224,16 @@ SkSurface* SkiaOutputDeviceVulkan::BeginPaint(
SkSurface::kFlushRead_BackendHandleAccess); SkSurface::kFlushRead_BackendHandleAccess);
backend.setVkImageLayout(scoped_write_->image_layout()); backend.setVkImageLayout(scoped_write_->image_layout());
} }
VkSemaphore vk_semaphore = scoped_write_->begin_semaphore();
if (vk_semaphore != VK_NULL_HANDLE) {
GrBackendSemaphore semaphore;
semaphore.initVulkan(vk_semaphore);
auto result =
sk_surface->wait(1, &semaphore, /*deleteSemaphoresAfterWait=*/false);
DCHECK(result);
}
VkSemaphore vk_semaphore = scoped_write_->begin_semaphore();
DCHECK(vk_semaphore != VK_NULL_HANDLE);
GrBackendSemaphore semaphore;
semaphore.initVulkan(vk_semaphore);
auto result =
sk_surface->wait(1, &semaphore, /*deleteSemaphoresAfterWait=*/false);
DCHECK(result);
DCHECK(scoped_write_->end_semaphore() != VK_NULL_HANDLE);
GrBackendSemaphore end_semaphore; GrBackendSemaphore end_semaphore;
end_semaphore.initVulkan(scoped_write_->end_semaphore()); end_semaphore.initVulkan(scoped_write_->end_semaphore());
end_semaphores->push_back(std::move(end_semaphore)); end_semaphores->push_back(std::move(end_semaphore));
...@@ -237,7 +249,7 @@ void SkiaOutputDeviceVulkan::EndPaint() { ...@@ -237,7 +249,7 @@ void SkiaOutputDeviceVulkan::EndPaint() {
auto backend = sk_surface->getBackendRenderTarget( auto backend = sk_surface->getBackendRenderTarget(
SkSurface::kFlushRead_BackendHandleAccess); SkSurface::kFlushRead_BackendHandleAccess);
GrVkImageInfo vk_image_info; GrVkImageInfo vk_image_info;
if (!backend.getVkImageInfo(&vk_image_info)) if (UNLIKELY(!backend.getVkImageInfo(&vk_image_info)))
NOTREACHED() << "Failed to get the image info."; NOTREACHED() << "Failed to get the image info.";
DCHECK_EQ(vk_image_info.fImageLayout, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); DCHECK_EQ(vk_image_info.fImageLayout, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
scoped_write_.reset(); scoped_write_.reset();
...@@ -259,12 +271,13 @@ bool SkiaOutputDeviceVulkan::Initialize() { ...@@ -259,12 +271,13 @@ bool SkiaOutputDeviceVulkan::Initialize() {
auto vulkan_surface = auto vulkan_surface =
context_provider_->GetVulkanImplementation()->CreateViewSurface( context_provider_->GetVulkanImplementation()->CreateViewSurface(
accelerated_widget); accelerated_widget);
if (!vulkan_surface) { if (UNLIKELY(!vulkan_surface)) {
LOG(ERROR) << "Failed to create vulkan surface."; LOG(ERROR) << "Failed to create vulkan surface.";
return false; return false;
} }
if (!vulkan_surface->Initialize(context_provider_->GetDeviceQueue(), auto result = vulkan_surface->Initialize(context_provider_->GetDeviceQueue(),
gpu::VulkanSurface::FORMAT_RGBA_32)) { gpu::VulkanSurface::FORMAT_RGBA_32);
if (UNLIKELY(!result)) {
LOG(ERROR) << "Failed to initialize vulkan surface."; LOG(ERROR) << "Failed to initialize vulkan surface.";
return false; return false;
} }
...@@ -304,11 +317,12 @@ bool SkiaOutputDeviceVulkan::RecreateSwapChain( ...@@ -304,11 +317,12 @@ bool SkiaOutputDeviceVulkan::RecreateSwapChain(
// Call vulkan_surface_->Reshape() will recreate vulkan swapchain if it is // Call vulkan_surface_->Reshape() will recreate vulkan swapchain if it is
// necessary. // necessary.
if (!vulkan_surface_->Reshape(size, transform)) if (UNLIKELY(!vulkan_surface_->Reshape(size, transform)))
return false; return false;
if (vulkan_surface_->swap_chain_generation() != generation || bool recreate = vulkan_surface_->swap_chain_generation() != generation ||
!SkColorSpace::Equals(color_space.get(), color_space_.get())) { !SkColorSpace::Equals(color_space.get(), color_space_.get());
if (LIKELY(recreate)) {
// swapchain is changed, we need recreate all cached sk surfaces. // swapchain is changed, we need recreate all cached sk surfaces.
for (const auto& sk_surface_size_pair : sk_surface_size_pairs_) { for (const auto& sk_surface_size_pair : sk_surface_size_pairs_) {
memory_type_tracker_->TrackMemFree(sk_surface_size_pair.bytes_allocated); memory_type_tracker_->TrackMemFree(sk_surface_size_pair.bytes_allocated);
...@@ -329,7 +343,7 @@ bool SkiaOutputDeviceVulkan::RecreateSwapChain( ...@@ -329,7 +343,7 @@ bool SkiaOutputDeviceVulkan::RecreateSwapChain(
void SkiaOutputDeviceVulkan::OnPostSubBufferFinished( void SkiaOutputDeviceVulkan::OnPostSubBufferFinished(
std::vector<ui::LatencyInfo> latency_info, std::vector<ui::LatencyInfo> latency_info,
gfx::SwapResult result) { gfx::SwapResult result) {
if (result == gfx::SwapResult::SWAP_ACK) { if (LIKELY(result == gfx::SwapResult::SWAP_ACK)) {
auto image_index = vulkan_surface_->swap_chain()->current_image_index(); auto image_index = vulkan_surface_->swap_chain()->current_image_index();
FinishSwapBuffers(gfx::SwapCompletionResult(result), FinishSwapBuffers(gfx::SwapCompletionResult(result),
vulkan_surface_->image_size(), std::move(latency_info), vulkan_surface_->image_size(), std::move(latency_info),
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "gpu/vulkan/vulkan_swap_chain.h" #include "gpu/vulkan/vulkan_swap_chain.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/task/task_traits.h" #include "base/task/task_traits.h"
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
...@@ -85,18 +86,26 @@ void VulkanSwapChain::Destroy() { ...@@ -85,18 +86,26 @@ void VulkanSwapChain::Destroy() {
WaitUntilPostSubBufferAsyncFinished(); WaitUntilPostSubBufferAsyncFinished();
VkDevice device = device_queue_->GetVulkanDevice(); if (UNLIKELY(!fence_and_semaphores_queue_.empty())) {
for (auto& fence_and_semaphores : fence_and_semaphores_queue_) { VkDevice device = device_queue_->GetVulkanDevice();
vkWaitForFences(device, 1, &fence_and_semaphores.fence, VK_TRUE, {
UINT64_MAX); // Make sure the last enqueued fence is passed, so we can release all
vkDestroyFence(device, fence_and_semaphores.fence, // other fences and semaphores safely.
nullptr /* pAllocator */); base::ScopedBlockingCall scoped_blocking_call(
vkDestroySemaphore(device, fence_and_semaphores.semaphores[0], FROM_HERE, base::BlockingType::MAY_BLOCK);
nullptr /* pAllocator */); vkWaitForFences(device, 1, &fence_and_semaphores_queue_.back().fence,
vkDestroySemaphore(device, fence_and_semaphores.semaphores[1], VK_TRUE, UINT64_MAX);
nullptr /* pAllocator */); }
for (auto& fence_and_semaphores : fence_and_semaphores_queue_) {
vkDestroyFence(device, fence_and_semaphores.fence,
nullptr /* pAllocator */);
vkDestroySemaphore(device, fence_and_semaphores.semaphores[0],
nullptr /* pAllocator */);
vkDestroySemaphore(device, fence_and_semaphores.semaphores[1],
nullptr /* pAllocator */);
}
fence_and_semaphores_queue_.clear();
} }
fence_and_semaphores_queue_.clear();
DCHECK(!is_writing_); DCHECK(!is_writing_);
DestroySwapImages(); DestroySwapImages();
...@@ -108,10 +117,10 @@ gfx::SwapResult VulkanSwapChain::PostSubBuffer(const gfx::Rect& rect) { ...@@ -108,10 +117,10 @@ gfx::SwapResult VulkanSwapChain::PostSubBuffer(const gfx::Rect& rect) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!has_pending_post_sub_buffer_); DCHECK(!has_pending_post_sub_buffer_);
if (!PresentBuffer(rect)) if (UNLIKELY(!PresentBuffer(rect)))
return gfx::SwapResult::SWAP_FAILED; return gfx::SwapResult::SWAP_FAILED;
if (!AcquireNextImage()) if (UNLIKELY(!AcquireNextImage()))
return gfx::SwapResult::SWAP_FAILED; return gfx::SwapResult::SWAP_FAILED;
return gfx::SwapResult::SWAP_ACK; return gfx::SwapResult::SWAP_ACK;
...@@ -124,7 +133,7 @@ void VulkanSwapChain::PostSubBufferAsync( ...@@ -124,7 +133,7 @@ void VulkanSwapChain::PostSubBufferAsync(
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!has_pending_post_sub_buffer_); DCHECK(!has_pending_post_sub_buffer_);
if (!PresentBuffer(rect)) { if (UNLIKELY(!PresentBuffer(rect))) {
task_runner_->PostTask( task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(std::move(callback), gfx::SwapResult::SWAP_FAILED)); base::BindOnce(std::move(callback), gfx::SwapResult::SWAP_FAILED));
...@@ -183,7 +192,7 @@ bool VulkanSwapChain::InitializeSwapChain( ...@@ -183,7 +192,7 @@ bool VulkanSwapChain::InitializeSwapChain(
.oldSwapchain = VK_NULL_HANDLE, .oldSwapchain = VK_NULL_HANDLE,
}; };
if (old_swap_chain) { if (LIKELY(old_swap_chain)) {
base::AutoLock auto_lock(old_swap_chain->lock_); base::AutoLock auto_lock(old_swap_chain->lock_);
old_swap_chain->WaitUntilPostSubBufferAsyncFinished(); old_swap_chain->WaitUntilPostSubBufferAsyncFinished();
swap_chain_create_info.oldSwapchain = old_swap_chain->swap_chain_; swap_chain_create_info.oldSwapchain = old_swap_chain->swap_chain_;
...@@ -199,13 +208,13 @@ bool VulkanSwapChain::InitializeSwapChain( ...@@ -199,13 +208,13 @@ bool VulkanSwapChain::InitializeSwapChain(
result = vkCreateSwapchainKHR(device, &swap_chain_create_info, nullptr, result = vkCreateSwapchainKHR(device, &swap_chain_create_info, nullptr,
&new_swap_chain); &new_swap_chain);
if (old_swap_chain) { if (LIKELY(old_swap_chain)) {
auto* fence_helper = device_queue_->GetFenceHelper(); auto* fence_helper = device_queue_->GetFenceHelper();
fence_helper->EnqueueVulkanObjectCleanupForSubmittedWork( fence_helper->EnqueueVulkanObjectCleanupForSubmittedWork(
std::move(old_swap_chain)); std::move(old_swap_chain));
} }
if (VK_SUCCESS != result) { if (UNLIKELY(VK_SUCCESS != result)) {
LOG(FATAL) << "vkCreateSwapchainKHR() failed: " << result; LOG(FATAL) << "vkCreateSwapchainKHR() failed: " << result;
return false; return false;
} }
...@@ -214,7 +223,7 @@ bool VulkanSwapChain::InitializeSwapChain( ...@@ -214,7 +223,7 @@ bool VulkanSwapChain::InitializeSwapChain(
size_ = gfx::Size(swap_chain_create_info.imageExtent.width, size_ = gfx::Size(swap_chain_create_info.imageExtent.width,
swap_chain_create_info.imageExtent.height); swap_chain_create_info.imageExtent.height);
if (!post_sub_buffer_task_runner_) { if (UNLIKELY(!post_sub_buffer_task_runner_)) {
post_sub_buffer_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner( post_sub_buffer_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
{base::TaskPriority::USER_BLOCKING, {base::TaskPriority::USER_BLOCKING,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()}); base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()});
...@@ -239,7 +248,7 @@ bool VulkanSwapChain::InitializeSwapImages( ...@@ -239,7 +248,7 @@ bool VulkanSwapChain::InitializeSwapImages(
uint32_t image_count = 0; uint32_t image_count = 0;
result = vkGetSwapchainImagesKHR(device, swap_chain_, &image_count, nullptr); result = vkGetSwapchainImagesKHR(device, swap_chain_, &image_count, nullptr);
if (VK_SUCCESS != result) { if (UNLIKELY(VK_SUCCESS != result)) {
LOG(FATAL) << "vkGetSwapchainImagesKHR(nullptr) failed: " << result; LOG(FATAL) << "vkGetSwapchainImagesKHR(nullptr) failed: " << result;
return false; return false;
} }
...@@ -247,7 +256,7 @@ bool VulkanSwapChain::InitializeSwapImages( ...@@ -247,7 +256,7 @@ bool VulkanSwapChain::InitializeSwapImages(
std::vector<VkImage> images(image_count); std::vector<VkImage> images(image_count);
result = result =
vkGetSwapchainImagesKHR(device, swap_chain_, &image_count, images.data()); vkGetSwapchainImagesKHR(device, swap_chain_, &image_count, images.data());
if (VK_SUCCESS != result) { if (UNLIKELY(VK_SUCCESS != result)) {
LOG(FATAL) << "vkGetSwapchainImagesKHR(images) failed: " << result; LOG(FATAL) << "vkGetSwapchainImagesKHR(images) failed: " << result;
return false; return false;
} }
...@@ -287,15 +296,15 @@ bool VulkanSwapChain::BeginWriteCurrentImage(VkImage* image, ...@@ -287,15 +296,15 @@ bool VulkanSwapChain::BeginWriteCurrentImage(VkImage* image,
DCHECK(end_semaphore); DCHECK(end_semaphore);
DCHECK(!is_writing_); DCHECK(!is_writing_);
if (state_ != VK_SUCCESS) if (UNLIKELY(state_ != VK_SUCCESS))
return false; return false;
if (!acquired_image_) if (UNLIKELY(!acquired_image_))
return false; return false;
auto& current_image_data = images_[*acquired_image_]; auto& current_image_data = images_[*acquired_image_];
if (!new_acquired_) { if (UNLIKELY(!new_acquired_)) {
// In this case, {Begin,End}WriteCurrentImage has been called, but // In this case, {Begin,End}WriteCurrentImage has been called, but
// PostSubBuffer() is not call, so |acquire_semaphore| has been wait on for // PostSubBuffer() is not call, so |acquire_semaphore| has been wait on for
// the previous write request, release it with FenceHelper. // the previous write request, release it with FenceHelper.
...@@ -306,7 +315,7 @@ bool VulkanSwapChain::BeginWriteCurrentImage(VkImage* image, ...@@ -306,7 +315,7 @@ bool VulkanSwapChain::BeginWriteCurrentImage(VkImage* image,
current_image_data.acquire_semaphore = current_image_data.present_semaphore; current_image_data.acquire_semaphore = current_image_data.present_semaphore;
current_image_data.present_semaphore = current_image_data.present_semaphore =
CreateSemaphore(device_queue_->GetVulkanDevice()); CreateSemaphore(device_queue_->GetVulkanDevice());
if (current_image_data.present_semaphore == VK_NULL_HANDLE) if (UNLIKELY(current_image_data.present_semaphore == VK_NULL_HANDLE))
return false; return false;
} }
...@@ -369,7 +378,7 @@ bool VulkanSwapChain::PresentBuffer(const gfx::Rect& rect) { ...@@ -369,7 +378,7 @@ bool VulkanSwapChain::PresentBuffer(const gfx::Rect& rect) {
VkQueue queue = device_queue_->GetVulkanQueue(); VkQueue queue = device_queue_->GetVulkanQueue();
auto result = vkQueuePresentKHR(queue, &present_info); auto result = vkQueuePresentKHR(queue, &present_info);
if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { if (UNLIKELY(result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)) {
LOG(DFATAL) << "vkQueuePresentKHR() failed: " << result; LOG(DFATAL) << "vkQueuePresentKHR() failed: " << result;
state_ = result; state_ = result;
return false; return false;
...@@ -409,7 +418,7 @@ bool VulkanSwapChain::AcquireNextImage() { ...@@ -409,7 +418,7 @@ bool VulkanSwapChain::AcquireNextImage() {
// TODO(penghuang): make VulkanDeviceQueue threadsafe. // TODO(penghuang): make VulkanDeviceQueue threadsafe.
VkDevice device = device_queue_->GetVulkanDevice(); VkDevice device = device_queue_->GetVulkanDevice();
auto fence_and_semaphores = GetOrCreateFenceAndSemaphores(); auto fence_and_semaphores = GetOrCreateFenceAndSemaphores();
if (fence_and_semaphores.fence == VK_NULL_HANDLE) { if (UNLIKELY(fence_and_semaphores.fence == VK_NULL_HANDLE)) {
DCHECK(fence_and_semaphores.semaphores[0] == VK_NULL_HANDLE); DCHECK(fence_and_semaphores.semaphores[0] == VK_NULL_HANDLE);
DCHECK(fence_and_semaphores.semaphores[1] == VK_NULL_HANDLE); DCHECK(fence_and_semaphores.semaphores[1] == VK_NULL_HANDLE);
return false; return false;
...@@ -424,12 +433,12 @@ bool VulkanSwapChain::AcquireNextImage() { ...@@ -424,12 +433,12 @@ bool VulkanSwapChain::AcquireNextImage() {
uint32_t next_image; uint32_t next_image;
auto result = ({ auto result = ({
base::ScopedBlockingCall scoped_blocking_call( base::ScopedBlockingCall scoped_blocking_call(
FROM_HERE, base::BlockingType::WILL_BLOCK); FROM_HERE, base::BlockingType::MAY_BLOCK);
vkAcquireNextImageKHR(device, swap_chain_, kTimeout, acquire_semaphore, vkAcquireNextImageKHR(device, swap_chain_, kTimeout, acquire_semaphore,
acquire_fence, &next_image); acquire_fence, &next_image);
}); });
if (result == VK_TIMEOUT) { if (UNLIKELY(result == VK_TIMEOUT)) {
LOG(ERROR) << "vkAcquireNextImageKHR() hangs."; LOG(ERROR) << "vkAcquireNextImageKHR() hangs.";
vkDestroySemaphore(device, acquire_semaphore, nullptr); vkDestroySemaphore(device, acquire_semaphore, nullptr);
vkDestroySemaphore(device, present_semaphore, nullptr); vkDestroySemaphore(device, present_semaphore, nullptr);
...@@ -438,7 +447,7 @@ bool VulkanSwapChain::AcquireNextImage() { ...@@ -438,7 +447,7 @@ bool VulkanSwapChain::AcquireNextImage() {
return false; return false;
} }
if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { if (UNLIKELY(result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)) {
LOG(DFATAL) << "vkAcquireNextImageKHR() failed: " << result; LOG(DFATAL) << "vkAcquireNextImageKHR() failed: " << result;
vkDestroySemaphore(device, acquire_semaphore, nullptr); vkDestroySemaphore(device, acquire_semaphore, nullptr);
vkDestroySemaphore(device, present_semaphore, nullptr); vkDestroySemaphore(device, present_semaphore, nullptr);
...@@ -481,13 +490,13 @@ VulkanSwapChain::GetOrCreateFenceAndSemaphores() { ...@@ -481,13 +490,13 @@ VulkanSwapChain::GetOrCreateFenceAndSemaphores() {
VkDevice device = device_queue_->GetVulkanDevice(); VkDevice device = device_queue_->GetVulkanDevice();
FenceAndSemaphores fence_and_semaphores; FenceAndSemaphores fence_and_semaphores;
do { do {
if (!fence_and_semaphores_queue_.empty()) { if (LIKELY(!fence_and_semaphores_queue_.empty())) {
fence_and_semaphores = fence_and_semaphores_queue_.front(); fence_and_semaphores = fence_and_semaphores_queue_.front();
auto result = vkGetFenceStatus(device, fence_and_semaphores.fence); auto result = vkGetFenceStatus(device, fence_and_semaphores.fence);
if (result == VK_SUCCESS) { if (LIKELY(result == VK_SUCCESS)) {
fence_and_semaphores_queue_.pop_front(); fence_and_semaphores_queue_.pop_front();
vkResetFences(device, 1, &fence_and_semaphores.fence); vkResetFences(device, 1, &fence_and_semaphores.fence);
} else if (result == VK_NOT_READY) { } else if (LIKELY(result == VK_NOT_READY)) {
// If fence is not passed, new fence and semaphores will be created. // If fence is not passed, new fence and semaphores will be created.
fence_and_semaphores = {}; fence_and_semaphores = {};
} else { } else {
...@@ -497,7 +506,7 @@ VulkanSwapChain::GetOrCreateFenceAndSemaphores() { ...@@ -497,7 +506,7 @@ VulkanSwapChain::GetOrCreateFenceAndSemaphores() {
} }
} }
if (fence_and_semaphores.fence == VK_NULL_HANDLE) { if (UNLIKELY(fence_and_semaphores.fence == VK_NULL_HANDLE)) {
constexpr VkFenceCreateInfo fence_create_info = { constexpr VkFenceCreateInfo fence_create_info = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
}; };
...@@ -510,13 +519,13 @@ VulkanSwapChain::GetOrCreateFenceAndSemaphores() { ...@@ -510,13 +519,13 @@ VulkanSwapChain::GetOrCreateFenceAndSemaphores() {
} }
} }
if (fence_and_semaphores.semaphores[0] == VK_NULL_HANDLE) if (UNLIKELY(fence_and_semaphores.semaphores[0] == VK_NULL_HANDLE))
fence_and_semaphores.semaphores[0] = CreateSemaphore(device); fence_and_semaphores.semaphores[0] = CreateSemaphore(device);
if (fence_and_semaphores.semaphores[1] == VK_NULL_HANDLE) if (UNLIKELY(fence_and_semaphores.semaphores[1] == VK_NULL_HANDLE))
fence_and_semaphores.semaphores[1] = CreateSemaphore(device); fence_and_semaphores.semaphores[1] = CreateSemaphore(device);
if (fence_and_semaphores.semaphores[0] == VK_NULL_HANDLE || if (UNLIKELY(fence_and_semaphores.semaphores[0] == VK_NULL_HANDLE ||
fence_and_semaphores.semaphores[1] == VK_NULL_HANDLE) { fence_and_semaphores.semaphores[1] == VK_NULL_HANDLE)) {
break; break;
} }
...@@ -543,7 +552,7 @@ VulkanSwapChain::ScopedWrite::ScopedWrite(VulkanSwapChain* swap_chain) ...@@ -543,7 +552,7 @@ VulkanSwapChain::ScopedWrite::ScopedWrite(VulkanSwapChain* swap_chain)
success_ = swap_chain_->BeginWriteCurrentImage( success_ = swap_chain_->BeginWriteCurrentImage(
&image_, &image_index_, &image_layout_, &begin_semaphore_, &image_, &image_index_, &image_layout_, &begin_semaphore_,
&end_semaphore_); &end_semaphore_);
if (success_) { if (LIKELY(success_)) {
DCHECK(begin_semaphore_ != VK_NULL_HANDLE); DCHECK(begin_semaphore_ != VK_NULL_HANDLE);
DCHECK(end_semaphore_ != VK_NULL_HANDLE); DCHECK(end_semaphore_ != VK_NULL_HANDLE);
} else { } else {
...@@ -553,7 +562,7 @@ VulkanSwapChain::ScopedWrite::ScopedWrite(VulkanSwapChain* swap_chain) ...@@ -553,7 +562,7 @@ VulkanSwapChain::ScopedWrite::ScopedWrite(VulkanSwapChain* swap_chain)
} }
VulkanSwapChain::ScopedWrite::~ScopedWrite() { VulkanSwapChain::ScopedWrite::~ScopedWrite() {
if (success_) { if (LIKELY(success_)) {
DCHECK(begin_semaphore_ != VK_NULL_HANDLE); DCHECK(begin_semaphore_ != VK_NULL_HANDLE);
DCHECK(end_semaphore_ != VK_NULL_HANDLE); DCHECK(end_semaphore_ != VK_NULL_HANDLE);
swap_chain_->EndWriteCurrentImage(); swap_chain_->EndWriteCurrentImage();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment