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" |
(...skipping 14 matching lines...) Expand all Loading... | |
25 #include "ui/gfx/buffer_types.h" | 25 #include "ui/gfx/buffer_types.h" |
26 | 26 |
27 namespace cc { | 27 namespace cc { |
28 | 28 |
29 Display::Display(DisplayClient* client, | 29 Display::Display(DisplayClient* client, |
30 SurfaceManager* manager, | 30 SurfaceManager* manager, |
31 SharedBitmapManager* bitmap_manager, | 31 SharedBitmapManager* bitmap_manager, |
32 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, | 32 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, |
33 const RendererSettings& settings) | 33 const RendererSettings& settings) |
34 : client_(client), | 34 : client_(client), |
35 manager_(manager), | 35 surface_manager_(manager), |
36 bitmap_manager_(bitmap_manager), | 36 bitmap_manager_(bitmap_manager), |
37 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), | 37 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), |
38 settings_(settings), | 38 settings_(settings), |
39 device_scale_factor_(1.f), | 39 device_scale_factor_(1.f), |
40 swapped_since_resize_(false), | 40 swapped_since_resize_(false), |
41 scheduler_(nullptr), | 41 vsync_begin_frame_source_(nullptr), |
42 scheduler_begin_frame_source_(nullptr), | |
42 texture_mailbox_deleter_(new TextureMailboxDeleter(nullptr)) { | 43 texture_mailbox_deleter_(new TextureMailboxDeleter(nullptr)) { |
43 manager_->AddObserver(this); | 44 surface_manager_->AddObserver(this); |
44 } | 45 } |
45 | 46 |
46 Display::~Display() { | 47 Display::~Display() { |
47 manager_->RemoveObserver(this); | 48 if (scheduler_begin_frame_source_) { |
49 surface_manager_->RegisterBeginFrameSource( | |
50 nullptr, current_surface_id_.id_namespace()); | |
51 } | |
52 surface_manager_->RemoveObserver(this); | |
48 if (aggregator_) { | 53 if (aggregator_) { |
49 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { | 54 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { |
50 Surface* surface = manager_->GetSurfaceForId(id_entry.first); | 55 Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); |
51 if (surface) | 56 if (surface) |
52 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); | 57 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); |
53 } | 58 } |
54 } | 59 } |
55 } | 60 } |
56 | 61 |
57 bool Display::Initialize(scoped_ptr<OutputSurface> output_surface, | 62 bool Display::Initialize(scoped_ptr<OutputSurface> output_surface, |
58 DisplayScheduler* scheduler) { | 63 base::SingleThreadTaskRunner* task_runner) { |
59 // TODO(enne): register/unregister BeginFrameSource with SurfaceManager here. | |
60 output_surface_ = std::move(output_surface); | 64 output_surface_ = std::move(output_surface); |
61 scheduler_ = scheduler; | 65 if (!output_surface_->BindToClient(this)) |
62 return output_surface_->BindToClient(this); | 66 return false; |
67 DCHECK(vsync_begin_frame_source_); | |
no sievers
2016/03/25 18:55:08
Then it looks like OutputSurfaceWithoutParent in c
| |
68 scheduler_.reset( | |
69 new DisplayScheduler(this, vsync_begin_frame_source_, task_runner, | |
70 output_surface_->capabilities().max_frames_pending)); | |
71 return true; | |
63 } | 72 } |
64 | 73 |
65 void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) { | 74 void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) { |
66 if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor) | 75 if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor) |
67 return; | 76 return; |
68 | 77 |
69 TRACE_EVENT0("cc", "Display::SetSurfaceId"); | 78 TRACE_EVENT0("cc", "Display::SetSurfaceId"); |
70 | 79 SurfaceId previous_id = current_surface_id_; |
71 current_surface_id_ = id; | 80 current_surface_id_ = id; |
72 device_scale_factor_ = device_scale_factor; | 81 device_scale_factor_ = device_scale_factor; |
73 | 82 |
74 UpdateRootSurfaceResourcesLocked(); | 83 UpdateRootSurfaceResourcesLocked(); |
75 if (scheduler_) | 84 if (scheduler_) |
76 scheduler_->SetNewRootSurface(id); | 85 scheduler_->SetNewRootSurface(id); |
86 | |
87 if (scheduler_begin_frame_source_ && previous_id != current_surface_id_) { | |
88 surface_manager_->RegisterBeginFrameSource(nullptr, | |
89 previous_id.id_namespace()); | |
90 surface_manager_->RegisterBeginFrameSource( | |
91 scheduler_begin_frame_source_, current_surface_id_.id_namespace()); | |
92 } | |
77 } | 93 } |
78 | 94 |
79 void Display::Resize(const gfx::Size& size) { | 95 void Display::Resize(const gfx::Size& size) { |
80 if (size == current_surface_size_) | 96 if (size == current_surface_size_) |
81 return; | 97 return; |
82 | 98 |
83 TRACE_EVENT0("cc", "Display::Resize"); | 99 TRACE_EVENT0("cc", "Display::Resize"); |
84 | 100 |
85 // Need to ensure all pending swaps have executed before the window is | 101 // Need to ensure all pending swaps have executed before the window is |
86 // resized, or D3D11 will scale the swap output. | 102 // resized, or D3D11 will scale the swap output. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 if (!renderer) | 144 if (!renderer) |
129 return; | 145 return; |
130 renderer_ = std::move(renderer); | 146 renderer_ = std::move(renderer); |
131 } | 147 } |
132 | 148 |
133 resource_provider_ = std::move(resource_provider); | 149 resource_provider_ = std::move(resource_provider); |
134 // TODO(jbauman): Outputting an incomplete quad list doesn't work when using | 150 // TODO(jbauman): Outputting an incomplete quad list doesn't work when using |
135 // overlays. | 151 // overlays. |
136 bool output_partial_list = renderer_->Capabilities().using_partial_swap && | 152 bool output_partial_list = renderer_->Capabilities().using_partial_swap && |
137 !output_surface_->GetOverlayCandidateValidator(); | 153 !output_surface_->GetOverlayCandidateValidator(); |
138 aggregator_.reset(new SurfaceAggregator(manager_, resource_provider_.get(), | 154 aggregator_.reset(new SurfaceAggregator( |
139 output_partial_list)); | 155 surface_manager_, resource_provider_.get(), output_partial_list)); |
140 } | 156 } |
141 | 157 |
142 void Display::DidLoseOutputSurface() { | 158 void Display::DidLoseOutputSurface() { |
143 if (scheduler_) | 159 if (scheduler_) |
144 scheduler_->OutputSurfaceLost(); | 160 scheduler_->OutputSurfaceLost(); |
145 // WARNING: The client may delete the Display in this method call. Do not | 161 // WARNING: The client may delete the Display in this method call. Do not |
146 // make any additional references to members after this call. | 162 // make any additional references to members after this call. |
147 client_->OutputSurfaceLost(); | 163 client_->OutputSurfaceLost(); |
148 } | 164 } |
149 | 165 |
150 void Display::UpdateRootSurfaceResourcesLocked() { | 166 void Display::UpdateRootSurfaceResourcesLocked() { |
151 Surface* surface = manager_->GetSurfaceForId(current_surface_id_); | 167 Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_); |
152 bool root_surface_resources_locked = !surface || !surface->GetEligibleFrame(); | 168 bool root_surface_resources_locked = !surface || !surface->GetEligibleFrame(); |
153 if (scheduler_) | 169 if (scheduler_) |
154 scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); | 170 scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); |
155 } | 171 } |
156 | 172 |
157 bool Display::DrawAndSwap() { | 173 bool Display::DrawAndSwap() { |
158 TRACE_EVENT0("cc", "Display::DrawAndSwap"); | 174 TRACE_EVENT0("cc", "Display::DrawAndSwap"); |
159 | 175 |
160 if (current_surface_id_.is_null()) { | 176 if (current_surface_id_.is_null()) { |
161 TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD); | 177 TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD); |
162 return false; | 178 return false; |
163 } | 179 } |
164 | 180 |
165 InitializeRenderer(); | 181 InitializeRenderer(); |
166 if (!output_surface_) { | 182 if (!output_surface_) { |
167 TRACE_EVENT_INSTANT0("cc", "No output surface", TRACE_EVENT_SCOPE_THREAD); | 183 TRACE_EVENT_INSTANT0("cc", "No output surface", TRACE_EVENT_SCOPE_THREAD); |
168 return false; | 184 return false; |
169 } | 185 } |
170 | 186 |
171 scoped_ptr<CompositorFrame> frame = | 187 scoped_ptr<CompositorFrame> frame = |
172 aggregator_->Aggregate(current_surface_id_); | 188 aggregator_->Aggregate(current_surface_id_); |
173 if (!frame) { | 189 if (!frame) { |
174 TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.", | 190 TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.", |
175 TRACE_EVENT_SCOPE_THREAD); | 191 TRACE_EVENT_SCOPE_THREAD); |
176 return false; | 192 return false; |
177 } | 193 } |
178 | 194 |
179 // Run callbacks early to allow pipelining. | 195 // Run callbacks early to allow pipelining. |
180 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { | 196 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { |
181 Surface* surface = manager_->GetSurfaceForId(id_entry.first); | 197 Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); |
182 if (surface) | 198 if (surface) |
183 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN); | 199 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN); |
184 } | 200 } |
185 | 201 |
186 DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); | 202 DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); |
187 | 203 |
188 frame->metadata.latency_info.insert(frame->metadata.latency_info.end(), | 204 frame->metadata.latency_info.insert(frame->metadata.latency_info.end(), |
189 stored_latency_info_.begin(), | 205 stored_latency_info_.begin(), |
190 stored_latency_info_.end()); | 206 stored_latency_info_.end()); |
191 stored_latency_info_.clear(); | 207 stored_latency_info_.clear(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
257 stored_latency_info_.insert(stored_latency_info_.end(), | 273 stored_latency_info_.insert(stored_latency_info_.end(), |
258 frame->metadata.latency_info.begin(), | 274 frame->metadata.latency_info.begin(), |
259 frame->metadata.latency_info.end()); | 275 frame->metadata.latency_info.end()); |
260 DidSwapBuffers(); | 276 DidSwapBuffers(); |
261 DidSwapBuffersComplete(); | 277 DidSwapBuffersComplete(); |
262 } | 278 } |
263 | 279 |
264 return true; | 280 return true; |
265 } | 281 } |
266 | 282 |
283 void Display::UpdateSchedulerBeginFrameSource(BeginFrameSource* source) { | |
284 if (source == scheduler_begin_frame_source_) | |
285 return; | |
286 | |
287 if (scheduler_begin_frame_source_) { | |
288 surface_manager_->RegisterBeginFrameSource( | |
289 nullptr, current_surface_id_.id_namespace()); | |
290 } | |
291 scheduler_begin_frame_source_ = source; | |
292 if (scheduler_begin_frame_source_) { | |
293 surface_manager_->RegisterBeginFrameSource( | |
294 scheduler_begin_frame_source_, current_surface_id_.id_namespace()); | |
295 } | |
296 } | |
297 | |
267 void Display::DidSwapBuffers() { | 298 void Display::DidSwapBuffers() { |
268 if (scheduler_) | 299 if (scheduler_) |
269 scheduler_->DidSwapBuffers(); | 300 scheduler_->DidSwapBuffers(); |
270 } | 301 } |
271 | 302 |
272 void Display::DidSwapBuffersComplete() { | 303 void Display::DidSwapBuffersComplete() { |
273 if (scheduler_) | 304 if (scheduler_) |
274 scheduler_->DidSwapBuffersComplete(); | 305 scheduler_->DidSwapBuffersComplete(); |
275 if (renderer_) | 306 if (renderer_) |
276 renderer_->SwapBuffersComplete(); | 307 renderer_->SwapBuffersComplete(); |
277 } | 308 } |
278 | 309 |
279 void Display::CommitVSyncParameters(base::TimeTicks timebase, | 310 void Display::SetBeginFrameSource(BeginFrameSource* source) { |
280 base::TimeDelta interval) { | 311 // It's expected that there's only a single source from the |
enne (OOO)
2016/03/25 17:55:36
I feel like this comment explains what has to happ
| |
281 client_->CommitVSyncParameters(timebase, interval); | 312 // BrowserCompositorOutputSurface that corresponds to vsync. The BFS is |
313 // passed BrowserCompositorOutputSurface -> Display -> DisplayScheduler as an | |
314 // input. DisplayScheduler makes a decision about which BFS to use and | |
315 // calls back to Display as DisplaySchedulerClient to register for that | |
316 // surface id. | |
317 DCHECK(!vsync_begin_frame_source_); | |
318 vsync_begin_frame_source_ = source; | |
282 } | 319 } |
283 | 320 |
284 void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { | 321 void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { |
285 client_->SetMemoryPolicy(policy); | 322 client_->SetMemoryPolicy(policy); |
286 } | 323 } |
287 | 324 |
288 void Display::OnDraw(const gfx::Transform& transform, | 325 void Display::OnDraw(const gfx::Transform& transform, |
289 const gfx::Rect& viewport, | 326 const gfx::Rect& viewport, |
290 const gfx::Rect& clip, | 327 const gfx::Rect& clip, |
291 bool resourceless_software_draw) { | 328 bool resourceless_software_draw) { |
(...skipping 21 matching lines...) Expand all Loading... | |
313 } | 350 } |
314 | 351 |
315 void Display::SetFullRootLayerDamage() { | 352 void Display::SetFullRootLayerDamage() { |
316 if (aggregator_ && !current_surface_id_.is_null()) | 353 if (aggregator_ && !current_surface_id_.is_null()) |
317 aggregator_->SetFullDamageForSurface(current_surface_id_); | 354 aggregator_->SetFullDamageForSurface(current_surface_id_); |
318 } | 355 } |
319 | 356 |
320 void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) { | 357 void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) { |
321 if (aggregator_ && | 358 if (aggregator_ && |
322 aggregator_->previous_contained_surfaces().count(surface_id)) { | 359 aggregator_->previous_contained_surfaces().count(surface_id)) { |
323 Surface* surface = manager_->GetSurfaceForId(surface_id); | 360 Surface* surface = surface_manager_->GetSurfaceForId(surface_id); |
324 if (surface) { | 361 if (surface) { |
325 const CompositorFrame* current_frame = surface->GetEligibleFrame(); | 362 const CompositorFrame* current_frame = surface->GetEligibleFrame(); |
326 if (!current_frame || !current_frame->delegated_frame_data || | 363 if (!current_frame || !current_frame->delegated_frame_data || |
327 !current_frame->delegated_frame_data->resource_list.size()) { | 364 !current_frame->delegated_frame_data->resource_list.size()) { |
328 aggregator_->ReleaseResources(surface_id); | 365 aggregator_->ReleaseResources(surface_id); |
329 } | 366 } |
330 } | 367 } |
331 if (scheduler_) | 368 if (scheduler_) |
332 scheduler_->SurfaceDamaged(surface_id); | 369 scheduler_->SurfaceDamaged(surface_id); |
333 *changed = true; | 370 *changed = true; |
334 } else if (surface_id == current_surface_id_) { | 371 } else if (surface_id == current_surface_id_) { |
335 if (scheduler_) | 372 if (scheduler_) |
336 scheduler_->SurfaceDamaged(surface_id); | 373 scheduler_->SurfaceDamaged(surface_id); |
337 *changed = true; | 374 *changed = true; |
338 } | 375 } |
339 | 376 |
340 if (surface_id == current_surface_id_) | 377 if (surface_id == current_surface_id_) |
341 UpdateRootSurfaceResourcesLocked(); | 378 UpdateRootSurfaceResourcesLocked(); |
342 } | 379 } |
343 | 380 |
344 SurfaceId Display::CurrentSurfaceId() { | 381 SurfaceId Display::CurrentSurfaceId() { |
345 return current_surface_id_; | 382 return current_surface_id_; |
346 } | 383 } |
347 | 384 |
348 } // namespace cc | 385 } // namespace cc |
OLD | NEW |