| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/services/view_manager/display_manager.h" | 5 #include "mojo/services/view_manager/display_manager.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/numerics/safe_conversions.h" |
| 8 #include "base/scoped_observer.h" | 8 #include "cc/surfaces/surface_id_allocator.h" |
| 9 #include "mojo/public/cpp/application/application_connection.h" | 9 #include "mojo/public/cpp/application/application_connection.h" |
| 10 #include "mojo/services/public/cpp/geometry/geometry_type_converters.h" |
| 11 #include "mojo/services/public/cpp/surfaces/surfaces_type_converters.h" |
| 12 #include "mojo/services/public/cpp/surfaces/surfaces_utils.h" |
| 10 #include "mojo/services/public/interfaces/gpu/gpu.mojom.h" | 13 #include "mojo/services/public/interfaces/gpu/gpu.mojom.h" |
| 14 #include "mojo/services/public/interfaces/surfaces/quads.mojom.h" |
| 11 #include "mojo/services/view_manager/connection_manager.h" | 15 #include "mojo/services/view_manager/connection_manager.h" |
| 12 #include "mojo/services/view_manager/display_manager_delegate.h" | |
| 13 #include "mojo/services/view_manager/screen_impl.h" | |
| 14 #include "mojo/services/view_manager/window_tree_host_impl.h" | |
| 15 #include "ui/aura/client/default_capture_client.h" | |
| 16 #include "ui/aura/client/focus_client.h" | |
| 17 #include "ui/aura/client/window_tree_client.h" | |
| 18 #include "ui/aura/window.h" | |
| 19 #include "ui/aura/window_delegate.h" | |
| 20 #include "ui/base/cursor/cursor.h" | |
| 21 #include "ui/base/hit_test.h" | |
| 22 #include "ui/compositor/layer.h" | |
| 23 #include "ui/gfx/canvas.h" | |
| 24 #include "ui/gfx/image/image_skia.h" | |
| 25 #include "ui/gfx/native_widget_types.h" | |
| 26 | 16 |
| 27 namespace mojo { | 17 namespace mojo { |
| 28 namespace service { | 18 namespace service { |
| 29 namespace { | 19 namespace { |
| 30 | 20 |
| 31 gfx::Rect ConvertRectToRoot(const ServerView* view, const gfx::Rect& bounds) { | 21 gfx::Rect ConvertRectToRoot(const ServerView* view, const gfx::Rect& bounds) { |
| 32 gfx::Point origin(bounds.origin()); | 22 gfx::Point origin(bounds.origin()); |
| 33 while (view->parent()) { | 23 while (view->parent()) { |
| 34 origin += view->bounds().OffsetFromOrigin(); | 24 origin += view->bounds().OffsetFromOrigin(); |
| 35 view = view->parent(); | 25 view = view->parent(); |
| 26 if (!view->visible()) |
| 27 return gfx::Rect(); |
| 36 } | 28 } |
| 37 return gfx::Rect(origin, bounds.size()); | 29 return gfx::Rect(origin, bounds.size()); |
| 38 } | 30 } |
| 39 | 31 |
| 40 void PaintViewTree(gfx::Canvas* canvas, | 32 void DrawViewTree(Pass* pass, const ServerView* view) { |
| 41 const ServerView* view, | |
| 42 const gfx::Point& origin) { | |
| 43 if (!view->visible()) | 33 if (!view->visible()) |
| 44 return; | 34 return; |
| 45 | 35 |
| 46 canvas->DrawImageInt(gfx::ImageSkia::CreateFrom1xBitmap(view->bitmap()), | 36 cc::SurfaceId node_id = view->surface_id(); |
| 47 origin.x(), | 37 |
| 48 origin.y()); | 38 SurfaceQuadStatePtr surface_quad_state = SurfaceQuadState::New(); |
| 39 surface_quad_state->surface = SurfaceId::From(node_id); |
| 40 |
| 41 const gfx::Rect& node_bounds = view->bounds(); |
| 42 gfx::Transform node_transform; |
| 43 node_transform.Translate(node_bounds.x(), node_bounds.y()); |
| 44 |
| 45 QuadPtr surface_quad = Quad::New(); |
| 46 surface_quad->material = Material::MATERIAL_SURFACE_CONTENT; |
| 47 surface_quad->rect = Rect::From(node_bounds); |
| 48 surface_quad->opaque_rect = Rect::From(node_bounds); |
| 49 surface_quad->visible_rect = Rect::From(node_bounds); |
| 50 surface_quad->needs_blending = true; |
| 51 surface_quad->shared_quad_state_index = |
| 52 base::saturated_cast<int32_t>(pass->shared_quad_states.size()); |
| 53 surface_quad->surface_quad_state = surface_quad_state.Pass(); |
| 54 |
| 55 SharedQuadStatePtr sqs = CreateDefaultSQS(node_bounds.size()); |
| 56 sqs->content_to_target_transform = Transform::From(node_transform); |
| 57 |
| 58 pass->quads.push_back(surface_quad.Pass()); |
| 59 pass->shared_quad_states.push_back(sqs.Pass()); |
| 60 |
| 49 std::vector<const ServerView*> children(view->GetChildren()); | 61 std::vector<const ServerView*> children(view->GetChildren()); |
| 50 for (size_t i = 0; i < children.size(); ++i) { | 62 for (std::vector<const ServerView*>::reverse_iterator it = children.rbegin(); |
| 51 PaintViewTree( | 63 it != children.rend(); |
| 52 canvas, children[i], origin + children[i]->bounds().OffsetFromOrigin()); | 64 ++it) { |
| 65 DrawViewTree(pass, *it); |
| 53 } | 66 } |
| 54 } | 67 } |
| 55 | 68 |
| 56 } // namespace | 69 } // namespace |
| 57 | 70 |
| 58 class DisplayManager::RootWindowDelegateImpl : public aura::WindowDelegate { | |
| 59 public: | |
| 60 explicit RootWindowDelegateImpl(ConnectionManager* connection_manager) | |
| 61 : connection_manager_(connection_manager) {} | |
| 62 virtual ~RootWindowDelegateImpl() {} | |
| 63 | |
| 64 // aura::WindowDelegate: | |
| 65 virtual gfx::Size GetMinimumSize() const OVERRIDE { | |
| 66 return gfx::Size(); | |
| 67 } | |
| 68 virtual gfx::Size GetMaximumSize() const OVERRIDE { | |
| 69 return gfx::Size(); | |
| 70 } | |
| 71 virtual void OnBoundsChanged(const gfx::Rect& old_bounds, | |
| 72 const gfx::Rect& new_bounds) OVERRIDE { | |
| 73 connection_manager_->ProcessViewBoundsChanged(connection_manager_->root(), | |
| 74 old_bounds, | |
| 75 new_bounds); | |
| 76 } | |
| 77 virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE { | |
| 78 return gfx::kNullCursor; | |
| 79 } | |
| 80 virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE { | |
| 81 return HTCAPTION; | |
| 82 } | |
| 83 virtual bool ShouldDescendIntoChildForEventHandling( | |
| 84 aura::Window* child, | |
| 85 const gfx::Point& location) OVERRIDE { | |
| 86 return true; | |
| 87 } | |
| 88 virtual bool CanFocus() OVERRIDE { | |
| 89 return true; | |
| 90 } | |
| 91 virtual void OnCaptureLost() OVERRIDE { | |
| 92 } | |
| 93 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { | |
| 94 PaintViewTree(canvas, connection_manager_->root(), gfx::Point()); | |
| 95 } | |
| 96 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE { | |
| 97 } | |
| 98 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { | |
| 99 } | |
| 100 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE { | |
| 101 } | |
| 102 virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE { | |
| 103 } | |
| 104 virtual bool HasHitTestMask() const OVERRIDE { | |
| 105 return false; | |
| 106 } | |
| 107 virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE { | |
| 108 } | |
| 109 | |
| 110 private: | |
| 111 ConnectionManager* connection_manager_; | |
| 112 | |
| 113 DISALLOW_COPY_AND_ASSIGN(RootWindowDelegateImpl); | |
| 114 }; | |
| 115 | |
| 116 // TODO(sky): Remove once aura is removed from the service. | |
| 117 class FocusClientImpl : public aura::client::FocusClient { | |
| 118 public: | |
| 119 FocusClientImpl() {} | |
| 120 virtual ~FocusClientImpl() {} | |
| 121 | |
| 122 private: | |
| 123 // Overridden from aura::client::FocusClient: | |
| 124 virtual void AddObserver( | |
| 125 aura::client::FocusChangeObserver* observer) OVERRIDE {} | |
| 126 virtual void RemoveObserver( | |
| 127 aura::client::FocusChangeObserver* observer) OVERRIDE {} | |
| 128 virtual void FocusWindow(aura::Window* window) OVERRIDE {} | |
| 129 virtual void ResetFocusWithinActiveWindow(aura::Window* window) OVERRIDE {} | |
| 130 virtual aura::Window* GetFocusedWindow() OVERRIDE { return NULL; } | |
| 131 | |
| 132 DISALLOW_COPY_AND_ASSIGN(FocusClientImpl); | |
| 133 }; | |
| 134 | |
| 135 class WindowTreeClientImpl : public aura::client::WindowTreeClient { | |
| 136 public: | |
| 137 explicit WindowTreeClientImpl(aura::Window* window) : window_(window) { | |
| 138 aura::client::SetWindowTreeClient(window_, this); | |
| 139 } | |
| 140 | |
| 141 virtual ~WindowTreeClientImpl() { | |
| 142 aura::client::SetWindowTreeClient(window_, NULL); | |
| 143 } | |
| 144 | |
| 145 // Overridden from aura::client::WindowTreeClient: | |
| 146 virtual aura::Window* GetDefaultParent(aura::Window* context, | |
| 147 aura::Window* window, | |
| 148 const gfx::Rect& bounds) OVERRIDE { | |
| 149 if (!capture_client_) { | |
| 150 capture_client_.reset( | |
| 151 new aura::client::DefaultCaptureClient(window_->GetRootWindow())); | |
| 152 } | |
| 153 return window_; | |
| 154 } | |
| 155 | |
| 156 private: | |
| 157 aura::Window* window_; | |
| 158 | |
| 159 scoped_ptr<aura::client::DefaultCaptureClient> capture_client_; | |
| 160 | |
| 161 DISALLOW_COPY_AND_ASSIGN(WindowTreeClientImpl); | |
| 162 }; | |
| 163 | |
| 164 DisplayManager::DisplayManager( | 71 DisplayManager::DisplayManager( |
| 165 ApplicationConnection* app_connection, | 72 ApplicationConnection* app_connection, |
| 166 ConnectionManager* connection_manager, | 73 ConnectionManager* connection_manager, |
| 167 DisplayManagerDelegate* delegate, | |
| 168 const Callback<void()>& native_viewport_closed_callback) | 74 const Callback<void()>& native_viewport_closed_callback) |
| 169 : delegate_(delegate), | 75 : connection_manager_(connection_manager), |
| 170 connection_manager_(connection_manager), | |
| 171 in_setup_(false), | 76 in_setup_(false), |
| 172 root_window_(NULL) { | 77 bounds_(800, 600), |
| 173 screen_.reset(ScreenImpl::Create()); | 78 draw_timer_(false, false), |
| 174 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); | 79 weak_factory_(this) { |
| 175 NativeViewportPtr viewport; | |
| 176 app_connection->ConnectToService( | |
| 177 "mojo:mojo_native_viewport_service", &viewport); | |
| 178 GpuPtr gpu_service; | |
| 179 // TODO(jamesr): Should be mojo:mojo_gpu_service | |
| 180 app_connection->ConnectToService("mojo:mojo_native_viewport_service", | 80 app_connection->ConnectToService("mojo:mojo_native_viewport_service", |
| 181 &gpu_service); | 81 &native_viewport_); |
| 182 window_tree_host_.reset(new WindowTreeHostImpl( | 82 native_viewport_.set_client(this); |
| 183 viewport.Pass(), | 83 native_viewport_->Create(Size::From(bounds_)); |
| 184 gpu_service.Pass(), | 84 native_viewport_->Show(); |
| 185 gfx::Rect(800, 600), | 85 app_connection->ConnectToService("mojo:mojo_surfaces_service", |
| 186 base::Bind(&DisplayManager::OnCompositorCreated, base::Unretained(this)), | 86 &surfaces_service_); |
| 187 native_viewport_closed_callback, | 87 surfaces_service_->CreateSurfaceConnection(base::Bind( |
| 188 base::Bind(&ConnectionManager::DispatchViewInputEventToWindowManager, | 88 &DisplayManager::OnSurfaceConnectionCreated, weak_factory_.GetWeakPtr())); |
| 189 base::Unretained(connection_manager_)))); | |
| 190 } | 89 } |
| 191 | 90 |
| 192 DisplayManager::~DisplayManager() { | 91 DisplayManager::~DisplayManager() { |
| 193 window_tree_client_.reset(); | |
| 194 window_tree_host_.reset(); | |
| 195 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, NULL); | |
| 196 } | 92 } |
| 197 | 93 |
| 198 void DisplayManager::SchedulePaint(const ServerView* view, | 94 void DisplayManager::SchedulePaint(const ServerView* view, |
| 199 const gfx::Rect& bounds) { | 95 const gfx::Rect& bounds) { |
| 200 if (root_window_) | 96 if (!view->visible()) |
| 201 root_window_->SchedulePaintInRect(ConvertRectToRoot(view, bounds)); | 97 return; |
| 98 gfx::Rect root_relative_rect = ConvertRectToRoot(view, bounds); |
| 99 if (root_relative_rect.IsEmpty()) |
| 100 return; |
| 101 dirty_rect_.Union(root_relative_rect); |
| 102 if (!draw_timer_.IsRunning()) { |
| 103 draw_timer_.Start( |
| 104 FROM_HERE, |
| 105 base::TimeDelta(), |
| 106 base::Bind(&DisplayManager::Draw, base::Unretained(this))); |
| 107 } |
| 202 } | 108 } |
| 203 | 109 |
| 204 void DisplayManager::OnCompositorCreated() { | 110 void DisplayManager::OnSurfaceConnectionCreated(SurfacePtr surface, |
| 205 base::AutoReset<bool> resetter(&in_setup_, true); | 111 uint32_t id_namespace) { |
| 206 window_tree_host_->InitHost(); | 112 surface_ = surface.Pass(); |
| 113 surface_.set_client(this); |
| 114 surface_id_allocator_.reset(new cc::SurfaceIdAllocator(id_namespace)); |
| 115 Draw(); |
| 116 } |
| 207 | 117 |
| 208 window_delegate_.reset( | 118 void DisplayManager::Draw() { |
| 209 new RootWindowDelegateImpl(connection_manager_)); | 119 if (!surface_) |
| 210 root_window_ = new aura::Window(window_delegate_.get()); | 120 return; |
| 211 root_window_->Init(aura::WINDOW_LAYER_TEXTURED); | 121 if (surface_id_.is_null()) { |
| 212 root_window_->Show(); | 122 surface_id_ = surface_id_allocator_->GenerateId(); |
| 213 root_window_->SetBounds( | 123 surface_->CreateSurface(SurfaceId::From(surface_id_), Size::From(bounds_)); |
| 214 gfx::Rect(window_tree_host_->window()->bounds().size())); | 124 } |
| 215 window_tree_host_->window()->AddChild(root_window_); | |
| 216 | 125 |
| 217 connection_manager_->root()->SetBounds( | 126 PassPtr pass = CreateDefaultPass(1, gfx::Rect(bounds_)); |
| 218 gfx::Rect(window_tree_host_->window()->bounds().size())); | 127 pass->damage_rect = Rect::From(dirty_rect_); |
| 219 | 128 |
| 220 window_tree_client_.reset( | 129 DrawViewTree(pass.get(), connection_manager_->root()); |
| 221 new WindowTreeClientImpl(window_tree_host_->window())); | |
| 222 | 130 |
| 223 focus_client_.reset(new FocusClientImpl); | 131 FramePtr frame = Frame::New(); |
| 224 aura::client::SetFocusClient(window_tree_host_->window(), | 132 frame->passes.push_back(pass.Pass()); |
| 225 focus_client_.get()); | 133 frame->resources.resize(0u); |
| 134 surface_->SubmitFrame(SurfaceId::From(surface_id_), frame.Pass()); |
| 226 | 135 |
| 227 window_tree_host_->Show(); | 136 native_viewport_->SubmittedFrame(SurfaceId::From(surface_id_)); |
| 228 | 137 |
| 229 delegate_->OnDisplayManagerWindowTreeHostCreated(); | 138 dirty_rect_ = gfx::Rect(); |
| 139 } |
| 140 |
| 141 void DisplayManager::OnCreated(uint64_t native_viewport_id) { |
| 142 } |
| 143 |
| 144 void DisplayManager::OnDestroyed() { |
| 145 native_viewport_closed_callback_.Run(); |
| 146 } |
| 147 |
| 148 void DisplayManager::OnBoundsChanged(SizePtr bounds) { |
| 149 bounds_ = bounds.To<gfx::Size>(); |
| 150 connection_manager_->root()->SetBounds(gfx::Rect(bounds_)); |
| 151 if (surface_id_.is_null()) |
| 152 return; |
| 153 surface_->DestroySurface(SurfaceId::From(surface_id_)); |
| 154 surface_id_ = cc::SurfaceId(); |
| 155 SchedulePaint(connection_manager_->root(), gfx::Rect(bounds_)); |
| 156 } |
| 157 |
| 158 void DisplayManager::OnEvent(EventPtr event, |
| 159 const mojo::Callback<void()>& callback) { |
| 160 connection_manager_->DispatchViewInputEventToWindowManager(event.Pass()); |
| 161 callback.Run(); |
| 162 } |
| 163 |
| 164 void DisplayManager::ReturnResources(Array<ReturnedResourcePtr> resources) { |
| 165 DCHECK_EQ(0u, resources.size()); |
| 230 } | 166 } |
| 231 | 167 |
| 232 } // namespace service | 168 } // namespace service |
| 233 } // namespace mojo | 169 } // namespace mojo |
| OLD | NEW |