Commit d239fd5a authored by Sergey Ulanov's avatar Sergey Ulanov Committed by Commit Bot

[Fuchsia] Use scenic_cpp in Ozone

Previously scenic platform was using FIDL Scenic interfaces directly.
SDK now includes scenic_cpp wrappers for Scenic interfaces. This CL
updates Scenic Ozone platform to use scenic_cpp, which makes the code
more readable and less error-prone.

Bug: 899348
Change-Id: Id5fac3485b6a8cfac1aaefe1a921555090ec8138
Reviewed-on: https://chromium-review.googlesource.com/c/1308987
Commit-Queue: Sergey Ulanov <sergeyu@chromium.org>
Reviewed-by: default avatarWez <wez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604102}
parent 5d014c91
...@@ -16,8 +16,6 @@ source_set("scenic") { ...@@ -16,8 +16,6 @@ source_set("scenic") {
"ozone_platform_scenic.h", "ozone_platform_scenic.h",
"scenic_screen.cc", "scenic_screen.cc",
"scenic_screen.h", "scenic_screen.h",
"scenic_session.cc",
"scenic_session.h",
"scenic_surface_factory.cc", "scenic_surface_factory.cc",
"scenic_surface_factory.h", "scenic_surface_factory.h",
"scenic_window.cc", "scenic_window.cc",
...@@ -37,6 +35,7 @@ source_set("scenic") { ...@@ -37,6 +35,7 @@ source_set("scenic") {
"//third_party/fuchsia-sdk/sdk:images", "//third_party/fuchsia-sdk/sdk:images",
"//third_party/fuchsia-sdk/sdk:mem", "//third_party/fuchsia-sdk/sdk:mem",
"//third_party/fuchsia-sdk/sdk:scenic", "//third_party/fuchsia-sdk/sdk:scenic",
"//third_party/fuchsia-sdk/sdk:scenic_cpp",
"//third_party/fuchsia-sdk/sdk:viewsv1", "//third_party/fuchsia-sdk/sdk:viewsv1",
"//third_party/fuchsia-sdk/sdk:viewsv1token", "//third_party/fuchsia-sdk/sdk:viewsv1token",
"//ui/base", "//ui/base",
......
// Copyright 2018 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_session.h"
#include "base/fuchsia/fuchsia_logging.h"
namespace ui {
namespace {
// Max number of commands that will fit in a single message.
//
// TODO(sergeyu): Improve this logic when FIDL provides a mechanism to estimate
// message size, see https://fuchsia.atlassian.net/browse/FIDL-212 .
constexpr size_t kCommandsPerMessage =
std::max(static_cast<size_t>(ZX_CHANNEL_MAX_MSG_HANDLES),
(ZX_CHANNEL_MAX_MSG_BYTES - sizeof(fidl_message_header_t) -
sizeof(fidl_vector_t)) /
sizeof(fuchsia::ui::gfx::Command));
// Helper function for all resource creation functions.
fuchsia::ui::gfx::Command NewCreateResourceCommand(
ScenicSession::ResourceId resource_id,
fuchsia::ui::gfx::ResourceArgs resource) {
fuchsia::ui::gfx::CreateResourceCmd create_resource;
create_resource.id = resource_id;
create_resource.resource = std::move(resource);
fuchsia::ui::gfx::Command command;
command.set_create_resource(std::move(create_resource));
return command;
}
fuchsia::ui::gfx::Command NewReleaseResourceCommand(
ScenicSession::ResourceId resource_id) {
fuchsia::ui::gfx::ReleaseResourceCmd release_resource;
release_resource.id = resource_id;
fuchsia::ui::gfx::Command command;
command.set_release_resource(std::move(release_resource));
return command;
}
} // namespace
ScenicSession::ScenicSession(fuchsia::ui::scenic::Scenic* scenic,
ScenicSessionListener* listener)
: listener_(listener), session_listener_binding_(this) {
scenic->CreateSession(session_.NewRequest(),
session_listener_binding_.NewBinding());
session_.set_error_handler([this]() {
Close();
listener_->OnScenicError("ScenicSession disconnected unexpectedly.");
});
}
ScenicSession::~ScenicSession() {
DCHECK_EQ(resource_count_, 0);
}
void ScenicSession::ReleaseResource(ResourceId resource_id) {
resource_count_--;
EnqueueGfxCommand(NewReleaseResourceCommand(resource_id));
}
ScenicSession::ResourceId ScenicSession::CreateMemory(
base::SharedMemoryHandle vmo,
fuchsia::images::MemoryType memory_type,
uint64_t allocation_size) {
DCHECK(vmo.IsValid());
fuchsia::ui::gfx::MemoryArgs memory;
memory.vmo = zx::vmo(vmo.GetHandle());
memory.memory_type = memory_type;
memory.allocation_size = allocation_size;
fuchsia::ui::gfx::ResourceArgs resource;
resource.set_memory(std::move(memory));
ResourceId memory_id = AllocateResourceId();
EnqueueGfxCommand(NewCreateResourceCommand(memory_id, std::move(resource)));
return memory_id;
}
ScenicSession::ResourceId ScenicSession::CreateImage(
ResourceId memory_id,
ResourceId memory_offset,
fuchsia::images::ImageInfo info) {
fuchsia::ui::gfx::ImageArgs image;
image.memory_id = memory_id;
image.memory_offset = memory_offset;
image.info = std::move(info);
fuchsia::ui::gfx::ResourceArgs resource;
resource.set_image(std::move(image));
ResourceId image_id = AllocateResourceId();
EnqueueGfxCommand(NewCreateResourceCommand(image_id, std::move(resource)));
return image_id;
}
ScenicSession::ResourceId ScenicSession::CreateImagePipe(
fidl::InterfaceRequest<fuchsia::images::ImagePipe> request) {
fuchsia::ui::gfx::ImagePipeArgs image_pipe;
image_pipe.image_pipe_request = std::move(request);
fuchsia::ui::gfx::ResourceArgs resource;
resource.set_image_pipe(std::move(image_pipe));
ResourceId image_pipe_id = AllocateResourceId();
EnqueueGfxCommand(
NewCreateResourceCommand(image_pipe_id, std::move(resource)));
return image_pipe_id;
}
ScenicSession::ResourceId ScenicSession::ImportResource(
fuchsia::ui::gfx::ImportSpec spec,
zx::eventpair import_token) {
DCHECK(import_token);
ResourceId resource_id = AllocateResourceId();
fuchsia::ui::gfx::ImportResourceCmd import_resource;
import_resource.id = resource_id;
import_resource.token = std::move(import_token);
import_resource.spec = spec;
fuchsia::ui::gfx::Command command;
command.set_import_resource(std::move(import_resource));
EnqueueGfxCommand(std::move(command));
return resource_id;
}
ScenicSession::ResourceId ScenicSession::CreateEntityNode() {
fuchsia::ui::gfx::ResourceArgs resource;
resource.set_entity_node(fuchsia::ui::gfx::EntityNodeArgs());
ResourceId node_id = AllocateResourceId();
EnqueueGfxCommand(NewCreateResourceCommand(node_id, std::move(resource)));
return node_id;
}
ScenicSession::ResourceId ScenicSession::CreateShapeNode() {
fuchsia::ui::gfx::ResourceArgs resource;
resource.set_shape_node(fuchsia::ui::gfx::ShapeNodeArgs());
ResourceId node_id = AllocateResourceId();
EnqueueGfxCommand(NewCreateResourceCommand(node_id, std::move(resource)));
return node_id;
}
void ScenicSession::AddNodeChild(ResourceId node_id, ResourceId child_id) {
fuchsia::ui::gfx::AddChildCmd add_child;
add_child.node_id = node_id;
add_child.child_id = child_id;
fuchsia::ui::gfx::Command command;
command.set_add_child(std::move(add_child));
EnqueueGfxCommand(std::move(command));
}
void ScenicSession::SetNodeTranslation(ResourceId node_id,
const float translation[3]) {
fuchsia::ui::gfx::SetTranslationCmd set_translation;
set_translation.id = node_id;
set_translation.value.variable_id = 0;
set_translation.value.value.x = translation[0];
set_translation.value.value.y = translation[1];
set_translation.value.value.z = translation[2];
fuchsia::ui::gfx::Command command;
command.set_set_translation(std::move(set_translation));
EnqueueGfxCommand(std::move(command));
}
ScenicSession::ResourceId ScenicSession::CreateRectangle(float width,
float height) {
fuchsia::ui::gfx::Value width_value;
width_value.set_vector1(width);
fuchsia::ui::gfx::Value height_value;
height_value.set_vector1(height);
fuchsia::ui::gfx::RectangleArgs rectangle;
rectangle.width = std::move(width_value);
rectangle.height = std::move(height_value);
fuchsia::ui::gfx::ResourceArgs resource;
resource.set_rectangle(std::move(rectangle));
ResourceId rectangle_id = AllocateResourceId();
EnqueueGfxCommand(
NewCreateResourceCommand(rectangle_id, std::move(resource)));
return rectangle_id;
}
ScenicSession::ResourceId ScenicSession::CreateMaterial() {
fuchsia::ui::gfx::ResourceArgs resource;
resource.set_material(fuchsia::ui::gfx::MaterialArgs());
ResourceId material_id = AllocateResourceId();
EnqueueGfxCommand(NewCreateResourceCommand(material_id, std::move(resource)));
return material_id;
}
void ScenicSession::SetNodeMaterial(ResourceId node_id,
ResourceId material_id) {
fuchsia::ui::gfx::SetMaterialCmd set_material;
set_material.node_id = node_id;
set_material.material_id = material_id;
fuchsia::ui::gfx::Command command;
command.set_set_material(std::move(set_material));
EnqueueGfxCommand(std::move(command));
}
void ScenicSession::SetNodeShape(ResourceId node_id, ResourceId shape_id) {
fuchsia::ui::gfx::SetShapeCmd set_shape;
set_shape.node_id = node_id;
set_shape.shape_id = shape_id;
fuchsia::ui::gfx::Command command;
command.set_set_shape(std::move(set_shape));
EnqueueGfxCommand(std::move(command));
}
void ScenicSession::SetMaterialTexture(ResourceId material_id,
ResourceId texture_id) {
fuchsia::ui::gfx::SetTextureCmd set_texture;
set_texture.material_id = material_id;
set_texture.texture_id = texture_id;
fuchsia::ui::gfx::Command command;
command.set_set_texture(std::move(set_texture));
EnqueueGfxCommand(std::move(command));
}
void ScenicSession::SetEventMask(ResourceId resource_id, uint32_t event_mask) {
fuchsia::ui::gfx::SetEventMaskCmd set_event_mask;
set_event_mask.id = resource_id;
set_event_mask.event_mask = event_mask;
fuchsia::ui::gfx::Command command;
command.set_set_event_mask(std::move(set_event_mask));
EnqueueGfxCommand(std::move(command));
}
void ScenicSession::AddAcquireFence(zx::event fence) {
acquire_fences_.push_back(std::move(fence));
}
void ScenicSession::AddReleaseFence(zx::event fence) {
release_fences_.push_back(std::move(fence));
}
void ScenicSession::Present() {
Flush();
session_->Present(/*flags=*/0,
fidl::VectorPtr<zx::event>(std::move(acquire_fences_)),
fidl::VectorPtr<zx::event>(std::move(release_fences_)),
[](fuchsia::images::PresentationInfo info) {});
}
void ScenicSession::Close() {
session_.set_error_handler(nullptr);
session_.Unbind();
session_listener_binding_.Unbind();
}
void ScenicSession::OnScenicError(fidl::StringPtr error) {
Close();
listener_->OnScenicError(error);
}
void ScenicSession::OnScenicEvent(
fidl::VectorPtr<fuchsia::ui::scenic::Event> events) {
listener_->OnScenicEvents(events.get());
}
ScenicSession::ResourceId ScenicSession::AllocateResourceId() {
resource_count_++;
return next_resource_id_++;
}
void ScenicSession::EnqueueGfxCommand(fuchsia::ui::gfx::Command command) {
fuchsia::ui::scenic::Command scenic_command;
scenic_command.set_gfx(std::move(command));
queued_commands_.push_back(std::move(scenic_command));
DCHECK_LE(queued_commands_->size(), kCommandsPerMessage);
if (queued_commands_->size() == kCommandsPerMessage)
Flush();
}
void ScenicSession::Flush() {
if (!queued_commands_->empty())
session_->Enqueue(std::move(queued_commands_));
}
} // namespace ui
// Copyright 2018 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_SESSION_H_
#define UI_OZONE_PLATFORM_SCENIC_SCENIC_SESSION_H_
#include <string>
#include <vector>
#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/zx/event.h>
#include <lib/zx/eventpair.h>
#include "base/macros.h"
#include "base/memory/shared_memory_handle.h"
namespace ui {
// Interface used to receive events and error notifications from ScenicSession.
class ScenicSessionListener {
public:
ScenicSessionListener() = default;
virtual void OnScenicError(const std::string& error) = 0;
virtual void OnScenicEvents(
const std::vector<fuchsia::ui::scenic::Event>& events) = 0;
protected:
virtual ~ScenicSessionListener() = default;
DISALLOW_COPY_AND_ASSIGN(ScenicSessionListener);
};
// ScenicSession represents a session used to interact with Scenic. It sends
// commands to Scenic via fuchsia::ui::scenic::Session interface. ScenicWindow
// creates a separate session for each window.
class ScenicSession : public fuchsia::ui::scenic::SessionListener {
public:
using ResourceId = uint32_t;
// Creates and wraps a new session for |scenic_service|. |listener| must
// outlive ScenicSession.
ScenicSession(fuchsia::ui::scenic::Scenic* scenic_service,
ScenicSessionListener* listener);
~ScenicSession() override;
// Following functions enqueue various Scenic commands. See
// https://fuchsia.googlesource.com/garnet/+/master/public/lib/ui/gfx/fidl/commands.fidl
// for descriptions of the commands and the fields. Create*() methods return
// ID of the created resource. Resource IDs are only valid within context of
// the session.
void ReleaseResource(ResourceId resource_id);
ResourceId CreateMemory(base::SharedMemoryHandle vmo,
fuchsia::images::MemoryType memory_type,
uint64_t allocation_size);
ResourceId CreateImage(ResourceId memory_id,
ResourceId memory_offset,
fuchsia::images::ImageInfo info);
ResourceId CreateImagePipe(
fidl::InterfaceRequest<fuchsia::images::ImagePipe> request);
ResourceId ImportResource(fuchsia::ui::gfx::ImportSpec spec,
zx::eventpair import_token);
ResourceId CreateEntityNode();
ResourceId CreateShapeNode();
void AddNodeChild(ResourceId node_id, ResourceId child_id);
void SetNodeTranslation(ResourceId node_id, const float translation[3]);
ResourceId CreateRectangle(float width, float height);
ResourceId CreateMaterial();
void SetNodeMaterial(ResourceId node_id, ResourceId material_id);
void SetNodeShape(ResourceId node_id, ResourceId shape_id);
void SetMaterialTexture(ResourceId material_id, ResourceId texture_id);
void SetEventMask(ResourceId resource_id, uint32_t event_mask);
// Enqueue acquire or release fences for the next Present() call. See
// Scenic documentation for description on how these should be used:
// https://fuchsia.googlesource.com/garnet/+/master/public/lib/ui/scenic/fidl/session.fidl
void AddAcquireFence(zx::event fence);
void AddReleaseFence(zx::event fence);
// Flushes queued commands and presents the resulting frame.
void Present();
private:
// fuchsia::ui::scenic::SessionListener interface.
void OnScenicError(fidl::StringPtr error) override;
void OnScenicEvent(
fidl::VectorPtr<fuchsia::ui::scenic::Event> events) override;
// Allocates a new unique resource id.
ResourceId AllocateResourceId();
// Enqueues a scenic |command|.
void EnqueueGfxCommand(fuchsia::ui::gfx::Command command);
// Flushes |queued_commands_|.
void Flush();
// Unbinds |session_| and |session_listener_binding_|, which frees the
// resources used for the session in Scenic and guarantees that we wont
// receive SessionListener events.
void Close();
ScenicSessionListener* const listener_;
fuchsia::ui::scenic::SessionPtr session_;
fidl::Binding<fuchsia::ui::scenic::SessionListener> session_listener_binding_;
ResourceId next_resource_id_ = 1u;
// Used to verify that all resources are freed when the session is closed.
int resource_count_ = 0u;
fidl::VectorPtr<fuchsia::ui::scenic::Command> queued_commands_;
// Pending acquire and release fences passed in the next Present() call.
std::vector<zx::event> acquire_fences_;
std::vector<zx::event> release_fences_;
DISALLOW_COPY_AND_ASSIGN(ScenicSession);
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_SCENIC_SCENIC_SESSION_H_
...@@ -32,28 +32,29 @@ ScenicWindow::ScenicWindow( ...@@ -32,28 +32,29 @@ ScenicWindow::ScenicWindow(
window_id_(manager_->AddWindow(this)), window_id_(manager_->AddWindow(this)),
event_dispatcher_(this), event_dispatcher_(this),
view_listener_binding_(this), view_listener_binding_(this),
scenic_session_(manager_->GetScenic(), this), scenic_session_(manager_->GetScenic()),
parent_node_(&scenic_session_),
node_(&scenic_session_),
shape_node_(&scenic_session_),
material_(&scenic_session_),
input_listener_binding_(this) { input_listener_binding_(this) {
// Create event pair to import parent view node to Scenic. One end is passed scenic_session_.set_error_handler(
// directly to Scenic in ImportResource command and the second one is passed fit::bind_member(this, &ScenicWindow::OnScenicError));
// to ViewManager::CreateView(). ViewManager will passes it to Scenic when the scenic_session_.set_event_handler(
// view is added to a container. fit::bind_member(this, &ScenicWindow::OnScenicEvents));
// Import parent node and create event pair to pass to the ViewManager.
zx::eventpair parent_export_token; zx::eventpair parent_export_token;
zx::eventpair parent_import_token; parent_node_.BindAsRequest(&parent_export_token);
zx_status_t status =
zx::eventpair::create(0u, &parent_import_token, &parent_export_token);
ZX_CHECK(status == ZX_OK, status) << "zx_eventpair_create()";
// Create a new node and add it as a child to the parent. // Setup entity node for the window.
parent_node_id_ = scenic_session_.ImportResource( parent_node_.AddChild(node_);
fuchsia::ui::gfx::ImportSpec::NODE, std::move(parent_import_token)); node_.AddChild(shape_node_);
node_id_ = scenic_session_.CreateEntityNode(); shape_node_.SetMaterial(material_);
scenic_session_.AddNodeChild(parent_node_id_, node_id_);
// 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.
scenic_session_.SetEventMask(parent_node_id_, parent_node_.SetEventMask(fuchsia::ui::gfx::kMetricsEventMask);
fuchsia::ui::gfx::kMetricsEventMask);
// Create the view. // Create the view.
manager_->GetViewManager()->CreateView( manager_->GetViewManager()->CreateView(
...@@ -74,31 +75,24 @@ ScenicWindow::ScenicWindow( ...@@ -74,31 +75,24 @@ ScenicWindow::ScenicWindow(
input_connection_.NewRequest().TakeChannel()); input_connection_.NewRequest().TakeChannel());
input_connection_->SetEventListener(input_listener_binding_.NewBinding()); input_connection_->SetEventListener(input_listener_binding_.NewBinding());
// Add shape node for window.
shape_id_ = scenic_session_.CreateShapeNode();
scenic_session_.AddNodeChild(node_id_, shape_id_);
material_id_ = scenic_session_.CreateMaterial();
scenic_session_.SetNodeMaterial(shape_id_, material_id_);
// Call Present() to ensure that the scenic session commands are processed, // Call Present() to ensure that the scenic session commands are processed,
// which is necessary to receive metrics event from Scenic. // which is necessary to receive metrics event from Scenic.
scenic_session_.Present(); scenic_session_.Present(
/*presentation_time=*/0, [](fuchsia::images::PresentationInfo info) {});
delegate_->OnAcceleratedWidgetAvailable(window_id_); delegate_->OnAcceleratedWidgetAvailable(window_id_);
} }
ScenicWindow::~ScenicWindow() { ScenicWindow::~ScenicWindow() {
scenic_session_.ReleaseResource(node_id_);
scenic_session_.ReleaseResource(parent_node_id_);
scenic_session_.ReleaseResource(shape_id_);
scenic_session_.ReleaseResource(material_id_);
manager_->RemoveWindow(window_id_, this); manager_->RemoveWindow(window_id_, this);
view_.Unbind();
} }
void ScenicWindow::SetTexture(ScenicSession::ResourceId texture) { void ScenicWindow::SetTexture(const scenic::Image& image) {
scenic_session_.SetMaterialTexture(material_id_, texture); material_.SetTexture(image);
}
void ScenicWindow::SetTexture(uint32_t image_id) {
material_.SetTexture(image_id);
} }
gfx::Rect ScenicWindow::GetBounds() { gfx::Rect ScenicWindow::GetBounds() {
...@@ -199,18 +193,15 @@ void ScenicWindow::UpdateSize() { ...@@ -199,18 +193,15 @@ 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_, size_dips_.width(),
size_dips_.height());
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.
const float translation[] = {size_dips_.width() / 2.0, shape_node_.SetTranslation(size_dips_.width() / 2.0,
size_dips_.height() / 2.0, 0.f}; size_dips_.height() / 2.0, 0.f);
// Set node shape to rectangle that matches size of the view.
ScenicSession::ResourceId rect_id =
scenic_session_.CreateRectangle(size_dips_.width(), size_dips_.height());
scenic_session_.SetNodeShape(shape_id_, rect_id);
scenic_session_.SetNodeTranslation(shape_id_, translation);
scenic_session_.ReleaseResource(rect_id);
scenic_session_.Present();
delegate_->OnBoundsChanged(size_rect); delegate_->OnBoundsChanged(size_rect);
} }
...@@ -228,19 +219,19 @@ void ScenicWindow::OnPropertiesChanged( ...@@ -228,19 +219,19 @@ void ScenicWindow::OnPropertiesChanged(
callback(); callback();
} }
void ScenicWindow::OnScenicError(const std::string& error) { void ScenicWindow::OnScenicError() {
LOG(ERROR) << "ScenicSession failed: " << error; LOG(ERROR) << "scenic::Session failed.";
delegate_->OnClosed(); delegate_->OnClosed();
} }
void ScenicWindow::OnScenicEvents( void ScenicWindow::OnScenicEvents(
const std::vector<fuchsia::ui::scenic::Event>& events) { fidl::VectorPtr<fuchsia::ui::scenic::Event> events) {
for (const auto& event : events) { for (const auto& event : events.get()) {
if (!event.is_gfx() || !event.gfx().is_metrics()) if (!event.is_gfx() || !event.gfx().is_metrics())
continue; continue;
auto& metrics = event.gfx().metrics(); auto& metrics = event.gfx().metrics();
if (metrics.node_id != parent_node_id_) if (metrics.node_id != parent_node_.id())
continue; continue;
device_pixel_ratio_ = device_pixel_ratio_ =
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <fuchsia/ui/input/cpp/fidl.h> #include <fuchsia/ui/input/cpp/fidl.h>
#include <fuchsia/ui/viewsv1/cpp/fidl.h> #include <fuchsia/ui/viewsv1/cpp/fidl.h>
#include <lib/ui/scenic/cpp/resources.h>
#include <lib/ui/scenic/cpp/session.h>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -18,7 +20,6 @@ ...@@ -18,7 +20,6 @@
#include "ui/gfx/geometry/size_f.h" #include "ui/gfx/geometry/size_f.h"
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
#include "ui/ozone/ozone_export.h" #include "ui/ozone/ozone_export.h"
#include "ui/ozone/platform/scenic/scenic_session.h"
#include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window.h"
namespace ui { namespace ui {
...@@ -27,7 +28,6 @@ class ScenicWindowManager; ...@@ -27,7 +28,6 @@ class ScenicWindowManager;
class PlatformWindowDelegate; class PlatformWindowDelegate;
class OZONE_EXPORT ScenicWindow : public PlatformWindow, class OZONE_EXPORT ScenicWindow : public PlatformWindow,
public ScenicSessionListener,
public fuchsia::ui::viewsv1::ViewListener, public fuchsia::ui::viewsv1::ViewListener,
public fuchsia::ui::input::InputListener, public fuchsia::ui::input::InputListener,
public InputEventDispatcherDelegate { public InputEventDispatcherDelegate {
...@@ -42,11 +42,12 @@ class OZONE_EXPORT ScenicWindow : public PlatformWindow, ...@@ -42,11 +42,12 @@ class OZONE_EXPORT ScenicWindow : public PlatformWindow,
view_owner_request); view_owner_request);
~ScenicWindow() override; ~ScenicWindow() override;
ScenicSession* scenic_session() { return &scenic_session_; } scenic::Session* scenic_session() { return &scenic_session_; }
ScenicSession::ResourceId node_id() const { return node_id_; } const scenic::Node& node() const { return node_; }
// Sets texture of the window to a scenic resource. // Sets texture of the window. |image| must be created in scenic_session().
void SetTexture(ScenicSession::ResourceId texture); void SetTexture(const scenic::Image& image);
void SetTexture(uint32_t image_id);
// PlatformWindow implementation. // PlatformWindow implementation.
gfx::Rect GetBounds() override; gfx::Rect GetBounds() override;
...@@ -80,10 +81,9 @@ class OZONE_EXPORT ScenicWindow : public PlatformWindow, ...@@ -80,10 +81,9 @@ class OZONE_EXPORT ScenicWindow : public PlatformWindow,
void OnEvent(fuchsia::ui::input::InputEvent event, void OnEvent(fuchsia::ui::input::InputEvent event,
OnEventCallback callback) override; OnEventCallback callback) override;
// ScenicSessionListener interface. // Callbacks for |scenic_session_|.
void OnScenicError(const std::string& error) override; void OnScenicError();
void OnScenicEvents( void OnScenicEvents(fidl::VectorPtr<fuchsia::ui::scenic::Event> events);
const std::vector<fuchsia::ui::scenic::Event>& events) override;
// InputEventDispatcher::Delegate interface. // InputEventDispatcher::Delegate interface.
void DispatchEvent(ui::Event* event) override; void DispatchEvent(ui::Event* event) override;
...@@ -106,19 +106,19 @@ class OZONE_EXPORT ScenicWindow : public PlatformWindow, ...@@ -106,19 +106,19 @@ class OZONE_EXPORT ScenicWindow : public PlatformWindow,
fidl::Binding<fuchsia::ui::viewsv1::ViewListener> view_listener_binding_; fidl::Binding<fuchsia::ui::viewsv1::ViewListener> view_listener_binding_;
// Scenic session used for all drawing operations in this View. // Scenic session used for all drawing operations in this View.
ScenicSession scenic_session_; scenic::Session scenic_session_;
// Node ID in |scenic_session_| for the parent view. // Node ID in |scenic_session_| for the parent view.
ScenicSession::ResourceId parent_node_id_; scenic::ImportNode parent_node_;
// Node ID in |scenic_session_| for the view. // Node ID in |scenic_session_| for the view.
ScenicSession::ResourceId node_id_; scenic::EntityNode node_;
// Shape and material resource ids for the view in the context of the scenic // Shape and material resources for the view in the context of
// session for the window. They are used to set shape and texture for the view // |scenic_session_|. They are used to set shape and texture for the view
// node. // node.
ScenicSession::ResourceId shape_id_; scenic::ShapeNode shape_node_;
ScenicSession::ResourceId material_id_; scenic::Material material_;
// The ratio used for translating device-independent coordinates to absolute // The ratio used for translating device-independent coordinates to absolute
// pixel coordinates. // pixel coordinates.
......
...@@ -20,32 +20,39 @@ ScenicWindowCanvas::Frame::Frame() = default; ...@@ -20,32 +20,39 @@ ScenicWindowCanvas::Frame::Frame() = default;
ScenicWindowCanvas::Frame::~Frame() = default; ScenicWindowCanvas::Frame::~Frame() = default;
void ScenicWindowCanvas::Frame::Initialize(gfx::Size size, void ScenicWindowCanvas::Frame::Initialize(gfx::Size size,
ScenicSession* scenic) { scenic::Session* scenic) {
memory.Unmap();
size_t bytes_per_row = size_t bytes_per_row =
size.width() * SkColorTypeBytesPerPixel(kN32_SkColorType); size.width() * SkColorTypeBytesPerPixel(kN32_SkColorType);
size_t buffer_size = bytes_per_row * size.height(); size_t buffer_size = bytes_per_row * size.height();
if (!memory.CreateAndMapAnonymous(buffer_size)) {
memory_region = base::UnsafeSharedMemoryRegion::Create(buffer_size);
memory_mapping = memory_region.Map();
if (!memory_region.IsValid()) {
LOG(WARNING) << "Failed to map memory for ScenicWindowCanvas."; LOG(WARNING) << "Failed to map memory for ScenicWindowCanvas.";
memory.Unmap(); memory_region = base::UnsafeSharedMemoryRegion();
memory_mapping = base::WritableSharedMemoryMapping();
surface.reset(); surface.reset();
} else { return;
memory_id = scenic->CreateMemory(memory.GetReadOnlyHandle(), }
fuchsia::images::MemoryType::HOST_MEMORY,
buffer_size); scenic_memory = std::make_unique<scenic::Memory>(
scenic,
base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
memory_region.Duplicate())
.PassPlatformHandle(),
buffer_size, fuchsia::images::MemoryType::HOST_MEMORY);
surface = SkSurface::MakeRasterDirect( surface = SkSurface::MakeRasterDirect(
SkImageInfo::MakeN32Premul(size.width(), size.height()), SkImageInfo::MakeN32Premul(size.width(), size.height()),
memory.memory(), bytes_per_row); memory_mapping.memory(), bytes_per_row);
dirty_region.setRect(gfx::RectToSkIRect(gfx::Rect(size))); dirty_region.setRect(gfx::RectToSkIRect(gfx::Rect(size)));
}
} }
void ScenicWindowCanvas::Frame::CopyDirtyRegionFrom(const Frame& frame) { void ScenicWindowCanvas::Frame::CopyDirtyRegionFrom(const Frame& frame) {
int stride = surface->width() * SkColorTypeBytesPerPixel(kN32_SkColorType); int stride = surface->width() * SkColorTypeBytesPerPixel(kN32_SkColorType);
for (SkRegion::Iterator i(dirty_region); !i.done(); i.next()) { for (SkRegion::Iterator i(dirty_region); !i.done(); i.next()) {
uint8_t* dst_ptr = uint8_t* dst_ptr =
static_cast<uint8_t*>(memory.memory()) + static_cast<uint8_t*>(memory_mapping.memory()) +
i.rect().x() * SkColorTypeBytesPerPixel(kN32_SkColorType) + i.rect().x() * SkColorTypeBytesPerPixel(kN32_SkColorType) +
i.rect().y() * stride; i.rect().y() * stride;
frame.surface->readPixels( frame.surface->readPixels(
...@@ -58,24 +65,16 @@ void ScenicWindowCanvas::Frame::CopyDirtyRegionFrom(const Frame& frame) { ...@@ -58,24 +65,16 @@ void ScenicWindowCanvas::Frame::CopyDirtyRegionFrom(const Frame& frame) {
ScenicWindowCanvas::ScenicWindowCanvas(ScenicWindow* window) ScenicWindowCanvas::ScenicWindowCanvas(ScenicWindow* window)
: window_(window) {} : window_(window) {}
ScenicWindowCanvas::~ScenicWindowCanvas() { ScenicWindowCanvas::~ScenicWindowCanvas() = default;
ScenicSession* scenic = window_->scenic_session();
for (int i = 0; i < kNumBuffers; ++i) {
if (!frames_[i].is_empty())
scenic->ReleaseResource(frames_[i].memory_id);
}
}
void ScenicWindowCanvas::ResizeCanvas(const gfx::Size& viewport_size) { 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));
ScenicSession* scenic = window_->scenic_session(); 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) {
if (!frames_[i].is_empty())
scenic->ReleaseResource(frames_[i].memory_id);
frames_[i].Initialize(viewport_size_, scenic); frames_[i].Initialize(viewport_size_, scenic);
} }
} }
...@@ -130,17 +129,14 @@ void ScenicWindowCanvas::PresentCanvas(const gfx::Rect& damage) { ...@@ -130,17 +129,14 @@ void ScenicWindowCanvas::PresentCanvas(const gfx::Rect& damage) {
} }
// Create image that wraps the buffer and attach it as texture for the node. // Create image that wraps the buffer and attach it as texture for the node.
ScenicSession* scenic = window_->scenic_session();
fuchsia::images::ImageInfo info; fuchsia::images::ImageInfo info;
info.width = viewport_size_.width(); info.width = viewport_size_.width();
info.height = viewport_size_.height(); info.height = viewport_size_.height();
info.stride = info.stride =
viewport_size_.width() * SkColorTypeBytesPerPixel(kN32_SkColorType); viewport_size_.width() * SkColorTypeBytesPerPixel(kN32_SkColorType);
ScenicSession::ResourceId image_id = scenic->CreateImage( scenic::Image image(*frames_[current_frame_].scenic_memory, 0,
frames_[current_frame_].memory_id, 0, std::move(info)); std::move(info));
window_->SetTexture(image);
window_->SetTexture(image_id);
scenic->ReleaseResource(image_id);
// 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 +157,10 @@ void ScenicWindowCanvas::PresentCanvas(const gfx::Rect& damage) { ...@@ -161,10 +157,10 @@ 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);
scenic->AddReleaseFence(std::move(release_fence_dup)); window_->scenic_session()->EnqueueReleaseFence(std::move(release_fence_dup));
// Present the frame. window_->scenic_session()->Present(
scenic->Present(); /*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;
......
...@@ -5,14 +5,20 @@ ...@@ -5,14 +5,20 @@
#ifndef UI_OZONE_PLATFORM_SCENIC_SCENIC_WINDOW_CANVAS_H_ #ifndef UI_OZONE_PLATFORM_SCENIC_SCENIC_WINDOW_CANVAS_H_
#define UI_OZONE_PLATFORM_SCENIC_SCENIC_WINDOW_CANVAS_H_ #define UI_OZONE_PLATFORM_SCENIC_SCENIC_WINDOW_CANVAS_H_
#include <lib/ui/scenic/cpp/resources.h>
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/shared_memory.h" #include "base/memory/shared_memory_mapping.h"
#include "base/memory/unsafe_shared_memory_region.h"
#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_session.h"
#include "ui/ozone/public/surface_ozone_canvas.h" #include "ui/ozone/public/surface_ozone_canvas.h"
namespace scenic {
class Session;
} // namespace scenic
namespace ui { namespace ui {
class ScenicWindow; class ScenicWindow;
...@@ -21,8 +27,8 @@ class ScenicWindow; ...@@ -21,8 +27,8 @@ class ScenicWindow;
// ScenicWindow. // ScenicWindow.
class ScenicWindowCanvas : public SurfaceOzoneCanvas { class ScenicWindowCanvas : public SurfaceOzoneCanvas {
public: public:
// |window| must outlive the surface. ScenicWindow owns the ScenicSession used // |window| must outlive the surface. ScenicWindow owns the scenic::Session
// in this class for all drawing operations. // used in this class for all drawing operations.
explicit ScenicWindowCanvas(ScenicWindow* window); explicit ScenicWindowCanvas(ScenicWindow* window);
~ScenicWindowCanvas() override; ~ScenicWindowCanvas() override;
...@@ -43,23 +49,24 @@ class ScenicWindowCanvas : public SurfaceOzoneCanvas { ...@@ -43,23 +49,24 @@ class ScenicWindowCanvas : public SurfaceOzoneCanvas {
// Allocates and maps memory for a frame of |size| (in physical in pixels) // Allocates and maps memory for a frame of |size| (in physical in pixels)
// and then registers it with |scenic|. // and then registers it with |scenic|.
void Initialize(gfx::Size size, ScenicSession* scenic); void Initialize(gfx::Size size, scenic::Session* scenic);
// Copies pixels covered by |dirty_region| from another |frame|. // Copies pixels covered by |dirty_region| from another |frame|.
void CopyDirtyRegionFrom(const Frame& frame); void CopyDirtyRegionFrom(const Frame& frame);
bool is_empty() { return memory.mapped_size() == 0; } bool is_empty() { return !surface; }
// Shared memory for the buffer. // Shared memory for the buffer.
base::SharedMemory memory; base::UnsafeSharedMemoryRegion memory_region;
base::WritableSharedMemoryMapping memory_mapping;
// SkSurface that wraps |memory|. // SkSurface that wraps |memory_mapping|.
sk_sp<SkSurface> surface; sk_sp<SkSurface> surface;
// Valid only when |memory| is set. // Scenic Memory resource for |memory_region|.
ScenicSession::ResourceId memory_id; std::unique_ptr<scenic::Memory> scenic_memory;
// Fence that will be release by Scenic when it stops using this frame. // Fence that will be released by Scenic when it stops using this frame.
zx::event release_fence; zx::event release_fence;
// The region of the frame that's not up-to-date. // The region of the frame that's not up-to-date.
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "ui/ozone/platform/scenic/vulkan_implementation_scenic.h" #include "ui/ozone/platform/scenic/vulkan_implementation_scenic.h"
#include <lib/ui/scenic/cpp/commands.h>
#include <lib/ui/scenic/cpp/session.h>
#include <lib/zx/channel.h> #include <lib/zx/channel.h>
#include "base/files/file_path.h" #include "base/files/file_path.h"
...@@ -75,13 +77,15 @@ VulkanImplementationScenic::CreateViewSurface(gfx::AcceleratedWidget window) { ...@@ -75,13 +77,15 @@ VulkanImplementationScenic::CreateViewSurface(gfx::AcceleratedWidget window) {
ScenicWindow* scenic_window = scenic_window_manager_->GetWindow(window); ScenicWindow* scenic_window = scenic_window_manager_->GetWindow(window);
if (!scenic_window) if (!scenic_window)
return nullptr; return nullptr;
ScenicSession* scenic_session = scenic_window->scenic_session(); scenic::Session* scenic_session = scenic_window->scenic_session();
fuchsia::images::ImagePipePtr image_pipe; fuchsia::images::ImagePipePtr image_pipe;
ScenicSession::ResourceId image_pipe_id = uint32_t image_pipe_id = scenic_session->AllocResourceId();
scenic_session->CreateImagePipe(image_pipe.NewRequest()); scenic_session->Enqueue(
scenic::NewCreateImagePipeCmd(image_pipe_id, image_pipe.NewRequest()));
scenic_window->SetTexture(image_pipe_id); scenic_window->SetTexture(image_pipe_id);
scenic_session->ReleaseResource(image_pipe_id); scenic_session->ReleaseResource(image_pipe_id);
scenic_session->Present(); scenic_session->Present(/*presentation_time=*/0,
[](fuchsia::images::PresentationInfo info) {});
VkSurfaceKHR surface; VkSurfaceKHR surface;
VkMagmaSurfaceCreateInfoKHR surface_create_info = {}; VkMagmaSurfaceCreateInfoKHR surface_create_info = {};
......
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