| Index: services/ui/launcher/launcher_view_tree.cc
|
| diff --git a/services/ui/launcher/launcher_view_tree.cc b/services/ui/launcher/launcher_view_tree.cc
|
| index 052b3c0750e0e0d0965c4eb4cad26029ae4a823f..1c2beb6d6a0327930ca4837b0c4f1a9d403f8492 100644
|
| --- a/services/ui/launcher/launcher_view_tree.cc
|
| +++ b/services/ui/launcher/launcher_view_tree.cc
|
| @@ -2,32 +2,68 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "base/bind.h"
|
| #include "services/ui/launcher/launcher_view_tree.h"
|
|
|
| +#include "base/bind.h"
|
| +#include "mojo/public/cpp/application/connect.h"
|
| +#include "mojo/services/gfx/composition/cpp/formatting.h"
|
| +#include "mojo/services/ui/views/cpp/formatting.h"
|
| +
|
| namespace launcher {
|
|
|
| -LauncherViewTree::LauncherViewTree(mojo::ApplicationImpl* app_impl,
|
| - mojo::DisplayPtr display,
|
| - mojo::ViewportMetricsPtr viewport_metrics)
|
| - : display_(display.Pass()),
|
| +constexpr uint32_t kViewSceneResourceId = 1;
|
| +constexpr uint32_t kRootNodeId = mojo::gfx::composition::kSceneRootNodeId;
|
| +constexpr uint32_t kViewNodeId = 1;
|
| +constexpr uint32_t kFallbackNodeId = 2;
|
| +
|
| +LauncherViewTree::LauncherViewTree(
|
| + mojo::gfx::composition::Compositor* compositor,
|
| + mojo::ui::ViewManager* view_manager,
|
| + mojo::ContextProviderPtr context_provider,
|
| + mojo::ViewportMetricsPtr viewport_metrics,
|
| + const base::Closure& shutdown_callback)
|
| + : compositor_(compositor),
|
| + view_manager_(view_manager),
|
| + context_provider_(context_provider.Pass()),
|
| viewport_metrics_(viewport_metrics.Pass()),
|
| - binding_(this),
|
| - root_key_(0),
|
| - frame_scheduled_(false),
|
| - frame_pending_(false) {
|
| - app_impl->ConnectToService("mojo:view_manager_service", &view_manager_);
|
| - view_manager_.set_connection_error_handler(base::Bind(
|
| - &LauncherViewTree::OnViewManagerConnectionError, base::Unretained(this)));
|
| -
|
| + shutdown_callback_(shutdown_callback),
|
| + scene_listener_binding_(this),
|
| + view_tree_binding_(this) {
|
| + // Create the renderer.
|
| + compositor_->CreateRenderer(context_provider_.Pass(), GetProxy(&renderer_),
|
| + "Launcher");
|
| + renderer_.set_connection_error_handler(base::Bind(
|
| + &LauncherViewTree::OnRendererConnectionError, base::Unretained(this)));
|
| +
|
| + // Create the root scene.
|
| + compositor_->CreateScene(
|
| + mojo::GetProxy(&scene_), "Launcher",
|
| + base::Bind(&LauncherViewTree::OnSceneRegistered, base::Unretained(this)));
|
| + mojo::gfx::composition::SceneListenerPtr scene_listener;
|
| + scene_listener_binding_.Bind(mojo::GetProxy(&scene_listener));
|
| + scene_->SetListener(scene_listener.Pass());
|
| + scene_.set_connection_error_handler(base::Bind(
|
| + &LauncherViewTree::OnSceneConnectionError, base::Unretained(this)));
|
| +
|
| + // Register the view tree.
|
| mojo::ui::ViewTreePtr view_tree;
|
| - binding_.Bind(mojo::GetProxy(&view_tree));
|
| + view_tree_binding_.Bind(mojo::GetProxy(&view_tree));
|
| view_manager_->RegisterViewTree(
|
| - view_tree.Pass(), mojo::GetProxy(&view_tree_host_),
|
| + view_tree.Pass(), mojo::GetProxy(&view_tree_host_), "Launcher",
|
| base::Bind(&LauncherViewTree::OnViewTreeRegistered,
|
| base::Unretained(this)));
|
| -
|
| - ScheduleFrame();
|
| + view_tree_host_.set_connection_error_handler(base::Bind(
|
| + &LauncherViewTree::OnViewTreeConnectionError, base::Unretained(this)));
|
| +
|
| + // Get view tree services.
|
| + mojo::ServiceProviderPtr view_tree_service_provider;
|
| + view_tree_host_->GetServiceProvider(
|
| + mojo::GetProxy(&view_tree_service_provider));
|
| + mojo::ConnectToService<mojo::ui::InputDispatcher>(
|
| + view_tree_service_provider.get(), &input_dispatcher_);
|
| + input_dispatcher_.set_connection_error_handler(
|
| + base::Bind(&LauncherViewTree::OnInputDispatcherConnectionError,
|
| + base::Unretained(this)));
|
| }
|
|
|
| LauncherViewTree::~LauncherViewTree() {}
|
| @@ -45,17 +81,53 @@ void LauncherViewTree::SetViewportMetrics(
|
| mojo::ViewportMetricsPtr viewport_metrics) {
|
| viewport_metrics_ = viewport_metrics.Pass();
|
| view_tree_host_->RequestLayout();
|
| + SetRootScene();
|
| }
|
|
|
| void LauncherViewTree::DispatchEvent(mojo::EventPtr event) {
|
| - // TODO(jeffbrown): Support input dispatch.
|
| + if (input_dispatcher_)
|
| + input_dispatcher_->DispatchEvent(event.Pass());
|
| +}
|
| +
|
| +void LauncherViewTree::OnRendererConnectionError() {
|
| + LOG(ERROR) << "Renderer connection error.";
|
| + Shutdown();
|
| +}
|
| +
|
| +void LauncherViewTree::OnSceneConnectionError() {
|
| + LOG(ERROR) << "Scene connection error.";
|
| + Shutdown();
|
| +}
|
| +
|
| +void LauncherViewTree::OnViewTreeConnectionError() {
|
| + LOG(ERROR) << "View tree connection error.";
|
| + Shutdown();
|
| }
|
|
|
| -void LauncherViewTree::OnViewManagerConnectionError() {
|
| - LOG(ERROR) << "View manager connection error.";
|
| +void LauncherViewTree::OnInputDispatcherConnectionError() {
|
| + // This isn't considered a fatal error right now since it is still useful
|
| + // to be able to test a view system that has graphics but no input.
|
| + LOG(WARNING) << "Input dispatcher connection error, input will not work.";
|
| + input_dispatcher_.reset();
|
| }
|
|
|
| -void LauncherViewTree::OnViewTreeRegistered() {}
|
| +void LauncherViewTree::OnSceneRegistered(
|
| + mojo::gfx::composition::SceneTokenPtr scene_token) {
|
| + DVLOG(1) << "OnSceneRegistered: scene_token=" << scene_token;
|
| + scene_token_ = scene_token.Pass();
|
| + SetRootScene();
|
| +}
|
| +
|
| +void LauncherViewTree::OnViewTreeRegistered(
|
| + mojo::ui::ViewTreeTokenPtr view_tree_token) {
|
| + DVLOG(1) << "OnViewTreeRegistered: view_tree_token=" << view_tree_token;
|
| +}
|
| +
|
| +void LauncherViewTree::OnResourceUnavailable(
|
| + uint32_t resource_id,
|
| + const OnResourceUnavailableCallback& callback) {
|
| + LOG(ERROR) << "Resource lost: resource_id=" << resource_id;
|
| +}
|
|
|
| void LauncherViewTree::OnLayout(const OnLayoutCallback& callback) {
|
| LayoutRoot();
|
| @@ -66,9 +138,8 @@ void LauncherViewTree::OnRootUnavailable(
|
| uint32_t root_key,
|
| const OnRootUnavailableCallback& callback) {
|
| if (root_key_ == root_key) {
|
| - // TODO(jeffbrown): We should probably shut down the launcher.
|
| LOG(ERROR) << "Root view terminated unexpectedly.";
|
| - SetRoot(mojo::ui::ViewTokenPtr());
|
| + Shutdown();
|
| }
|
| callback.Run();
|
| }
|
| @@ -97,63 +168,74 @@ void LauncherViewTree::OnLayoutResult(mojo::ui::ViewLayoutInfoPtr info) {
|
|
|
| DVLOG(1) << "Root layout: size.width=" << info->size->width
|
| << ", size.height=" << info->size->height
|
| - << ", surface_id.id_namespace=" << info->surface_id->id_namespace
|
| - << ", surface_id.local=" << info->surface_id->local;
|
| + << ", scene_token.value=" << info->scene_token->value;
|
|
|
| root_layout_info_ = info.Pass();
|
| - ScheduleFrame();
|
| + PublishFrame();
|
| }
|
|
|
| -void LauncherViewTree::ScheduleFrame() {
|
| - frame_scheduled_ = true;
|
| - FinishFrame();
|
| +void LauncherViewTree::SetRootScene() {
|
| + if (scene_token_) {
|
| + mojo::Rect viewport;
|
| + viewport.width = viewport_metrics_->size->width;
|
| + viewport.height = viewport_metrics_->size->height;
|
| + scene_version_++;
|
| + renderer_->SetRootScene(scene_token_.Clone(), scene_version_,
|
| + viewport.Clone());
|
| + PublishFrame();
|
| + }
|
| }
|
|
|
| -void LauncherViewTree::FinishFrame() {
|
| - if (!frame_scheduled_ || frame_pending_)
|
| - return;
|
| - frame_scheduled_ = false;
|
| -
|
| - mojo::FramePtr frame = mojo::Frame::New();
|
| - frame->resources.resize(0u);
|
| -
|
| +void LauncherViewTree::PublishFrame() {
|
| mojo::Rect bounds;
|
| bounds.width = viewport_metrics_->size->width;
|
| bounds.height = viewport_metrics_->size->height;
|
| - mojo::PassPtr pass = mojo::CreateDefaultPass(1, bounds);
|
| - pass->shared_quad_states.push_back(
|
| - mojo::CreateDefaultSQS(*viewport_metrics_->size));
|
|
|
| - mojo::QuadPtr quad = mojo::Quad::New();
|
| - quad->rect = bounds.Clone();
|
| - quad->opaque_rect = bounds.Clone();
|
| - quad->visible_rect = bounds.Clone();
|
| - quad->shared_quad_state_index = 0u;
|
| + auto update = mojo::gfx::composition::SceneUpdate::New();
|
|
|
| if (root_layout_info_) {
|
| - quad->material = mojo::Material::SURFACE_CONTENT;
|
| - quad->surface_quad_state = mojo::SurfaceQuadState::New();
|
| - quad->surface_quad_state->surface = root_layout_info_->surface_id.Clone();
|
| + auto view_resource = mojo::gfx::composition::Resource::New();
|
| + view_resource->set_scene(mojo::gfx::composition::SceneResource::New());
|
| + view_resource->get_scene()->scene_token =
|
| + root_layout_info_->scene_token.Clone();
|
| + update->resources.insert(kViewSceneResourceId, view_resource.Pass());
|
| +
|
| + auto view_node = mojo::gfx::composition::Node::New();
|
| + view_node->op = mojo::gfx::composition::NodeOp::New();
|
| + view_node->op->set_scene(mojo::gfx::composition::SceneNodeOp::New());
|
| + view_node->op->get_scene()->scene_resource_id = kViewSceneResourceId;
|
| + update->nodes.insert(kViewNodeId, view_node.Pass());
|
| } else {
|
| - quad->material = mojo::Material::SOLID_COLOR;
|
| - quad->solid_color_quad_state = mojo::SolidColorQuadState::New();
|
| - quad->solid_color_quad_state->color = mojo::Color::New();
|
| - quad->solid_color_quad_state->color->rgba = 0xffff0000;
|
| + update->resources.insert(kViewSceneResourceId, nullptr);
|
| + update->nodes.insert(kViewNodeId, nullptr);
|
| + }
|
| +
|
| + auto fallback_node = mojo::gfx::composition::Node::New();
|
| + fallback_node->op = mojo::gfx::composition::NodeOp::New();
|
| + fallback_node->op->set_rect(mojo::gfx::composition::RectNodeOp::New());
|
| + fallback_node->op->get_rect()->content_rect = bounds.Clone();
|
| + fallback_node->op->get_rect()->color = mojo::gfx::composition::Color::New();
|
| + fallback_node->op->get_rect()->color->red = 255;
|
| + fallback_node->op->get_rect()->color->alpha = 255;
|
| + update->nodes.insert(kFallbackNodeId, fallback_node.Pass());
|
| +
|
| + auto root_node = mojo::gfx::composition::Node::New();
|
| + root_node->combinator = mojo::gfx::composition::Node::Combinator::FALLBACK;
|
| + if (root_layout_info_) {
|
| + root_node->child_node_ids.push_back(kViewNodeId);
|
| }
|
| + root_node->child_node_ids.push_back(kFallbackNodeId);
|
| + update->nodes.insert(kRootNodeId, root_node.Pass());
|
|
|
| - pass->quads.push_back(quad.Pass());
|
| - frame->passes.push_back(pass.Pass());
|
| + auto metadata = mojo::gfx::composition::SceneMetadata::New();
|
| + metadata->version = scene_version_;
|
|
|
| - frame_pending_ = true;
|
| - display_->SubmitFrame(
|
| - frame.Pass(),
|
| - base::Bind(&LauncherViewTree::OnFrameSubmitted, base::Unretained(this)));
|
| + scene_->Update(update.Pass());
|
| + scene_->Publish(metadata.Pass());
|
| }
|
|
|
| -void LauncherViewTree::OnFrameSubmitted() {
|
| - DCHECK(frame_pending_);
|
| - frame_pending_ = false;
|
| - FinishFrame();
|
| +void LauncherViewTree::Shutdown() {
|
| + shutdown_callback_.Run();
|
| }
|
|
|
| } // namespace launcher
|
|
|