OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/exo/surface.h" | 5 #include "components/exo/surface.h" |
6 | 6 |
7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/trace_event/trace_event.h" | 9 #include "base/trace_event/trace_event.h" |
10 #include "base/trace_event/trace_event_argument.h" | 10 #include "base/trace_event/trace_event_argument.h" |
11 #include "cc/resources/single_release_callback.h" | 11 #include "cc/resources/single_release_callback.h" |
12 #include "components/exo/buffer.h" | 12 #include "components/exo/buffer.h" |
13 #include "components/exo/surface_delegate.h" | 13 #include "components/exo/surface_delegate.h" |
14 #include "components/exo/surface_observer.h" | 14 #include "components/exo/surface_observer.h" |
| 15 #include "ui/aura/window_delegate.h" |
| 16 #include "ui/base/cursor/cursor.h" |
| 17 #include "ui/base/hit_test.h" |
15 #include "ui/compositor/layer.h" | 18 #include "ui/compositor/layer.h" |
16 #include "ui/gfx/buffer_format_util.h" | 19 #include "ui/gfx/buffer_format_util.h" |
17 #include "ui/gfx/gpu_memory_buffer.h" | 20 #include "ui/gfx/gpu_memory_buffer.h" |
18 | 21 |
19 namespace exo { | 22 namespace exo { |
20 namespace { | 23 namespace { |
21 | 24 |
22 // Helper function that returns an iterator to the first entry in |list| | 25 // Helper function that returns an iterator to the first entry in |list| |
23 // with |key|. | 26 // with |key|. |
24 template <typename T, typename U> | 27 template <typename T, typename U> |
25 typename T::iterator FindListEntry(T& list, U key) { | 28 typename T::iterator FindListEntry(T& list, U key) { |
26 return std::find_if(list.begin(), list.end(), | 29 return std::find_if(list.begin(), list.end(), |
27 [key](const typename T::value_type& entry) { | 30 [key](const typename T::value_type& entry) { |
28 return entry.first == key; | 31 return entry.first == key; |
29 }); | 32 }); |
30 } | 33 } |
31 | 34 |
32 // Helper function that returns true if |list| contains an entry with |key|. | 35 // Helper function that returns true if |list| contains an entry with |key|. |
33 template <typename T, typename U> | 36 template <typename T, typename U> |
34 bool ListContainsEntry(T& list, U key) { | 37 bool ListContainsEntry(T& list, U key) { |
35 return FindListEntry(list, key) != list.end(); | 38 return FindListEntry(list, key) != list.end(); |
36 } | 39 } |
37 | 40 |
| 41 // A window delegate which does nothing. Used to create a window that |
| 42 // is an event target, but do nothing. |
| 43 class EmptyWindowDelegate : public aura::WindowDelegate { |
| 44 public: |
| 45 EmptyWindowDelegate() {} |
| 46 ~EmptyWindowDelegate() override {} |
| 47 |
| 48 // Overridden from aura::WindowDelegate: |
| 49 gfx::Size GetMinimumSize() const override { return gfx::Size(); } |
| 50 gfx::Size GetMaximumSize() const override { return gfx::Size(); } |
| 51 void OnBoundsChanged(const gfx::Rect& old_bounds, |
| 52 const gfx::Rect& new_bounds) override {} |
| 53 gfx::NativeCursor GetCursor(const gfx::Point& point) override { |
| 54 return gfx::kNullCursor; |
| 55 } |
| 56 int GetNonClientComponent(const gfx::Point& point) const override { |
| 57 return HTNOWHERE; |
| 58 } |
| 59 bool ShouldDescendIntoChildForEventHandling( |
| 60 aura::Window* child, |
| 61 const gfx::Point& location) override { |
| 62 return false; |
| 63 } |
| 64 bool CanFocus() override { return true; } |
| 65 void OnCaptureLost() override {} |
| 66 void OnPaint(const ui::PaintContext& context) override {} |
| 67 void OnDeviceScaleFactorChanged(float device_scale_factor) override {} |
| 68 void OnWindowDestroying(aura::Window* window) override {} |
| 69 void OnWindowDestroyed(aura::Window* window) override { delete this; } |
| 70 void OnWindowTargetVisibilityChanged(bool visible) override {} |
| 71 bool HasHitTestMask() const override { return false; } |
| 72 void GetHitTestMask(gfx::Path* mask) const override {} |
| 73 |
| 74 private: |
| 75 DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate); |
| 76 }; |
| 77 |
38 } // namespace | 78 } // namespace |
39 | 79 |
40 //////////////////////////////////////////////////////////////////////////////// | 80 //////////////////////////////////////////////////////////////////////////////// |
41 // Surface, public: | 81 // Surface, public: |
42 | 82 |
43 Surface::Surface() | 83 Surface::Surface() |
44 : has_pending_contents_(false), | 84 : aura::Window(new EmptyWindowDelegate), |
| 85 has_pending_contents_(false), |
45 needs_commit_surface_hierarchy_(false), | 86 needs_commit_surface_hierarchy_(false), |
46 update_contents_after_successful_compositing_(false), | 87 update_contents_after_successful_compositing_(false), |
47 compositor_(nullptr), | 88 compositor_(nullptr), |
48 delegate_(nullptr) { | 89 delegate_(nullptr) { |
49 SetLayer(new ui::Layer(ui::LAYER_SOLID_COLOR)); | 90 SetType(ui::wm::WINDOW_TYPE_CONTROL); |
50 set_owned_by_client(); | 91 Init(ui::LAYER_SOLID_COLOR); |
51 SetVisible(false); | 92 set_owned_by_parent(false); |
52 SetEnabled(false); | 93 SetName("ExoSurface"); |
53 } | 94 } |
54 | 95 |
55 Surface::~Surface() { | 96 Surface::~Surface() { |
56 FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this)); | 97 FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this)); |
57 | 98 |
58 layer()->SetShowSolidColorContent(); | 99 layer()->SetShowSolidColorContent(); |
59 | 100 |
60 if (compositor_) | 101 if (compositor_) |
61 compositor_->RemoveObserver(this); | 102 compositor_->RemoveObserver(this); |
62 | 103 |
63 // Call pending frame callbacks with a null frame time to indicate that they | 104 // Call pending frame callbacks with a null frame time to indicate that they |
64 // have been cancelled. | 105 // have been cancelled. |
65 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); | 106 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); |
66 active_frame_callbacks_.splice(active_frame_callbacks_.end(), | 107 active_frame_callbacks_.splice(active_frame_callbacks_.end(), |
67 frame_callbacks_); | 108 frame_callbacks_); |
68 for (const auto& frame_callback : active_frame_callbacks_) | 109 for (const auto& frame_callback : active_frame_callbacks_) |
69 frame_callback.Run(base::TimeTicks()); | 110 frame_callback.Run(base::TimeTicks()); |
70 } | 111 } |
71 | 112 |
72 void Surface::Attach(Buffer* buffer) { | 113 void Surface::Attach(Buffer* buffer) { |
73 TRACE_EVENT1("exo", "Surface::Attach", "buffer", buffer->AsTracedValue()); | 114 TRACE_EVENT1("exo", "Surface::Attach", "buffer", buffer->AsTracedValue()); |
74 | 115 |
75 has_pending_contents_ = true; | 116 has_pending_contents_ = true; |
76 pending_buffer_ = buffer ? buffer->AsWeakPtr() : base::WeakPtr<Buffer>(); | 117 pending_buffer_ = buffer ? buffer->AsWeakPtr() : base::WeakPtr<Buffer>(); |
77 PreferredSizeChanged(); | |
78 } | 118 } |
79 | 119 |
80 void Surface::Damage(const gfx::Rect& damage) { | 120 void Surface::Damage(const gfx::Rect& damage) { |
81 TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString()); | 121 TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString()); |
82 | 122 |
83 pending_damage_.Union(damage); | 123 pending_damage_.Union(damage); |
84 } | 124 } |
85 | 125 |
86 void Surface::RequestFrameCallback(const FrameCallback& callback) { | 126 void Surface::RequestFrameCallback(const FrameCallback& callback) { |
87 TRACE_EVENT0("exo", "Surface::RequestFrameCallback"); | 127 TRACE_EVENT0("exo", "Surface::RequestFrameCallback"); |
88 | 128 |
89 pending_frame_callbacks_.push_back(callback); | 129 pending_frame_callbacks_.push_back(callback); |
90 } | 130 } |
91 | 131 |
92 void Surface::SetOpaqueRegion(const SkRegion& region) { | 132 void Surface::SetOpaqueRegion(const SkRegion& region) { |
93 TRACE_EVENT1("exo", "Surface::SetOpaqueRegion", "region", | 133 TRACE_EVENT1("exo", "Surface::SetOpaqueRegion", "region", |
94 gfx::SkIRectToRect(region.getBounds()).ToString()); | 134 gfx::SkIRectToRect(region.getBounds()).ToString()); |
95 | 135 |
96 pending_opaque_region_ = region; | 136 pending_opaque_region_ = region; |
97 } | 137 } |
98 | 138 |
99 void Surface::AddSubSurface(Surface* sub_surface) { | 139 void Surface::AddSubSurface(Surface* sub_surface) { |
100 TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface", | 140 TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface", |
101 sub_surface->AsTracedValue()); | 141 sub_surface->AsTracedValue()); |
102 | 142 |
103 DCHECK(!sub_surface->parent()); | 143 DCHECK(!sub_surface->parent()); |
104 DCHECK(!sub_surface->visible()); | 144 DCHECK(!sub_surface->IsVisible()); |
105 DCHECK(!sub_surface->enabled()); | |
106 DCHECK(sub_surface->bounds().origin() == gfx::Point()); | 145 DCHECK(sub_surface->bounds().origin() == gfx::Point()); |
107 AddChildView(sub_surface); | 146 AddChild(sub_surface); |
108 | 147 |
109 DCHECK(!ListContainsEntry(pending_sub_surfaces_, sub_surface)); | 148 DCHECK(!ListContainsEntry(pending_sub_surfaces_, sub_surface)); |
110 pending_sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point())); | 149 pending_sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point())); |
111 } | 150 } |
112 | 151 |
113 void Surface::RemoveSubSurface(Surface* sub_surface) { | 152 void Surface::RemoveSubSurface(Surface* sub_surface) { |
114 TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface", | 153 TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface", |
115 sub_surface->AsTracedValue()); | 154 sub_surface->AsTracedValue()); |
116 | 155 |
117 RemoveChildView(sub_surface); | 156 RemoveChild(sub_surface); |
118 | 157 |
119 DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface)); | 158 DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface)); |
120 pending_sub_surfaces_.erase( | 159 pending_sub_surfaces_.erase( |
121 FindListEntry(pending_sub_surfaces_, sub_surface)); | 160 FindListEntry(pending_sub_surfaces_, sub_surface)); |
122 } | 161 } |
123 | 162 |
124 void Surface::SetSubSurfacePosition(Surface* sub_surface, | 163 void Surface::SetSubSurfacePosition(Surface* sub_surface, |
125 const gfx::Point& position) { | 164 const gfx::Point& position) { |
126 TRACE_EVENT2("exo", "Surface::SetSubSurfacePosition", "sub_surface", | 165 TRACE_EVENT2("exo", "Surface::SetSubSurfacePosition", "sub_surface", |
127 sub_surface->AsTracedValue(), "position", position.ToString()); | 166 sub_surface->AsTracedValue(), "position", position.ToString()); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 // Start observing the compositor for frame callbacks. | 279 // Start observing the compositor for frame callbacks. |
241 if (!compositor_) { | 280 if (!compositor_) { |
242 compositor->AddObserver(this); | 281 compositor->AddObserver(this); |
243 compositor_ = compositor; | 282 compositor_ = compositor; |
244 } | 283 } |
245 | 284 |
246 // Move pending frame callbacks to the end of |frame_callbacks_|. | 285 // Move pending frame callbacks to the end of |frame_callbacks_|. |
247 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); | 286 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); |
248 } | 287 } |
249 | 288 |
250 // Synchronize view hierarchy. This will position and update the stacking | 289 // Synchronize window hierarchy. This will position and update the stacking |
251 // order of all sub-surfaces after committing all pending state of sub-surface | 290 // order of all sub-surfaces after committing all pending state of sub-surface |
252 // descendants. | 291 // descendants. |
253 int index = 0; | 292 aura::Window* stacking_target = nullptr; |
254 for (auto& sub_surface_entry : pending_sub_surfaces_) { | 293 for (auto& sub_surface_entry : pending_sub_surfaces_) { |
255 Surface* sub_surface = sub_surface_entry.first; | 294 Surface* sub_surface = sub_surface_entry.first; |
256 | 295 |
257 // Synchronsouly commit all pending state of the sub-surface and its | 296 // Synchronsouly commit all pending state of the sub-surface and its |
258 // decendents. | 297 // decendents. |
259 if (sub_surface->needs_commit_surface_hierarchy()) | 298 if (sub_surface->needs_commit_surface_hierarchy()) |
260 sub_surface->CommitSurfaceHierarchy(); | 299 sub_surface->CommitSurfaceHierarchy(); |
261 | 300 |
262 // Enable/disable sub-surface based on if it has contents. | 301 // Enable/disable sub-surface based on if it has contents. |
263 sub_surface->SetVisible(sub_surface->has_contents()); | 302 if (sub_surface->has_contents()) |
264 sub_surface->SetEnabled(sub_surface->has_contents()); | 303 sub_surface->Show(); |
| 304 else |
| 305 sub_surface->Hide(); |
265 | 306 |
266 // Move sub-surface to its new position in the stack. | 307 // Move sub-surface to its new position in the stack. |
267 DCHECK_LT(index, child_count()); | 308 if (stacking_target) |
268 ReorderChildView(sub_surface, index); | 309 StackChildAbove(sub_surface, stacking_target); |
| 310 |
| 311 // Stack next sub-surface above this sub-surface. |
| 312 stacking_target = sub_surface; |
269 | 313 |
270 // Update sub-surface position relative to surface origin. | 314 // Update sub-surface position relative to surface origin. |
271 sub_surface->SetPosition(sub_surface_entry.second); | 315 sub_surface->SetBounds( |
| 316 gfx::Rect(sub_surface_entry.second, sub_surface->layer()->size())); |
| 317 } |
| 318 } |
272 | 319 |
273 ++index; | 320 gfx::Size Surface::GetPreferredSize() const { |
274 } | 321 return pending_buffer_ ? pending_buffer_->GetSize() : layer()->size(); |
275 } | 322 } |
276 | 323 |
277 bool Surface::IsSynchronized() const { | 324 bool Surface::IsSynchronized() const { |
278 return delegate_ ? delegate_->IsSurfaceSynchronized() : false; | 325 return delegate_ ? delegate_->IsSurfaceSynchronized() : false; |
279 } | 326 } |
280 | 327 |
281 void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) { | 328 void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) { |
282 DCHECK(!delegate_ || !delegate); | 329 DCHECK(!delegate_ || !delegate); |
283 delegate_ = delegate; | 330 delegate_ = delegate; |
284 } | 331 } |
(...skipping 15 matching lines...) Expand all Loading... |
300 } | 347 } |
301 | 348 |
302 scoped_refptr<base::trace_event::TracedValue> Surface::AsTracedValue() const { | 349 scoped_refptr<base::trace_event::TracedValue> Surface::AsTracedValue() const { |
303 scoped_refptr<base::trace_event::TracedValue> value = | 350 scoped_refptr<base::trace_event::TracedValue> value = |
304 new base::trace_event::TracedValue; | 351 new base::trace_event::TracedValue; |
305 value->SetString("name", layer()->name()); | 352 value->SetString("name", layer()->name()); |
306 return value; | 353 return value; |
307 } | 354 } |
308 | 355 |
309 //////////////////////////////////////////////////////////////////////////////// | 356 //////////////////////////////////////////////////////////////////////////////// |
310 // views::Views overrides: | |
311 | |
312 gfx::Size Surface::GetPreferredSize() const { | |
313 return pending_buffer_ ? pending_buffer_->GetSize() : layer()->size(); | |
314 } | |
315 | |
316 //////////////////////////////////////////////////////////////////////////////// | |
317 // ui::CompositorObserver overrides: | 357 // ui::CompositorObserver overrides: |
318 | 358 |
319 void Surface::OnCompositingDidCommit(ui::Compositor* compositor) { | 359 void Surface::OnCompositingDidCommit(ui::Compositor* compositor) { |
320 // Move frame callbacks to the end of |active_frame_callbacks_|. | 360 // Move frame callbacks to the end of |active_frame_callbacks_|. |
321 active_frame_callbacks_.splice(active_frame_callbacks_.end(), | 361 active_frame_callbacks_.splice(active_frame_callbacks_.end(), |
322 frame_callbacks_); | 362 frame_callbacks_); |
323 } | 363 } |
324 | 364 |
325 void Surface::OnCompositingStarted(ui::Compositor* compositor, | 365 void Surface::OnCompositingStarted(ui::Compositor* compositor, |
326 base::TimeTicks start_time) { | 366 base::TimeTicks start_time) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 // of the surface next time the compositor successfully ends compositing. | 401 // of the surface next time the compositor successfully ends compositing. |
362 update_contents_after_successful_compositing_ = true; | 402 update_contents_after_successful_compositing_ = true; |
363 } | 403 } |
364 | 404 |
365 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) { | 405 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) { |
366 compositor->RemoveObserver(this); | 406 compositor->RemoveObserver(this); |
367 compositor_ = nullptr; | 407 compositor_ = nullptr; |
368 } | 408 } |
369 | 409 |
370 } // namespace exo | 410 } // namespace exo |
OLD | NEW |