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 "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/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 // overlays. | 207 // overlays. |
| 208 bool output_partial_list = renderer_->use_partial_swap() && | 208 bool output_partial_list = renderer_->use_partial_swap() && |
| 209 !output_surface_->GetOverlayCandidateValidator(); | 209 !output_surface_->GetOverlayCandidateValidator(); |
| 210 aggregator_.reset(new SurfaceAggregator( | 210 aggregator_.reset(new SurfaceAggregator( |
| 211 surface_manager_, resource_provider_.get(), output_partial_list)); | 211 surface_manager_, resource_provider_.get(), output_partial_list)); |
| 212 aggregator_->set_output_is_secure(output_is_secure_); | 212 aggregator_->set_output_is_secure(output_is_secure_); |
| 213 } | 213 } |
| 214 | 214 |
| 215 void Display::UpdateRootSurfaceResourcesLocked() { | 215 void Display::UpdateRootSurfaceResourcesLocked() { |
| 216 Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_); | 216 Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_); |
| 217 bool root_surface_resources_locked = | 217 bool root_surface_resources_locked = !surface || !surface->HasFrame(); |
|
Fady Samuel
2016/11/16 00:38:23
I think the right check here is:
root_surface_res
danakj
2016/11/16 01:23:17
Why? The old code did not check for an empty rende
Saman Sami
2016/11/16 01:40:26
It didn't explicitly, what we believe it meant to
danakj
2016/11/16 01:56:17
I see, this should be false if an empty frame was
| |
| 218 !surface || !surface->GetEligibleFrame().delegated_frame_data; | |
| 219 if (scheduler_) | 218 if (scheduler_) |
| 220 scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); | 219 scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); |
| 221 } | 220 } |
| 222 | 221 |
| 223 void Display::DidLoseContextProvider() { | 222 void Display::DidLoseContextProvider() { |
| 224 if (scheduler_) | 223 if (scheduler_) |
| 225 scheduler_->OutputSurfaceLost(); | 224 scheduler_->OutputSurfaceLost(); |
| 226 // WARNING: The client may delete the Display in this method call. Do not | 225 // WARNING: The client may delete the Display in this method call. Do not |
| 227 // make any additional references to members after this call. | 226 // make any additional references to members after this call. |
| 228 client_->DisplayOutputSurfaceLost(); | 227 client_->DisplayOutputSurfaceLost(); |
| 229 } | 228 } |
| 230 | 229 |
| 231 bool Display::DrawAndSwap() { | 230 bool Display::DrawAndSwap() { |
| 232 TRACE_EVENT0("cc", "Display::DrawAndSwap"); | 231 TRACE_EVENT0("cc", "Display::DrawAndSwap"); |
| 233 | 232 |
| 234 if (current_surface_id_.is_null()) { | 233 if (current_surface_id_.is_null()) { |
| 235 TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD); | 234 TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD); |
| 236 return false; | 235 return false; |
| 237 } | 236 } |
| 238 | 237 |
| 239 if (!output_surface_) { | 238 if (!output_surface_) { |
| 240 TRACE_EVENT_INSTANT0("cc", "No output surface", TRACE_EVENT_SCOPE_THREAD); | 239 TRACE_EVENT_INSTANT0("cc", "No output surface", TRACE_EVENT_SCOPE_THREAD); |
| 241 return false; | 240 return false; |
| 242 } | 241 } |
| 243 | 242 |
| 244 CompositorFrame frame = aggregator_->Aggregate(current_surface_id_); | 243 CompositorFrame frame = aggregator_->Aggregate(current_surface_id_); |
| 245 if (!frame.delegated_frame_data) { | 244 |
| 245 if (frame.render_pass_list.empty()) { | |
| 246 TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.", | 246 TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.", |
| 247 TRACE_EVENT_SCOPE_THREAD); | 247 TRACE_EVENT_SCOPE_THREAD); |
| 248 return false; | 248 return false; |
| 249 } | 249 } |
| 250 | 250 |
| 251 // Run callbacks early to allow pipelining. | 251 // Run callbacks early to allow pipelining. |
| 252 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { | 252 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { |
| 253 Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); | 253 Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); |
| 254 if (surface) | 254 if (surface) |
| 255 surface->RunDrawCallbacks(); | 255 surface->RunDrawCallbacks(); |
| 256 } | 256 } |
| 257 | 257 |
| 258 DelegatedFrameData* frame_data = frame.delegated_frame_data.get(); | |
| 259 | |
| 260 frame.metadata.latency_info.insert(frame.metadata.latency_info.end(), | 258 frame.metadata.latency_info.insert(frame.metadata.latency_info.end(), |
| 261 stored_latency_info_.begin(), | 259 stored_latency_info_.begin(), |
| 262 stored_latency_info_.end()); | 260 stored_latency_info_.end()); |
| 263 stored_latency_info_.clear(); | 261 stored_latency_info_.clear(); |
| 264 bool have_copy_requests = false; | 262 bool have_copy_requests = false; |
| 265 for (const auto& pass : frame_data->render_pass_list) { | 263 for (const auto& pass : frame.render_pass_list) { |
| 266 have_copy_requests |= !pass->copy_requests.empty(); | 264 have_copy_requests |= !pass->copy_requests.empty(); |
| 267 } | 265 } |
| 268 | 266 |
| 269 gfx::Size surface_size; | 267 gfx::Size surface_size; |
| 270 bool have_damage = false; | 268 bool have_damage = false; |
| 271 if (!frame_data->render_pass_list.empty()) { | 269 if (!frame.render_pass_list.empty()) { |
| 272 RenderPass& last_render_pass = *frame_data->render_pass_list.back(); | 270 RenderPass& last_render_pass = *frame.render_pass_list.back(); |
| 273 if (last_render_pass.output_rect.size() != current_surface_size_ && | 271 if (last_render_pass.output_rect.size() != current_surface_size_ && |
| 274 last_render_pass.damage_rect == last_render_pass.output_rect && | 272 last_render_pass.damage_rect == last_render_pass.output_rect && |
| 275 !current_surface_size_.IsEmpty()) { | 273 !current_surface_size_.IsEmpty()) { |
| 276 // Resize the output rect to the current surface size so that we won't | 274 // Resize the output rect to the current surface size so that we won't |
| 277 // skip the draw and so that the GL swap won't stretch the output. | 275 // skip the draw and so that the GL swap won't stretch the output. |
| 278 last_render_pass.output_rect.set_size(current_surface_size_); | 276 last_render_pass.output_rect.set_size(current_surface_size_); |
| 279 last_render_pass.damage_rect = last_render_pass.output_rect; | 277 last_render_pass.damage_rect = last_render_pass.output_rect; |
| 280 } | 278 } |
| 281 surface_size = last_render_pass.output_rect.size(); | 279 surface_size = last_render_pass.output_rect.size(); |
| 282 have_damage = !last_render_pass.damage_rect.size().IsEmpty(); | 280 have_damage = !last_render_pass.damage_rect.size().IsEmpty(); |
| 283 } | 281 } |
| 284 | 282 |
| 285 bool size_matches = surface_size == current_surface_size_; | 283 bool size_matches = surface_size == current_surface_size_; |
| 286 if (!size_matches) | 284 if (!size_matches) |
| 287 TRACE_EVENT_INSTANT0("cc", "Size mismatch.", TRACE_EVENT_SCOPE_THREAD); | 285 TRACE_EVENT_INSTANT0("cc", "Size mismatch.", TRACE_EVENT_SCOPE_THREAD); |
| 288 | 286 |
| 289 bool should_draw = have_copy_requests || (have_damage && size_matches); | 287 bool should_draw = have_copy_requests || (have_damage && size_matches); |
| 290 | 288 |
| 291 // If the surface is suspended then the resources to be used by the draw are | 289 // If the surface is suspended then the resources to be used by the draw are |
| 292 // likely destroyed. | 290 // likely destroyed. |
| 293 if (output_surface_->SurfaceIsSuspendForRecycle()) { | 291 if (output_surface_->SurfaceIsSuspendForRecycle()) { |
| 294 TRACE_EVENT_INSTANT0("cc", "Surface is suspended for recycle.", | 292 TRACE_EVENT_INSTANT0("cc", "Surface is suspended for recycle.", |
| 295 TRACE_EVENT_SCOPE_THREAD); | 293 TRACE_EVENT_SCOPE_THREAD); |
| 296 should_draw = false; | 294 should_draw = false; |
| 297 } | 295 } |
| 298 | 296 |
| 299 client_->DisplayWillDrawAndSwap(should_draw, frame_data->render_pass_list); | 297 client_->DisplayWillDrawAndSwap(should_draw, frame.render_pass_list); |
| 300 | 298 |
| 301 if (should_draw) { | 299 if (should_draw) { |
| 302 bool disable_image_filtering = | 300 bool disable_image_filtering = |
| 303 frame.metadata.is_resourceless_software_draw_with_scroll_or_animation; | 301 frame.metadata.is_resourceless_software_draw_with_scroll_or_animation; |
| 304 if (software_renderer_) { | 302 if (software_renderer_) { |
| 305 software_renderer_->SetDisablePictureQuadImageFiltering( | 303 software_renderer_->SetDisablePictureQuadImageFiltering( |
| 306 disable_image_filtering); | 304 disable_image_filtering); |
| 307 } else { | 305 } else { |
| 308 // This should only be set for software draws in synchronous compositor. | 306 // This should only be set for software draws in synchronous compositor. |
| 309 DCHECK(!disable_image_filtering); | 307 DCHECK(!disable_image_filtering); |
| 310 } | 308 } |
| 311 | 309 |
| 312 renderer_->DecideRenderPassAllocationsForFrame( | 310 renderer_->DecideRenderPassAllocationsForFrame(frame.render_pass_list); |
| 313 frame_data->render_pass_list); | 311 renderer_->DrawFrame(&frame.render_pass_list, device_scale_factor_, |
| 314 renderer_->DrawFrame(&frame_data->render_pass_list, device_scale_factor_, | |
| 315 device_color_space_, current_surface_size_); | 312 device_color_space_, current_surface_size_); |
| 316 } else { | 313 } else { |
| 317 TRACE_EVENT_INSTANT0("cc", "Draw skipped.", TRACE_EVENT_SCOPE_THREAD); | 314 TRACE_EVENT_INSTANT0("cc", "Draw skipped.", TRACE_EVENT_SCOPE_THREAD); |
| 318 } | 315 } |
| 319 | 316 |
| 320 bool should_swap = should_draw && size_matches; | 317 bool should_swap = should_draw && size_matches; |
| 321 if (should_swap) { | 318 if (should_swap) { |
| 322 swapped_since_resize_ = true; | 319 swapped_since_resize_ = true; |
| 323 for (auto& latency : frame.metadata.latency_info) { | 320 for (auto& latency : frame.metadata.latency_info) { |
| 324 TRACE_EVENT_WITH_FLOW1( | 321 TRACE_EVENT_WITH_FLOW1( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 aggregator_->SetFullDamageForSurface(current_surface_id_); | 362 aggregator_->SetFullDamageForSurface(current_surface_id_); |
| 366 if (scheduler_) | 363 if (scheduler_) |
| 367 scheduler_->SurfaceDamaged(current_surface_id_); | 364 scheduler_->SurfaceDamaged(current_surface_id_); |
| 368 } | 365 } |
| 369 | 366 |
| 370 void Display::OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) { | 367 void Display::OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) { |
| 371 if (aggregator_ && | 368 if (aggregator_ && |
| 372 aggregator_->previous_contained_surfaces().count(surface_id)) { | 369 aggregator_->previous_contained_surfaces().count(surface_id)) { |
| 373 Surface* surface = surface_manager_->GetSurfaceForId(surface_id); | 370 Surface* surface = surface_manager_->GetSurfaceForId(surface_id); |
| 374 if (surface) { | 371 if (surface) { |
| 375 const CompositorFrame& current_frame = surface->GetEligibleFrame(); | 372 if (!surface->HasFrame() || |
| 376 if (!current_frame.delegated_frame_data || | 373 surface->GetEligibleFrame().resource_list.empty()) { |
| 377 current_frame.delegated_frame_data->resource_list.empty()) { | |
| 378 aggregator_->ReleaseResources(surface_id); | 374 aggregator_->ReleaseResources(surface_id); |
| 379 } | 375 } |
| 380 } | 376 } |
| 381 if (scheduler_) | 377 if (scheduler_) |
| 382 scheduler_->SurfaceDamaged(surface_id); | 378 scheduler_->SurfaceDamaged(surface_id); |
| 383 *changed = true; | 379 *changed = true; |
| 384 } else if (surface_id == current_surface_id_) { | 380 } else if (surface_id == current_surface_id_) { |
| 385 if (scheduler_) | 381 if (scheduler_) |
| 386 scheduler_->SurfaceDamaged(surface_id); | 382 scheduler_->SurfaceDamaged(surface_id); |
| 387 *changed = true; | 383 *changed = true; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 398 const SurfaceId& Display::CurrentSurfaceId() { | 394 const SurfaceId& Display::CurrentSurfaceId() { |
| 399 return current_surface_id_; | 395 return current_surface_id_; |
| 400 } | 396 } |
| 401 | 397 |
| 402 void Display::ForceImmediateDrawAndSwapIfPossible() { | 398 void Display::ForceImmediateDrawAndSwapIfPossible() { |
| 403 if (scheduler_) | 399 if (scheduler_) |
| 404 scheduler_->ForceImmediateSwapIfPossible(); | 400 scheduler_->ForceImmediateSwapIfPossible(); |
| 405 } | 401 } |
| 406 | 402 |
| 407 } // namespace cc | 403 } // namespace cc |
| OLD | NEW |