aboutsummaryrefslogtreecommitdiff
path: root/tools/Vulkan-Tools/cube/fuchsia
diff options
context:
space:
mode:
authorLizzy Fleckenstein <lizzy@vlhl.dev>2026-03-31 01:30:36 +0200
committerLizzy Fleckenstein <lizzy@vlhl.dev>2026-03-31 01:30:36 +0200
commit8e2ff15dbd3fe70fe2b52397b1eaba3fe2d7a5e8 (patch)
tree925fa596210d1a1f01e00e0743a643f4552e7a7a /tools/Vulkan-Tools/cube/fuchsia
parent1f17b4df127bd280e50d93a46ae93df704adc2b0 (diff)
parent90bf5bc4fd8bea0d300f6564af256a51a34124b8 (diff)
downloadusermoji-8e2ff15dbd3fe70fe2b52397b1eaba3fe2d7a5e8.tar.xz
add tools/Vulkan-Tools
Diffstat (limited to 'tools/Vulkan-Tools/cube/fuchsia')
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/flatland_view.cpp210
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/flatland_view.h102
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb-protected.cml27
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb.cml26
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic-protected.cml45
-rw-r--r--tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic.cml36
6 files changed, 446 insertions, 0 deletions
diff --git a/tools/Vulkan-Tools/cube/fuchsia/flatland_view.cpp b/tools/Vulkan-Tools/cube/fuchsia/flatland_view.cpp
new file mode 100644
index 00000000..029c07d3
--- /dev/null
+++ b/tools/Vulkan-Tools/cube/fuchsia/flatland_view.cpp
@@ -0,0 +1,210 @@
+// Copyright (c) 2025 The Fuchsia Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "flatland_view.h"
+
+#include <fidl/fuchsia.ui.app/cpp/fidl.h>
+#include <fidl/fuchsia.ui.composition/cpp/fidl.h>
+#include <fidl/fuchsia.ui.views/cpp/fidl.h>
+#include <lib/component/incoming/cpp/protocol.h>
+#include <lib/component/outgoing/cpp/outgoing_directory.h>
+#include <lib/syslog/cpp/macros.h>
+#include <lib/syslog/global.h>
+#include <lib/ui/scenic/cpp/view_creation_tokens.h>
+#include <lib/ui/scenic/cpp/view_identity.h>
+
+#include <cinttypes>
+
+namespace {
+
+const char* const kTag = "FlatlandView";
+
+const fuchsia_ui_composition::TransformId kRootTransform = {1};
+const fuchsia_ui_composition::ContentId kViewport = {1};
+
+} // namespace
+
+// static
+std::unique_ptr<FlatlandView> FlatlandView::Create(fidl::UnownedClientEnd<fuchsia_io::Directory> service_directory,
+ fuchsia_ui_views::ViewCreationToken view_creation_token,
+ ResizeCallback resize_callback, async_dispatcher_t* dispatcher) {
+ ZX_DEBUG_ASSERT(dispatcher != nullptr);
+ auto view = std::make_unique<FlatlandView>(std::move(resize_callback), dispatcher);
+ if (!view) return nullptr;
+ if (!view->Init(service_directory, std::move(view_creation_token))) return nullptr;
+ return view;
+}
+
+FlatlandView::FlatlandView(ResizeCallback resize_callback, async_dispatcher_t* dispatcher)
+ : resize_callback_(std::move(resize_callback)), dispatcher_(dispatcher) {
+ ZX_DEBUG_ASSERT(dispatcher != nullptr);
+}
+
+bool FlatlandView::Init(fidl::UnownedClientEnd<fuchsia_io::Directory> service_directory,
+ fuchsia_ui_views::ViewCreationToken view_creation_token) {
+ zx::result<fidl::ClientEnd<fuchsia_ui_composition::Flatland>> connect_result =
+ component::ConnectAt<fuchsia_ui_composition::Flatland>(service_directory);
+ if (connect_result.is_error()) {
+ FX_LOGS(ERROR) << "Failed to connect to Flatland: " << connect_result.status_string();
+ return false;
+ }
+ fidl::ClientEnd<fuchsia_ui_composition::Flatland> flatland_client = std::move(connect_result).value();
+ flatland_.Bind(std::move(flatland_client), dispatcher_, /*event_handler=*/this);
+ fit::result<fidl::OneWayError> set_debug_name_result = flatland_->SetDebugName({{.name = kTag}});
+ if (set_debug_name_result.is_error()) {
+ FX_LOGS(ERROR) << "Failed to set debug name: " << set_debug_name_result.error_value().FormatDescription();
+ }
+
+ fit::result<fidl::OneWayError> create_transform_result = flatland_->CreateTransform(kRootTransform);
+ if (create_transform_result.is_error()) {
+ FX_LOGS(ERROR) << "Failed to call CreateTransform: " << create_transform_result.error_value().FormatDescription();
+ return false;
+ }
+
+ fit::result<fidl::OneWayError> set_root_transform_result = flatland_->SetRootTransform(kRootTransform);
+ if (set_root_transform_result.is_error()) {
+ FX_LOGS(ERROR) << "Failed to call SetRootTransform: " << set_root_transform_result.error_value().FormatDescription();
+ return false;
+ }
+
+ auto [parent_viewport_watcher_client, parent_viewport_watcher_server] =
+ fidl::Endpoints<fuchsia_ui_composition::ParentViewportWatcher>::Create();
+ fit::result<fidl::OneWayError> create_view2_result = flatland_->CreateView2({{
+ .token = std::move(view_creation_token),
+ .view_identity = scenic::cpp::NewViewIdentityOnCreation(),
+ .protocols = {},
+ .parent_viewport_watcher = std::move(parent_viewport_watcher_server),
+ }});
+ if (create_view2_result.is_error()) {
+ FX_LOGS(ERROR) << "Failed to call CreateView2: " << set_root_transform_result.error_value().FormatDescription();
+ return false;
+ }
+
+ parent_viewport_watcher_.Bind(std::move(parent_viewport_watcher_client), dispatcher_);
+ parent_viewport_watcher_->GetLayout().Then(
+ [this](fidl::Result<fuchsia_ui_composition::ParentViewportWatcher::GetLayout>& result) {
+ if (result.is_error()) {
+ FX_LOGS(ERROR) << "GetLayout() failed: " << result.error_value().FormatDescription();
+ return;
+ }
+ OnGetLayout(std::move(result.value().info()));
+ });
+
+ zx::channel::create(0, &viewport_creation_token_.value(), &child_view_creation_token_.value());
+
+ return true;
+}
+
+void FlatlandView::OnGetLayout(fuchsia_ui_composition::LayoutInfo info) {
+ ZX_DEBUG_ASSERT(info.logical_size().has_value());
+ const fuchsia_math::SizeU& logical_size = info.logical_size().value();
+ resize_callback_(logical_size.width(), logical_size.height());
+
+ fuchsia_ui_composition::ViewportProperties properties = {{.logical_size = logical_size}};
+ if (viewport_creation_token_.value().is_valid()) {
+ // The first time that we receive layout information, create a viewport using the token that was stashed during Init().
+ // External code will attach a view to this viewport via the token obtained from TakeChildViewCreationToken().
+ auto [child_view_watcher_client, child_view_watcher_server] =
+ fidl::Endpoints<fuchsia_ui_composition::ChildViewWatcher>::Create();
+ fit::result<fidl::OneWayError> create_viewport_result = flatland_->CreateViewport({{
+ .viewport_id = kViewport,
+ .token = std::move(viewport_creation_token_),
+ .properties = std::move(properties),
+ .child_view_watcher = std::move(child_view_watcher_server),
+ }});
+ if (create_viewport_result.is_error()) {
+ FX_LOGS(ERROR) << "Failed to call CreateViewport(): " << create_viewport_result.error_value().FormatDescription();
+ return;
+ }
+
+ fit::result<fidl::OneWayError> set_content_result = flatland_->SetContent({{
+ .transform_id = kRootTransform,
+ .content_id = kViewport,
+ }});
+ if (set_content_result.is_error()) {
+ FX_LOGS(ERROR) << "Failed to call SetContent(): " << set_content_result.error_value().FormatDescription();
+ return;
+ }
+ } else {
+ auto set_viewport_properties_result = flatland_->SetViewportProperties({{
+ .viewport_id = kViewport,
+ .properties = std::move(properties),
+ }});
+ if (set_viewport_properties_result.is_error()) {
+ FX_LOGS(ERROR) << "Failed to call SetViewportProperties(): "
+ << set_viewport_properties_result.error_value().FormatDescription();
+ return;
+ }
+ }
+
+ Present();
+ parent_viewport_watcher_->GetLayout().Then(
+ [this](fidl::Result<fuchsia_ui_composition::ParentViewportWatcher::GetLayout>& result) {
+ if (result.is_error()) {
+ FX_LOGS(ERROR) << "GetLayout() failed: " << result.error_value().FormatDescription();
+ return;
+ }
+ OnGetLayout(std::move(result.value().info()));
+ });
+}
+
+void FlatlandView::OnError(fidl::Event<fuchsia_ui_composition::Flatland::OnError>& event) {
+ FX_LOGF(ERROR, kTag, "OnFlatlandError: %" PRIu32, static_cast<uint32_t>(event.error()));
+}
+
+void FlatlandView::Present() {
+ if (present_credits_ == 0) {
+ pending_present_ = true;
+ return;
+ }
+ --present_credits_;
+ fuchsia_ui_composition::PresentArgs present_args = {{
+ .requested_presentation_time = 0,
+ .acquire_fences = {},
+ .release_fences = {},
+ .unsquashable = false,
+ }};
+ fit::result<fidl::OneWayError> present_result = flatland_->Present(std::move(present_args));
+ if (present_result.is_error()) {
+ FX_LOGS(ERROR) << "Failed to call Present(): " << present_result.error_value().FormatDescription();
+ }
+}
+
+void FlatlandView::OnFramePresented(fidl::Event<fuchsia_ui_composition::Flatland::OnFramePresented>& event) {}
+
+void FlatlandView::OnNextFrameBegin(fidl::Event<fuchsia_ui_composition::Flatland::OnNextFrameBegin>& event) {
+ present_credits_ += event.values().additional_present_credits().value_or(0);
+ if (present_credits_ > 0 && pending_present_) {
+ Present();
+ pending_present_ = false;
+ }
+}
+
+FlatlandViewProviderService::FlatlandViewProviderService(CreateView2Callback create_view_callback, async_dispatcher_t* dispatcher)
+ : create_view_callback_(std::move(create_view_callback)), dispatcher_(dispatcher) {
+ ZX_DEBUG_ASSERT(dispatcher != nullptr);
+}
+
+void FlatlandViewProviderService::CreateViewWithViewRef(CreateViewWithViewRefRequest& request,
+ CreateViewWithViewRefCompleter::Sync& completer) {
+ FX_NOTIMPLEMENTED() << "Only Flatland is supported. This is a Gfx ViewProvider method.";
+}
+
+void FlatlandViewProviderService::CreateView2(CreateView2Request& request, CreateView2Completer::Sync& completer) {
+ create_view_callback_(std::move(request.args()));
+}
+
+void FlatlandViewProviderService::HandleViewProviderRequest(fidl::ServerEnd<fuchsia_ui_app::ViewProvider> server_end) {
+ bindings_.AddBinding(dispatcher_, std::move(server_end), this, fidl::kIgnoreBindingClosure);
+}
diff --git a/tools/Vulkan-Tools/cube/fuchsia/flatland_view.h b/tools/Vulkan-Tools/cube/fuchsia/flatland_view.h
new file mode 100644
index 00000000..01a8c6f9
--- /dev/null
+++ b/tools/Vulkan-Tools/cube/fuchsia/flatland_view.h
@@ -0,0 +1,102 @@
+// Copyright (c) 2025 The Fuchsia Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef FUCHSIA_FLATLAND_VIEW_H_
+#define FUCHSIA_FLATLAND_VIEW_H_
+
+#include <fidl/fuchsia.io/cpp/fidl.h>
+#include <fidl/fuchsia.ui.app/cpp/fidl.h>
+#include <fidl/fuchsia.ui.composition/cpp/fidl.h>
+#include <fidl/fuchsia.ui.views/cpp/fidl.h>
+#include <lib/fit/function.h>
+#include <lib/async/dispatcher.h>
+#include <lib/syslog/cpp/macros.h>
+
+#include <cstdint>
+#include <utility>
+
+#include <memory>
+
+// This class provides a convenient wrapper around the scenic fidl apis needed to get a Flatland
+// View. Only SDK available constructs should be used so that this code may be leveraged by Vulkan
+// applications built with the SDK.
+class FlatlandView : public fidl::AsyncEventHandler<fuchsia_ui_composition::Flatland> {
+ public:
+ using ResizeCallback = fit::function<void(uint32_t width, uint32_t height)>;
+
+ // Creates and initializes a `FlatlandView` instance.
+ //
+ // `dispatcher` must be non-null.
+ static std::unique_ptr<FlatlandView> Create(fidl::UnownedClientEnd<fuchsia_io::Directory> service_directory,
+ fuchsia_ui_views::ViewCreationToken view_creation_token,
+ ResizeCallback resize_callback, async_dispatcher_t* dispatcher);
+
+ // Production code must use the `Create()` factory method.
+ //
+ // `dispatcher` must be non-null.
+ explicit FlatlandView(ResizeCallback resize_callback, async_dispatcher_t* dispatcher);
+
+ fuchsia_ui_views::ViewCreationToken TakeChildViewCreationToken() {
+ FX_DCHECK(child_view_creation_token_.value().is_valid());
+ return std::move(child_view_creation_token_);
+ }
+
+ bool Init(fidl::UnownedClientEnd<fuchsia_io::Directory> service_directory,
+ fuchsia_ui_views::ViewCreationToken view_creation_token);
+
+ private:
+ void OnNextFrameBegin(fidl::Event<fuchsia_ui_composition::Flatland::OnNextFrameBegin>& event) override;
+ void OnFramePresented(fidl::Event<fuchsia_ui_composition::Flatland::OnFramePresented>& event) override;
+ void OnError(fidl::Event<fuchsia_ui_composition::Flatland::OnError>& event) override;
+
+ void OnGetLayout(fuchsia_ui_composition::LayoutInfo info);
+ void OnFlatlandError(fuchsia_ui_composition::FlatlandError error);
+ void Present();
+
+ fidl::SharedClient<fuchsia_ui_composition::Flatland> flatland_;
+ fidl::SharedClient<fuchsia_ui_composition::ParentViewportWatcher> parent_viewport_watcher_;
+
+ fuchsia_ui_views::ViewportCreationToken viewport_creation_token_;
+ fuchsia_ui_views::ViewCreationToken child_view_creation_token_;
+ ResizeCallback resize_callback_;
+
+ int64_t present_credits_ = 1;
+ bool pending_present_ = false;
+
+ async_dispatcher_t* const dispatcher_;
+
+ friend class FlatlandViewTest;
+};
+
+class FlatlandViewProviderService : public fidl::Server<fuchsia_ui_app::ViewProvider> {
+ public:
+ using CreateView2Callback = fit::function<void(fuchsia_ui_app::CreateView2Args args)>;
+
+ // `dispatcher` must be non-null.
+ explicit FlatlandViewProviderService(CreateView2Callback create_view_callback, async_dispatcher_t* dispatcher);
+
+ // fuchsia::ui::app::ViewProvider methods.
+ void CreateViewWithViewRef(CreateViewWithViewRefRequest& request, CreateViewWithViewRefCompleter::Sync& completer) override;
+ void CreateView2(CreateView2Request& request, CreateView2Completer::Sync& completer) override;
+
+ void HandleViewProviderRequest(fidl::ServerEnd<fuchsia_ui_app::ViewProvider> server_end);
+
+ private:
+ CreateView2Callback create_view_callback_;
+ fidl::ServerBindingGroup<fuchsia_ui_app::ViewProvider> bindings_;
+
+ async_dispatcher_t* const dispatcher_;
+};
+
+#endif // FUCHSIA_FLATLAND_VIEW_H_
diff --git a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb-protected.cml b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb-protected.cml
new file mode 100644
index 00000000..43d51a6e
--- /dev/null
+++ b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb-protected.cml
@@ -0,0 +1,27 @@
+// Copyright (c) 2025 The Fuchsia Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+{
+ include: [
+ "//src/lib/vulkan/swapchain/VkLayer_image_pipe_swapchain_fb.shard.cml",
+ "sys/testing/elf_test_runner.shard.cml",
+ ],
+ program: {
+ binary: "bin/vkcube",
+ args: [
+ "--protected_output",
+ "--wsi",
+ "fuchsia_display",
+ ],
+ },
+}
diff --git a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb.cml b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb.cml
new file mode 100644
index 00000000..eaa78aae
--- /dev/null
+++ b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-fb.cml
@@ -0,0 +1,26 @@
+// Copyright (c) 2025 The Fuchsia Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+{
+ include: [
+ "//src/lib/vulkan/swapchain/VkLayer_image_pipe_swapchain_fb.shard.cml",
+ "sys/testing/elf_test_runner.shard.cml",
+ ],
+ program: {
+ binary: "bin/vkcube",
+ args: [
+ "--wsi",
+ "fuchsia_display",
+ ],
+ },
+}
diff --git a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic-protected.cml b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic-protected.cml
new file mode 100644
index 00000000..3138b605
--- /dev/null
+++ b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic-protected.cml
@@ -0,0 +1,45 @@
+// Copyright (c) 2025 The Fuchsia Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+{
+ include: [ "//src/lib/vulkan/swapchain/VkLayer_image_pipe_swapchain.shard.cml" ],
+ program: {
+ runner: "elf",
+ binary: "bin/vkcube",
+ args: [
+ "--protected_output",
+ "--wsi",
+ "fuchsia_scenic",
+ ],
+ },
+ capabilities: [
+ {
+ protocol: [ "fuchsia.ui.app.ViewProvider" ],
+ },
+ ],
+ use: [
+ {
+ protocol: [
+ "fuchsia.ui.composition.Allocator",
+ "fuchsia.ui.composition.Flatland",
+ ],
+ },
+ ],
+ expose: [
+ {
+ protocol: [ "fuchsia.ui.app.ViewProvider" ],
+ from: "self",
+ to: "parent",
+ },
+ ],
+}
diff --git a/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic.cml b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic.cml
new file mode 100644
index 00000000..cf940b5b
--- /dev/null
+++ b/tools/Vulkan-Tools/cube/fuchsia/meta/vkcube-on-scenic.cml
@@ -0,0 +1,36 @@
+// Copyright (c) 2025 The Fuchsia Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+{
+ include: [ "//src/lib/vulkan/swapchain/VkLayer_image_pipe_swapchain.shard.cml" ],
+ program: {
+ runner: "elf",
+ binary: "bin/vkcube",
+ args: [
+ "--wsi",
+ "fuchsia_scenic",
+ ],
+ },
+ capabilities: [
+ {
+ protocol: [ "fuchsia.ui.app.ViewProvider" ],
+ },
+ ],
+ expose: [
+ {
+ protocol: [ "fuchsia.ui.app.ViewProvider" ],
+ from: "self",
+ to: "parent",
+ },
+ ],
+}