Commit e2c42e85 authored by Michael Spang's avatar Michael Spang Committed by Commit Bot

ozone: scenic: Move vulkan surface resources out of browser's Scenic session

This creates a new session with the system compositor (Scenic) and uses
it to create the vulkan surface resources. This is necessary in order to
support vulkan surfaces from the GPU process, since the browser Scenic
session will not be accessible there.

In order for this to work, we need to be able to run platform code when a
gpu::VulkanSurface is destroyed. To accomplish this, this adds a
destruction callback to gpu::VulkanSurface which cleans up the Scenic
resources associated with the surface.

Bug: 861853
Test: run_content_shell --ozone-platform=scenic --disable-gpu --enable-vulkan

Change-Id: If08c25746ba73569afae63040a7f6551861eeaad
Reviewed-on: https://chromium-review.googlesource.com/c/1343238
Commit-Queue: Michael Spang <spang@chromium.org>
Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Reviewed-by: default avatarSergey Ulanov <sergeyu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611830}
parent 9d0b6c88
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "gpu/vulkan/android/vulkan_implementation_android.h" #include "gpu/vulkan/android/vulkan_implementation_android.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/logging.h" #include "base/logging.h"
#include "gpu/vulkan/vulkan_device_queue.h" #include "gpu/vulkan/vulkan_device_queue.h"
...@@ -69,7 +70,8 @@ std::unique_ptr<VulkanSurface> VulkanImplementationAndroid::CreateViewSurface( ...@@ -69,7 +70,8 @@ std::unique_ptr<VulkanSurface> VulkanImplementationAndroid::CreateViewSurface(
return nullptr; return nullptr;
} }
return std::make_unique<VulkanSurface>(GetVulkanInstance(), surface); return std::make_unique<VulkanSurface>(GetVulkanInstance(), surface,
base::DoNothing());
} }
bool VulkanImplementationAndroid::GetPhysicalDevicePresentationSupport( bool VulkanImplementationAndroid::GetPhysicalDevicePresentationSupport(
......
...@@ -30,8 +30,12 @@ VulkanSurface::~VulkanSurface() { ...@@ -30,8 +30,12 @@ VulkanSurface::~VulkanSurface() {
DCHECK_EQ(static_cast<VkSurfaceKHR>(VK_NULL_HANDLE), surface_); DCHECK_EQ(static_cast<VkSurfaceKHR>(VK_NULL_HANDLE), surface_);
} }
VulkanSurface::VulkanSurface(VkInstance vk_instance, VkSurfaceKHR surface) VulkanSurface::VulkanSurface(VkInstance vk_instance,
: vk_instance_(vk_instance), surface_(surface) { VkSurfaceKHR surface,
base::OnceClosure destruction_callback)
: vk_instance_(vk_instance),
surface_(surface),
destruction_callback_(std::move(destruction_callback)) {
DCHECK_NE(static_cast<VkSurfaceKHR>(VK_NULL_HANDLE), surface_); DCHECK_NE(static_cast<VkSurfaceKHR>(VK_NULL_HANDLE), surface_);
} }
...@@ -114,6 +118,7 @@ void VulkanSurface::Destroy() { ...@@ -114,6 +118,7 @@ void VulkanSurface::Destroy() {
swap_chain_->Destroy(); swap_chain_->Destroy();
vkDestroySurfaceKHR(vk_instance_, surface_, nullptr); vkDestroySurfaceKHR(vk_instance_, surface_, nullptr);
surface_ = VK_NULL_HANDLE; surface_ = VK_NULL_HANDLE;
std::move(destruction_callback_).Run();
} }
gfx::SwapResult VulkanSurface::SwapBuffers() { gfx::SwapResult VulkanSurface::SwapBuffers() {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include "base/callback.h"
#include "gpu/vulkan/vulkan_device_queue.h" #include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_export.h" #include "gpu/vulkan/vulkan_export.h"
#include "gpu/vulkan/vulkan_swap_chain.h" #include "gpu/vulkan/vulkan_swap_chain.h"
...@@ -29,7 +30,9 @@ class VULKAN_EXPORT VulkanSurface { ...@@ -29,7 +30,9 @@ class VULKAN_EXPORT VulkanSurface {
DEFAULT_SURFACE_FORMAT = FORMAT_RGBA_32 DEFAULT_SURFACE_FORMAT = FORMAT_RGBA_32
}; };
VulkanSurface(VkInstance vk_instance, VkSurfaceKHR surface); VulkanSurface(VkInstance vk_instance,
VkSurfaceKHR surface,
base::OnceClosure destruction_callback);
~VulkanSurface(); ~VulkanSurface();
...@@ -55,6 +58,9 @@ class VULKAN_EXPORT VulkanSurface { ...@@ -55,6 +58,9 @@ class VULKAN_EXPORT VulkanSurface {
VulkanDeviceQueue* device_queue_ = nullptr; VulkanDeviceQueue* device_queue_ = nullptr;
std::unique_ptr<VulkanSwapChain> swap_chain_; std::unique_ptr<VulkanSwapChain> swap_chain_;
// Called after destruction to clean up platform state, if any.
base::OnceClosure destruction_callback_;
DISALLOW_COPY_AND_ASSIGN(VulkanSurface); DISALLOW_COPY_AND_ASSIGN(VulkanSurface);
}; };
......
...@@ -78,7 +78,8 @@ std::unique_ptr<VulkanSurface> VulkanImplementationWin32::CreateViewSurface( ...@@ -78,7 +78,8 @@ std::unique_ptr<VulkanSurface> VulkanImplementationWin32::CreateViewSurface(
return nullptr; return nullptr;
} }
return std::make_unique<VulkanSurface>(GetVulkanInstance(), surface); return std::make_unique<VulkanSurface>(GetVulkanInstance(), surface,
base::DoNothing());
} }
bool VulkanImplementationWin32::GetPhysicalDevicePresentationSupport( bool VulkanImplementationWin32::GetPhysicalDevicePresentationSupport(
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "gpu/vulkan/x/vulkan_implementation_x11.h" #include "gpu/vulkan/x/vulkan_implementation_x11.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/logging.h" #include "base/logging.h"
#include "gpu/vulkan/vulkan_function_pointers.h" #include "gpu/vulkan/vulkan_function_pointers.h"
...@@ -82,7 +83,8 @@ std::unique_ptr<VulkanSurface> VulkanImplementationX11::CreateViewSurface( ...@@ -82,7 +83,8 @@ std::unique_ptr<VulkanSurface> VulkanImplementationX11::CreateViewSurface(
return nullptr; return nullptr;
} }
return std::make_unique<VulkanSurface>(GetVulkanInstance(), surface); return std::make_unique<VulkanSurface>(GetVulkanInstance(), surface,
base::DoNothing());
} }
bool VulkanImplementationX11::GetPhysicalDevicePresentationSupport( bool VulkanImplementationX11::GetPhysicalDevicePresentationSupport(
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <lib/zx/event.h> #include <lib/zx/event.h>
#include "base/fuchsia/component_context.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "ui/gfx/native_pixmap.h" #include "ui/gfx/native_pixmap.h"
...@@ -108,6 +110,17 @@ ScenicSurfaceFactory::ScenicSurfaceFactory(ScenicWindowManager* window_manager) ...@@ -108,6 +110,17 @@ ScenicSurfaceFactory::ScenicSurfaceFactory(ScenicWindowManager* window_manager)
ScenicSurfaceFactory::~ScenicSurfaceFactory() = default; ScenicSurfaceFactory::~ScenicSurfaceFactory() = default;
fuchsia::ui::scenic::Scenic* ScenicSurfaceFactory::GetScenic() {
if (!scenic_) {
scenic_ = base::fuchsia::ComponentContext::GetDefault()
->ConnectToService<fuchsia::ui::scenic::Scenic>();
scenic_.set_error_handler([](zx_status_t status) {
ZX_LOG(FATAL, status) << "Scenic connection failed";
});
}
return scenic_.get();
}
std::vector<gl::GLImplementation> std::vector<gl::GLImplementation>
ScenicSurfaceFactory::GetAllowedGLImplementations() { ScenicSurfaceFactory::GetAllowedGLImplementations() {
// TODO(spang): Remove this after crbug.com/897208 is fixed. // TODO(spang): Remove this after crbug.com/897208 is fixed.
...@@ -128,7 +141,7 @@ std::unique_ptr<SurfaceOzoneCanvas> ScenicSurfaceFactory::CreateCanvasForWidget( ...@@ -128,7 +141,7 @@ std::unique_ptr<SurfaceOzoneCanvas> ScenicSurfaceFactory::CreateCanvasForWidget(
ScenicWindow* window = window_manager_->GetWindow(widget); ScenicWindow* window = window_manager_->GetWindow(widget);
if (!window) if (!window)
return nullptr; return nullptr;
return std::make_unique<ScenicWindowCanvas>(window); return std::make_unique<ScenicWindowCanvas>(GetScenic(), window);
} }
scoped_refptr<gfx::NativePixmap> ScenicSurfaceFactory::CreateNativePixmap( scoped_refptr<gfx::NativePixmap> ScenicSurfaceFactory::CreateNativePixmap(
...@@ -142,7 +155,8 @@ scoped_refptr<gfx::NativePixmap> ScenicSurfaceFactory::CreateNativePixmap( ...@@ -142,7 +155,8 @@ scoped_refptr<gfx::NativePixmap> ScenicSurfaceFactory::CreateNativePixmap(
#if BUILDFLAG(ENABLE_VULKAN) #if BUILDFLAG(ENABLE_VULKAN)
std::unique_ptr<gpu::VulkanImplementation> std::unique_ptr<gpu::VulkanImplementation>
ScenicSurfaceFactory::CreateVulkanImplementation() { ScenicSurfaceFactory::CreateVulkanImplementation() {
return std::make_unique<ui::VulkanImplementationScenic>(window_manager_); return std::make_unique<ui::VulkanImplementationScenic>(window_manager_,
GetScenic());
} }
#endif #endif
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef UI_OZONE_PLATFORM_SCENIC_SCENIC_SURFACE_FACTORY_H_ #ifndef UI_OZONE_PLATFORM_SCENIC_SCENIC_SURFACE_FACTORY_H_
#define UI_OZONE_PLATFORM_SCENIC_SCENIC_SURFACE_FACTORY_H_ #define UI_OZONE_PLATFORM_SCENIC_SCENIC_SURFACE_FACTORY_H_
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <memory> #include <memory>
#include <vector> #include <vector>
...@@ -38,8 +39,11 @@ class ScenicSurfaceFactory : public SurfaceFactoryOzone { ...@@ -38,8 +39,11 @@ class ScenicSurfaceFactory : public SurfaceFactoryOzone {
#endif #endif
private: private:
fuchsia::ui::scenic::Scenic* GetScenic();
ScenicWindowManager* const window_manager_; ScenicWindowManager* const window_manager_;
std::unique_ptr<GLOzone> egl_implementation_; std::unique_ptr<GLOzone> egl_implementation_;
fuchsia::ui::scenic::ScenicPtr scenic_;
DISALLOW_COPY_AND_ASSIGN(ScenicSurfaceFactory); DISALLOW_COPY_AND_ASSIGN(ScenicSurfaceFactory);
}; };
......
...@@ -33,8 +33,8 @@ ScenicWindow::ScenicWindow(ScenicWindowManager* window_manager, ...@@ -33,8 +33,8 @@ ScenicWindow::ScenicWindow(ScenicWindowManager* window_manager,
scenic_session_(manager_->GetScenic()), scenic_session_(manager_->GetScenic()),
parent_node_(&scenic_session_), parent_node_(&scenic_session_),
node_(&scenic_session_), node_(&scenic_session_),
shape_node_(&scenic_session_), input_node_(&scenic_session_),
material_(&scenic_session_), render_node_(&scenic_session_),
input_listener_binding_(this) { input_listener_binding_(this) {
scenic_session_.set_error_handler( scenic_session_.set_error_handler(
fit::bind_member(this, &ScenicWindow::OnScenicError)); fit::bind_member(this, &ScenicWindow::OnScenicError));
...@@ -45,13 +45,19 @@ ScenicWindow::ScenicWindow(ScenicWindowManager* window_manager, ...@@ -45,13 +45,19 @@ ScenicWindow::ScenicWindow(ScenicWindowManager* window_manager,
zx::eventpair parent_export_token; zx::eventpair parent_export_token;
parent_node_.BindAsRequest(&parent_export_token); parent_node_.BindAsRequest(&parent_export_token);
// Setup entity node for the window.
node_.AddChild(shape_node_);
shape_node_.SetMaterial(material_);
// Subscribe to metrics events from the parent node. These events are used to // Subscribe to metrics events from the parent node. These events are used to
// get the device pixel ratio for the screen. // get the device pixel ratio for the screen.
parent_node_.SetEventMask(fuchsia::ui::gfx::kMetricsEventMask); parent_node_.SetEventMask(fuchsia::ui::gfx::kMetricsEventMask);
parent_node_.AddChild(node_);
// Add input shape.
input_node_.SetShape(scenic::Rectangle(&scenic_session_, 1.f, 1.f));
node_.AddChild(input_node_);
// Add rendering subtree. Hit testing is disabled to prevent GPU process from
// receiving input.
render_node_.SetHitTestBehavior(fuchsia::ui::gfx::HitTestBehavior::kSuppress);
node_.AddChild(render_node_);
// Create the view. // Create the view.
manager_->GetViewManager()->CreateView2( manager_->GetViewManager()->CreateView2(
...@@ -83,12 +89,15 @@ ScenicWindow::~ScenicWindow() { ...@@ -83,12 +89,15 @@ ScenicWindow::~ScenicWindow() {
manager_->RemoveWindow(window_id_, this); manager_->RemoveWindow(window_id_, this);
} }
void ScenicWindow::SetTexture(const scenic::Image& image) { void ScenicWindow::ExportRenderingEntity(zx::eventpair export_token) {
material_.SetTexture(image); scenic::EntityNode export_node(&scenic_session_);
}
void ScenicWindow::SetTexture(uint32_t image_id) { render_node_.DetachChildren();
material_.SetTexture(image_id); render_node_.AddChild(export_node);
export_node.Export(std::move(export_token));
scenic_session_.Present(
/*presentation_time=*/0, [](fuchsia::images::PresentationInfo info) {});
} }
gfx::Rect ScenicWindow::GetBounds() { gfx::Rect ScenicWindow::GetBounds() {
...@@ -190,10 +199,6 @@ void ScenicWindow::UpdateSize() { ...@@ -190,10 +199,6 @@ void ScenicWindow::UpdateSize() {
if (screen) if (screen)
screen->OnWindowBoundsChanged(window_id_, size_rect); screen->OnWindowBoundsChanged(window_id_, size_rect);
// Set node shape to rectangle that matches size of the view.
scenic::Rectangle rect(&scenic_session_, 1.f, 1.f);
shape_node_.SetShape(rect);
// Translate the node by half of the view dimensions to put it in the center // Translate the node by half of the view dimensions to put it in the center
// of the view. // of the view.
node_.SetTranslation(size_dips_.width() / 2.0, size_dips_.height() / 2.0, node_.SetTranslation(size_dips_.width() / 2.0, size_dips_.height() / 2.0,
......
...@@ -40,11 +40,8 @@ class OZONE_EXPORT ScenicWindow : public PlatformWindow, ...@@ -40,11 +40,8 @@ class OZONE_EXPORT ScenicWindow : public PlatformWindow,
~ScenicWindow() override; ~ScenicWindow() override;
scenic::Session* scenic_session() { return &scenic_session_; } scenic::Session* scenic_session() { return &scenic_session_; }
const scenic::Node& node() const { return node_; }
// Sets texture of the window. |image| must be created in scenic_session(). void ExportRenderingEntity(zx::eventpair export_token);
void SetTexture(const scenic::Image& image);
void SetTexture(uint32_t image_id);
// PlatformWindow implementation. // PlatformWindow implementation.
gfx::Rect GetBounds() override; gfx::Rect GetBounds() override;
...@@ -106,17 +103,17 @@ class OZONE_EXPORT ScenicWindow : public PlatformWindow, ...@@ -106,17 +103,17 @@ class OZONE_EXPORT ScenicWindow : public PlatformWindow,
// Scenic session used for all drawing operations in this View. // Scenic session used for all drawing operations in this View.
scenic::Session scenic_session_; scenic::Session scenic_session_;
// Node ID in |scenic_session_| for the parent view. // Node in |scenic_session_| for the parent view.
scenic::ImportNode parent_node_; scenic::ImportNode parent_node_;
// Node ID in |scenic_session_| for the view. // Node in |scenic_session_| for the parent view.
scenic::EntityNode node_; scenic::EntityNode node_;
// Shape and material resources for the view in the context of // Node in |scenic_session_| for receiving input that hits within our View.
// |scenic_session_|. They are used to set shape and texture for the view scenic::ShapeNode input_node_;
// node.
scenic::ShapeNode shape_node_; // Node in |scenic_session_| for rendering (hit testing disabled).
scenic::Material material_; scenic::EntityNode render_node_;
// The ratio used for translating device-independent coordinates to absolute // The ratio used for translating device-independent coordinates to absolute
// pixel coordinates. // pixel coordinates.
......
...@@ -66,8 +66,21 @@ void ScenicWindowCanvas::Frame::CopyDirtyRegionFrom(const Frame& frame) { ...@@ -66,8 +66,21 @@ void ScenicWindowCanvas::Frame::CopyDirtyRegionFrom(const Frame& frame) {
dirty_region.setEmpty(); dirty_region.setEmpty();
} }
ScenicWindowCanvas::ScenicWindowCanvas(ScenicWindow* window) ScenicWindowCanvas::ScenicWindowCanvas(fuchsia::ui::scenic::Scenic* scenic,
: window_(window) {} ScenicWindow* window)
: window_(window),
scenic_session_(scenic),
parent_(&scenic_session_),
material_(&scenic_session_) {
scenic::ShapeNode shape(&scenic_session_);
shape.SetShape(scenic::Rectangle(&scenic_session_, 1.f, 1.f));
shape.SetMaterial(material_);
zx::eventpair export_token;
parent_.BindAsRequest(&export_token);
parent_.AddChild(shape);
window_->ExportRenderingEntity(std::move(export_token));
}
ScenicWindowCanvas::~ScenicWindowCanvas() = default; ScenicWindowCanvas::~ScenicWindowCanvas() = default;
...@@ -75,11 +88,9 @@ void ScenicWindowCanvas::ResizeCanvas(const gfx::Size& viewport_size) { ...@@ -75,11 +88,9 @@ void ScenicWindowCanvas::ResizeCanvas(const gfx::Size& viewport_size) {
viewport_size_ = viewport_size; viewport_size_ = viewport_size;
viewport_size_.SetToMax(gfx::Size(1, 1)); viewport_size_.SetToMax(gfx::Size(1, 1));
scenic::Session* scenic = window_->scenic_session();
// Allocate new buffers with the new size. // Allocate new buffers with the new size.
for (int i = 0; i < kNumBuffers; ++i) { for (int i = 0; i < kNumBuffers; ++i) {
frames_[i].Initialize(viewport_size_, scenic); frames_[i].Initialize(viewport_size_, &scenic_session_);
} }
} }
...@@ -140,7 +151,7 @@ void ScenicWindowCanvas::PresentCanvas(const gfx::Rect& damage) { ...@@ -140,7 +151,7 @@ void ScenicWindowCanvas::PresentCanvas(const gfx::Rect& damage) {
viewport_size_.width() * SkColorTypeBytesPerPixel(kN32_SkColorType); viewport_size_.width() * SkColorTypeBytesPerPixel(kN32_SkColorType);
scenic::Image image(*frames_[current_frame_].scenic_memory, 0, scenic::Image image(*frames_[current_frame_].scenic_memory, 0,
std::move(info)); std::move(info));
window_->SetTexture(image); material_.SetTexture(image);
// Create release fence for the current buffer or reset it if it already // Create release fence for the current buffer or reset it if it already
// exists. // exists.
...@@ -161,10 +172,9 @@ void ScenicWindowCanvas::PresentCanvas(const gfx::Rect& damage) { ...@@ -161,10 +172,9 @@ void ScenicWindowCanvas::PresentCanvas(const gfx::Rect& damage) {
auto status = frames_[current_frame_].release_fence.duplicate( auto status = frames_[current_frame_].release_fence.duplicate(
ZX_RIGHT_SAME_RIGHTS, &release_fence_dup); ZX_RIGHT_SAME_RIGHTS, &release_fence_dup);
ZX_CHECK(status == ZX_OK, status); ZX_CHECK(status == ZX_OK, status);
window_->scenic_session()->EnqueueReleaseFence(std::move(release_fence_dup)); scenic_session_.EnqueueReleaseFence(std::move(release_fence_dup));
scenic_session_.Present(/*presentation_time=*/0,
window_->scenic_session()->Present( [](fuchsia::images::PresentationInfo info) {});
/*presentation_time=*/0, [](fuchsia::images::PresentationInfo info) {});
// Move to the next buffer. // Move to the next buffer.
current_frame_ = (current_frame_ + 1) % kNumBuffers; current_frame_ = (current_frame_ + 1) % kNumBuffers;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "third_party/skia/include/core/SkRegion.h" #include "third_party/skia/include/core/SkRegion.h"
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#include "ui/ozone/platform/scenic/scenic_surface_factory.h"
#include "ui/ozone/public/surface_ozone_canvas.h" #include "ui/ozone/public/surface_ozone_canvas.h"
namespace scenic { namespace scenic {
...@@ -28,7 +29,8 @@ class ScenicWindowCanvas : public SurfaceOzoneCanvas { ...@@ -28,7 +29,8 @@ class ScenicWindowCanvas : public SurfaceOzoneCanvas {
public: public:
// |window| must outlive the surface. ScenicWindow owns the scenic::Session // |window| must outlive the surface. ScenicWindow owns the scenic::Session
// used in this class for all drawing operations. // used in this class for all drawing operations.
explicit ScenicWindowCanvas(ScenicWindow* window); explicit ScenicWindowCanvas(fuchsia::ui::scenic::Scenic* scenic,
ScenicWindow* window);
~ScenicWindowCanvas() override; ~ScenicWindowCanvas() override;
// SurfaceOzoneCanvas implementation. // SurfaceOzoneCanvas implementation.
...@@ -81,6 +83,10 @@ class ScenicWindowCanvas : public SurfaceOzoneCanvas { ...@@ -81,6 +83,10 @@ class ScenicWindowCanvas : public SurfaceOzoneCanvas {
// View size in device pixels. // View size in device pixels.
gfx::Size viewport_size_; gfx::Size viewport_size_;
scenic::Session scenic_session_;
scenic::ImportNode parent_;
scenic::Material material_;
DISALLOW_COPY_AND_ASSIGN(ScenicWindowCanvas); DISALLOW_COPY_AND_ASSIGN(ScenicWindowCanvas);
}; };
......
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
#include <lib/ui/scenic/cpp/session.h> #include <lib/ui/scenic/cpp/session.h>
#include <lib/zx/channel.h> #include <lib/zx/channel.h>
#include "base/bind_helpers.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/fuchsia_logging.h"
#include "base/macros.h"
#include "base/native_library.h" #include "base/native_library.h"
#include "gpu/vulkan/vulkan_function_pointers.h" #include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_instance.h" #include "gpu/vulkan/vulkan_instance.h"
...@@ -21,9 +23,62 @@ ...@@ -21,9 +23,62 @@
namespace ui { namespace ui {
namespace {
// Holds resources necessary for presenting to a View using a VkSurfaceKHR.
class ScenicSurface {
public:
ScenicSurface(fuchsia::ui::scenic::Scenic* scenic)
: scenic_(scenic),
parent_(&scenic_),
shape_(&scenic_),
material_(&scenic_) {
shape_.SetShape(scenic::Rectangle(&scenic_, 1.f, 1.f));
shape_.SetMaterial(material_);
}
// Sets the texture of the surface to a new image pipe.
void SetTextureToNewImagePipe(
fidl::InterfaceRequest<fuchsia::images::ImagePipe> image_pipe_request) {
uint32_t image_pipe_id = scenic_.AllocResourceId();
scenic_.Enqueue(scenic::NewCreateImagePipeCmd(
image_pipe_id, std::move(image_pipe_request)));
material_.SetTexture(image_pipe_id);
scenic_.ReleaseResource(image_pipe_id);
}
// Imports a node to attach the surface to and returns its export token.
//
// Scenic does not care about order here; it's totally fine for imports to
// cause exports, and that's what's done here.
zx::eventpair Import() {
zx::eventpair export_token;
parent_.BindAsRequest(&export_token);
parent_.AddChild(shape_);
return export_token;
}
// Flushes commands to scenic & executes them.
void Commit() {
scenic_.Present(
/*presentation_time=*/0, [](fuchsia::images::PresentationInfo info) {});
}
private:
scenic::Session scenic_;
scenic::ImportNode parent_;
scenic::ShapeNode shape_;
scenic::Material material_;
DISALLOW_COPY_AND_ASSIGN(ScenicSurface);
};
} // namespace
VulkanImplementationScenic::VulkanImplementationScenic( VulkanImplementationScenic::VulkanImplementationScenic(
ScenicWindowManager* scenic_window_manager) ScenicWindowManager* scenic_window_manager,
: scenic_window_manager_(scenic_window_manager) {} fuchsia::ui::scenic::Scenic* scenic)
: scenic_window_manager_(scenic_window_manager), scenic_(scenic) {}
VulkanImplementationScenic::~VulkanImplementationScenic() = default; VulkanImplementationScenic::~VulkanImplementationScenic() = default;
...@@ -74,18 +129,18 @@ VkInstance VulkanImplementationScenic::GetVulkanInstance() { ...@@ -74,18 +129,18 @@ VkInstance VulkanImplementationScenic::GetVulkanInstance() {
std::unique_ptr<gpu::VulkanSurface> std::unique_ptr<gpu::VulkanSurface>
VulkanImplementationScenic::CreateViewSurface(gfx::AcceleratedWidget window) { VulkanImplementationScenic::CreateViewSurface(gfx::AcceleratedWidget window) {
std::unique_ptr<ScenicSurface> scenic_surface =
std::make_unique<ScenicSurface>(scenic_);
// Attach the surface to the window.
// TODO(spang): Use IPC rather than direct call for this step so that it will
// work from the GPU process.
ScenicWindow* scenic_window = scenic_window_manager_->GetWindow(window); ScenicWindow* scenic_window = scenic_window_manager_->GetWindow(window);
if (!scenic_window) if (scenic_window)
return nullptr; scenic_window->ExportRenderingEntity(scenic_surface->Import());
scenic::Session* scenic_session = scenic_window->scenic_session();
fuchsia::images::ImagePipePtr image_pipe; fuchsia::images::ImagePipePtr image_pipe;
uint32_t image_pipe_id = scenic_session->AllocResourceId(); scenic_surface->SetTextureToNewImagePipe(image_pipe.NewRequest());
scenic_session->Enqueue(
scenic::NewCreateImagePipeCmd(image_pipe_id, image_pipe.NewRequest()));
scenic_window->SetTexture(image_pipe_id);
scenic_session->ReleaseResource(image_pipe_id);
scenic_session->Present(/*presentation_time=*/0,
[](fuchsia::images::PresentationInfo info) {});
VkSurfaceKHR surface; VkSurfaceKHR surface;
VkMagmaSurfaceCreateInfoKHR surface_create_info = {}; VkMagmaSurfaceCreateInfoKHR surface_create_info = {};
...@@ -102,7 +157,17 @@ VulkanImplementationScenic::CreateViewSurface(gfx::AcceleratedWidget window) { ...@@ -102,7 +157,17 @@ VulkanImplementationScenic::CreateViewSurface(gfx::AcceleratedWidget window) {
LOG(FATAL) << "vkCreateMagmaSurfaceKHR failed: " << result; LOG(FATAL) << "vkCreateMagmaSurfaceKHR failed: " << result;
} }
return std::make_unique<gpu::VulkanSurface>(GetVulkanInstance(), surface); // Execute the initialization commands. Once this is done we won't need to
// make any further changes to ScenicSurface other than to keep it alive; the
// texture can be replaced through the vulkan swapchain API.
scenic_surface->Commit();
auto destruction_callback =
base::BindOnce(base::DoNothing::Once<std::unique_ptr<ScenicSurface>>(),
std::move(scenic_surface));
return std::make_unique<gpu::VulkanSurface>(GetVulkanInstance(), surface,
std::move(destruction_callback));
} }
bool VulkanImplementationScenic::GetPhysicalDevicePresentationSupport( bool VulkanImplementationScenic::GetPhysicalDevicePresentationSupport(
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef UI_OZONE_PLATFORM_SCENIC_VULKAN_IMPLEMENTATION_SCENIC_H_ #ifndef UI_OZONE_PLATFORM_SCENIC_VULKAN_IMPLEMENTATION_SCENIC_H_
#define UI_OZONE_PLATFORM_SCENIC_VULKAN_IMPLEMENTATION_SCENIC_H_ #define UI_OZONE_PLATFORM_SCENIC_VULKAN_IMPLEMENTATION_SCENIC_H_
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <memory> #include <memory>
#include "gpu/vulkan/vulkan_implementation.h" #include "gpu/vulkan/vulkan_implementation.h"
...@@ -16,7 +17,8 @@ class ScenicWindowManager; ...@@ -16,7 +17,8 @@ class ScenicWindowManager;
class VulkanImplementationScenic : public gpu::VulkanImplementation { class VulkanImplementationScenic : public gpu::VulkanImplementation {
public: public:
VulkanImplementationScenic(ScenicWindowManager* scenic_window_manager); VulkanImplementationScenic(ScenicWindowManager* scenic_window_manager,
fuchsia::ui::scenic::Scenic* scenic);
~VulkanImplementationScenic() override; ~VulkanImplementationScenic() override;
// VulkanImplementation: // VulkanImplementation:
...@@ -36,6 +38,7 @@ class VulkanImplementationScenic : public gpu::VulkanImplementation { ...@@ -36,6 +38,7 @@ class VulkanImplementationScenic : public gpu::VulkanImplementation {
private: private:
ScenicWindowManager* const scenic_window_manager_; ScenicWindowManager* const scenic_window_manager_;
fuchsia::ui::scenic::Scenic* const scenic_;
gpu::VulkanInstance vulkan_instance_; gpu::VulkanInstance vulkan_instance_;
PFN_vkVoidFunction vkCreateMagmaSurfaceKHR_ = nullptr; PFN_vkVoidFunction vkCreateMagmaSurfaceKHR_ = nullptr;
......
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