Commit 36b7dd54 authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

vulkan: add ExternalSemaphore for reusing external semaphore

This CL doesn't reuse the external semaphores, it just adds a new class
ExternalSemaphore which will be reused in follow-up CLs.

Bug: 1004772,1004774
Change-Id: I28930c3accdd3e004db058e32ff688630c66a20c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2308873Reviewed-by: default avatarVasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790536}
parent 16e0ce78
...@@ -338,6 +338,8 @@ target(link_target_type, "gles2_sources") { ...@@ -338,6 +338,8 @@ target(link_target_type, "gles2_sources") {
if (is_linux || is_fuchsia || is_android || is_win) { if (is_linux || is_fuchsia || is_android || is_win) {
sources += [ sources += [
"external_semaphore.cc",
"external_semaphore.h",
"external_vk_image_backing.cc", "external_vk_image_backing.cc",
"external_vk_image_backing.h", "external_vk_image_backing.h",
"external_vk_image_factory.cc", "external_vk_image_factory.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// 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.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "components/viz/common/gpu/vulkan_context_provider.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_implementation.h"
#include "gpu/vulkan/vulkan_util.h"
#include "ui/gl/gl_bindings.h"
#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586
#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587
#define GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE 0x93AE
#define GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE 0x93AF
namespace gpu {
namespace {
GLuint ImportSemaphoreHandleToGLSemaphore(SemaphoreHandle handle) {
if (!handle.is_valid())
return 0;
RecordImportingVKSemaphoreIntoGL();
base::ScopedClosureRunner uma_runner(base::BindOnce(
[](base::Time time) {
UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
"GPU.Vulkan.ImportVkSemaphoreIntoGL", base::Time::Now() - time,
base::TimeDelta::FromMicroseconds(1),
base::TimeDelta::FromMicroseconds(200), 50);
},
base::Time::Now()));
#if defined(OS_LINUX) || defined(OS_ANDROID)
if (handle.vk_handle_type() !=
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) {
DLOG(ERROR) << "Importing semaphore handle of unexpected type:"
<< handle.vk_handle_type();
return 0;
}
base::ScopedFD fd = handle.TakeHandle();
gl::GLApi* api = gl::g_current_gl_context;
GLuint gl_semaphore;
api->glGenSemaphoresEXTFn(1, &gl_semaphore);
api->glImportSemaphoreFdEXTFn(gl_semaphore, GL_HANDLE_TYPE_OPAQUE_FD_EXT,
fd.release());
return gl_semaphore;
#elif defined(OS_WIN)
if (handle.vk_handle_type() !=
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT) {
DLOG(ERROR) << "Importing semaphore handle of unexpected type:"
<< handle.vk_handle_type();
return 0;
}
auto win32_handle = handle.TakeHandle();
gl::GLApi* api = gl::g_current_gl_context;
GLuint gl_semaphore;
api->glGenSemaphoresEXTFn(1, &gl_semaphore);
api->glImportSemaphoreWin32HandleEXTFn(
gl_semaphore, GL_HANDLE_TYPE_OPAQUE_WIN32_EXT, win32_handle.Take());
return gl_semaphore;
#elif defined(OS_FUCHSIA)
if (handle.vk_handle_type() !=
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA) {
DLOG(ERROR) << "Importing semaphore handle of unexpected type:"
<< handle.vk_handle_type();
return 0;
}
zx::event event = handle.TakeHandle();
gl::GLApi* api = gl::g_current_gl_context;
GLuint gl_semaphore;
api->glGenSemaphoresEXTFn(1, &gl_semaphore);
api->glImportSemaphoreZirconHandleANGLEFn(
gl_semaphore, GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE, event.release());
return gl_semaphore;
#else
#error Unsupported OS
#endif
}
} // namespace
// static
ExternalSemaphore ExternalSemaphore::Create(
viz::VulkanContextProvider* context_provider) {
auto* implementation = context_provider->GetVulkanImplementation();
VkDevice device = context_provider->GetDeviceQueue()->GetVulkanDevice();
VkSemaphore semaphore = implementation->CreateExternalSemaphore(device);
if (semaphore == VK_NULL_HANDLE)
return {};
auto handle = implementation->GetSemaphoreHandle(device, semaphore);
if (!handle.is_valid()) {
vkDestroySemaphore(device, semaphore, /*pAllocator=*/nullptr);
return {};
}
return ExternalSemaphore(util::PassKey<ExternalSemaphore>(), context_provider,
semaphore, std::move(handle));
}
// static
ExternalSemaphore ExternalSemaphore::CreateFromHandle(
viz::VulkanContextProvider* context_provider,
SemaphoreHandle handle) {
if (!handle.is_valid())
return {};
auto* implementation = context_provider->GetVulkanImplementation();
VkDevice device = context_provider->GetDeviceQueue()->GetVulkanDevice();
VkSemaphore semaphore =
implementation->ImportSemaphoreHandle(device, handle.Duplicate());
if (semaphore == VK_NULL_HANDLE)
return {};
return ExternalSemaphore(util::PassKey<ExternalSemaphore>(), context_provider,
semaphore, std::move(handle));
}
ExternalSemaphore::ExternalSemaphore() = default;
ExternalSemaphore::ExternalSemaphore(ExternalSemaphore&& other) {
*this = std::move(other);
}
ExternalSemaphore::ExternalSemaphore(
util::PassKey<ExternalSemaphore>,
viz::VulkanContextProvider* context_provider,
VkSemaphore semaphore,
SemaphoreHandle handle)
: context_provider_(context_provider),
semaphore_(semaphore),
handle_(std::move(handle)) {}
ExternalSemaphore::~ExternalSemaphore() {
Reset();
}
ExternalSemaphore& ExternalSemaphore::operator=(ExternalSemaphore&& other) {
Reset();
std::swap(context_provider_, other.context_provider_);
std::swap(semaphore_, other.semaphore_);
std::swap(handle_, other.handle_);
std::swap(gl_semaphore_, other.gl_semaphore_);
return *this;
}
void ExternalSemaphore::Reset() {
if (semaphore_ != VK_NULL_HANDLE) {
DCHECK(context_provider_);
VkDevice device = context_provider_->GetDeviceQueue()->GetVulkanDevice();
vkDestroySemaphore(device, semaphore_, /*pAllocator=*/nullptr);
context_provider_ = nullptr;
semaphore_ = VK_NULL_HANDLE;
}
if (gl_semaphore_ != 0) {
if (gl::GLApi* api = gl::g_current_gl_context)
api->glDeleteSemaphoresEXTFn(1, &gl_semaphore_);
gl_semaphore_ = 0;
}
handle_ = {};
}
unsigned int ExternalSemaphore::GetGLSemaphore() {
DCHECK(handle_.is_valid());
if (gl_semaphore_ == 0) {
gl_semaphore_ = ImportSemaphoreHandleToGLSemaphore(handle_.Duplicate());
}
return gl_semaphore_;
}
unsigned int ExternalSemaphore::TakeGLSemaphore() {
auto gl_semaphore = GetGLSemaphore();
gl_semaphore_ = 0;
return gl_semaphore;
}
VkSemaphore ExternalSemaphore::GetVkSemaphore() {
DCHECK(handle_.is_valid());
if (semaphore_ == VK_NULL_HANDLE) {
auto* implementation = context_provider_->GetVulkanImplementation();
VkDevice device = context_provider_->GetDeviceQueue()->GetVulkanDevice();
semaphore_ =
implementation->ImportSemaphoreHandle(device, handle_.Duplicate());
}
return semaphore_;
}
VkSemaphore ExternalSemaphore::TakeVkSemaphore() {
VkSemaphore semaphore = GetVkSemaphore();
semaphore_ = VK_NULL_HANDLE;
return semaphore;
}
} // namespace gpu
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_SEMAPHORE_H_
#define GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_SEMAPHORE_H_
#include <vulkan/vulkan.h>
#include "base/util/type_safety/pass_key.h"
#include "gpu/vulkan/semaphore_handle.h"
namespace viz {
class VulkanContextProvider;
}
namespace gpu {
class ExternalSemaphore {
public:
static ExternalSemaphore Create(viz::VulkanContextProvider* context_provider);
static ExternalSemaphore CreateFromHandle(
viz::VulkanContextProvider* context_provider,
SemaphoreHandle handle);
ExternalSemaphore();
ExternalSemaphore(ExternalSemaphore&& other);
ExternalSemaphore(util::PassKey<ExternalSemaphore>,
viz::VulkanContextProvider* context_provider,
VkSemaphore semaphore,
SemaphoreHandle handle);
~ExternalSemaphore();
ExternalSemaphore& operator=(ExternalSemaphore&& other);
ExternalSemaphore(const ExternalSemaphore&) = delete;
ExternalSemaphore& operator=(const ExternalSemaphore&) = delete;
explicit operator bool() const { return is_valid(); }
void Reset();
// Take the GL semaphore. The ownership is transferred to caller. The caller
// is responsible for releasing it.
unsigned int TakeGLSemaphore();
// Get a VkSemaphore. The ownership is not transferred to caller.
VkSemaphore GetVkSemaphore();
// Take the VkSemaphore. The ownership is transferred to caller. The caller is
// responsible for releasing it.
VkSemaphore TakeVkSemaphore();
bool is_valid() const { return context_provider_ && handle_.is_valid(); }
SemaphoreHandle handle() { return handle_.Duplicate(); }
private:
// GL semaphore cannot be shared between passthrough GL contexts,
// since gl contexts are not created with the same global shared group with
// passthrough. So we cannot reuse GL semaphores safely.
// TODO(penghuang): share GL semaphore across GL contexts and reuse
// GL semaphores.
unsigned int GetGLSemaphore();
viz::VulkanContextProvider* context_provider_ = nullptr;
VkSemaphore semaphore_ = VK_NULL_HANDLE;
SemaphoreHandle handle_;
unsigned int gl_semaphore_ = 0;
};
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_SEMAPHORE_H_
\ No newline at end of file
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#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/common/shared_image_usage.h" #include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/external_semaphore.h"
#include "gpu/command_buffer/service/shared_context_state.h" #include "gpu/command_buffer/service/shared_context_state.h"
#include "gpu/command_buffer/service/shared_image_backing.h" #include "gpu/command_buffer/service/shared_image_backing.h"
#include "gpu/command_buffer/service/shared_memory_region_wrapper.h" #include "gpu/command_buffer/service/shared_memory_region_wrapper.h"
...@@ -83,20 +84,17 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking { ...@@ -83,20 +84,17 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking {
const { const {
return texture_passthrough_; return texture_passthrough_;
} }
viz::VulkanContextProvider* context_provider() const {
return context_state()->vk_context_provider();
}
VulkanImplementation* vulkan_implementation() const { VulkanImplementation* vulkan_implementation() const {
return context_state()->vk_context_provider()->GetVulkanImplementation(); return context_provider()->GetVulkanImplementation();
} }
VulkanFenceHelper* fence_helper() const { VulkanFenceHelper* fence_helper() const {
return context_state() return context_provider()->GetDeviceQueue()->GetFenceHelper();
->vk_context_provider()
->GetDeviceQueue()
->GetFenceHelper();
} }
VkDevice device() const { VkDevice device() const {
return context_state() return context_provider()->GetDeviceQueue()->GetVulkanDevice();
->vk_context_provider()
->GetDeviceQueue()
->GetVulkanDevice();
} }
bool use_separate_gl_texture() const { return use_separate_gl_texture_; } bool use_separate_gl_texture() const { return use_separate_gl_texture_; }
bool need_synchronization() const { bool need_synchronization() const {
...@@ -116,13 +114,15 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking { ...@@ -116,13 +114,15 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking {
// currently any other conflict access in progress. Otherwise, returns true // currently any other conflict access in progress. Otherwise, returns true
// and semaphore handles which will be waited on before accessing. // and semaphore handles which will be waited on before accessing.
bool BeginAccess(bool readonly, bool BeginAccess(bool readonly,
std::vector<SemaphoreHandle>* semaphore_handles, std::vector<ExternalSemaphore>* external_semaphores,
bool is_gl); bool is_gl);
// Notifies the backing that an access has ended. The representation must // Notifies the backing that an access has ended. The representation must
// provide a semaphore handle that has been signaled at the end of the write // provide a semaphore handle that has been signaled at the end of the write
// access. // access.
void EndAccess(bool readonly, SemaphoreHandle semaphore_handle, bool is_gl); void EndAccess(bool readonly,
ExternalSemaphore external_semaphore,
bool is_gl);
// SharedImageBacking implementation. // SharedImageBacking implementation.
void Update(std::unique_ptr<gfx::GpuFence> in_fence) override; void Update(std::unique_ptr<gfx::GpuFence> in_fence) override;
...@@ -143,8 +143,8 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking { ...@@ -143,8 +143,8 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking {
void UpdateContent(uint32_t content_flags); void UpdateContent(uint32_t content_flags);
bool BeginAccessInternal(bool readonly, bool BeginAccessInternal(bool readonly,
std::vector<SemaphoreHandle>* semaphore_handles); std::vector<ExternalSemaphore>* external_semaphores);
void EndAccessInternal(bool readonly, SemaphoreHandle semaphore_handle); void EndAccessInternal(bool readonly, ExternalSemaphore external_semaphore);
// SharedImageBacking implementation. // SharedImageBacking implementation.
std::unique_ptr<SharedImageRepresentationDawn> ProduceDawn( std::unique_ptr<SharedImageRepresentationDawn> ProduceDawn(
...@@ -191,8 +191,8 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking { ...@@ -191,8 +191,8 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking {
VulkanCommandPool* const command_pool_; VulkanCommandPool* const command_pool_;
const bool use_separate_gl_texture_; const bool use_separate_gl_texture_;
SemaphoreHandle write_semaphore_handle_; ExternalSemaphore write_semaphore_;
std::vector<SemaphoreHandle> read_semaphore_handles_; std::vector<ExternalSemaphore> read_semaphores_;
bool is_write_in_progress_ = false; bool is_write_in_progress_ = false;
uint32_t reads_in_progress_ = 0; uint32_t reads_in_progress_ = 0;
......
...@@ -46,9 +46,10 @@ ExternalVkImageDawnRepresentation::~ExternalVkImageDawnRepresentation() { ...@@ -46,9 +46,10 @@ ExternalVkImageDawnRepresentation::~ExternalVkImageDawnRepresentation() {
WGPUTexture ExternalVkImageDawnRepresentation::BeginAccess( WGPUTexture ExternalVkImageDawnRepresentation::BeginAccess(
WGPUTextureUsage usage) { WGPUTextureUsage usage) {
std::vector<SemaphoreHandle> handles; std::vector<ExternalSemaphore> external_semaphores;
if (!backing_impl()->BeginAccess(false, &handles, false /* is_gl */)) { if (!backing_impl()->BeginAccess(false, &external_semaphores,
false /* is_gl */)) {
return nullptr; return nullptr;
} }
...@@ -72,9 +73,9 @@ WGPUTexture ExternalVkImageDawnRepresentation::BeginAccess( ...@@ -72,9 +73,9 @@ WGPUTexture ExternalVkImageDawnRepresentation::BeginAccess(
// TODO(http://crbug.com/dawn/200): We may not be obeying all of the rules // TODO(http://crbug.com/dawn/200): We may not be obeying all of the rules
// specified by Vulkan for external queue transfer barriers. Investigate this. // specified by Vulkan for external queue transfer barriers. Investigate this.
// Take ownership of file descriptors and transfer to dawn for (auto& external_semaphore : external_semaphores) {
for (SemaphoreHandle& handle : handles) { descriptor.waitFDs.push_back(
descriptor.waitFDs.push_back(handle.TakeHandle().release()); external_semaphore.handle().TakeHandle().release());
} }
texture_ = dawn_native::vulkan::WrapVulkanImage(device_, &descriptor); texture_ = dawn_native::vulkan::WrapVulkanImage(device_, &descriptor);
...@@ -102,11 +103,12 @@ void ExternalVkImageDawnRepresentation::EndAccess() { ...@@ -102,11 +103,12 @@ void ExternalVkImageDawnRepresentation::EndAccess() {
} }
// Wrap file descriptor in a handle // Wrap file descriptor in a handle
SemaphoreHandle signal_semaphore( SemaphoreHandle handle(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
base::ScopedFD(signal_semaphore_fd)); base::ScopedFD(signal_semaphore_fd));
backing_impl()->EndAccess(false, std::move(signal_semaphore), backing_impl()->EndAccess(false,
ExternalSemaphore::CreateFromHandle(
context_provider(), std::move(handle)),
false /* is_gl */); false /* is_gl */);
// Destroy the texture, signaling the semaphore in dawn // Destroy the texture, signaling the semaphore in dawn
......
...@@ -35,9 +35,12 @@ class ExternalVkImageDawnRepresentation : public SharedImageRepresentationDawn { ...@@ -35,9 +35,12 @@ class ExternalVkImageDawnRepresentation : public SharedImageRepresentationDawn {
// created and pass a pointer to them around? // created and pass a pointer to them around?
const DawnProcTable dawn_procs_; const DawnProcTable dawn_procs_;
ExternalVkImageBacking* backing_impl() { ExternalVkImageBacking* backing_impl() const {
return static_cast<ExternalVkImageBacking*>(backing()); return static_cast<ExternalVkImageBacking*>(backing());
} }
viz::VulkanContextProvider* context_provider() const {
return backing_impl()->context_provider();
}
DISALLOW_COPY_AND_ASSIGN(ExternalVkImageDawnRepresentation); DISALLOW_COPY_AND_ASSIGN(ExternalVkImageDawnRepresentation);
}; };
......
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_GL_REPRESENTATION_H_ #ifndef GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_GL_REPRESENTATION_H_
#define GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_GL_REPRESENTATION_H_ #define GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_GL_REPRESENTATION_H_
#include <memory> #include "gpu/command_buffer/service/external_semaphore.h"
#include "gpu/command_buffer/service/external_vk_image_backing.h" #include "gpu/command_buffer/service/external_vk_image_backing.h"
#include "gpu/command_buffer/service/shared_image_representation.h" #include "gpu/command_buffer/service/shared_image_representation.h"
...@@ -17,6 +16,14 @@ namespace gpu { ...@@ -17,6 +16,14 @@ namespace gpu {
// ExternalVkImageGLPassthroughRepresentation. // ExternalVkImageGLPassthroughRepresentation.
class ExternalVkImageGLRepresentationShared { class ExternalVkImageGLRepresentationShared {
public: public:
static void AcquireTexture(ExternalSemaphore* semaphore,
GLuint texture_id,
VkImageLayout src_layout);
static ExternalSemaphore ReleaseTexture(
viz::VulkanContextProvider* context_provider,
GLuint texture_id,
VkImageLayout dst_layout);
ExternalVkImageGLRepresentationShared(SharedImageBacking* backing, ExternalVkImageGLRepresentationShared(SharedImageBacking* backing,
GLuint texture_service_id); GLuint texture_service_id);
~ExternalVkImageGLRepresentationShared() = default; ~ExternalVkImageGLRepresentationShared() = default;
...@@ -24,39 +31,15 @@ class ExternalVkImageGLRepresentationShared { ...@@ -24,39 +31,15 @@ class ExternalVkImageGLRepresentationShared {
bool BeginAccess(GLenum mode); bool BeginAccess(GLenum mode);
void EndAccess(); void EndAccess();
ExternalVkImageBacking* backing_impl() { return backing_; } ExternalVkImageBacking* backing_impl() const { return backing_; }
private: private:
gpu::VulkanImplementation* vk_implementation() { viz::VulkanContextProvider* context_provider() const {
return backing_impl() return backing_impl()->context_provider();
->context_state()
->vk_context_provider()
->GetVulkanImplementation();
}
VkDevice vk_device() {
return backing_impl()
->context_state()
->vk_context_provider()
->GetDeviceQueue()
->GetVulkanDevice();
} }
VkQueue vk_queue() { ExternalVkImageBacking* const backing_;
return backing_impl() const GLuint texture_service_id_;
->context_state()
->vk_context_provider()
->GetDeviceQueue()
->GetVulkanQueue();
}
gl::GLApi* api() { return gl::g_current_gl_context; }
GLuint ImportVkSemaphoreIntoGL(SemaphoreHandle handle);
void DestroyEndAccessSemaphore();
ExternalVkImageBacking* backing_;
GLuint texture_service_id_ = 0;
GLenum current_access_mode_ = 0; GLenum current_access_mode_ = 0;
DISALLOW_COPY_AND_ASSIGN(ExternalVkImageGLRepresentationShared); DISALLOW_COPY_AND_ASSIGN(ExternalVkImageGLRepresentationShared);
...@@ -78,7 +61,7 @@ class ExternalVkImageGLRepresentation ...@@ -78,7 +61,7 @@ class ExternalVkImageGLRepresentation
void EndAccess() override; void EndAccess() override;
private: private:
gles2::Texture* texture_ = nullptr; gles2::Texture* const texture_;
ExternalVkImageGLRepresentationShared representation_shared_; ExternalVkImageGLRepresentationShared representation_shared_;
DISALLOW_COPY_AND_ASSIGN(ExternalVkImageGLRepresentation); DISALLOW_COPY_AND_ASSIGN(ExternalVkImageGLRepresentation);
......
...@@ -26,7 +26,7 @@ ExternalVkImageSkiaRepresentation::ExternalVkImageSkiaRepresentation( ...@@ -26,7 +26,7 @@ ExternalVkImageSkiaRepresentation::ExternalVkImageSkiaRepresentation(
ExternalVkImageSkiaRepresentation::~ExternalVkImageSkiaRepresentation() { ExternalVkImageSkiaRepresentation::~ExternalVkImageSkiaRepresentation() {
DCHECK_EQ(access_mode_, kNone) << "Previous access hasn't end yet."; DCHECK_EQ(access_mode_, kNone) << "Previous access hasn't end yet.";
DCHECK(end_access_semaphore_ == VK_NULL_HANDLE); DCHECK(!end_access_semaphore_);
backing_impl()->context_state()->EraseCachedSkSurface(this); backing_impl()->context_state()->EraseCachedSkSurface(this);
} }
...@@ -148,16 +148,16 @@ sk_sp<SkPromiseImageTexture> ExternalVkImageSkiaRepresentation::BeginAccess( ...@@ -148,16 +148,16 @@ sk_sp<SkPromiseImageTexture> ExternalVkImageSkiaRepresentation::BeginAccess(
std::vector<GrBackendSemaphore>* begin_semaphores, std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores) { std::vector<GrBackendSemaphore>* end_semaphores) {
DCHECK_EQ(access_mode_, kNone); DCHECK_EQ(access_mode_, kNone);
DCHECK(end_access_semaphore_ == VK_NULL_HANDLE); DCHECK(!end_access_semaphore_);
std::vector<SemaphoreHandle> handles; std::vector<ExternalSemaphore> external_semaphores;
if (!backing_impl()->BeginAccess(readonly, &handles, false /* is_gl */)) if (!backing_impl()->BeginAccess(readonly, &external_semaphores,
false /* is_gl */))
return nullptr; return nullptr;
for (auto& handle : handles) { for (auto& external_semaphore : external_semaphores) {
DCHECK(handle.is_valid()); DCHECK(external_semaphore.is_valid());
VkSemaphore semaphore = vk_implementation()->ImportSemaphoreHandle( VkSemaphore semaphore = external_semaphore.TakeVkSemaphore();
vk_device(), std::move(handle));
DCHECK(semaphore != VK_NULL_HANDLE); DCHECK(semaphore != VK_NULL_HANDLE);
// The ownership of semaphore is passed to caller. // The ownership of semaphore is passed to caller.
begin_semaphores->emplace_back(); begin_semaphores->emplace_back();
...@@ -166,11 +166,10 @@ sk_sp<SkPromiseImageTexture> ExternalVkImageSkiaRepresentation::BeginAccess( ...@@ -166,11 +166,10 @@ sk_sp<SkPromiseImageTexture> ExternalVkImageSkiaRepresentation::BeginAccess(
if (backing_impl()->need_synchronization() && end_semaphores) { if (backing_impl()->need_synchronization() && end_semaphores) {
// Create an |end_access_semaphore_| which will be signalled by the caller. // Create an |end_access_semaphore_| which will be signalled by the caller.
end_access_semaphore_ = end_access_semaphore_ = ExternalSemaphore::Create(context_provider());
vk_implementation()->CreateExternalSemaphore(backing_impl()->device()); DCHECK(end_access_semaphore_);
DCHECK(end_access_semaphore_ != VK_NULL_HANDLE);
end_semaphores->emplace_back(); end_semaphores->emplace_back();
end_semaphores->back().initVulkan(end_access_semaphore_); end_semaphores->back().initVulkan(end_access_semaphore_.GetVkSemaphore());
} }
return SkPromiseImageTexture::Make(backing_impl()->backend_texture()); return SkPromiseImageTexture::Make(backing_impl()->backend_texture());
...@@ -178,23 +177,19 @@ sk_sp<SkPromiseImageTexture> ExternalVkImageSkiaRepresentation::BeginAccess( ...@@ -178,23 +177,19 @@ sk_sp<SkPromiseImageTexture> ExternalVkImageSkiaRepresentation::BeginAccess(
void ExternalVkImageSkiaRepresentation::EndAccess(bool readonly) { void ExternalVkImageSkiaRepresentation::EndAccess(bool readonly) {
DCHECK_NE(access_mode_, kNone); DCHECK_NE(access_mode_, kNone);
DCHECK(backing_impl()->need_synchronization() || DCHECK(backing_impl()->need_synchronization() || !end_access_semaphore_);
end_access_semaphore_ == VK_NULL_HANDLE);
SemaphoreHandle handle; if (backing_impl()->need_synchronization() && end_access_semaphore_) {
if (backing_impl()->need_synchronization() && DCHECK(end_access_semaphore_);
end_access_semaphore_ != VK_NULL_HANDLE) {
handle = vk_implementation()->GetSemaphoreHandle(vk_device(),
end_access_semaphore_);
DCHECK(handle.is_valid());
// We're done with the semaphore, enqueue deferred cleanup. // We're done with the semaphore, enqueue deferred cleanup.
// TODO(penghuang): reuse VkSemaphore.
fence_helper()->EnqueueSemaphoreCleanupForSubmittedWork( fence_helper()->EnqueueSemaphoreCleanupForSubmittedWork(
end_access_semaphore_); end_access_semaphore_.TakeVkSemaphore());
end_access_semaphore_ = VK_NULL_HANDLE;
} }
backing_impl()->EndAccess(readonly, std::move(handle), false /* is_gl */); backing_impl()->EndAccess(readonly, std::move(end_access_semaphore_),
false /* is_gl */);
} }
} // namespace gpu } // namespace gpu
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "components/viz/common/gpu/vulkan_context_provider.h" #include "components/viz/common/gpu/vulkan_context_provider.h"
#include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/command_buffer/service/external_semaphore.h"
#include "gpu/command_buffer/service/external_vk_image_backing.h" #include "gpu/command_buffer/service/external_vk_image_backing.h"
#include "gpu/command_buffer/service/shared_image_representation.h" #include "gpu/command_buffer/service/shared_image_representation.h"
#include "gpu/vulkan/vulkan_device_queue.h" #include "gpu/vulkan/vulkan_device_queue.h"
...@@ -38,39 +39,14 @@ class ExternalVkImageSkiaRepresentation : public SharedImageRepresentationSkia { ...@@ -38,39 +39,14 @@ class ExternalVkImageSkiaRepresentation : public SharedImageRepresentationSkia {
void EndReadAccess() override; void EndReadAccess() override;
private: private:
gpu::VulkanImplementation* vk_implementation() { ExternalVkImageBacking* backing_impl() const {
return backing_impl() return static_cast<ExternalVkImageBacking*>(backing());
->context_state()
->vk_context_provider()
->GetVulkanImplementation();
}
VkDevice vk_device() {
return backing_impl()
->context_state()
->vk_context_provider()
->GetDeviceQueue()
->GetVulkanDevice();
}
VkQueue vk_queue() {
return backing_impl()
->context_state()
->vk_context_provider()
->GetDeviceQueue()
->GetVulkanQueue();
} }
viz::VulkanContextProvider* context_provider() const {
VulkanFenceHelper* fence_helper() { return backing_impl()->context_provider();
return backing_impl()
->context_state()
->vk_context_provider()
->GetDeviceQueue()
->GetFenceHelper();
} }
VulkanFenceHelper* fence_helper() const {
ExternalVkImageBacking* backing_impl() { return backing_impl()->fence_helper();
return static_cast<ExternalVkImageBacking*>(backing());
} }
sk_sp<SkPromiseImageTexture> BeginAccess( sk_sp<SkPromiseImageTexture> BeginAccess(
...@@ -87,7 +63,7 @@ class ExternalVkImageSkiaRepresentation : public SharedImageRepresentationSkia { ...@@ -87,7 +63,7 @@ class ExternalVkImageSkiaRepresentation : public SharedImageRepresentationSkia {
}; };
AccessMode access_mode_ = kNone; AccessMode access_mode_ = kNone;
int surface_msaa_count_ = 0; int surface_msaa_count_ = 0;
VkSemaphore end_access_semaphore_ = VK_NULL_HANDLE; ExternalSemaphore end_access_semaphore_;
}; };
} // namespace gpu } // namespace gpu
......
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