Chromium Code Reviews| 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 "content/browser/renderer_host/browser_compositor_view_mac.h" | 5 #include "content/browser/renderer_host/browser_compositor_view_mac.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 12 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
| 13 #include "content/browser/compositor/image_transport_factory.h" | 13 #include "content/browser/compositor/image_transport_factory.h" |
| 14 #include "content/browser/renderer_host/resize_lock.h" | 14 #include "content/browser/renderer_host/resize_lock.h" |
| 15 #include "content/public/browser/browser_thread.h" | |
| 15 #include "content/public/browser/context_factory.h" | 16 #include "content/public/browser/context_factory.h" |
| 16 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" | 17 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" |
| 17 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" | 18 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" |
| 18 #include "ui/base/layout.h" | 19 #include "ui/base/layout.h" |
| 19 #include "ui/gfx/geometry/dip_util.h" | 20 #include "ui/gfx/geometry/dip_util.h" |
| 20 | 21 |
| 21 namespace content { | 22 namespace content { |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 25 // Set when no browser compositors should remain alive. | 26 // Set when no browser compositors should remain alive. |
| 26 bool g_has_shut_down = false; | 27 bool g_has_shut_down = false; |
| 27 | 28 |
| 28 // The number of placeholder objects allocated. If this reaches zero, then | 29 // The number of placeholder objects allocated. If this reaches zero, then |
| 29 // the RecyclableCompositorMac being held on to for recycling, | 30 // the RecyclableCompositorMac being held on to for recycling, |
| 30 // |g_spare_recyclable_compositor|, will be freed. | 31 // |g_spare_recyclable_compositors|, will be freed. |
| 31 uint32_t g_browser_compositor_count = 0; | 32 uint32_t g_browser_compositor_count = 0; |
| 32 | 33 |
| 33 // A spare RecyclableCompositorMac kept around for recycling. | 34 // A spare RecyclableCompositorMac kept around for recycling. |
| 34 base::LazyInstance<std::unique_ptr<RecyclableCompositorMac>> | 35 base::LazyInstance<std::deque<std::unique_ptr<RecyclableCompositorMac>>> |
| 35 g_spare_recyclable_compositor; | 36 g_spare_recyclable_compositors; |
| 37 | |
| 38 void ReleaseSpareCompositors() { | |
| 39 // Allow at most one spare recyclable compositor. | |
| 40 while (g_spare_recyclable_compositors.Get().size() > 1) | |
| 41 g_spare_recyclable_compositors.Get().pop_front(); | |
| 42 | |
| 43 if (!g_browser_compositor_count) | |
| 44 g_spare_recyclable_compositors.Get().clear(); | |
| 45 } | |
| 36 | 46 |
| 37 } // namespace | 47 } // namespace |
| 38 | 48 |
| 39 //////////////////////////////////////////////////////////////////////////////// | 49 //////////////////////////////////////////////////////////////////////////////// |
| 40 // RecyclableCompositorMac | 50 // RecyclableCompositorMac |
| 41 | 51 |
| 42 // A ui::Compositor and a gfx::AcceleratedWidget (and helper) that it draws | 52 // A ui::Compositor and a gfx::AcceleratedWidget (and helper) that it draws |
| 43 // into. This structure is used to efficiently recycle these structures across | 53 // into. This structure is used to efficiently recycle these structures across |
| 44 // tabs (because creating a new ui::Compositor for each tab would be expensive | 54 // tabs (because creating a new ui::Compositor for each tab would be expensive |
| 45 // in terms of time and resources). | 55 // in terms of time and resources). |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 void RecyclableCompositorMac::OnCompositingDidCommit( | 123 void RecyclableCompositorMac::OnCompositingDidCommit( |
| 114 ui::Compositor* compositor_that_did_commit) { | 124 ui::Compositor* compositor_that_did_commit) { |
| 115 DCHECK_EQ(compositor_that_did_commit, compositor()); | 125 DCHECK_EQ(compositor_that_did_commit, compositor()); |
| 116 content::ImageTransportFactory::GetInstance() | 126 content::ImageTransportFactory::GetInstance() |
| 117 ->SetCompositorSuspendedForRecycle(compositor(), false); | 127 ->SetCompositorSuspendedForRecycle(compositor(), false); |
| 118 } | 128 } |
| 119 | 129 |
| 120 // static | 130 // static |
| 121 std::unique_ptr<RecyclableCompositorMac> RecyclableCompositorMac::Create() { | 131 std::unique_ptr<RecyclableCompositorMac> RecyclableCompositorMac::Create() { |
| 122 DCHECK(ui::WindowResizeHelperMac::Get()->task_runner()); | 132 DCHECK(ui::WindowResizeHelperMac::Get()->task_runner()); |
| 123 if (g_spare_recyclable_compositor.Get()) | 133 if (!g_spare_recyclable_compositors.Get().empty()) { |
| 124 return std::move(g_spare_recyclable_compositor.Get()); | 134 std::unique_ptr<RecyclableCompositorMac> result; |
| 135 result = std::move(g_spare_recyclable_compositors.Get().front()); | |
| 136 g_spare_recyclable_compositors.Get().pop_front(); | |
|
enne (OOO)
2016/07/20 23:53:48
Did you want to delete the remaining spare composi
ccameron
2016/07/20 23:59:33
There will only be >0 when there is an outstanding
| |
| 137 return result; | |
| 138 } | |
| 125 return std::unique_ptr<RecyclableCompositorMac>(new RecyclableCompositorMac); | 139 return std::unique_ptr<RecyclableCompositorMac>(new RecyclableCompositorMac); |
| 126 } | 140 } |
| 127 | 141 |
| 128 // static | 142 // static |
| 129 void RecyclableCompositorMac::Recycle( | 143 void RecyclableCompositorMac::Recycle( |
| 130 std::unique_ptr<RecyclableCompositorMac> compositor) { | 144 std::unique_ptr<RecyclableCompositorMac> compositor) { |
| 131 DCHECK(compositor); | 145 DCHECK(compositor); |
| 132 content::ImageTransportFactory::GetInstance() | 146 content::ImageTransportFactory::GetInstance() |
| 133 ->SetCompositorSuspendedForRecycle(compositor->compositor(), true); | 147 ->SetCompositorSuspendedForRecycle(compositor->compositor(), true); |
| 134 | 148 |
| 135 // It is an error to have a browser compositor continue to exist after | 149 // It is an error to have a browser compositor continue to exist after |
| 136 // shutdown. | 150 // shutdown. |
| 137 CHECK(!g_has_shut_down); | 151 CHECK(!g_has_shut_down); |
| 138 | 152 |
| 139 // Make this RecyclableCompositorMac recyclable for future instances. | 153 // Make this RecyclableCompositorMac recyclable for future instances. |
| 140 g_spare_recyclable_compositor.Get().swap(compositor); | 154 g_spare_recyclable_compositors.Get().push_back(std::move(compositor)); |
| 141 | 155 |
| 142 // If there are no placeholders allocated, destroy the recyclable | 156 // Post a task to free up the spare ui::Compositors when needed. Post this |
| 143 // RecyclableCompositorMac that we just populated. | 157 // to the browser main thread so that we won't free any compositors while |
| 144 if (!g_browser_compositor_count) | 158 // in a nested loop waiting to put up a new frame. |
| 145 g_spare_recyclable_compositor.Get().reset(); | 159 BrowserThread::PostTask( |
| 160 BrowserThread::UI, FROM_HERE, base::Bind(&ReleaseSpareCompositors)); | |
| 146 } | 161 } |
| 147 | 162 |
| 148 //////////////////////////////////////////////////////////////////////////////// | 163 //////////////////////////////////////////////////////////////////////////////// |
| 149 // BrowserCompositorMac | 164 // BrowserCompositorMac |
| 150 | 165 |
| 151 BrowserCompositorMac::BrowserCompositorMac( | 166 BrowserCompositorMac::BrowserCompositorMac( |
| 152 ui::AcceleratedWidgetMacNSView* accelerated_widget_mac_ns_view, | 167 ui::AcceleratedWidgetMacNSView* accelerated_widget_mac_ns_view, |
| 153 BrowserCompositorMacClient* client, | 168 BrowserCompositorMacClient* client, |
| 154 bool render_widget_host_is_hidden, | 169 bool render_widget_host_is_hidden, |
| 155 bool ns_view_attached_to_window) | 170 bool ns_view_attached_to_window) |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 173 TransitionToState(HasNoCompositor); | 188 TransitionToState(HasNoCompositor); |
| 174 delegated_frame_host_.reset(); | 189 delegated_frame_host_.reset(); |
| 175 root_layer_.reset(); | 190 root_layer_.reset(); |
| 176 | 191 |
| 177 DCHECK_GT(g_browser_compositor_count, 0u); | 192 DCHECK_GT(g_browser_compositor_count, 0u); |
| 178 g_browser_compositor_count -= 1; | 193 g_browser_compositor_count -= 1; |
| 179 | 194 |
| 180 // If there are no compositors allocated, destroy the recyclable | 195 // If there are no compositors allocated, destroy the recyclable |
| 181 // RecyclableCompositorMac. | 196 // RecyclableCompositorMac. |
| 182 if (!g_browser_compositor_count) | 197 if (!g_browser_compositor_count) |
| 183 g_spare_recyclable_compositor.Get().reset(); | 198 g_spare_recyclable_compositors.Get().clear(); |
| 184 } | 199 } |
| 185 | 200 |
| 186 ui::AcceleratedWidgetMac* BrowserCompositorMac::GetAcceleratedWidgetMac() { | 201 ui::AcceleratedWidgetMac* BrowserCompositorMac::GetAcceleratedWidgetMac() { |
| 187 if (recyclable_compositor_) | 202 if (recyclable_compositor_) |
| 188 return recyclable_compositor_->accelerated_widget_mac(); | 203 return recyclable_compositor_->accelerated_widget_mac(); |
| 189 return nullptr; | 204 return nullptr; |
| 190 } | 205 } |
| 191 | 206 |
| 192 DelegatedFrameHost* BrowserCompositorMac::GetDelegatedFrameHost() { | 207 DelegatedFrameHost* BrowserCompositorMac::GetDelegatedFrameHost() { |
| 193 DCHECK(delegated_frame_host_); | 208 DCHECK(delegated_frame_host_); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 recyclable_compositor_->compositor()->SetScaleAndSize(1.0, gfx::Size(0, 0)); | 375 recyclable_compositor_->compositor()->SetScaleAndSize(1.0, gfx::Size(0, 0)); |
| 361 recyclable_compositor_->compositor()->SetRootLayer(nullptr); | 376 recyclable_compositor_->compositor()->SetRootLayer(nullptr); |
| 362 RecyclableCompositorMac::Recycle(std::move(recyclable_compositor_)); | 377 RecyclableCompositorMac::Recycle(std::move(recyclable_compositor_)); |
| 363 state_ = HasNoCompositor; | 378 state_ = HasNoCompositor; |
| 364 } | 379 } |
| 365 } | 380 } |
| 366 | 381 |
| 367 // static | 382 // static |
| 368 void BrowserCompositorMac::DisableRecyclingForShutdown() { | 383 void BrowserCompositorMac::DisableRecyclingForShutdown() { |
| 369 g_has_shut_down = true; | 384 g_has_shut_down = true; |
| 370 g_spare_recyclable_compositor.Get().reset(); | 385 g_spare_recyclable_compositors.Get().clear(); |
| 371 } | 386 } |
| 372 | 387 |
| 373 void BrowserCompositorMac::SetNeedsBeginFrames(bool needs_begin_frames) { | 388 void BrowserCompositorMac::SetNeedsBeginFrames(bool needs_begin_frames) { |
| 374 if (needs_begin_frames_ == needs_begin_frames) | 389 if (needs_begin_frames_ == needs_begin_frames) |
| 375 return; | 390 return; |
| 376 | 391 |
| 377 needs_begin_frames_ = needs_begin_frames; | 392 needs_begin_frames_ = needs_begin_frames; |
| 378 if (begin_frame_source_) { | 393 if (begin_frame_source_) { |
| 379 if (needs_begin_frames_) | 394 if (needs_begin_frames_) |
| 380 begin_frame_source_->AddObserver(this); | 395 begin_frame_source_->AddObserver(this); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 462 | 477 |
| 463 const cc::BeginFrameArgs& BrowserCompositorMac::LastUsedBeginFrameArgs() const { | 478 const cc::BeginFrameArgs& BrowserCompositorMac::LastUsedBeginFrameArgs() const { |
| 464 return last_begin_frame_args_; | 479 return last_begin_frame_args_; |
| 465 } | 480 } |
| 466 | 481 |
| 467 void BrowserCompositorMac::OnBeginFrameSourcePausedChanged(bool paused) { | 482 void BrowserCompositorMac::OnBeginFrameSourcePausedChanged(bool paused) { |
| 468 // Only used on Android WebView. | 483 // Only used on Android WebView. |
| 469 } | 484 } |
| 470 | 485 |
| 471 } // namespace content | 486 } // namespace content |
| OLD | NEW |