| 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 |