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 "cc/surfaces/display.h" | 5 #include "cc/surfaces/display.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/thread_task_runner_handle.h" | 9 #include "base/thread_task_runner_handle.h" |
10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
11 #include "cc/debug/benchmark_instrumentation.h" | 11 #include "cc/debug/benchmark_instrumentation.h" |
12 #include "cc/output/compositor_frame.h" | 12 #include "cc/output/compositor_frame.h" |
13 #include "cc/output/compositor_frame_ack.h" | 13 #include "cc/output/compositor_frame_ack.h" |
14 #include "cc/output/direct_renderer.h" | 14 #include "cc/output/direct_renderer.h" |
15 #include "cc/output/gl_renderer.h" | 15 #include "cc/output/gl_renderer.h" |
16 #include "cc/output/renderer_settings.h" | 16 #include "cc/output/renderer_settings.h" |
17 #include "cc/output/software_renderer.h" | 17 #include "cc/output/software_renderer.h" |
18 #include "cc/output/texture_mailbox_deleter.h" | 18 #include "cc/output/texture_mailbox_deleter.h" |
19 #include "cc/surfaces/display_client.h" | 19 #include "cc/surfaces/display_client.h" |
20 #include "cc/surfaces/display_scheduler.h" | 20 #include "cc/surfaces/display_scheduler.h" |
21 #include "cc/surfaces/surface.h" | 21 #include "cc/surfaces/surface.h" |
22 #include "cc/surfaces/surface_aggregator.h" | 22 #include "cc/surfaces/surface_aggregator.h" |
23 #include "cc/surfaces/surface_manager.h" | 23 #include "cc/surfaces/surface_manager.h" |
24 #include "gpu/command_buffer/client/gles2_interface.h" | 24 #include "gpu/command_buffer/client/gles2_interface.h" |
25 #include "ui/gfx/buffer_types.h" | 25 #include "ui/gfx/buffer_types.h" |
26 | 26 |
| 27 namespace { |
| 28 |
| 29 class EmptyBeginFrameSource : public cc::BeginFrameSource { |
| 30 public: |
| 31 void DidFinishFrame(size_t remaining_frames) override{}; |
| 32 void AddObserver(cc::BeginFrameObserver* obs) override{}; |
| 33 void RemoveObserver(cc::BeginFrameObserver* obs) override{}; |
| 34 void AsValueInto(base::trace_event::TracedValue* dict) const override{}; |
| 35 }; |
| 36 |
| 37 } // namespace |
| 38 |
27 namespace cc { | 39 namespace cc { |
28 | 40 |
29 Display::Display(DisplayClient* client, | 41 Display::Display(DisplayClient* client, |
30 SurfaceManager* manager, | 42 SurfaceManager* manager, |
31 SharedBitmapManager* bitmap_manager, | 43 SharedBitmapManager* bitmap_manager, |
32 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, | 44 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, |
33 const RendererSettings& settings) | 45 const RendererSettings& settings, |
| 46 uint32_t compositor_surface_namespace) |
34 : client_(client), | 47 : client_(client), |
35 manager_(manager), | 48 surface_manager_(manager), |
36 bitmap_manager_(bitmap_manager), | 49 bitmap_manager_(bitmap_manager), |
37 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), | 50 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), |
38 settings_(settings), | 51 settings_(settings), |
| 52 compositor_surface_namespace_(compositor_surface_namespace), |
39 device_scale_factor_(1.f), | 53 device_scale_factor_(1.f), |
40 swapped_since_resize_(false), | 54 swapped_since_resize_(false), |
41 scheduler_(nullptr), | 55 vsync_begin_frame_source_(nullptr), |
| 56 observed_begin_frame_source_(nullptr), |
42 texture_mailbox_deleter_(new TextureMailboxDeleter(nullptr)) { | 57 texture_mailbox_deleter_(new TextureMailboxDeleter(nullptr)) { |
43 manager_->AddObserver(this); | 58 surface_manager_->AddObserver(this); |
44 } | 59 } |
45 | 60 |
46 Display::~Display() { | 61 Display::~Display() { |
47 manager_->RemoveObserver(this); | 62 if (observed_begin_frame_source_) |
| 63 surface_manager_->UnregisterBeginFrameSource(observed_begin_frame_source_); |
| 64 surface_manager_->RemoveObserver(this); |
48 if (aggregator_) { | 65 if (aggregator_) { |
49 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { | 66 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { |
50 Surface* surface = manager_->GetSurfaceForId(id_entry.first); | 67 Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); |
51 if (surface) | 68 if (surface) |
52 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); | 69 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); |
53 } | 70 } |
54 } | 71 } |
55 } | 72 } |
56 | 73 |
| 74 void Display::CreateScheduler(base::SingleThreadTaskRunner* task_runner) { |
| 75 DCHECK(!scheduler_); |
| 76 if (!task_runner) { |
| 77 // WebView doesn't have a task runner or a real begin frame source, |
| 78 // so just create something fake here. |
| 79 internal_begin_frame_source_.reset(new EmptyBeginFrameSource()); |
| 80 vsync_begin_frame_source_ = internal_begin_frame_source_.get(); |
| 81 observed_begin_frame_source_ = vsync_begin_frame_source_; |
| 82 } else { |
| 83 DCHECK(vsync_begin_frame_source_); |
| 84 |
| 85 observed_begin_frame_source_ = vsync_begin_frame_source_; |
| 86 if (settings_.disable_display_vsync) { |
| 87 internal_begin_frame_source_.reset( |
| 88 new BackToBackBeginFrameSource(task_runner)); |
| 89 observed_begin_frame_source_ = internal_begin_frame_source_.get(); |
| 90 } |
| 91 } |
| 92 |
| 93 scheduler_.reset( |
| 94 new DisplayScheduler(this, observed_begin_frame_source_, task_runner, |
| 95 output_surface_->capabilities().max_frames_pending)); |
| 96 surface_manager_->RegisterBeginFrameSource(observed_begin_frame_source_, |
| 97 compositor_surface_namespace_); |
| 98 } |
| 99 |
57 bool Display::Initialize(std::unique_ptr<OutputSurface> output_surface, | 100 bool Display::Initialize(std::unique_ptr<OutputSurface> output_surface, |
58 DisplayScheduler* scheduler) { | 101 base::SingleThreadTaskRunner* task_runner) { |
59 // TODO(enne): register/unregister BeginFrameSource with SurfaceManager here. | |
60 output_surface_ = std::move(output_surface); | 102 output_surface_ = std::move(output_surface); |
61 scheduler_ = scheduler; | 103 if (!output_surface_->BindToClient(this)) |
62 return output_surface_->BindToClient(this); | 104 return false; |
| 105 CreateScheduler(task_runner); |
| 106 return true; |
63 } | 107 } |
64 | 108 |
65 void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) { | 109 void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) { |
| 110 DCHECK_EQ(id.id_namespace(), compositor_surface_namespace_); |
66 if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor) | 111 if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor) |
67 return; | 112 return; |
68 | 113 |
69 TRACE_EVENT0("cc", "Display::SetSurfaceId"); | 114 TRACE_EVENT0("cc", "Display::SetSurfaceId"); |
70 | |
71 current_surface_id_ = id; | 115 current_surface_id_ = id; |
72 device_scale_factor_ = device_scale_factor; | 116 device_scale_factor_ = device_scale_factor; |
73 | 117 |
74 UpdateRootSurfaceResourcesLocked(); | 118 UpdateRootSurfaceResourcesLocked(); |
75 if (scheduler_) | 119 if (scheduler_) |
76 scheduler_->SetNewRootSurface(id); | 120 scheduler_->SetNewRootSurface(id); |
77 } | 121 } |
78 | 122 |
79 void Display::Resize(const gfx::Size& size) { | 123 void Display::Resize(const gfx::Size& size) { |
80 if (size == current_surface_size_) | 124 if (size == current_surface_size_) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 if (!renderer) | 173 if (!renderer) |
130 return; | 174 return; |
131 renderer_ = std::move(renderer); | 175 renderer_ = std::move(renderer); |
132 } | 176 } |
133 | 177 |
134 resource_provider_ = std::move(resource_provider); | 178 resource_provider_ = std::move(resource_provider); |
135 // TODO(jbauman): Outputting an incomplete quad list doesn't work when using | 179 // TODO(jbauman): Outputting an incomplete quad list doesn't work when using |
136 // overlays. | 180 // overlays. |
137 bool output_partial_list = renderer_->Capabilities().using_partial_swap && | 181 bool output_partial_list = renderer_->Capabilities().using_partial_swap && |
138 !output_surface_->GetOverlayCandidateValidator(); | 182 !output_surface_->GetOverlayCandidateValidator(); |
139 aggregator_.reset(new SurfaceAggregator(manager_, resource_provider_.get(), | 183 aggregator_.reset(new SurfaceAggregator( |
140 output_partial_list)); | 184 surface_manager_, resource_provider_.get(), output_partial_list)); |
141 } | 185 } |
142 | 186 |
143 void Display::DidLoseOutputSurface() { | 187 void Display::DidLoseOutputSurface() { |
144 if (scheduler_) | 188 if (scheduler_) |
145 scheduler_->OutputSurfaceLost(); | 189 scheduler_->OutputSurfaceLost(); |
146 // WARNING: The client may delete the Display in this method call. Do not | 190 // WARNING: The client may delete the Display in this method call. Do not |
147 // make any additional references to members after this call. | 191 // make any additional references to members after this call. |
148 client_->OutputSurfaceLost(); | 192 client_->OutputSurfaceLost(); |
149 } | 193 } |
150 | 194 |
151 void Display::UpdateRootSurfaceResourcesLocked() { | 195 void Display::UpdateRootSurfaceResourcesLocked() { |
152 Surface* surface = manager_->GetSurfaceForId(current_surface_id_); | 196 Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_); |
153 bool root_surface_resources_locked = !surface || !surface->GetEligibleFrame(); | 197 bool root_surface_resources_locked = !surface || !surface->GetEligibleFrame(); |
154 if (scheduler_) | 198 if (scheduler_) |
155 scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); | 199 scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); |
156 } | 200 } |
157 | 201 |
158 bool Display::DrawAndSwap() { | 202 bool Display::DrawAndSwap() { |
159 TRACE_EVENT0("cc", "Display::DrawAndSwap"); | 203 TRACE_EVENT0("cc", "Display::DrawAndSwap"); |
160 | 204 |
161 if (current_surface_id_.is_null()) { | 205 if (current_surface_id_.is_null()) { |
162 TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD); | 206 TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD); |
163 return false; | 207 return false; |
164 } | 208 } |
165 | 209 |
166 InitializeRenderer(); | 210 InitializeRenderer(); |
167 if (!output_surface_) { | 211 if (!output_surface_) { |
168 TRACE_EVENT_INSTANT0("cc", "No output surface", TRACE_EVENT_SCOPE_THREAD); | 212 TRACE_EVENT_INSTANT0("cc", "No output surface", TRACE_EVENT_SCOPE_THREAD); |
169 return false; | 213 return false; |
170 } | 214 } |
171 | 215 |
172 std::unique_ptr<CompositorFrame> frame = | 216 std::unique_ptr<CompositorFrame> frame = |
173 aggregator_->Aggregate(current_surface_id_); | 217 aggregator_->Aggregate(current_surface_id_); |
174 if (!frame) { | 218 if (!frame) { |
175 TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.", | 219 TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.", |
176 TRACE_EVENT_SCOPE_THREAD); | 220 TRACE_EVENT_SCOPE_THREAD); |
177 return false; | 221 return false; |
178 } | 222 } |
179 | 223 |
180 // Run callbacks early to allow pipelining. | 224 // Run callbacks early to allow pipelining. |
181 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { | 225 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { |
182 Surface* surface = manager_->GetSurfaceForId(id_entry.first); | 226 Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); |
183 if (surface) | 227 if (surface) |
184 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN); | 228 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN); |
185 } | 229 } |
186 | 230 |
187 DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); | 231 DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); |
188 | 232 |
189 frame->metadata.latency_info.insert(frame->metadata.latency_info.end(), | 233 frame->metadata.latency_info.insert(frame->metadata.latency_info.end(), |
190 stored_latency_info_.begin(), | 234 stored_latency_info_.begin(), |
191 stored_latency_info_.end()); | 235 stored_latency_info_.end()); |
192 stored_latency_info_.clear(); | 236 stored_latency_info_.clear(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 scheduler_->DidSwapBuffers(); | 314 scheduler_->DidSwapBuffers(); |
271 } | 315 } |
272 | 316 |
273 void Display::DidSwapBuffersComplete() { | 317 void Display::DidSwapBuffersComplete() { |
274 if (scheduler_) | 318 if (scheduler_) |
275 scheduler_->DidSwapBuffersComplete(); | 319 scheduler_->DidSwapBuffersComplete(); |
276 if (renderer_) | 320 if (renderer_) |
277 renderer_->SwapBuffersComplete(); | 321 renderer_->SwapBuffersComplete(); |
278 } | 322 } |
279 | 323 |
280 void Display::CommitVSyncParameters(base::TimeTicks timebase, | 324 void Display::SetBeginFrameSource(BeginFrameSource* source) { |
281 base::TimeDelta interval) { | 325 // It's expected that there's only a single source from the |
282 client_->CommitVSyncParameters(timebase, interval); | 326 // BrowserCompositorOutputSurface that corresponds to vsync. The BFS is |
| 327 // passed BrowserCompositorOutputSurface -> Display -> DisplayScheduler as an |
| 328 // input. DisplayScheduler makes a decision about which BFS to use and |
| 329 // calls back to Display as DisplaySchedulerClient to register for that |
| 330 // surface id. |
| 331 DCHECK(!vsync_begin_frame_source_); |
| 332 vsync_begin_frame_source_ = source; |
283 } | 333 } |
284 | 334 |
285 void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { | 335 void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { |
286 client_->SetMemoryPolicy(policy); | 336 client_->SetMemoryPolicy(policy); |
287 } | 337 } |
288 | 338 |
289 void Display::OnDraw(const gfx::Transform& transform, | 339 void Display::OnDraw(const gfx::Transform& transform, |
290 const gfx::Rect& viewport, | 340 const gfx::Rect& viewport, |
291 const gfx::Rect& clip, | 341 const gfx::Rect& clip, |
292 bool resourceless_software_draw) { | 342 bool resourceless_software_draw) { |
(...skipping 21 matching lines...) Expand all Loading... |
314 } | 364 } |
315 | 365 |
316 void Display::SetFullRootLayerDamage() { | 366 void Display::SetFullRootLayerDamage() { |
317 if (aggregator_ && !current_surface_id_.is_null()) | 367 if (aggregator_ && !current_surface_id_.is_null()) |
318 aggregator_->SetFullDamageForSurface(current_surface_id_); | 368 aggregator_->SetFullDamageForSurface(current_surface_id_); |
319 } | 369 } |
320 | 370 |
321 void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) { | 371 void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) { |
322 if (aggregator_ && | 372 if (aggregator_ && |
323 aggregator_->previous_contained_surfaces().count(surface_id)) { | 373 aggregator_->previous_contained_surfaces().count(surface_id)) { |
324 Surface* surface = manager_->GetSurfaceForId(surface_id); | 374 Surface* surface = surface_manager_->GetSurfaceForId(surface_id); |
325 if (surface) { | 375 if (surface) { |
326 const CompositorFrame* current_frame = surface->GetEligibleFrame(); | 376 const CompositorFrame* current_frame = surface->GetEligibleFrame(); |
327 if (!current_frame || !current_frame->delegated_frame_data || | 377 if (!current_frame || !current_frame->delegated_frame_data || |
328 !current_frame->delegated_frame_data->resource_list.size()) { | 378 !current_frame->delegated_frame_data->resource_list.size()) { |
329 aggregator_->ReleaseResources(surface_id); | 379 aggregator_->ReleaseResources(surface_id); |
330 } | 380 } |
331 } | 381 } |
332 if (scheduler_) | 382 if (scheduler_) |
333 scheduler_->SurfaceDamaged(surface_id); | 383 scheduler_->SurfaceDamaged(surface_id); |
334 *changed = true; | 384 *changed = true; |
335 } else if (surface_id == current_surface_id_) { | 385 } else if (surface_id == current_surface_id_) { |
336 if (scheduler_) | 386 if (scheduler_) |
337 scheduler_->SurfaceDamaged(surface_id); | 387 scheduler_->SurfaceDamaged(surface_id); |
338 *changed = true; | 388 *changed = true; |
339 } | 389 } |
340 | 390 |
341 if (surface_id == current_surface_id_) | 391 if (surface_id == current_surface_id_) |
342 UpdateRootSurfaceResourcesLocked(); | 392 UpdateRootSurfaceResourcesLocked(); |
343 } | 393 } |
344 | 394 |
345 SurfaceId Display::CurrentSurfaceId() { | 395 SurfaceId Display::CurrentSurfaceId() { |
346 return current_surface_id_; | 396 return current_surface_id_; |
347 } | 397 } |
348 | 398 |
349 } // namespace cc | 399 } // namespace cc |
OLD | NEW |