Commit 23c657d5 authored by Emircan Uysaler's avatar Emircan Uysaler Committed by Commit Bot

[Fuchsia] Add options for registering video with ImagePipe

This CL adds the groundwork for video overlays on fuchsia:
- Adds feature flags for an alternative path for displaying video
as overlays through an ImagePipe on fuchsia.
- Makes use of these flags for the initial step of associating video
BufferCollections with an ImagePipe before their allocation. There is
one-to-map mapping between BufferCollections and ImagePipe.
ImagePipe is owned by SysmemBufferCollection instance.

Bug: 1127984
Change-Id: Iaa8fa7961b7f1601d7af6a19eaf23f0f73eb7aab
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2415381Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Reviewed-by: default avatarSergey Ulanov <sergeyu@chromium.org>
Commit-Queue: Emircan Uysaler <emircan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812120}
parent af56b532
......@@ -257,7 +257,8 @@ OutputPresenterFuchsia::AllocateImages(gfx::ColorSpace color_space,
->GetVulkanDevice();
buffer_collection_ = vulkan->RegisterSysmemBufferCollection(
vk_device, buffer_collection_id, collection_token.Unbind().TakeChannel(),
buffer_format_, gfx::BufferUsage::SCANOUT, frame_size_, num_images);
buffer_format_, gfx::BufferUsage::SCANOUT, frame_size_, num_images,
false /* register_with_image_pipe */);
if (!buffer_collection_) {
ZX_DLOG(ERROR, status) << "Failed to allocate sysmem buffer collection";
......
......@@ -222,7 +222,8 @@ void TestSharedImageInterface::RegisterSysmemBufferCollection(
gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) {
gfx::BufferUsage usage,
bool register_with_image_pipe) {
NOTREACHED();
}
......@@ -486,7 +487,6 @@ TestGLES2Interface* TestContextProvider::TestContextGL() {
return context_gl_.get();
}
void TestContextProvider::AddObserver(ContextLostObserver* obs) {
observers_.AddObserver(obs);
}
......
......@@ -92,7 +92,8 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
void RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) override;
gfx::BufferUsage usage,
bool register_with_image_pipe) override;
void ReleaseSysmemBufferCollection(gfx::SysmemBufferCollectionId id) override;
#endif // defined(OS_FUCHSIA)
......
......@@ -168,6 +168,7 @@ void WebEngineContentBrowserClient::AppendExtraCommandLineSwitches(
switches::kForceProtectedVideoOutputBuffers,
switches::kMaxDecodedImageSizeMb,
switches::kPlayreadyKeySystem,
switches::kUseOverlaysForVideo,
};
command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
......
......@@ -42,6 +42,7 @@
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "components/viz/common/features.h"
#include "components/viz/common/switches.h"
#include "content/public/common/content_switches.h"
#include "fuchsia/base/config_reader.h"
#include "fuchsia/base/string_util.h"
......@@ -390,9 +391,13 @@ void ContextProviderImpl::Create(
bool enable_protected_graphics =
((enable_playready || enable_widevine) && allow_protected_graphics) ||
force_protected_graphics;
bool use_overlays_for_video =
web_engine_config.FindBoolPath("use-overlays-for-video").value_or(false);
if (enable_protected_graphics) {
launch_command.AppendSwitch(switches::kEnforceVulkanProtectedMemory);
if (force_protected_graphics || !use_overlays_for_video) {
launch_command.AppendSwitch(switches::kEnforceVulkanProtectedMemory);
}
launch_command.AppendSwitch(switches::kEnableProtectedVideoBuffers);
bool force_protected_video_buffers =
web_engine_config.FindBoolPath("force-protected-video-buffers")
......@@ -402,6 +407,16 @@ void ContextProviderImpl::Create(
}
}
if (use_overlays_for_video) {
// Overlays are only available if OutputPresenterFuchsia is in use.
AppendFeature(switches::kEnableFeatures,
features::kUseSkiaOutputDeviceBufferQueue.name,
&launch_command);
launch_command.AppendSwitchASCII(switches::kEnableHardwareOverlays,
"underlay");
launch_command.AppendSwitch(switches::kUseOverlaysForVideo);
}
if (enable_vulkan) {
if (is_headless) {
DLOG(ERROR) << "VULKAN and HEADLESS features cannot be used together.";
......
......@@ -169,10 +169,15 @@ class GPU_EXPORT SharedImageInterface {
// |buffer_collection_id| and |buffer_index| fields in NativePixmapHandle,
// wrapping it in GpuMemoryBufferHandle and then creating GpuMemoryBuffer from
// that handle.
virtual void RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) = 0;
// If |register_with_image_pipe| field is set, a new ImagePipe is created and
// |token| is duped to collect ImagePipe constraints. SysmemBufferCollection
// is then available for direct presentation.
virtual void RegisterSysmemBufferCollection(
gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage,
bool register_with_image_pipe) = 0;
virtual void ReleaseSysmemBufferCollection(
gfx::SysmemBufferCollectionId id) = 0;
......
......@@ -341,7 +341,8 @@ bool SharedImageFactory::RegisterSysmemBufferCollection(
gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) {
gfx::BufferUsage usage,
bool register_with_image_pipe) {
decltype(buffer_collections_)::iterator it;
bool inserted;
std::tie(it, inserted) =
......@@ -362,10 +363,10 @@ bool SharedImageFactory::RegisterSysmemBufferCollection(
VkDevice device =
vulkan_context_provider_->GetDeviceQueue()->GetVulkanDevice();
DCHECK(device != VK_NULL_HANDLE);
it->second =
vulkan_context_provider_->GetVulkanImplementation()
->RegisterSysmemBufferCollection(device, id, std::move(token), format,
usage, gfx::Size(), 0);
it->second = vulkan_context_provider_->GetVulkanImplementation()
->RegisterSysmemBufferCollection(
device, id, std::move(token), format, usage, gfx::Size(),
0, register_with_image_pipe);
return true;
}
......
......@@ -111,7 +111,8 @@ class GPU_GLES2_EXPORT SharedImageFactory {
bool RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage);
gfx::BufferUsage usage,
bool register_with_image_pipe);
bool ReleaseSysmemBufferCollection(gfx::SysmemBufferCollectionId id);
#endif // defined(OS_FUCHSIA)
......
......@@ -42,8 +42,10 @@ void ClientSharedImageInterface::RegisterSysmemBufferCollection(
gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) {
proxy_->RegisterSysmemBufferCollection(id, std::move(token), format, usage);
gfx::BufferUsage usage,
bool register_with_image_pipe) {
proxy_->RegisterSysmemBufferCollection(id, std::move(token), format, usage,
register_with_image_pipe);
}
void ClientSharedImageInterface::ReleaseSysmemBufferCollection(
......
......@@ -35,7 +35,8 @@ class GPU_EXPORT ClientSharedImageInterface : public SharedImageInterface {
void RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) override;
gfx::BufferUsage usage,
bool register_with_image_pipe) override;
void ReleaseSysmemBufferCollection(gfx::SysmemBufferCollectionId id) override;
#endif // defined(OS_FUCHSIA)
SyncToken GenUnverifiedSyncToken() override;
......
......@@ -435,9 +435,10 @@ void SharedImageInterfaceProxy::RegisterSysmemBufferCollection(
gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) {
gfx::BufferUsage usage,
bool register_with_image_pipe) {
host_->Send(new GpuChannelMsg_RegisterSysmemBufferCollection(
route_id_, id, token, format, usage));
route_id_, id, token, format, usage, register_with_image_pipe));
}
void SharedImageInterfaceProxy::ReleaseSysmemBufferCollection(
......
......@@ -70,7 +70,8 @@ class SharedImageInterfaceProxy {
void RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage);
gfx::BufferUsage usage,
bool register_with_image_pipe);
void ReleaseSysmemBufferCollection(gfx::SysmemBufferCollectionId id);
#endif // defined(OS_FUCHSIA)
......
......@@ -209,11 +209,12 @@ IPC_MESSAGE_ROUTED2(GpuChannelMsg_PresentSwapChain,
uint32_t /* release_id */)
#endif // OS_WIN
#if defined(OS_FUCHSIA)
IPC_MESSAGE_ROUTED4(GpuChannelMsg_RegisterSysmemBufferCollection,
IPC_MESSAGE_ROUTED5(GpuChannelMsg_RegisterSysmemBufferCollection,
gfx::SysmemBufferCollectionId /* id */,
zx::channel /* token */,
gfx::BufferFormat /* format */,
gfx::BufferUsage /* usage */)
gfx::BufferUsage /* usage */,
bool /* register_with_image_pipe */)
IPC_MESSAGE_ROUTED1(GpuChannelMsg_ReleaseSysmemBufferCollection,
gfx::SysmemBufferCollectionId /* id */)
#endif // OS_FUCHSIA
......
......@@ -409,14 +409,15 @@ void SharedImageStub::OnRegisterSysmemBufferCollection(
gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) {
gfx::BufferUsage usage,
bool register_with_image_pipe) {
if (!id || !token) {
OnError();
return;
}
if (!factory_->RegisterSysmemBufferCollection(id, std::move(token), format,
usage)) {
if (!factory_->RegisterSysmemBufferCollection(
id, std::move(token), format, usage, register_with_image_pipe)) {
OnError();
}
}
......
......@@ -104,7 +104,8 @@ class GPU_IPC_SERVICE_EXPORT SharedImageStub
void OnRegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage);
gfx::BufferUsage usage,
bool register_with_image_pipe);
void OnReleaseSysmemBufferCollection(gfx::SysmemBufferCollectionId id);
#endif // OS_FUCHSIA
......
......@@ -376,7 +376,8 @@ void SharedImageInterfaceInProcess::RegisterSysmemBufferCollection(
gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) {
gfx::BufferUsage usage,
bool register_with_image_pipe) {
NOTREACHED();
}
void SharedImageInterfaceInProcess::ReleaseSysmemBufferCollection(
......
......@@ -128,7 +128,8 @@ class GL_IN_PROCESS_CONTEXT_EXPORT SharedImageInterfaceInProcess
void RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) override;
gfx::BufferUsage usage,
bool register_with_image_pipe) override;
// Not reached in this implementation.
void ReleaseSysmemBufferCollection(gfx::SysmemBufferCollectionId id) override;
......
......@@ -138,7 +138,8 @@ class COMPONENT_EXPORT(VULKAN) VulkanImplementation {
gfx::BufferFormat format,
gfx::BufferUsage usage,
gfx::Size size,
size_t min_buffer_count) = 0;
size_t min_buffer_count,
bool register_with_image_pipe) = 0;
#endif // defined(OS_FUCHSIA)
bool use_swiftshader() const { return use_swiftshader_; }
......
......@@ -79,6 +79,9 @@ const char kForceProtectedVideoOutputBuffers[] =
"force-protected-video-output-buffers";
const char kDisableAudioInput[] = "disable-audio-input";
// Present video content as overlays.
const char kUseOverlaysForVideo[] = "use-overlays-for-video";
#endif // defined(OS_FUCHSIA)
#if defined(USE_CRAS)
......
......@@ -52,6 +52,7 @@ MEDIA_EXPORT extern const char kWaveOutBuffers[];
MEDIA_EXPORT extern const char kEnableProtectedVideoBuffers[];
MEDIA_EXPORT extern const char kForceProtectedVideoOutputBuffers[];
MEDIA_EXPORT extern const char kDisableAudioInput[];
MEDIA_EXPORT extern const char kUseOverlaysForVideo[];
#endif
#if defined(OS_CHROMEOS)
......
......@@ -251,6 +251,7 @@ class FuchsiaVideoDecoder : public VideoDecoder,
gpu::SharedImageInterface* const shared_image_interface_;
gpu::ContextSupport* const gpu_context_support_;
const bool enable_sw_decoding_;
const bool use_overlays_for_video_;
OutputCB output_cb_;
WaitingCB waiting_cb_;
......@@ -316,6 +317,8 @@ FuchsiaVideoDecoder::FuchsiaVideoDecoder(
: shared_image_interface_(shared_image_interface),
gpu_context_support_(gpu_context_support),
enable_sw_decoding_(enable_sw_decoding),
use_overlays_for_video_(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseOverlaysForVideo)),
client_native_pixmap_factory_(ui::CreateClientNativePixmapFactoryOzone()),
weak_factory_(this) {
DCHECK(shared_image_interface_);
......@@ -944,6 +947,10 @@ void FuchsiaVideoDecoder::OnOutputPacket(fuchsia::media::Packet output_packet,
// doesn't matter because software decoders can be enabled only for tests.
frame->metadata()->power_efficient = !enable_sw_decoding_;
// Allow this video frame to be promoted as an overlay, because it was
// registered with an ImagePipe.
frame->metadata()->allow_overlay = use_overlays_for_video_;
output_cb_.Run(std::move(frame));
}
......@@ -1024,7 +1031,8 @@ void FuchsiaVideoDecoder::InitializeOutputBufferCollection(
shared_image_interface_->RegisterSysmemBufferCollection(
output_buffer_collection_id_,
collection_token_for_gpu.Unbind().TakeChannel(),
gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::GPU_READ);
gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::GPU_READ,
true /*register_with_image_pipe*/);
// Pass new output buffer settings to the codec.
fuchsia::media::StreamBufferPartialSettings settings;
......
......@@ -122,7 +122,7 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
collection_it->second->GetNumBuffers());
auto result = gpu::Mailbox::Generate();
mailoxes_.insert(result);
mailboxes_.insert(result);
return result;
}
......@@ -138,7 +138,7 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
void DestroySharedImage(const gpu::SyncToken& sync_token,
const gpu::Mailbox& mailbox) override {
CHECK_EQ(mailoxes_.erase(mailbox), 1U);
CHECK_EQ(mailboxes_.erase(mailbox), 1U);
}
SwapChainMailboxes CreateSwapChain(viz::ResourceFormat format,
......@@ -158,7 +158,8 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
void RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
gfx::BufferUsage usage) override {
gfx::BufferUsage usage,
bool register_with_image_pipe) override {
EXPECT_EQ(format, gfx::BufferFormat::YUV_420_BIPLANAR);
EXPECT_EQ(usage, gfx::BufferUsage::GPU_READ);
std::unique_ptr<TestBufferCollection>& collection =
......@@ -196,7 +197,7 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
std::unique_ptr<TestBufferCollection>>
sysmem_buffer_collections_;
base::flat_set<gpu::Mailbox> mailoxes_;
base::flat_set<gpu::Mailbox> mailboxes_;
};
} // namespace
......
......@@ -18,6 +18,8 @@ source_set("scenic") {
"scenic_gpu_host.h",
"scenic_gpu_service.cc",
"scenic_gpu_service.h",
"scenic_overlay_view.cc",
"scenic_overlay_view.h",
"scenic_screen.cc",
"scenic_screen.h",
"scenic_surface.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 "ui/ozone/platform/scenic/scenic_overlay_view.h"
#include <lib/ui/scenic/cpp/commands.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include "base/fuchsia/fuchsia_logging.h"
namespace ui {
namespace {
// |buffer_collection_id| that is passed to ImagePipe::AddBufferCollection() if
// SysmemBufferCollection instance is registered with one.
static const uint32_t kImagePipeBufferCollectionId = 1;
static const std::string kSessionDebugName = "chromium scenic overlay";
fuchsia::ui::views::ViewToken CreateViewToken(
fuchsia::ui::views::ViewHolderToken* holder_token) {
auto token_pair = scenic::ViewTokenPair::New();
*holder_token = std::move(token_pair.view_holder_token);
return std::move(token_pair.view_token);
}
} // namespace
ScenicOverlayView::ScenicOverlayView(
scenic::SessionPtrAndListenerRequest session_and_listener_request)
: scenic_session_(std::move(session_and_listener_request)),
view_(&scenic_session_,
CreateViewToken(&view_holder_token_),
kSessionDebugName) {
scenic_session_.SetDebugName(kSessionDebugName);
scenic_session_.set_error_handler([](zx_status_t status) {
ZX_LOG(FATAL, status) << "Lost connection to scenic session.";
});
}
ScenicOverlayView::~ScenicOverlayView() = default;
void ScenicOverlayView::Initialize(
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
collection_token) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
uint32_t image_pipe_id = scenic_session_.AllocResourceId();
scenic_session_.Enqueue(
scenic::NewCreateImagePipe2Cmd(image_pipe_id, image_pipe_.NewRequest()));
image_pipe_.set_error_handler([](zx_status_t status) {
ZX_LOG(FATAL, status) << "ImagePipe disconnected";
});
scenic::Material image_material(&scenic_session_);
image_material.SetTexture(image_pipe_id);
scenic::ShapeNode shape(&scenic_session_);
shape.SetShape(scenic::Rectangle(&scenic_session_, 1.f, 1.f));
shape.SetMaterial(image_material);
view_.AddChild(shape);
scenic_session_.ReleaseResource(image_pipe_id);
scenic_session_.Present2(
/*requested_presentation_time=*/0,
/*requested_prediction_span=*/0,
[](fuchsia::scenic::scheduling::FuturePresentationTimes info) {});
// Since there is one ImagePipe for each BufferCollection, it is ok to use a
// fixed buffer_collection_id.
// TODO(emircan): Consider using one ImagePipe per video decoder instead.
image_pipe_->AddBufferCollection(kImagePipeBufferCollectionId,
std::move(collection_token));
LOG(ERROR) << __func__;
}
} // namespace ui
// 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 UI_OZONE_PLATFORM_SCENIC_SCENIC_OVERLAY_VIEW_H_
#define UI_OZONE_PLATFORM_SCENIC_SCENIC_OVERLAY_VIEW_H_
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <lib/ui/scenic/cpp/resources.h>
#include <lib/ui/scenic/cpp/session.h>
#include "base/threading/thread_checker.h"
namespace ui {
// Holder for scenic::Session and scenic::View that owns an Image Pipe.
//
// This class allows the callers to access an ImagePipe and a scenic::View that
// displays only that ImagePipe. This is used inside SysmemBufferCollection
// instances to display overlays.
class ScenicOverlayView {
public:
ScenicOverlayView(
scenic::SessionPtrAndListenerRequest session_and_listener_request);
~ScenicOverlayView();
ScenicOverlayView(const ScenicOverlayView&) = delete;
ScenicOverlayView& operator=(const ScenicOverlayView&) = delete;
void Initialize(fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
collection_token);
private:
scenic::Session scenic_session_;
fuchsia::ui::views::ViewHolderToken view_holder_token_;
scenic::View view_;
fuchsia::images::ImagePipe2Ptr image_pipe_;
THREAD_CHECKER(thread_checker_);
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_SCENIC_SCENIC_OVERLAY_VIEW_H_
......@@ -138,6 +138,7 @@ fuchsia::sysmem::AllocatorHandle ConnectSysmemAllocator() {
ScenicSurfaceFactory::ScenicSurfaceFactory()
: egl_implementation_(std::make_unique<GLOzoneEGLScenic>(this)),
sysmem_buffer_manager_(this),
weak_ptr_factory_(this) {}
ScenicSurfaceFactory::~ScenicSurfaceFactory() {
......
......@@ -85,10 +85,10 @@ class ScenicSurfaceFactory : public SurfaceFactoryOzone {
ScenicSurface* GetSurface(gfx::AcceleratedWidget widget)
LOCKS_EXCLUDED(surface_lock_);
private:
// Creates a new scenic session on any thread.
scenic::SessionPtrAndListenerRequest CreateScenicSession();
private:
// Links a surface to its parent window in the host process.
void AttachSurfaceToWindow(
gfx::AcceleratedWidget window,
......
......@@ -10,6 +10,7 @@
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/native_pixmap.h"
#include "ui/ozone/platform/scenic/scenic_surface_factory.h"
namespace ui {
......@@ -129,13 +130,15 @@ SysmemBufferCollection::SysmemBufferCollection(gfx::SysmemBufferCollectionId id)
bool SysmemBufferCollection::Initialize(
fuchsia::sysmem::Allocator_Sync* allocator,
ScenicSurfaceFactory* scenic_surface_factory,
zx::channel token_handle,
gfx::Size size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
VkDevice vk_device,
size_t min_buffer_count,
bool force_protected) {
bool force_protected,
bool register_with_image_pipe) {
DCHECK(IsNativePixmapConfigSupported(format, usage));
DCHECK(!collection_);
DCHECK(!vk_buffer_collection_);
......@@ -165,6 +168,10 @@ bool SysmemBufferCollection::Initialize(
vk_device_ = vk_device;
is_protected_ = force_protected;
if (register_with_image_pipe) {
scenic_overlay_view_.emplace(scenic_surface_factory->CreateScenicSession());
}
fuchsia::sysmem::BufferCollectionTokenSyncPtr collection_token;
if (token_handle) {
collection_token.Bind(std::move(token_handle));
......@@ -365,12 +372,26 @@ bool SysmemBufferCollection::InitializeInternal(
collection_token_for_vulkan;
collection_token->Duplicate(ZX_RIGHT_SAME_RIGHTS,
collection_token_for_vulkan.NewRequest());
// Duplicate one more token for Scenic if this collection can be used as an
// overlay.
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
collection_token_for_scenic;
if (scenic_overlay_view_.has_value()) {
collection_token->Duplicate(ZX_RIGHT_SAME_RIGHTS,
collection_token_for_scenic.NewRequest());
}
zx_status_t status = collection_token->Sync();
if (status != ZX_OK) {
ZX_DLOG(ERROR, status) << "fuchsia.sysmem.BufferCollectionToken.Sync()";
return false;
}
if (scenic_overlay_view_.has_value()) {
scenic_overlay_view_->Initialize(std::move(collection_token_for_scenic));
}
status = allocator->BindSharedCollection(std::move(collection_token),
collection_.NewRequest());
if (status != ZX_OK) {
......
......@@ -6,17 +6,20 @@
#define UI_OZONE_PLATFORM_SCENIC_SYSMEM_BUFFER_COLLECTION_H_
#include <fuchsia/sysmem/cpp/fidl.h>
#include <lib/ui/scenic/cpp/session.h>
#include <vulkan/vulkan.h>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "gpu/ipc/common/vulkan_ycbcr_info.h"
#include "gpu/vulkan/fuchsia/vulkan_fuchsia_ext.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/native_pixmap_handle.h"
#include "ui/ozone/platform/scenic/scenic_overlay_view.h"
namespace gfx {
class NativePixmap;
......@@ -24,6 +27,8 @@ class NativePixmap;
namespace ui {
class ScenicSurfaceFactory;
// SysmemBufferCollection keeps sysmem.BufferCollection interface along with the
// corresponding VkBufferCollectionFUCHSIA. It allows to create either
// gfx::NativePixmap or VkImage from the buffers in the collection.
......@@ -44,14 +49,18 @@ class SysmemBufferCollection
// 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.
// If |register_with_image_pipe| is true, new ScenicOverlayView instance is
// created and |token_handle| gets duplicated to be added to its ImagePipe.
bool Initialize(fuchsia::sysmem::Allocator_Sync* allocator,
ScenicSurfaceFactory* scenic_surface_factory,
zx::channel token_handle,
gfx::Size size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
VkDevice vk_device,
size_t min_buffer_count,
bool force_protected);
bool force_protected,
bool register_with_image_pipe);
// Must not be called more than once.
void SetOnDeletedCallback(base::OnceClosure on_deleted);
......@@ -117,6 +126,11 @@ class SysmemBufferCollection
// that is referenced by |collection_|.
VkBufferCollectionFUCHSIA vk_buffer_collection_ = VK_NULL_HANDLE;
// If ScenicOverlayView is created and its ImagePipe is added as a participant
// in buffer allocation negotiations, the associated images can be displayed
// as overlays.
base::Optional<ScenicOverlayView> scenic_overlay_view_;
// Thread checker used to verify that CreateVkImage() is always called from
// the same thread. It may be unsafe to use vk_buffer_collection_ on different
// threads.
......@@ -133,4 +147,4 @@ class SysmemBufferCollection
} // namespace ui
#endif // UI_OZONE_PLATFORM_SCENIC_SYSMEM_BUFFER_COLLECTION_H_
\ No newline at end of file
#endif // UI_OZONE_PLATFORM_SCENIC_SYSMEM_BUFFER_COLLECTION_H_
......@@ -12,7 +12,9 @@
namespace ui {
SysmemBufferManager::SysmemBufferManager() = default;
SysmemBufferManager::SysmemBufferManager(
ScenicSurfaceFactory* scenic_surface_factory)
: scenic_surface_factory_(scenic_surface_factory) {}
SysmemBufferManager::~SysmemBufferManager() {
Shutdown();
......@@ -39,9 +41,11 @@ scoped_refptr<SysmemBufferCollection> SysmemBufferManager::CreateCollection(
gfx::BufferUsage usage,
size_t min_buffer_count) {
auto result = base::MakeRefCounted<SysmemBufferCollection>();
if (!result->Initialize(allocator_.get(), /*token_channel=*/zx::channel(),
size, format, usage, vk_device, min_buffer_count,
/*force_protected=*/false)) {
if (!result->Initialize(allocator_.get(), scenic_surface_factory_,
/*token_channel=*/zx::channel(), size, format, usage,
vk_device, min_buffer_count,
/*force_protected=*/false,
/*register_with_image_pipe=*/false)) {
return nullptr;
}
RegisterCollection(result.get());
......@@ -57,11 +61,13 @@ SysmemBufferManager::ImportSysmemBufferCollection(
gfx::BufferFormat format,
gfx::BufferUsage usage,
size_t min_buffer_count,
bool force_protected) {
bool force_protected,
bool register_with_image_pipe) {
auto result = base::MakeRefCounted<SysmemBufferCollection>(id);
if (!result->Initialize(allocator_.get(), std::move(token), size, format,
usage, vk_device, min_buffer_count,
force_protected)) {
if (!result->Initialize(allocator_.get(), scenic_surface_factory_,
std::move(token), size, format, usage, vk_device,
min_buffer_count, force_protected,
register_with_image_pipe)) {
return nullptr;
}
RegisterCollection(result.get());
......
......@@ -6,6 +6,7 @@
#define UI_OZONE_PLATFORM_SCENIC_SYSMEM_BUFFER_MANAGER_H_
#include <fuchsia/sysmem/cpp/fidl.h>
#include <lib/ui/scenic/cpp/session.h>
#include <vulkan/vulkan.h>
#include <unordered_map>
......@@ -23,10 +24,11 @@
namespace ui {
class SysmemBufferCollection;
class ScenicSurfaceFactory;
class SysmemBufferManager {
public:
explicit SysmemBufferManager();
explicit SysmemBufferManager(ScenicSurfaceFactory* scenic_surface_factory);
~SysmemBufferManager();
// Initializes the buffer manager with a connection to the sysmem service.
......@@ -51,7 +53,8 @@ class SysmemBufferManager {
gfx::BufferFormat format,
gfx::BufferUsage usage,
size_t min_buffer_count,
bool force_protected);
bool force_protected,
bool register_with_image_pipe);
scoped_refptr<SysmemBufferCollection> GetCollectionById(
gfx::SysmemBufferCollectionId id);
......@@ -60,6 +63,7 @@ class SysmemBufferManager {
void RegisterCollection(SysmemBufferCollection* collection);
void OnCollectionDestroyed(gfx::SysmemBufferCollectionId id);
ScenicSurfaceFactory* const scenic_surface_factory_;
fuchsia::sysmem::AllocatorSyncPtr allocator_;
base::small_map<std::unordered_map<gfx::SysmemBufferCollectionId,
......
......@@ -302,14 +302,16 @@ VulkanImplementationScenic::RegisterSysmemBufferCollection(
gfx::BufferFormat format,
gfx::BufferUsage usage,
gfx::Size size,
size_t min_buffer_count) {
size_t min_buffer_count,
bool register_with_image_pipe) {
// SCANOUT images must be protected in protected mode.
bool force_protected =
usage == gfx::BufferUsage::SCANOUT && enforce_protected_memory();
fuchsia::images::ImagePipe2Ptr image_pipe = nullptr;
auto buffer_collection = sysmem_buffer_manager_->ImportSysmemBufferCollection(
device, id, std::move(token), size, format, usage, min_buffer_count,
force_protected);
force_protected, register_with_image_pipe);
if (!buffer_collection)
return nullptr;
......
......@@ -60,7 +60,8 @@ class VulkanImplementationScenic : public gpu::VulkanImplementation {
gfx::BufferFormat format,
gfx::BufferUsage usage,
gfx::Size size,
size_t min_buffer_count) override;
size_t min_buffer_count,
bool register_with_image_pipe) override;
private:
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