Commit 4165f719 authored by Sergey Ulanov's avatar Sergey Ulanov Committed by Commit Bot

[Fuchsia] Stop setting image constraints in OutputPresenterFuchsia

OutputPresenterFuchsia was setting image constraints for allocated
buffers. As result the images were always allocated with
pixel_format=R8G8B8A8 without any flags set in format_modifiers. As
result, device-specific optimizations were not enabled for these
buffers, so GPU was using more memory bandwidth than would be possible
otherwise. This change updates OutputPresenterFuchsia to avoid setting
any constraints for the buffer collection. Instead buffer collection
constraints are set only through Vulkan. This ensures that the buffers
are allocated with all possible optimizations supported by the Vulkan
driver.

Bug: 1128740
Change-Id: I7ec8f605ace86a33062d5296a1b6b2e1f647b3c5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2414757Reviewed-by: default avatarEmircan Uysaler <emircan@chromium.org>
Reviewed-by: default avatarPeng Huang <penghuang@chromium.org>
Commit-Queue: Emircan Uysaler <emircan@chromium.org>
Auto-Submit: Sergey Ulanov <sergeyu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808101}
parent 0cf9c873
...@@ -226,7 +226,7 @@ OutputPresenterFuchsia::AllocateImages(gfx::ColorSpace color_space, ...@@ -226,7 +226,7 @@ OutputPresenterFuchsia::AllocateImages(gfx::ColorSpace color_space,
// Create buffer collection with 2 extra tokens: one for Vulkan and one for // Create buffer collection with 2 extra tokens: one for Vulkan and one for
// the ImagePipe. // the ImagePipe.
fuchsia::sysmem::BufferCollectionTokenPtr collection_token; fuchsia::sysmem::BufferCollectionTokenSyncPtr collection_token;
sysmem_allocator_->AllocateSharedCollection(collection_token.NewRequest()); sysmem_allocator_->AllocateSharedCollection(collection_token.NewRequest());
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
...@@ -234,16 +234,7 @@ OutputPresenterFuchsia::AllocateImages(gfx::ColorSpace color_space, ...@@ -234,16 +234,7 @@ OutputPresenterFuchsia::AllocateImages(gfx::ColorSpace color_space,
collection_token->Duplicate(ZX_RIGHT_SAME_RIGHTS, collection_token->Duplicate(ZX_RIGHT_SAME_RIGHTS,
token_for_scenic.NewRequest()); token_for_scenic.NewRequest());
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> zx_status_t status = collection_token->Sync();
token_for_vulkan;
collection_token->Duplicate(ZX_RIGHT_SAME_RIGHTS,
token_for_vulkan.NewRequest());
fuchsia::sysmem::BufferCollectionSyncPtr collection;
sysmem_allocator_->BindSharedCollection(std::move(collection_token),
collection.NewRequest());
zx_status_t status = collection->Sync();
if (status != ZX_OK) { if (status != ZX_OK) {
ZX_DLOG(ERROR, status) << "fuchsia.sysmem.BufferCollection.Sync()"; ZX_DLOG(ERROR, status) << "fuchsia.sysmem.BufferCollection.Sync()";
return {}; return {};
...@@ -252,21 +243,6 @@ OutputPresenterFuchsia::AllocateImages(gfx::ColorSpace color_space, ...@@ -252,21 +243,6 @@ OutputPresenterFuchsia::AllocateImages(gfx::ColorSpace color_space,
auto* vulkan = auto* vulkan =
dependency_->GetVulkanContextProvider()->GetVulkanImplementation(); dependency_->GetVulkanContextProvider()->GetVulkanImplementation();
// Set constraints for the new collection.
fuchsia::sysmem::BufferCollectionConstraints constraints;
constraints.min_buffer_count = num_images;
constraints.usage.none = fuchsia::sysmem::noneUsage;
constraints.image_format_constraints_count = 1;
constraints.image_format_constraints[0].pixel_format.type =
fuchsia::sysmem::PixelFormatType::R8G8B8A8;
constraints.image_format_constraints[0].min_coded_width = frame_size_.width();
constraints.image_format_constraints[0].min_coded_height =
frame_size_.height();
constraints.image_format_constraints[0].color_spaces_count = 1;
constraints.image_format_constraints[0].color_space[0].type =
fuchsia::sysmem::ColorSpaceType::SRGB;
collection->SetConstraints(true, constraints);
// Register the new buffer collection with the ImagePipe. // Register the new buffer collection with the ImagePipe.
last_buffer_collection_id_++; last_buffer_collection_id_++;
image_pipe_->AddBufferCollection(last_buffer_collection_id_, image_pipe_->AddBufferCollection(last_buffer_collection_id_,
...@@ -280,31 +256,14 @@ OutputPresenterFuchsia::AllocateImages(gfx::ColorSpace color_space, ...@@ -280,31 +256,14 @@ OutputPresenterFuchsia::AllocateImages(gfx::ColorSpace color_space,
->GetDeviceQueue() ->GetDeviceQueue()
->GetVulkanDevice(); ->GetVulkanDevice();
buffer_collection_ = vulkan->RegisterSysmemBufferCollection( buffer_collection_ = vulkan->RegisterSysmemBufferCollection(
vk_device, buffer_collection_id, token_for_vulkan.TakeChannel(), vk_device, buffer_collection_id, collection_token.Unbind().TakeChannel(),
buffer_format_, gfx::BufferUsage::SCANOUT); buffer_format_, gfx::BufferUsage::SCANOUT, frame_size_, num_images);
// Wait for the images to be allocated. if (!buffer_collection_) {
zx_status_t wait_status; ZX_DLOG(ERROR, status) << "Failed to allocate sysmem buffer collection";
fuchsia::sysmem::BufferCollectionInfo_2 buffers_info;
status = collection->WaitForBuffersAllocated(&wait_status, &buffers_info);
if (status != ZX_OK) {
ZX_DLOG(ERROR, status) << "fuchsia.sysmem.BufferCollection failed";
return {}; return {};
} }
if (wait_status != ZX_OK) {
ZX_DLOG(ERROR, wait_status)
<< "Sysmem buffer collection allocation failed.";
return {};
}
DCHECK_GE(buffers_info.buffer_count, num_images);
// We no longer need the BufferCollection connection. Close it to ensure
// ImagePipe can still use the collection after BufferCollection connection
// is dropped below.
collection->Close();
// Create PresenterImageFuchsia for each buffer in the collection. // Create PresenterImageFuchsia for each buffer in the collection.
uint32_t image_usage = uint32_t image_usage =
gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_SCANOUT; gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_SCANOUT;
......
...@@ -362,9 +362,10 @@ bool SharedImageFactory::RegisterSysmemBufferCollection( ...@@ -362,9 +362,10 @@ bool SharedImageFactory::RegisterSysmemBufferCollection(
VkDevice device = VkDevice device =
vulkan_context_provider_->GetDeviceQueue()->GetVulkanDevice(); vulkan_context_provider_->GetDeviceQueue()->GetVulkanDevice();
DCHECK(device != VK_NULL_HANDLE); DCHECK(device != VK_NULL_HANDLE);
it->second = vulkan_context_provider_->GetVulkanImplementation() it->second =
->RegisterSysmemBufferCollection( vulkan_context_provider_->GetVulkanImplementation()
device, id, std::move(token), format, usage); ->RegisterSysmemBufferCollection(device, id, std::move(token), format,
usage, gfx::Size(), 0);
return true; return true;
} }
......
...@@ -136,7 +136,9 @@ class COMPONENT_EXPORT(VULKAN) VulkanImplementation { ...@@ -136,7 +136,9 @@ class COMPONENT_EXPORT(VULKAN) VulkanImplementation {
gfx::SysmemBufferCollectionId id, gfx::SysmemBufferCollectionId id,
zx::channel token, zx::channel token,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage) = 0; gfx::BufferUsage usage,
gfx::Size size,
size_t min_buffer_count) = 0;
#endif // defined(OS_FUCHSIA) #endif // defined(OS_FUCHSIA)
bool use_swiftshader() const { return use_swiftshader_; } bool use_swiftshader() const { return use_swiftshader_; }
......
...@@ -129,11 +129,13 @@ SysmemBufferCollection::SysmemBufferCollection(gfx::SysmemBufferCollectionId id) ...@@ -129,11 +129,13 @@ SysmemBufferCollection::SysmemBufferCollection(gfx::SysmemBufferCollectionId id)
bool SysmemBufferCollection::Initialize( bool SysmemBufferCollection::Initialize(
fuchsia::sysmem::Allocator_Sync* allocator, fuchsia::sysmem::Allocator_Sync* allocator,
zx::channel token_handle,
gfx::Size size, gfx::Size size,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage, gfx::BufferUsage usage,
VkDevice vk_device, VkDevice vk_device,
size_t num_buffers) { size_t min_buffer_count,
bool force_protected) {
DCHECK(IsNativePixmapConfigSupported(format, usage)); DCHECK(IsNativePixmapConfigSupported(format, usage));
DCHECK(!collection_); DCHECK(!collection_);
DCHECK(!vk_buffer_collection_); DCHECK(!vk_buffer_collection_);
...@@ -143,12 +145,30 @@ bool SysmemBufferCollection::Initialize( ...@@ -143,12 +145,30 @@ bool SysmemBufferCollection::Initialize(
if (vk_device == VK_NULL_HANDLE) if (vk_device == VK_NULL_HANDLE)
return false; return false;
if (size.IsEmpty()) {
// Buffer collection that doesn't have explicit size is expected to be
// shared with other participants, who will determine the actual image size.
DCHECK(token_handle);
// Set nominal size of 1x1, which will be used only for
// vkSetBufferCollectionConstraintsFUCHSIA(). The actual size of the
// allocated buffers is determined by constraints set by other sysmem
// clients for the same collection. Size of the Vulkan image is determined
// by the values passed to CreateVkImage().
min_size_ = gfx::Size(1, 1);
} else {
min_size_ = size; min_size_ = size;
}
format_ = format; format_ = format;
usage_ = usage; usage_ = usage;
vk_device_ = vk_device; vk_device_ = vk_device;
is_protected_ = force_protected;
fuchsia::sysmem::BufferCollectionTokenSyncPtr collection_token; fuchsia::sysmem::BufferCollectionTokenSyncPtr collection_token;
if (token_handle) {
collection_token.Bind(std::move(token_handle));
} else {
zx_status_t status = zx_status_t status =
allocator->AllocateSharedCollection(collection_token.NewRequest()); allocator->AllocateSharedCollection(collection_token.NewRequest());
if (status != ZX_OK) { if (status != ZX_OK) {
...@@ -156,38 +176,10 @@ bool SysmemBufferCollection::Initialize( ...@@ -156,38 +176,10 @@ bool SysmemBufferCollection::Initialize(
<< "fuchsia.sysmem.Allocator.AllocateSharedCollection()"; << "fuchsia.sysmem.Allocator.AllocateSharedCollection()";
return false; return false;
} }
}
return InitializeInternal(allocator, std::move(collection_token), return InitializeInternal(allocator, std::move(collection_token),
num_buffers); min_buffer_count);
}
bool SysmemBufferCollection::Initialize(
fuchsia::sysmem::Allocator_Sync* allocator,
VkDevice vk_device,
zx::channel token_handle,
gfx::BufferFormat format,
gfx::BufferUsage usage,
bool force_protected) {
DCHECK(!collection_);
DCHECK(!vk_buffer_collection_);
// Set nominal size of 1x1, which will be used only for
// vkSetBufferCollectionConstraintsFUCHSIA(). The actual size of the allocated
// buffers is determined by constraints set by other sysmem clients for the
// same collection. Size of the Vulkan image is determined by the valus passed
// to CreateVkImage().
min_size_ = gfx::Size(1, 1);
vk_device_ = vk_device;
format_ = format;
usage_ = usage;
is_protected_ = force_protected;
fuchsia::sysmem::BufferCollectionTokenSyncPtr token;
token.Bind(std::move(token_handle));
return InitializeInternal(allocator, std::move(token),
/*buffers_for_camping=*/0);
} }
scoped_refptr<gfx::NativePixmap> SysmemBufferCollection::CreateNativePixmap( scoped_refptr<gfx::NativePixmap> SysmemBufferCollection::CreateNativePixmap(
......
...@@ -39,18 +39,18 @@ class SysmemBufferCollection ...@@ -39,18 +39,18 @@ class SysmemBufferCollection
SysmemBufferCollection(); SysmemBufferCollection();
explicit SysmemBufferCollection(gfx::SysmemBufferCollectionId id); explicit SysmemBufferCollection(gfx::SysmemBufferCollectionId id);
// Initializes the buffer collection and registers it with Vulkan using the
// specified |vk_device|. If |token_handle| is null then a new collection
// collection is created. |size| may be empty. In that case |token_handle|
// must not be null and the image size is determined by the other sysmem
// participants.
bool Initialize(fuchsia::sysmem::Allocator_Sync* allocator, bool Initialize(fuchsia::sysmem::Allocator_Sync* allocator,
zx::channel token_handle,
gfx::Size size, gfx::Size size,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage, gfx::BufferUsage usage,
VkDevice vk_device, VkDevice vk_device,
size_t num_buffers); size_t min_buffer_count,
bool Initialize(fuchsia::sysmem::Allocator_Sync* allocator,
VkDevice vk_device,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage,
bool force_protected); bool force_protected);
// Must not be called more than once. // Must not be called more than once.
......
...@@ -37,10 +37,11 @@ scoped_refptr<SysmemBufferCollection> SysmemBufferManager::CreateCollection( ...@@ -37,10 +37,11 @@ scoped_refptr<SysmemBufferCollection> SysmemBufferManager::CreateCollection(
gfx::Size size, gfx::Size size,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage, gfx::BufferUsage usage,
size_t num_buffers) { size_t min_buffer_count) {
auto result = base::MakeRefCounted<SysmemBufferCollection>(); auto result = base::MakeRefCounted<SysmemBufferCollection>();
if (!result->Initialize(allocator_.get(), size, format, usage, vk_device, if (!result->Initialize(allocator_.get(), /*token_channel=*/zx::channel(),
num_buffers)) { size, format, usage, vk_device, min_buffer_count,
/*force_protected=*/false)) {
return nullptr; return nullptr;
} }
RegisterCollection(result.get()); RegisterCollection(result.get());
...@@ -52,12 +53,15 @@ SysmemBufferManager::ImportSysmemBufferCollection( ...@@ -52,12 +53,15 @@ SysmemBufferManager::ImportSysmemBufferCollection(
VkDevice vk_device, VkDevice vk_device,
gfx::SysmemBufferCollectionId id, gfx::SysmemBufferCollectionId id,
zx::channel token, zx::channel token,
gfx::Size size,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage, gfx::BufferUsage usage,
size_t min_buffer_count,
bool force_protected) { bool force_protected) {
auto result = base::MakeRefCounted<SysmemBufferCollection>(id); auto result = base::MakeRefCounted<SysmemBufferCollection>(id);
if (!result->Initialize(allocator_.get(), vk_device, std::move(token), format, if (!result->Initialize(allocator_.get(), std::move(token), size, format,
usage, force_protected)) { usage, vk_device, min_buffer_count,
force_protected)) {
return nullptr; return nullptr;
} }
RegisterCollection(result.get()); RegisterCollection(result.get());
......
...@@ -47,8 +47,10 @@ class SysmemBufferManager { ...@@ -47,8 +47,10 @@ class SysmemBufferManager {
VkDevice vk_device, VkDevice vk_device,
gfx::SysmemBufferCollectionId id, gfx::SysmemBufferCollectionId id,
zx::channel token, zx::channel token,
gfx::Size size,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage, gfx::BufferUsage usage,
size_t min_buffer_count,
bool force_protected); bool force_protected);
scoped_refptr<SysmemBufferCollection> GetCollectionById( scoped_refptr<SysmemBufferCollection> GetCollectionById(
......
...@@ -300,14 +300,21 @@ VulkanImplementationScenic::RegisterSysmemBufferCollection( ...@@ -300,14 +300,21 @@ VulkanImplementationScenic::RegisterSysmemBufferCollection(
gfx::SysmemBufferCollectionId id, gfx::SysmemBufferCollectionId id,
zx::channel token, zx::channel token,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage) { gfx::BufferUsage usage,
gfx::Size size,
size_t min_buffer_count) {
// SCANOUT images must be protected in protected mode. // SCANOUT images must be protected in protected mode.
bool force_protected = bool force_protected =
usage == gfx::BufferUsage::SCANOUT && enforce_protected_memory(); usage == gfx::BufferUsage::SCANOUT && enforce_protected_memory();
auto buffer_collection = sysmem_buffer_manager_->ImportSysmemBufferCollection(
device, id, std::move(token), size, format, usage, min_buffer_count,
force_protected);
if (!buffer_collection)
return nullptr;
return std::make_unique<SysmemBufferCollectionImpl>( return std::make_unique<SysmemBufferCollectionImpl>(
sysmem_buffer_manager_->ImportSysmemBufferCollection( std::move(buffer_collection));
device, id, std::move(token), format, usage, force_protected));
} }
} // namespace ui } // namespace ui
...@@ -58,7 +58,9 @@ class VulkanImplementationScenic : public gpu::VulkanImplementation { ...@@ -58,7 +58,9 @@ class VulkanImplementationScenic : public gpu::VulkanImplementation {
gfx::SysmemBufferCollectionId id, gfx::SysmemBufferCollectionId id,
zx::channel token, zx::channel token,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage) override; gfx::BufferUsage usage,
gfx::Size size,
size_t min_buffer_count) override;
private: private:
ScenicSurfaceFactory* const scenic_surface_factory_; ScenicSurfaceFactory* const scenic_surface_factory_;
......
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