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..dae831aaad8b2b1233307f98f426369dfa4432d2 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/logging.h" |
+#include "mojo/services/ui/views/cpp/logging.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))); |
abarth
2016/01/10 01:42:54
Do we not support lambdas here?
jeffbrown
2016/01/26 05:59:12
We do support lambdas but I've been avoiding mixin
|
+ |
+ // 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 |