| // 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 "content/renderer/mus/render_widget_mus_connection.h" |
| |
| #include <map> |
| |
| #include "base/lazy_instance.h" |
| #include "base/macros.h" |
| #include "components/mus/public/cpp/context_provider.h" |
| #include "components/mus/public/cpp/output_surface.h" |
| #include "components/mus/public/interfaces/command_buffer.mojom.h" |
| #include "components/mus/public/interfaces/compositor_frame.mojom.h" |
| #include "components/mus/public/interfaces/gpu.mojom.h" |
| #include "components/mus/public/interfaces/window_tree.mojom.h" |
| #include "content/public/common/mojo_shell_connection.h" |
| #include "content/renderer/mus/compositor_mus_connection.h" |
| #include "content/renderer/render_thread_impl.h" |
| #include "content/renderer/render_view_impl.h" |
| #include "mojo/converters/geometry/geometry_type_converters.h" |
| #include "mojo/converters/surfaces/surfaces_utils.h" |
| #include "mojo/shell/public/cpp/shell.h" |
| |
| namespace content { |
| |
| namespace { |
| |
| typedef std::map<int, RenderWidgetMusConnection*> ConnectionMap; |
| base::LazyInstance<ConnectionMap>::Leaky g_connections = |
| LAZY_INSTANCE_INITIALIZER; |
| } |
| |
| void RenderWidgetMusConnection::Bind( |
| mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| RenderThreadImpl* render_thread = RenderThreadImpl::current(); |
| compositor_mus_connection_ = new CompositorMusConnection( |
| routing_id_, render_thread->GetCompositorMainThreadTaskRunner(), |
| render_thread->compositor_task_runner(), std::move(request), |
| render_thread->input_handler_manager()); |
| if (window_surface_binding_) { |
| compositor_mus_connection_->AttachSurfaceOnMainThread( |
| std::move(window_surface_binding_)); |
| } |
| } |
| |
| scoped_ptr<cc::OutputSurface> RenderWidgetMusConnection::CreateOutputSurface() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| DCHECK(!window_surface_binding_); |
| mus::mojom::GpuPtr gpu_service; |
| MojoShellConnection::Get()->GetShell()->ConnectToInterface("mojo:mus", |
| &gpu_service); |
| mus::mojom::CommandBufferPtr cb; |
| gpu_service->CreateOffscreenGLES2Context(GetProxy(&cb)); |
| scoped_refptr<cc::ContextProvider> context_provider( |
| new mus::ContextProvider(cb.PassInterface().PassHandle())); |
| scoped_ptr<cc::OutputSurface> surface(new mus::OutputSurface( |
| context_provider, mus::WindowSurface::Create(&window_surface_binding_))); |
| if (compositor_mus_connection_) { |
| compositor_mus_connection_->AttachSurfaceOnMainThread( |
| std::move(window_surface_binding_)); |
| } |
| return surface; |
| } |
| |
| // static |
| RenderWidgetMusConnection* RenderWidgetMusConnection::Get(int routing_id) { |
| auto it = g_connections.Get().find(routing_id); |
| if (it != g_connections.Get().end()) |
| return it->second; |
| return nullptr; |
| } |
| |
| // static |
| RenderWidgetMusConnection* RenderWidgetMusConnection::GetOrCreate( |
| int routing_id) { |
| RenderWidgetMusConnection* connection = Get(routing_id); |
| if (!connection) { |
| connection = new RenderWidgetMusConnection(routing_id); |
| g_connections.Get().insert(std::make_pair(routing_id, connection)); |
| } |
| return connection; |
| } |
| |
| RenderWidgetMusConnection::RenderWidgetMusConnection(int routing_id) |
| : routing_id_(routing_id), input_handler_(nullptr) { |
| DCHECK(routing_id); |
| } |
| |
| RenderWidgetMusConnection::~RenderWidgetMusConnection() {} |
| |
| void RenderWidgetMusConnection::FocusChangeComplete() { |
| NOTIMPLEMENTED(); |
| } |
| |
| bool RenderWidgetMusConnection::HasTouchEventHandlersAt( |
| const gfx::Point& point) const { |
| return true; |
| } |
| |
| void RenderWidgetMusConnection::ObserveWheelEventAndResult( |
| const blink::WebMouseWheelEvent& wheel_event, |
| const gfx::Vector2dF& wheel_unused_delta, |
| bool event_processed) { |
| NOTIMPLEMENTED(); |
| } |
| |
| void RenderWidgetMusConnection::OnDidHandleKeyEvent() { |
| NOTIMPLEMENTED(); |
| } |
| |
| void RenderWidgetMusConnection::OnDidOverscroll( |
| const DidOverscrollParams& params) { |
| NOTIMPLEMENTED(); |
| } |
| |
| void RenderWidgetMusConnection::OnInputEventAck( |
| scoped_ptr<InputEventAck> input_event_ack) { |
| DCHECK(!pending_ack_.is_null()); |
| // TODO(fsamuel): Use the state in |input_event_ack|. |
| pending_ack_.Run(); |
| pending_ack_.Reset(); |
| } |
| |
| void RenderWidgetMusConnection::NonBlockingInputEventHandled( |
| blink::WebInputEvent::Type handled_type) { |
| NOTIMPLEMENTED(); |
| } |
| |
| void RenderWidgetMusConnection::SetInputHandler( |
| RenderWidgetInputHandler* input_handler) { |
| DCHECK(!input_handler_); |
| input_handler_ = input_handler; |
| } |
| |
| void RenderWidgetMusConnection::UpdateTextInputState( |
| ShowIme show_ime, |
| ChangeSource change_source) { |
| NOTIMPLEMENTED(); |
| } |
| |
| bool RenderWidgetMusConnection::WillHandleGestureEvent( |
| const blink::WebGestureEvent& event) { |
| NOTIMPLEMENTED(); |
| return false; |
| } |
| |
| bool RenderWidgetMusConnection::WillHandleMouseEvent( |
| const blink::WebMouseEvent& event) { |
| // TODO(fsamuel): NOTIMPLEMENTED() is too noisy. |
| // NOTIMPLEMENTED(); |
| return false; |
| } |
| |
| void RenderWidgetMusConnection::OnConnectionLost() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| g_connections.Get().erase(routing_id_); |
| delete this; |
| } |
| |
| void RenderWidgetMusConnection::OnWindowInputEvent( |
| scoped_ptr<blink::WebInputEvent> input_event, |
| const base::Closure& ack) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| // If we don't yet have a RenderWidgetInputHandler then we don't yet have |
| // an initialized RenderWidget. |
| if (!input_handler_) { |
| ack.Run(); |
| return; |
| } |
| // TODO(fsamuel): It would be nice to add this DCHECK but the reality is an |
| // event could timeout and we could receive the next event before we ack the |
| // previous event. |
| // DCHECK(pending_ack_.is_null()); |
| pending_ack_ = ack; |
| // TODO(fsamuel, sadrul): Track real latency info. |
| ui::LatencyInfo latency_info; |
| input_handler_->HandleInputEvent(*input_event, latency_info, |
| DISPATCH_TYPE_NORMAL); |
| } |
| |
| } // namespace content |