From 411c6bfa4b8f20002256c73f6759ecdcea655c2e Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Wed, 27 Jan 2016 22:10:37 -0800 Subject: [PATCH] Port flutter.mojo to Mozart Everything should work except the keyboard. --- sky/services/engine/BUILD.gn | 1 + sky/services/engine/sky_engine.mojom | 2 + sky/shell/BUILD.gn | 11 +- sky/shell/gpu/mojo/gl_texture_recycler.cc | 126 +++++++++++ sky/shell/gpu/mojo/gl_texture_recycler.h | 86 ++++++++ sky/shell/gpu/mojo/rasterizer_mojo.cc | 101 +++++---- sky/shell/gpu/mojo/rasterizer_mojo.h | 38 ++-- sky/shell/platform/mojo/BUILD.gn | 15 +- sky/shell/platform/mojo/application_impl.cc | 84 ++++++++ ..._application_impl.h => application_impl.h} | 38 ++-- .../platform/mojo/content_handler_impl.cc | 4 +- .../platform/mojo/content_handler_impl.h | 3 +- sky/shell/platform/mojo/platform_view_mojo.cc | 201 +----------------- sky/shell/platform/mojo/platform_view_mojo.h | 48 +---- .../platform/mojo/pointer_converter_mojo.cc | 111 ++++++++++ .../platform/mojo/pointer_converter_mojo.h | 37 ++++ .../platform/mojo/sky_application_impl.cc | 69 ------ sky/shell/platform/mojo/view_impl.cc | 98 +++++++++ sky/shell/platform/mojo/view_impl.h | 69 ++++++ sky/shell/ui/animator.cc | 19 +- sky/shell/ui/animator.h | 8 + sky/shell/ui/engine.cc | 22 +- 22 files changed, 785 insertions(+), 406 deletions(-) create mode 100644 sky/shell/gpu/mojo/gl_texture_recycler.cc create mode 100644 sky/shell/gpu/mojo/gl_texture_recycler.h create mode 100644 sky/shell/platform/mojo/application_impl.cc rename sky/shell/platform/mojo/{sky_application_impl.h => application_impl.h} (51%) create mode 100644 sky/shell/platform/mojo/pointer_converter_mojo.cc create mode 100644 sky/shell/platform/mojo/pointer_converter_mojo.h delete mode 100644 sky/shell/platform/mojo/sky_application_impl.cc create mode 100644 sky/shell/platform/mojo/view_impl.cc create mode 100644 sky/shell/platform/mojo/view_impl.h diff --git a/sky/services/engine/BUILD.gn b/sky/services/engine/BUILD.gn index 7821e994fc5..cee7cf016f1 100644 --- a/sky/services/engine/BUILD.gn +++ b/sky/services/engine/BUILD.gn @@ -13,6 +13,7 @@ mojom("interfaces") { deps = [ "//mojo/public/interfaces/application", "//mojo/services/asset_bundle/interfaces", + "//mojo/services/gfx/composition/interfaces", "//mojo/services/service_registry/interfaces", "//sky/services/pointer:interfaces", ] diff --git a/sky/services/engine/sky_engine.mojom b/sky/services/engine/sky_engine.mojom index 3aa9c38de27..1064f99ec96 100644 --- a/sky/services/engine/sky_engine.mojom +++ b/sky/services/engine/sky_engine.mojom @@ -7,6 +7,7 @@ module sky; import "mojo/public/interfaces/application/service_provider.mojom"; import "mojo/public/interfaces/application/shell.mojom"; import "mojo/services/asset_bundle/interfaces/asset_bundle.mojom"; +import "mojo/services/gfx/composition/interfaces/scheduling.mojom"; import "mojo/services/service_registry/interfaces/service_registry.mojom"; import "sky/services/engine/input_event.mojom"; import "sky/services/pointer/pointer.mojom"; @@ -31,6 +32,7 @@ struct ServicesData { mojo.ServiceRegistry? service_registry; mojo.ServiceProvider? services_provided_by_embedder; mojo.ServiceProvider&? services_provided_to_embedder; + mojo.gfx.composition.SceneScheduler? scene_scheduler; }; [ServiceName="sky::SkyEngine"] diff --git a/sky/shell/BUILD.gn b/sky/shell/BUILD.gn index ab1cd2b3e77..f86417197c1 100644 --- a/sky/shell/BUILD.gn +++ b/sky/shell/BUILD.gn @@ -44,6 +44,7 @@ source_set("common") { "//mojo/public/cpp/application", "//mojo/public/interfaces/application", "//mojo/services/asset_bundle/interfaces", + "//mojo/services/gfx/composition/interfaces", "//mojo/services/keyboard/interfaces", "//mojo/services/navigation/interfaces", "//mojo/services/vsync/interfaces", @@ -76,17 +77,17 @@ source_set("gpu_direct") { source_set("gpu_mojo") { sources = [ + "gpu/mojo/gl_texture_recycler.cc", + "gpu/mojo/gl_texture_recycler.h", "gpu/mojo/rasterizer_mojo.cc", "gpu/mojo/rasterizer_mojo.h", ] deps = [ - ":common", + "//mojo/gpu", "//mojo/public/c/gpu", - "//mojo/public/c/gpu:gpu_onscreen", - "//mojo/services/gpu/interfaces", - "//mojo/services/native_viewport/interfaces", - "//mojo/skia:skia_bindings", + "//mojo/skia", + ":common", ] } diff --git a/sky/shell/gpu/mojo/gl_texture_recycler.cc b/sky/shell/gpu/mojo/gl_texture_recycler.cc new file mode 100644 index 00000000000..2d642588681 --- /dev/null +++ b/sky/shell/gpu/mojo/gl_texture_recycler.cc @@ -0,0 +1,126 @@ +// Copyright 2016 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 "sky/shell/gpu/mojo/gl_texture_recycler.h" + +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif +#include +#include + +#include "mojo/gpu/gl_context.h" +#include "mojo/gpu/gl_texture.h" + +namespace sky { +namespace shell { + +GLTextureRecycler::GLTextureRecycler(base::WeakPtr gl_context, + uint32_t max_recycled_textures) + : gl_context_(gl_context), + max_recycled_textures_(max_recycled_textures), + weak_factory_(this) {} + +GLTextureRecycler::~GLTextureRecycler() {} + +std::unique_ptr GLTextureRecycler::GetTexture( + const mojo::Size& requested_size) { + if (!gl_context_) { + recycled_textures_.clear(); + return nullptr; + } + + while (!recycled_textures_.empty()) { + GLRecycledTextureInfo texture_info(std::move(recycled_textures_.front())); + recycled_textures_.pop_front(); + if (texture_info.first->size().Equals(requested_size)) { + gl_context_->MakeCurrent(); + glWaitSyncPointCHROMIUM(texture_info.second); + return std::move(texture_info.first); + } + } + + return std::unique_ptr( + new mojo::GLTexture(gl_context_, requested_size)); +} + +mojo::gfx::composition::ResourcePtr GLTextureRecycler::BindTextureResource( + std::unique_ptr texture) { + if (!gl_context_) + return nullptr; + + // Produce the texture. + gl_context_->MakeCurrent(); + glBindTexture(GL_TEXTURE_2D, texture->texture_id()); + GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM]; + glGenMailboxCHROMIUM(mailbox); + glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox); + glBindTexture(GL_TEXTURE_2D, 0); + GLuint sync_point = glInsertSyncPointCHROMIUM(); + + // Populate the resource description. + auto resource = mojo::gfx::composition::Resource::New(); + resource->set_mailbox_texture( + mojo::gfx::composition::MailboxTextureResource::New()); + resource->get_mailbox_texture()->mailbox_name.resize(sizeof(mailbox)); + memcpy(resource->get_mailbox_texture()->mailbox_name.data(), mailbox, + sizeof(mailbox)); + resource->get_mailbox_texture()->sync_point = sync_point; + resource->get_mailbox_texture()->size = texture->size().Clone(); + resource->get_mailbox_texture()->callback = + (new GLTextureReleaser( + weak_factory_.GetWeakPtr(), + GLRecycledTextureInfo(std::move(texture), sync_point))) + ->StrongBind() + .Pass(); + + bound_textures_++; + DVLOG(2) << "bind: bound_textures=" << bound_textures_; + return resource; +} + +void GLTextureRecycler::ReleaseTexture(GLRecycledTextureInfo texture_info, + bool recyclable) { + DCHECK(bound_textures_); + bound_textures_--; + if (recyclable && recycled_textures_.size() < max_recycled_textures_) { + recycled_textures_.emplace_back(std::move(texture_info)); + } + DVLOG(2) << "release: bound_textures=" << bound_textures_ + << ", recycled_textures=" << recycled_textures_.size(); +} + +GLTextureRecycler::GLTextureReleaser::GLTextureReleaser( + const base::WeakPtr& provider, + GLRecycledTextureInfo info) + : provider_(provider), texture_info_(std::move(info)), binding_(this) {} + +GLTextureRecycler::GLTextureReleaser::~GLTextureReleaser() { + // It's possible for the object to be destroyed due to a connection + // error on the callback pipe. When this happens we don't want to + // recycle the texture since we have too little knowledge about its + // state to confirm that it will be safe to do so. + Release(false /*recyclable*/); +} + +mojo::gfx::composition::MailboxTextureCallbackPtr +GLTextureRecycler::GLTextureReleaser::StrongBind() { + mojo::gfx::composition::MailboxTextureCallbackPtr callback; + binding_.Bind(mojo::GetProxy(&callback)); + return callback; +} + +void GLTextureRecycler::GLTextureReleaser::OnMailboxTextureReleased() { + Release(true /*recyclable*/); +} + +void GLTextureRecycler::GLTextureReleaser::Release(bool recyclable) { + if (provider_) { + provider_->ReleaseTexture(std::move(texture_info_), recyclable); + provider_.reset(); + } +} + +} // namespace shell +} // namespace sky diff --git a/sky/shell/gpu/mojo/gl_texture_recycler.h b/sky/shell/gpu/mojo/gl_texture_recycler.h new file mode 100644 index 00000000000..f980cc559d9 --- /dev/null +++ b/sky/shell/gpu/mojo/gl_texture_recycler.h @@ -0,0 +1,86 @@ +// Copyright 2016 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 SKY_SHELL_GPU_GL_RENDERER_H_ +#define SKY_SHELL_GPU_GL_RENDERER_H_ + +#include +#include + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/services/gfx/composition/interfaces/resources.mojom.h" + +namespace mojo { +class GLContext; +class GLTexture; +class Size; +} // namespace mojo + +namespace sky { +namespace shell { + +// Provides support for rendering GL commands into a pool of textures +// and producing scene resources for them. +// TODO(abarth): Move to //mojo/gpu and reconcile with mojo::ui::GLRenderer. +class GLTextureRecycler { + public: + GLTextureRecycler(base::WeakPtr gl_context, + uint32_t max_recycled_textures = 3u); + ~GLTextureRecycler(); + + // Obtains a texture of the specified size. + // Returns a nullptr if the GLContext was destroyed. + std::unique_ptr GetTexture(const mojo::Size& requested_size); + + // Takes ownership of the specified texture, issues GL commands to + // produce a mailbox texture, and returns its resource pointer. + // The caller should add the resource to its scene. + // Returns a nullptr if the GLContext was destroyed. + mojo::gfx::composition::ResourcePtr BindTextureResource( + std::unique_ptr texture); + + private: + using GLRecycledTextureInfo = + std::pair, uint32_t>; + + // TODO(jeffbrown): Avoid creating new callbacks each time, perhaps by + // migrating to image pipes. + class GLTextureReleaser : mojo::gfx::composition::MailboxTextureCallback { + public: + GLTextureReleaser(const base::WeakPtr& provider, + GLRecycledTextureInfo info); + ~GLTextureReleaser() override; + + mojo::gfx::composition::MailboxTextureCallbackPtr StrongBind(); + + private: + void OnMailboxTextureReleased() override; + void Release(bool recyclable); + + base::WeakPtr provider_; + GLRecycledTextureInfo texture_info_; + mojo::StrongBinding + binding_; + }; + + void ReleaseTexture(GLRecycledTextureInfo texture_info, bool recyclable); + + const base::WeakPtr gl_context_; + const uint32_t max_recycled_textures_; + + std::deque recycled_textures_; + uint32_t bound_textures_ = 0u; + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(GLTextureRecycler); +}; + +} // namespace shell +} // namespace sky + +#endif // SKY_SHELL_GPU_GL_RENDERER_H_ diff --git a/sky/shell/gpu/mojo/rasterizer_mojo.cc b/sky/shell/gpu/mojo/rasterizer_mojo.cc index 77f12b23db0..1cfc8ae9f5d 100644 --- a/sky/shell/gpu/mojo/rasterizer_mojo.cc +++ b/sky/shell/gpu/mojo/rasterizer_mojo.cc @@ -1,24 +1,19 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. +// Copyright 2016 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 "sky/shell/gpu/mojo/rasterizer_mojo.h" #include "base/trace_event/trace_event.h" -#include "mojo/public/c/gpu/MGL/mgl.h" -#include "mojo/public/c/gpu/MGL/mgl_onscreen.h" -#include "mojo/skia/gl_bindings_skia.h" +#include "mojo/gpu/gl_texture.h" +#include "mojo/skia/ganesh_texture_surface.h" #include "third_party/skia/include/core/SkCanvas.h" namespace sky { namespace shell { -namespace { -void ContextLostThunk(void* closure) { - static_cast(closure)->OnContextLost(); -} - -} // namespace +const uint32_t kContentImageResourceId = 1; +const uint32_t kRootNodeId = mojo::gfx::composition::kSceneRootNodeId; std::unique_ptr Rasterizer::Create() { return std::unique_ptr(new RasterizerMojo()); @@ -43,6 +38,12 @@ void RasterizerMojo::ConnectToRasterizer ( binding_.Bind(request.Pass()); } +void RasterizerMojo::Init(mojo::ApplicationConnectorPtr connector, + mojo::gfx::composition::ScenePtr scene) { + gl_state_.reset(new GLState(connector.get())); + scene_ = scene.Pass(); +} + void RasterizerMojo::Draw(uint64_t layer_tree_ptr, const DrawCallback& callback) { TRACE_EVENT0("flutter", "RasterizerMojo::Draw"); @@ -50,53 +51,61 @@ void RasterizerMojo::Draw(uint64_t layer_tree_ptr, std::unique_ptr layer_tree( reinterpret_cast(layer_tree_ptr)); - if (!MGLGetCurrentContext()) { + if (!scene_ || !gl_state_ || !gl_state_->gl_context_owner.context()) { callback.Run(); return; } - if (layer_tree->frame_size().isEmpty()) { - callback.Run(); - return; + mojo::Size size; + size.width = layer_tree->frame_size().width(); + size.height = layer_tree->frame_size().height(); + + // TODO(abarth): Handle size == 0x0. + + std::unique_ptr texture = + gl_state_->gl_texture_recycler.GetTexture(size); + DCHECK(texture); + + { + mojo::skia::GaneshContext::Scope scope(&gl_state_->ganesh_context); + mojo::skia::GaneshTextureSurface texture_surface(scope, std::move(texture)); + + SkCanvas* canvas = texture_surface.canvas(); + flow::PaintContext::ScopedFrame frame = + paint_context_.AcquireFrame(scope.gr_context(), *canvas); + canvas->clear(SK_ColorBLACK); + layer_tree->Raster(frame); + + texture = texture_surface.TakeTexture(); } - MGLResizeSurface(layer_tree->frame_size().width(), - layer_tree->frame_size().height()); - SkCanvas* canvas = ganesh_canvas_.GetCanvas(0, layer_tree->frame_size()); - flow::PaintContext::ScopedFrame frame = - paint_context_.AcquireFrame(ganesh_canvas_.gr_context(), *canvas); - canvas->clear(SK_ColorBLACK); - layer_tree->Raster(frame); - canvas->flush(); - MGLSwapBuffers(); + mojo::gfx::composition::ResourcePtr resource = + gl_state_->gl_texture_recycler.BindTextureResource(std::move(texture)); + DCHECK(resource); + + auto update = mojo::gfx::composition::SceneUpdate::New(); + update->resources.insert(kContentImageResourceId, resource.Pass()); + auto root_node = mojo::gfx::composition::Node::New(); + root_node->op = mojo::gfx::composition::NodeOp::New(); + root_node->op->set_image(mojo::gfx::composition::ImageNodeOp::New()); + root_node->op->get_image()->content_rect = mojo::Rect::New(); + root_node->op->get_image()->content_rect->width = size.width; + root_node->op->get_image()->content_rect->height = size.height; + root_node->op->get_image()->image_resource_id = kContentImageResourceId; + update->nodes.insert(kRootNodeId, root_node.Pass()); + + scene_->Update(update.Pass()); + scene_->Publish(nullptr); callback.Run(); } -void RasterizerMojo::OnContextProviderAvailable( - mojo::InterfacePtrInfo context_provider) { - context_provider_ = mojo::MakeProxy(context_provider.Pass()); - context_provider_->Create(nullptr, - base::Bind(&RasterizerMojo::OnContextCreated, base::Unretained(this))); +RasterizerMojo::GLState::GLState(mojo::ApplicationConnector* connector) + : gl_context_owner(connector), + gl_texture_recycler(gl_context_owner.context()), + ganesh_context(gl_context_owner.context()) { } -void RasterizerMojo::OnContextCreated(mojo::CommandBufferPtr command_buffer) { - context_ = MGLCreateContext( - MGL_API_VERSION_GLES2, - command_buffer.PassInterface().PassHandle().release().value(), - MGL_NO_CONTEXT, &ContextLostThunk, this, - mojo::Environment::GetDefaultAsyncWaiter()); - MGLMakeCurrent(context_); - if (!gr_gl_interface_) - gr_gl_interface_ = skia::AdoptRef(skia_bindings::CreateMojoSkiaGLBinding()); - ganesh_canvas_.SetGrGLInterface(gr_gl_interface_.get()); -} - -void RasterizerMojo::OnContextLost() { - ganesh_canvas_.SetGrGLInterface(nullptr); - MGLDestroyContext(context_); - context_ = nullptr; - context_provider_->Create(nullptr, - base::Bind(&RasterizerMojo::OnContextCreated, base::Unretained(this))); +RasterizerMojo::GLState::~GLState() { } } // namespace shell diff --git a/sky/shell/gpu/mojo/rasterizer_mojo.h b/sky/shell/gpu/mojo/rasterizer_mojo.h index 612a09e1c78..47882a47a72 100644 --- a/sky/shell/gpu/mojo/rasterizer_mojo.h +++ b/sky/shell/gpu/mojo/rasterizer_mojo.h @@ -1,4 +1,4 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. +// Copyright 2016 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. @@ -6,46 +6,48 @@ #define SKY_SHELL_GPU_MOJO_RASTERIZER_MOJO_H_ #include "base/memory/weak_ptr.h" -#include "mojo/public/c/gpu/MGL/mgl.h" -#include "mojo/services/native_viewport/interfaces/native_viewport.mojom.h" -#include "skia/ext/refptr.h" #include "flow/paint_context.h" -#include "sky/shell/gpu/ganesh_canvas.h" +#include "mojo/gpu/gl_context_owner.h" +#include "mojo/public/interfaces/application/application_connector.mojom.h" +#include "mojo/services/gfx/composition/interfaces/scenes.mojom.h" +#include "mojo/skia/ganesh_context.h" +#include "sky/shell/gpu/mojo/gl_texture_recycler.h" #include "sky/shell/rasterizer.h" namespace sky { namespace shell { -class RasterizerMojo : public ::sky::shell::Rasterizer { +class RasterizerMojo : public Rasterizer { public: explicit RasterizerMojo(); ~RasterizerMojo() override; base::WeakPtr GetWeakPtr(); - base::WeakPtr<::sky::shell::Rasterizer> GetWeakRasterizerPtr() override; + base::WeakPtr GetWeakRasterizerPtr() override; void ConnectToRasterizer( mojo::InterfaceRequest request) override; - void OnContextProviderAvailable( - mojo::InterfacePtrInfo context_provder); - - void OnContextLost(); + void Init(mojo::ApplicationConnectorPtr connector, + mojo::gfx::composition::ScenePtr scene); private: - void OnContextCreated(mojo::CommandBufferPtr command_buffer); - void Draw(uint64_t layer_tree_ptr, const DrawCallback& callback) override; - mojo::ContextProviderPtr context_provider_; - skia::RefPtr gr_gl_interface_; - MGLContext context_; - GaneshCanvas ganesh_canvas_; + struct GLState { + explicit GLState(mojo::ApplicationConnector* connector); + ~GLState(); - flow::PaintContext paint_context_; + mojo::GLContextOwner gl_context_owner; + GLTextureRecycler gl_texture_recycler; + mojo::skia::GaneshContext ganesh_context; + }; mojo::Binding binding_; + mojo::gfx::composition::ScenePtr scene_; + std::unique_ptr gl_state_; + flow::PaintContext paint_context_; base::WeakPtrFactory weak_factory_; diff --git a/sky/shell/platform/mojo/BUILD.gn b/sky/shell/platform/mojo/BUILD.gn index 0c25302674b..d72d0ff18f0 100644 --- a/sky/shell/platform/mojo/BUILD.gn +++ b/sky/shell/platform/mojo/BUILD.gn @@ -9,13 +9,17 @@ mojo_native_application("mojo") { output_name = "flutter" sources = [ + "application_impl.cc", + "application_impl.h", "content_handler_impl.cc", "content_handler_impl.h", "main_mojo.cc", "platform_view_mojo.cc", "platform_view_mojo.h", - "sky_application_impl.cc", - "sky_application_impl.h", + "pointer_converter_mojo.cc", + "pointer_converter_mojo.h", + "view_impl.cc", + "view_impl.h", ] deps = [ @@ -30,10 +34,11 @@ mojo_native_application("mojo") { "//mojo/public/interfaces/application", "//mojo/services/asset_bundle/interfaces", "//mojo/services/content_handler/interfaces", - "//mojo/services/gpu/interfaces", - "//mojo/services/keyboard/interfaces", - "//mojo/services/native_viewport/interfaces", + "//mojo/services/gfx/composition/interfaces", + "//mojo/services/input_events/interfaces", "//mojo/services/service_registry/interfaces", + "//mojo/services/ui/input/interfaces", + "//mojo/services/ui/views/interfaces", "//services/asset_bundle:lib", "//skia", "//sky/engine/public/sky", diff --git a/sky/shell/platform/mojo/application_impl.cc b/sky/shell/platform/mojo/application_impl.cc new file mode 100644 index 00000000000..51c597e8a68 --- /dev/null +++ b/sky/shell/platform/mojo/application_impl.cc @@ -0,0 +1,84 @@ +// Copyright 2016 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 "sky/shell/platform/mojo/application_impl.h" + +#include "mojo/public/cpp/application/connect.h" +#include "sky/shell/platform/mojo/view_impl.h" + +namespace sky { +namespace shell { + +ApplicationImpl::ApplicationImpl( + mojo::InterfaceRequest application, + mojo::URLResponsePtr response) + : binding_(this, application.Pass()), + initial_response_(response.Pass()) { +} + +ApplicationImpl::~ApplicationImpl() { +} + +void ApplicationImpl::Initialize(mojo::ShellPtr shell, + mojo::Array args, + const mojo::String& url) { + DCHECK(initial_response_); + shell_ = shell.Pass(); + url_ = url; + UnpackInitialResponse(shell_.get()); +} + +void ApplicationImpl::AcceptConnection( + const mojo::String& requestor_url, + mojo::InterfaceRequest outgoing_services, + mojo::ServiceProviderPtr incoming_services, + const mojo::String& resolved_url) { + service_provider_bindings_.AddBinding(this, outgoing_services.Pass()); +} + +void ApplicationImpl::RequestQuit() { +} + +void ApplicationImpl::ConnectToService(const mojo::String& service_name, + mojo::ScopedMessagePipeHandle handle) { + if (service_name == mojo::ui::ViewProvider::Name_) { + view_provider_bindings_.AddBinding( + this, mojo::MakeRequest(handle.Pass())); + } +} + +void ApplicationImpl::CreateView( + mojo::InterfaceRequest outgoing_services, + mojo::ServiceProviderPtr incoming_services, + const mojo::ui::ViewProvider::CreateViewCallback& callback) { + if (!bundle_) { + LOG(ERROR) << "We only support creating one view."; + return; + } + + mojo::ServiceRegistryPtr service_registry; + if (incoming_services) + mojo::ConnectToService(incoming_services.get(), &service_registry); + ServicesDataPtr services = ServicesData::New(); + services->shell = shell_.Pass(); + services->service_registry = service_registry.Pass(); + services->services_provided_by_embedder = incoming_services.Pass(); + services->services_provided_to_embedder = outgoing_services.Pass(); + + ViewImpl* view = new ViewImpl(services.Pass(), url_, callback); + view->Run(bundle_.Pass()); +} + +void ApplicationImpl::UnpackInitialResponse(mojo::Shell* shell) { + DCHECK(initial_response_); + DCHECK(!bundle_); + mojo::asset_bundle::AssetUnpackerPtr unpacker; + mojo::ConnectToService(shell, "mojo:asset_bundle", &unpacker); + unpacker->UnpackZipStream(initial_response_->body.Pass(), + mojo::GetProxy(&bundle_)); + initial_response_ = nullptr; +} + +} // namespace shell +} // namespace sky diff --git a/sky/shell/platform/mojo/sky_application_impl.h b/sky/shell/platform/mojo/application_impl.h similarity index 51% rename from sky/shell/platform/mojo/sky_application_impl.h rename to sky/shell/platform/mojo/application_impl.h index ccefe76970f..26530800477 100644 --- a/sky/shell/platform/mojo/sky_application_impl.h +++ b/sky/shell/platform/mojo/application_impl.h @@ -1,11 +1,10 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. +// Copyright 2016 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 SKY_SHELL_PLATFORM_MOJO_SKY_APPLICATION_IMPL_H_ -#define SKY_SHELL_PLATFORM_MOJO_SKY_APPLICATION_IMPL_H_ +#ifndef SKY_SHELL_PLATFORM_MOJO_APPLICATION_IMPL_H_ +#define SKY_SHELL_PLATFORM_MOJO_APPLICATION_IMPL_H_ -#include "base/message_loop/message_loop.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/interfaces/application/application.mojom.h" #include "mojo/public/interfaces/application/shell.mojom.h" @@ -14,14 +13,19 @@ #include "sky/shell/platform/mojo/platform_view_mojo.h" #include "sky/shell/shell_view.h" +#include "mojo/services/ui/views/interfaces/view_provider.mojom.h" +#include "mojo/common/binding_set.h" + namespace sky { namespace shell { -class SkyApplicationImpl : public mojo::Application { +class ApplicationImpl : public mojo::Application, + public mojo::ServiceProvider, + public mojo::ui::ViewProvider { public: - SkyApplicationImpl(mojo::InterfaceRequest application, - mojo::URLResponsePtr response); - ~SkyApplicationImpl() override; + ApplicationImpl(mojo::InterfaceRequest application, + mojo::URLResponsePtr response); + ~ApplicationImpl() override; private: // mojo::Application @@ -35,20 +39,28 @@ class SkyApplicationImpl : public mojo::Application { const mojo::String& resolved_url) override; void RequestQuit() override; - PlatformViewMojo* platform_view() { - return static_cast(shell_view_->view()); - } + // mojo::ServiceProvider + void ConnectToService(const mojo::String& service_name, + mojo::ScopedMessagePipeHandle client_handle) override; + + // mojo::ui::ViewProvider + void CreateView( + mojo::InterfaceRequest services, + mojo::ServiceProviderPtr exposed_services, + const mojo::ui::ViewProvider::CreateViewCallback& callback) override; void UnpackInitialResponse(mojo::Shell* shell); mojo::StrongBinding binding_; mojo::URLResponsePtr initial_response_; + mojo::BindingSet service_provider_bindings_; + mojo::BindingSet view_provider_bindings_; + std::string url_; mojo::ShellPtr shell_; mojo::asset_bundle::AssetBundlePtr bundle_; - std::unique_ptr shell_view_; }; } // namespace shell } // namespace sky -#endif // SKY_SHELL_PLATFORM_MOJO_SKY_APPLICATION_IMPL_H_ +#endif // SKY_SHELL_PLATFORM_MOJO_APPLICATION_IMPL_H_ diff --git a/sky/shell/platform/mojo/content_handler_impl.cc b/sky/shell/platform/mojo/content_handler_impl.cc index cdcbc65e4e1..9094f61c8fe 100644 --- a/sky/shell/platform/mojo/content_handler_impl.cc +++ b/sky/shell/platform/mojo/content_handler_impl.cc @@ -4,7 +4,7 @@ #include "sky/shell/platform/mojo/content_handler_impl.h" -#include "sky/shell/platform/mojo/sky_application_impl.h" +#include "sky/shell/platform/mojo/application_impl.h" namespace sky { namespace shell { @@ -20,7 +20,7 @@ ContentHandlerImpl::~ContentHandlerImpl() { void ContentHandlerImpl::StartApplication( mojo::InterfaceRequest application, mojo::URLResponsePtr response) { - new SkyApplicationImpl(application.Pass(), response.Pass()); + new ApplicationImpl(application.Pass(), response.Pass()); } } // namespace shell diff --git a/sky/shell/platform/mojo/content_handler_impl.h b/sky/shell/platform/mojo/content_handler_impl.h index aae97a95554..1bf19a0d645 100644 --- a/sky/shell/platform/mojo/content_handler_impl.h +++ b/sky/shell/platform/mojo/content_handler_impl.h @@ -5,9 +5,8 @@ #ifndef SKY_SHELL_PLATFORM_MOJO_CONTENT_HANDLER_IMPL_H_ #define SKY_SHELL_PLATFORM_MOJO_CONTENT_HANDLER_IMPL_H_ -#include "base/message_loop/message_loop.h" +#include "base/macros.h" #include "mojo/public/cpp/bindings/strong_binding.h" -#include "mojo/public/interfaces/application/shell.mojom.h" #include "mojo/services/content_handler/interfaces/content_handler.mojom.h" namespace sky { diff --git a/sky/shell/platform/mojo/platform_view_mojo.cc b/sky/shell/platform/mojo/platform_view_mojo.cc index 12efedf3721..6c6040cdf4d 100644 --- a/sky/shell/platform/mojo/platform_view_mojo.cc +++ b/sky/shell/platform/mojo/platform_view_mojo.cc @@ -1,4 +1,4 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. +// Copyright 2016 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. @@ -7,211 +7,32 @@ #include "base/bind.h" #include "base/location.h" #include "base/single_thread_task_runner.h" -#include "mojo/public/cpp/application/connect.h" #include "sky/shell/gpu/mojo/rasterizer_mojo.h" namespace sky { namespace shell { -namespace { - -pointer::PointerType GetTypeFromAction(mojo::EventType type) { - switch (type) { - case mojo::EventType::POINTER_CANCEL: - return pointer::PointerType::CANCEL; - case mojo::EventType::POINTER_DOWN: - return pointer::PointerType::DOWN; - case mojo::EventType::POINTER_MOVE: - return pointer::PointerType::MOVE; - case mojo::EventType::POINTER_UP: - return pointer::PointerType::UP; - default: - DCHECK(false); - return pointer::PointerType::CANCEL; - } -} - -pointer::PointerKind GetKindFromKind(mojo::PointerKind kind) { - switch (kind) { - case mojo::PointerKind::TOUCH: - return pointer::PointerKind::TOUCH; - case mojo::PointerKind::MOUSE: - return pointer::PointerKind::MOUSE; - } - DCHECK(false); - return pointer::PointerKind::TOUCH; -} - -} // namespace PlatformView* PlatformView::Create(const Config& config) { return new PlatformViewMojo(config); } PlatformViewMojo::PlatformViewMojo(const Config& config) - : PlatformView(config), dispatcher_binding_(this) { + : PlatformView(config) { } PlatformViewMojo::~PlatformViewMojo() { } -void PlatformViewMojo::Init(mojo::Shell* shell) { - mojo::ConnectToService(shell, "mojo:native_viewport_service", &viewport_); - - // Grab the application connector so that we can connect to services later - shell->CreateApplicationConnector(GetProxy(&connector_)); - - mojo::NativeViewportEventDispatcherPtr ptr; - dispatcher_binding_.Bind(GetProxy(&ptr)); - viewport_->SetEventDispatcher(ptr.Pass()); - - mojo::SizePtr size = mojo::Size::New(); - size->width = 320; - size->height = 640; - - viewport_->Create( - size.Clone(), - mojo::SurfaceConfiguration::New(), - [this](mojo::ViewportMetricsPtr metrics) { - OnMetricsChanged(metrics.Pass()); - }); - viewport_->Show(); - - mojo::ContextProviderPtr context_provider; - viewport_->GetContextProvider(GetProxy(&context_provider)); - - mojo::InterfacePtrInfo context_provider_info = context_provider.PassInterface(); - +void PlatformViewMojo::InitRasterizer(mojo::ApplicationConnectorPtr connector, + mojo::gfx::composition::ScenePtr scene) { RasterizerMojo* rasterizer = static_cast(config_.rasterizer); - config_.ui_task_runner->PostTask( - FROM_HERE, base::Bind(&UIDelegate::OnOutputSurfaceCreated, - config_.ui_delegate, - base::Bind(&RasterizerMojo::OnContextProviderAvailable, - rasterizer->GetWeakPtr(), base::Passed(&context_provider_info)))); - - ConnectToEngine(GetProxy(&sky_engine_)); - -} - -void PlatformViewMojo::Run(const mojo::String& url, - ServicesDataPtr services, - mojo::asset_bundle::AssetBundlePtr bundle) { - - mojo::ServiceProviderPtr services_provided_by_embedder; - service_provider_.Bind(GetProxy(&services_provided_by_embedder)); - service_provider_.AddService(this); - services->services_provided_by_embedder = services_provided_by_embedder.Pass(); - - sky_engine_->SetServices(services.Pass()); - sky_engine_->RunFromAssetBundle(url, bundle.Pass()); -} - -void PlatformViewMojo::OnMetricsChanged(mojo::ViewportMetricsPtr metrics) { - DCHECK(metrics); - viewport_->RequestMetrics( - [this](mojo::ViewportMetricsPtr metrics) { - OnMetricsChanged(metrics.Pass()); - }); - - sky::ViewportMetricsPtr sky_metrics = sky::ViewportMetrics::New(); - sky_metrics->physical_width = metrics->size->width; - sky_metrics->physical_height = metrics->size->height; - sky_metrics->device_pixel_ratio = metrics->device_pixel_ratio; - sky_engine_->OnViewportMetricsChanged(sky_metrics.Pass()); -} - -void PlatformViewMojo::OnEvent(mojo::EventPtr event, - const mojo::Callback& callback) { - DCHECK(event); - switch (event->action) { - case mojo::EventType::POINTER_CANCEL: - case mojo::EventType::POINTER_DOWN: - case mojo::EventType::POINTER_MOVE: - case mojo::EventType::POINTER_UP: { - mojo::PointerDataPtr data = event->pointer_data.Pass(); - if (!data) - break; - pointer::PointerPacketPtr packet; - int packetIndex = 0; - if (pointer_positions_.count(data->pointer_id) > 0) { - if (event->action == mojo::EventType::POINTER_UP || - event->action == mojo::EventType::POINTER_CANCEL) { - std::pair last_position = pointer_positions_[data->pointer_id]; - if (last_position.first != data->x || last_position.second != data->y) { - packet = pointer::PointerPacket::New(); - packet->pointers = mojo::Array::New(2); - packet->pointers[packetIndex] = CreateEvent(pointer::PointerType::MOVE, event.get(), data.get()); - packetIndex += 1; - } - pointer_positions_.erase(data->pointer_id); - } - } else { - // We don't currently support hover moves. - // If we want to support those, we have to first implement - // added/removed events for pointers. - // See: https://github.com/flutter/flutter/issues/720 - if (event->action != mojo::EventType::POINTER_DOWN) - break; - } - if (packetIndex == 0) { - packet = pointer::PointerPacket::New(); - packet->pointers = mojo::Array::New(1); - } - packet->pointers[packetIndex] = CreateEvent(GetTypeFromAction(event->action), event.get(), data.get()); - sky_engine_->OnPointerPacket(packet.Pass()); - break; - } - case mojo::EventType::KEY_PRESSED: - case mojo::EventType::KEY_RELEASED: - if (key_event_dispatcher_) { - key_event_dispatcher_->OnEvent(event.Pass(), callback); - return; // key_event_dispatcher_ will invoke callback - } - default: - break; - } - - callback.Run(); -} - -pointer::PointerPtr PlatformViewMojo::CreateEvent(pointer::PointerType type, mojo::Event* event, mojo::PointerData* data) { - DCHECK(data); - pointer::PointerPtr pointer = pointer::Pointer::New(); - pointer->time_stamp = event->time_stamp; - pointer->pointer = data->pointer_id; - pointer->type = type; - pointer->kind = GetKindFromKind(data->kind); - pointer->x = data->x; - pointer->y = data->y; - pointer->buttons = static_cast(event->flags); - pointer->pressure = data->pressure; - pointer->radius_major = data->radius_major; - pointer->radius_minor = data->radius_minor; - pointer->orientation = data->orientation; - if (event->action != mojo::EventType::POINTER_UP && - event->action != mojo::EventType::POINTER_CANCEL) - pointer_positions_[data->pointer_id] = { data->x, data->y }; - return pointer.Pass(); -} - -void PlatformViewMojo::Create( - mojo::ApplicationConnection* connection, - mojo::InterfaceRequest request) { - - mojo::ServiceProviderPtr keyboard_service_provider; - connector_->ConnectToApplication( - "mojo:keyboard", - GetProxy(&keyboard_service_provider), - nullptr); - -#if defined(OS_LINUX) - keyboard::KeyboardServiceFactoryPtr factory; - mojo::ConnectToService(keyboard_service_provider.get(), &factory); - factory->CreateKeyboardService(GetProxy(&key_event_dispatcher_), request.Pass()); -#else - keyboard_service_provider->ConnectToService( - keyboard::KeyboardService::Name_, - request.PassMessagePipe()); -#endif + config_.ui_task_runner->PostTask(FROM_HERE, base::Bind( + &UIDelegate::OnOutputSurfaceCreated, + config_.ui_delegate, + base::Bind(&RasterizerMojo::Init, + rasterizer->GetWeakPtr(), + base::Passed(&connector), + base::Passed(&scene)))); } } // namespace shell diff --git a/sky/shell/platform/mojo/platform_view_mojo.h b/sky/shell/platform/mojo/platform_view_mojo.h index a6f6ac74731..7706aed6139 100644 --- a/sky/shell/platform/mojo/platform_view_mojo.h +++ b/sky/shell/platform/mojo/platform_view_mojo.h @@ -1,62 +1,26 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. +// Copyright 2016 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 SKY_SHELL_PLATFORM_MOJO_PLATFORM_VIEW_MOJO_H_ #define SKY_SHELL_PLATFORM_MOJO_PLATFORM_VIEW_MOJO_H_ -#include "mojo/public/cpp/application/service_provider_impl.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/interfaces/application/service_provider.mojom.h" -#include "mojo/public/interfaces/application/shell.mojom.h" -#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h" -#include "mojo/services/keyboard/interfaces/keyboard.mojom.h" -#include "mojo/services/native_viewport/interfaces/native_viewport.mojom.h" +#include "mojo/public/interfaces/application/application_connector.mojom.h" +#include "mojo/services/gfx/composition/interfaces/scenes.mojom.h" #include "sky/shell/platform_view.h" namespace sky { namespace shell { -class PlatformViewMojo : public PlatformView, - public mojo::NativeViewportEventDispatcher, - public mojo::InterfaceFactory<::keyboard::KeyboardService> { +class PlatformViewMojo : public PlatformView { public: explicit PlatformViewMojo(const Config& config); ~PlatformViewMojo() override; - void Init(mojo::Shell* shell); - - void Run(const mojo::String& url, - ServicesDataPtr services, - mojo::asset_bundle::AssetBundlePtr bundle); + void InitRasterizer(mojo::ApplicationConnectorPtr connector, + mojo::gfx::composition::ScenePtr scene); private: - void OnMetricsChanged(mojo::ViewportMetricsPtr metrics); - - // mojo::NativeViewportEventDispatcher - void OnEvent(mojo::EventPtr event, - const mojo::Callback& callback) override; - - pointer::PointerPtr CreateEvent(pointer::PointerType type, mojo::Event* event, mojo::PointerData* data); - - // |mojo::InterfaceFactory| implementation: - void Create( - mojo::ApplicationConnection* connection, - mojo::InterfaceRequest<::keyboard::KeyboardService>) override; - - mojo::ApplicationConnectorPtr connector_; - - mojo::NativeViewportPtr viewport_; - mojo::Binding dispatcher_binding_; - - sky::SkyEnginePtr sky_engine_; - - mojo::ServiceProviderImpl service_provider_; - - mojo::NativeViewportEventDispatcherPtr key_event_dispatcher_; - - std::map> pointer_positions_; - DISALLOW_COPY_AND_ASSIGN(PlatformViewMojo); }; diff --git a/sky/shell/platform/mojo/pointer_converter_mojo.cc b/sky/shell/platform/mojo/pointer_converter_mojo.cc new file mode 100644 index 00000000000..06a3798ef66 --- /dev/null +++ b/sky/shell/platform/mojo/pointer_converter_mojo.cc @@ -0,0 +1,111 @@ +// Copyright 2016 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 "sky/shell/platform/mojo/pointer_converter_mojo.h" + +#include "base/logging.h" + +namespace sky { +namespace shell { +namespace { + +pointer::PointerType GetTypeFromAction(mojo::EventType type) { + switch (type) { + case mojo::EventType::POINTER_CANCEL: + return pointer::PointerType::CANCEL; + case mojo::EventType::POINTER_DOWN: + return pointer::PointerType::DOWN; + case mojo::EventType::POINTER_MOVE: + return pointer::PointerType::MOVE; + case mojo::EventType::POINTER_UP: + return pointer::PointerType::UP; + default: + DCHECK(false); + return pointer::PointerType::CANCEL; + } +} + +pointer::PointerKind GetKindFromKind(mojo::PointerKind kind) { + switch (kind) { + case mojo::PointerKind::TOUCH: + return pointer::PointerKind::TOUCH; + case mojo::PointerKind::MOUSE: + return pointer::PointerKind::MOUSE; + } + DCHECK(false); + return pointer::PointerKind::TOUCH; +} + +} // namespace + +PointerConverterMojo::PointerConverterMojo() { +} + +PointerConverterMojo::~PointerConverterMojo() { +} + +pointer::PointerPacketPtr PointerConverterMojo::ConvertEvent( + mojo::EventPtr event) { + DCHECK(event->action == mojo::EventType::POINTER_CANCEL + || event->action == mojo::EventType::POINTER_DOWN + || event->action == mojo::EventType::POINTER_MOVE + || event->action == mojo::EventType::POINTER_UP); + mojo::PointerDataPtr data = event->pointer_data.Pass(); + if (!data) + return nullptr; + pointer::PointerPacketPtr packet; + int packetIndex = 0; + if (pointer_positions_.count(data->pointer_id) > 0) { + if (event->action == mojo::EventType::POINTER_UP || + event->action == mojo::EventType::POINTER_CANCEL) { + auto last_position = pointer_positions_[data->pointer_id]; + if (last_position.first != data->x || last_position.second != data->y) { + packet = pointer::PointerPacket::New(); + packet->pointers = mojo::Array::New(2); + packet->pointers[packetIndex] = CreatePointer( + pointer::PointerType::MOVE, event.get(), data.get()); + packetIndex += 1; + } + pointer_positions_.erase(data->pointer_id); + } + } else { + // We don't currently support hover moves. + // If we want to support those, we have to first implement + // added/removed events for pointers. + // See: https://github.com/flutter/flutter/issues/720 + if (event->action != mojo::EventType::POINTER_DOWN) + return nullptr; + } + if (packetIndex == 0) { + packet = pointer::PointerPacket::New(); + packet->pointers = mojo::Array::New(1); + } + packet->pointers[packetIndex] = CreatePointer( + GetTypeFromAction(event->action), event.get(), data.get()); + return packet.Pass(); +} + +pointer::PointerPtr PointerConverterMojo::CreatePointer( + pointer::PointerType type, mojo::Event* event, mojo::PointerData* data) { + DCHECK(data); + pointer::PointerPtr pointer = pointer::Pointer::New(); + pointer->time_stamp = event->time_stamp; + pointer->pointer = data->pointer_id; + pointer->type = type; + pointer->kind = GetKindFromKind(data->kind); + pointer->x = data->x; + pointer->y = data->y; + pointer->buttons = static_cast(event->flags); + pointer->pressure = data->pressure; + pointer->radius_major = data->radius_major; + pointer->radius_minor = data->radius_minor; + pointer->orientation = data->orientation; + if (event->action != mojo::EventType::POINTER_UP && + event->action != mojo::EventType::POINTER_CANCEL) + pointer_positions_[data->pointer_id] = { data->x, data->y }; + return pointer.Pass(); +} + +} // namespace shell +} // namespace sky diff --git a/sky/shell/platform/mojo/pointer_converter_mojo.h b/sky/shell/platform/mojo/pointer_converter_mojo.h new file mode 100644 index 00000000000..5775f7cc15f --- /dev/null +++ b/sky/shell/platform/mojo/pointer_converter_mojo.h @@ -0,0 +1,37 @@ +// Copyright 2016 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 SKY_SHELL_PLATFORM_MOJO_POINTER_CONVERTER_MOJO_H_ +#define SKY_SHELL_PLATFORM_MOJO_POINTER_CONVERTER_MOJO_H_ + +#include + +#include "base/macros.h" +#include "mojo/services/input_events/interfaces/input_events.mojom.h" +#include "sky/services/pointer/pointer.mojom.h" + +namespace sky { +namespace shell { + +class PointerConverterMojo { + public: + PointerConverterMojo(); + ~PointerConverterMojo(); + + pointer::PointerPacketPtr ConvertEvent(mojo::EventPtr event); + + private: + pointer::PointerPtr CreatePointer(pointer::PointerType type, + mojo::Event* event, + mojo::PointerData* data); + + std::map> pointer_positions_; + + DISALLOW_COPY_AND_ASSIGN(PointerConverterMojo); +}; + +} // namespace shell +} // namespace sky + +#endif // SKY_SHELL_PLATFORM_MOJO_POINTER_CONVERTER_MOJO_H_ diff --git a/sky/shell/platform/mojo/sky_application_impl.cc b/sky/shell/platform/mojo/sky_application_impl.cc deleted file mode 100644 index 305791ace3c..00000000000 --- a/sky/shell/platform/mojo/sky_application_impl.cc +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2015 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 "sky/shell/platform/mojo/sky_application_impl.h" - -#include "mojo/public/cpp/application/connect.h" -#include "mojo/public/cpp/utility/run_loop.h" -#include "sky/shell/shell.h" - -namespace sky { -namespace shell { - -SkyApplicationImpl::SkyApplicationImpl( - mojo::InterfaceRequest application, - mojo::URLResponsePtr response) - : binding_(this, application.Pass()), - initial_response_(response.Pass()) { -} - -SkyApplicationImpl::~SkyApplicationImpl() { -} - -void SkyApplicationImpl::Initialize(mojo::ShellPtr shell, - mojo::Array args, - const mojo::String& url) { - DCHECK(initial_response_); - UnpackInitialResponse(shell.get()); - shell_view_.reset(new ShellView(Shell::Shared())); - platform_view()->Init(shell.get()); - shell_ = shell.Pass(); -} - -void SkyApplicationImpl::AcceptConnection( - const mojo::String& requestor_url, - mojo::InterfaceRequest outgoing_services, - mojo::ServiceProviderPtr incoming_services, - const mojo::String& resolved_url) { - if (!bundle_) { - LOG(INFO) << "Cannot handle multiple connections yet."; - return; - } - - mojo::ServiceRegistryPtr service_registry; - - if (incoming_services) - mojo::ConnectToService(incoming_services.get(), &service_registry); - - ServicesDataPtr services = ServicesData::New(); - services->shell = shell_.Pass(); - services->service_registry = service_registry.Pass(); - platform_view()->Run(resolved_url, services.Pass(), bundle_.Pass()); -} - -void SkyApplicationImpl::RequestQuit() { -} - -void SkyApplicationImpl::UnpackInitialResponse(mojo::Shell* shell) { - DCHECK(initial_response_); - DCHECK(!bundle_); - mojo::asset_bundle::AssetUnpackerPtr unpacker; - mojo::ConnectToService(shell, "mojo:asset_bundle", &unpacker); - unpacker->UnpackZipStream(initial_response_->body.Pass(), - mojo::GetProxy(&bundle_)); - initial_response_ = nullptr; -} - -} // namespace shell -} // namespace sky diff --git a/sky/shell/platform/mojo/view_impl.cc b/sky/shell/platform/mojo/view_impl.cc new file mode 100644 index 00000000000..e1c3013899e --- /dev/null +++ b/sky/shell/platform/mojo/view_impl.cc @@ -0,0 +1,98 @@ +// Copyright 2016 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 "sky/shell/platform/mojo/view_impl.h" + +#include "mojo/public/cpp/application/connect.h" +#include "mojo/services/gfx/composition/interfaces/scheduling.mojom.h" +#include "sky/shell/shell.h" + +namespace sky { +namespace shell { + +ViewImpl::ViewImpl(ServicesDataPtr services, + const std::string& url, + const mojo::ui::ViewProvider::CreateViewCallback& callback) + : binding_(this), url_(url), listener_binding_(this) { + DCHECK(services); + + // Views + mojo::ConnectToService( + services->shell.get(), "mojo:view_manager_service", &view_manager_); + mojo::ui::ViewPtr view; + binding_.Bind(mojo::GetProxy(&view)); + view_manager_->RegisterView( + view.Pass(), mojo::GetProxy(&view_host_), url_, callback); + view_host_->GetServiceProvider(mojo::GetProxy(&view_service_provider_)); + + // Input + mojo::ConnectToService(view_service_provider_.get(), &input_connection_); + mojo::ui::InputListenerPtr listener; + listener_binding_.Bind(mojo::GetProxy(&listener)); + input_connection_->SetListener(listener.Pass()); + + // Compositing + mojo::gfx::composition::ScenePtr scene; + view_host_->CreateScene(mojo::GetProxy(&scene)); + scene->GetScheduler(mojo::GetProxy(&services->scene_scheduler)); + + // Engine + shell_view_.reset(new ShellView(Shell::Shared())); + shell_view_->view()->ConnectToEngine(GetProxy(&engine_)); + mojo::ApplicationConnectorPtr connector; + services->shell->CreateApplicationConnector(mojo::GetProxy(&connector)); + platform_view()->InitRasterizer(connector.Pass(), scene.Pass()); + engine_->SetServices(services.Pass()); +} + +ViewImpl::~ViewImpl() { +} + +void ViewImpl::Run(mojo::asset_bundle::AssetBundlePtr bundle) { + engine_->RunFromAssetBundle(url_, bundle.Pass()); +} + +void ViewImpl::OnLayout(mojo::ui::ViewLayoutParamsPtr layout_params, + mojo::Array children_needing_layout, + const OnLayoutCallback& callback) { + viewport_metrics_.device_pixel_ratio = layout_params->device_pixel_ratio; + viewport_metrics_.physical_width = layout_params->constraints->max_width; + viewport_metrics_.physical_height = layout_params->constraints->max_height; + engine_->OnViewportMetricsChanged(viewport_metrics_.Clone()); + + auto info = mojo::ui::ViewLayoutResult::New(); + info->size = mojo::Size::New(); + info->size->width = viewport_metrics_.physical_width; + info->size->height = viewport_metrics_.physical_height; + callback.Run(info.Pass()); +} + +void ViewImpl::OnChildUnavailable(uint32_t child_key, + const OnChildUnavailableCallback& callback) { + callback.Run(); +} + +void ViewImpl::OnEvent(mojo::EventPtr event, const OnEventCallback& callback) { + DCHECK(event); + bool consumed = false; + switch (event->action) { + case mojo::EventType::POINTER_CANCEL: + case mojo::EventType::POINTER_DOWN: + case mojo::EventType::POINTER_MOVE: + case mojo::EventType::POINTER_UP: { + auto packet = pointer_converter_.ConvertEvent(event.Pass()); + if (packet) { + engine_->OnPointerPacket(packet.Pass()); + consumed = true; + } + break; + } + default: + break; + } + callback.Run(consumed); +} + +} // namespace shell +} // namespace sky diff --git a/sky/shell/platform/mojo/view_impl.h b/sky/shell/platform/mojo/view_impl.h new file mode 100644 index 00000000000..c3500684aab --- /dev/null +++ b/sky/shell/platform/mojo/view_impl.h @@ -0,0 +1,69 @@ +// Copyright 2016 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 SKY_SHELL_PLATFORM_MOJO_VIEW_IMPL_H_ +#define SKY_SHELL_PLATFORM_MOJO_VIEW_IMPL_H_ + +#include "base/macros.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/interfaces/application/application_connector.mojom.h" +#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h" +#include "mojo/services/gfx/composition/interfaces/scenes.mojom.h" +#include "mojo/services/ui/input/interfaces/input_connection.mojom.h" +#include "mojo/services/ui/views/interfaces/view_manager.mojom.h" +#include "mojo/services/ui/views/interfaces/view_provider.mojom.h" +#include "mojo/services/ui/views/interfaces/views.mojom.h" +#include "sky/shell/platform/mojo/platform_view_mojo.h" +#include "sky/shell/platform/mojo/pointer_converter_mojo.h" +#include "sky/shell/shell_view.h" + +namespace sky { +namespace shell { + +class ViewImpl : public mojo::ui::View, + public mojo::ui::InputListener { + public: + ViewImpl(ServicesDataPtr services, + const std::string& url, + const mojo::ui::ViewProvider::CreateViewCallback& callback); + ~ViewImpl() override; + + void Run(mojo::asset_bundle::AssetBundlePtr bundle); + + private: + // mojo::ui::View + void OnLayout(mojo::ui::ViewLayoutParamsPtr layout_params, + mojo::Array children_needing_layout, + const OnLayoutCallback& callback) override; + void OnChildUnavailable(uint32_t child_key, + const OnChildUnavailableCallback& callback) override; + + // mojo::ui::InputListener + void OnEvent(mojo::EventPtr event, const OnEventCallback& callback) override; + + PlatformViewMojo* platform_view() { + return static_cast(shell_view_->view()); + } + + mojo::StrongBinding binding_; + std::string url_; + mojo::ui::ViewManagerPtr view_manager_; + mojo::ui::ViewHostPtr view_host_; + mojo::ServiceProviderPtr view_service_provider_; + mojo::ui::InputConnectionPtr input_connection_; + mojo::Binding listener_binding_; + + std::unique_ptr shell_view_; + SkyEnginePtr engine_; + ViewportMetrics viewport_metrics_; + + PointerConverterMojo pointer_converter_; + + DISALLOW_COPY_AND_ASSIGN(ViewImpl); +}; + +} // namespace shell +} // namespace sky + +#endif // SKY_SHELL_PLATFORM_MOJO_VIEW_IMPL_H_ diff --git a/sky/shell/ui/animator.cc b/sky/shell/ui/animator.cc index 3a2962ff298..072a65b19bc 100644 --- a/sky/shell/ui/animator.cc +++ b/sky/shell/ui/animator.cc @@ -67,6 +67,10 @@ void Animator::Start() { RequestFrame(); } +void Animator::Animate(mojo::gfx::composition::FrameInfoPtr frame_info) { + BeginFrame(frame_info->frame_time); +} + void Animator::BeginFrame(int64_t time_stamp) { TRACE_EVENT_ASYNC_END0("flutter", "Frame request pending", this); DCHECK(engine_requested_frame_); @@ -110,11 +114,16 @@ void Animator::OnFrameComplete() { } bool Animator::AwaitVSync() { - if (!vsync_provider_) - return false; - vsync_provider_->AwaitVSync( - base::Bind(&Animator::BeginFrame, weak_factory_.GetWeakPtr())); - return true; + if (scene_scheduler_) { + scene_scheduler_->ScheduleFrame( + base::Bind(&Animator::Animate, weak_factory_.GetWeakPtr())); + return true; + } else if (vsync_provider_) { + vsync_provider_->AwaitVSync( + base::Bind(&Animator::BeginFrame, weak_factory_.GetWeakPtr())); + return true; + } + return false; } } // namespace shell diff --git a/sky/shell/ui/animator.h b/sky/shell/ui/animator.h index e30db1704bc..a0f19aa81f8 100644 --- a/sky/shell/ui/animator.h +++ b/sky/shell/ui/animator.h @@ -6,6 +6,7 @@ #define SKY_SHELL_UI_ANIMATOR_H_ #include "base/memory/weak_ptr.h" +#include "mojo/services/gfx/composition/interfaces/scheduling.mojom.h" #include "mojo/services/vsync/interfaces/vsync.mojom.h" #include "sky/shell/ui/engine.h" @@ -24,11 +25,17 @@ class Animator { void Start(); void Stop(); + void set_scene_scheduler( + mojo::gfx::composition::SceneSchedulerPtr scene_scheduler) { + scene_scheduler_ = scene_scheduler.Pass(); + } + void set_vsync_provider(vsync::VSyncProviderPtr vsync_provider) { vsync_provider_ = vsync_provider.Pass(); } private: + void Animate(mojo::gfx::composition::FrameInfoPtr frame_info); void BeginFrame(int64_t time_stamp); void OnFrameComplete(); bool AwaitVSync(); @@ -36,6 +43,7 @@ class Animator { Engine::Config config_; rasterizer::RasterizerPtr rasterizer_; Engine* engine_; + mojo::gfx::composition::SceneSchedulerPtr scene_scheduler_; vsync::VSyncProviderPtr vsync_provider_; int outstanding_requests_; bool did_defer_frame_request_; diff --git a/sky/shell/ui/engine.cc b/sky/shell/ui/engine.cc index b0dd33ee90d..aa1036d2843 100644 --- a/sky/shell/ui/engine.cc +++ b/sky/shell/ui/engine.cc @@ -118,17 +118,21 @@ void Engine::OnOutputSurfaceDestroyed(const base::Closure& gpu_continuation) { void Engine::SetServices(ServicesDataPtr services) { services_ = services.Pass(); -#if defined(OS_ANDROID) || defined(OS_IOS) - vsync::VSyncProviderPtr vsync_provider; - if (services_->shell) { - mojo::ConnectToService(services_->shell.get(), "mojo:vsync", - &vsync_provider); + if (services_->scene_scheduler) { + animator_->set_scene_scheduler(services_->scene_scheduler.Pass()); } else { - mojo::ConnectToService(services_->services_provided_by_embedder.get(), - &vsync_provider); - } - animator_->set_vsync_provider(vsync_provider.Pass()); +#if defined(OS_ANDROID) || defined(OS_IOS) + vsync::VSyncProviderPtr vsync_provider; + if (services_->shell) { + mojo::ConnectToService(services_->shell.get(), "mojo:vsync", + &vsync_provider); + } else { + mojo::ConnectToService(services_->services_provided_by_embedder.get(), + &vsync_provider); + } + animator_->set_vsync_provider(vsync_provider.Pass()); #endif + } } void Engine::OnViewportMetricsChanged(ViewportMetricsPtr metrics) {