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