| 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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 void Display::DidLoseOutputSurface() { | 205 void Display::DidLoseOutputSurface() { |
| 206 if (scheduler_) | 206 if (scheduler_) |
| 207 scheduler_->OutputSurfaceLost(); | 207 scheduler_->OutputSurfaceLost(); |
| 208 // WARNING: The client may delete the Display in this method call. Do not | 208 // WARNING: The client may delete the Display in this method call. Do not |
| 209 // make any additional references to members after this call. | 209 // make any additional references to members after this call. |
| 210 client_->DisplayOutputSurfaceLost(); | 210 client_->DisplayOutputSurfaceLost(); |
| 211 } | 211 } |
| 212 | 212 |
| 213 void Display::UpdateRootSurfaceResourcesLocked() { | 213 void Display::UpdateRootSurfaceResourcesLocked() { |
| 214 Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_); | 214 Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_); |
| 215 bool root_surface_resources_locked = | 215 bool root_surface_resources_locked = !surface || !surface->HasFrame(); |
| 216 !surface || !surface->GetEligibleFrame().delegated_frame_data; | |
| 217 if (scheduler_) | 216 if (scheduler_) |
| 218 scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); | 217 scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); |
| 219 } | 218 } |
| 220 | 219 |
| 221 bool Display::DrawAndSwap() { | 220 bool Display::DrawAndSwap() { |
| 222 TRACE_EVENT0("cc", "Display::DrawAndSwap"); | 221 TRACE_EVENT0("cc", "Display::DrawAndSwap"); |
| 223 | 222 |
| 224 if (current_surface_id_.is_null()) { | 223 if (current_surface_id_.is_null()) { |
| 225 TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD); | 224 TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD); |
| 226 return false; | 225 return false; |
| 227 } | 226 } |
| 228 | 227 |
| 229 if (!output_surface_) { | 228 if (!output_surface_) { |
| 230 TRACE_EVENT_INSTANT0("cc", "No output surface", TRACE_EVENT_SCOPE_THREAD); | 229 TRACE_EVENT_INSTANT0("cc", "No output surface", TRACE_EVENT_SCOPE_THREAD); |
| 231 return false; | 230 return false; |
| 232 } | 231 } |
| 233 | 232 |
| 234 CompositorFrame frame = aggregator_->Aggregate(current_surface_id_); | 233 CompositorFrame frame = aggregator_->Aggregate(current_surface_id_); |
| 235 if (!frame.delegated_frame_data) { | 234 |
| 235 if (frame.render_pass_list.empty()) { |
| 236 TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.", | 236 TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.", |
| 237 TRACE_EVENT_SCOPE_THREAD); | 237 TRACE_EVENT_SCOPE_THREAD); |
| 238 return false; | 238 return false; |
| 239 } | 239 } |
| 240 | 240 |
| 241 // Run callbacks early to allow pipelining. | 241 // Run callbacks early to allow pipelining. |
| 242 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { | 242 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { |
| 243 Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); | 243 Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); |
| 244 if (surface) | 244 if (surface) |
| 245 surface->RunDrawCallbacks(); | 245 surface->RunDrawCallbacks(); |
| 246 } | 246 } |
| 247 | 247 |
| 248 DelegatedFrameData* frame_data = frame.delegated_frame_data.get(); | |
| 249 | |
| 250 frame.metadata.latency_info.insert(frame.metadata.latency_info.end(), | 248 frame.metadata.latency_info.insert(frame.metadata.latency_info.end(), |
| 251 stored_latency_info_.begin(), | 249 stored_latency_info_.begin(), |
| 252 stored_latency_info_.end()); | 250 stored_latency_info_.end()); |
| 253 stored_latency_info_.clear(); | 251 stored_latency_info_.clear(); |
| 254 bool have_copy_requests = false; | 252 bool have_copy_requests = false; |
| 255 for (const auto& pass : frame_data->render_pass_list) { | 253 for (const auto& pass : frame.render_pass_list) { |
| 256 have_copy_requests |= !pass->copy_requests.empty(); | 254 have_copy_requests |= !pass->copy_requests.empty(); |
| 257 } | 255 } |
| 258 | 256 |
| 259 gfx::Size surface_size; | 257 gfx::Size surface_size; |
| 260 bool have_damage = false; | 258 bool have_damage = false; |
| 261 if (!frame_data->render_pass_list.empty()) { | 259 if (!frame.render_pass_list.empty()) { |
| 262 RenderPass& last_render_pass = *frame_data->render_pass_list.back(); | 260 RenderPass& last_render_pass = *frame.render_pass_list.back(); |
| 263 if (last_render_pass.output_rect.size() != current_surface_size_ && | 261 if (last_render_pass.output_rect.size() != current_surface_size_ && |
| 264 last_render_pass.damage_rect == last_render_pass.output_rect && | 262 last_render_pass.damage_rect == last_render_pass.output_rect && |
| 265 !current_surface_size_.IsEmpty()) { | 263 !current_surface_size_.IsEmpty()) { |
| 266 // Resize the output rect to the current surface size so that we won't | 264 // Resize the output rect to the current surface size so that we won't |
| 267 // skip the draw and so that the GL swap won't stretch the output. | 265 // skip the draw and so that the GL swap won't stretch the output. |
| 268 last_render_pass.output_rect.set_size(current_surface_size_); | 266 last_render_pass.output_rect.set_size(current_surface_size_); |
| 269 last_render_pass.damage_rect = last_render_pass.output_rect; | 267 last_render_pass.damage_rect = last_render_pass.output_rect; |
| 270 } | 268 } |
| 271 surface_size = last_render_pass.output_rect.size(); | 269 surface_size = last_render_pass.output_rect.size(); |
| 272 have_damage = !last_render_pass.damage_rect.size().IsEmpty(); | 270 have_damage = !last_render_pass.damage_rect.size().IsEmpty(); |
| 273 } | 271 } |
| 274 | 272 |
| 275 bool size_matches = surface_size == current_surface_size_; | 273 bool size_matches = surface_size == current_surface_size_; |
| 276 if (!size_matches) | 274 if (!size_matches) |
| 277 TRACE_EVENT_INSTANT0("cc", "Size mismatch.", TRACE_EVENT_SCOPE_THREAD); | 275 TRACE_EVENT_INSTANT0("cc", "Size mismatch.", TRACE_EVENT_SCOPE_THREAD); |
| 278 | 276 |
| 279 bool should_draw = have_copy_requests || (have_damage && size_matches); | 277 bool should_draw = have_copy_requests || (have_damage && size_matches); |
| 280 | 278 |
| 281 // If the surface is suspended then the resources to be used by the draw are | 279 // If the surface is suspended then the resources to be used by the draw are |
| 282 // likely destroyed. | 280 // likely destroyed. |
| 283 if (output_surface_->SurfaceIsSuspendForRecycle()) { | 281 if (output_surface_->SurfaceIsSuspendForRecycle()) { |
| 284 TRACE_EVENT_INSTANT0("cc", "Surface is suspended for recycle.", | 282 TRACE_EVENT_INSTANT0("cc", "Surface is suspended for recycle.", |
| 285 TRACE_EVENT_SCOPE_THREAD); | 283 TRACE_EVENT_SCOPE_THREAD); |
| 286 should_draw = false; | 284 should_draw = false; |
| 287 } | 285 } |
| 288 | 286 |
| 289 client_->DisplayWillDrawAndSwap(should_draw, frame_data->render_pass_list); | 287 client_->DisplayWillDrawAndSwap(should_draw, frame.render_pass_list); |
| 290 | 288 |
| 291 if (should_draw) { | 289 if (should_draw) { |
| 292 bool disable_image_filtering = | 290 bool disable_image_filtering = |
| 293 frame.metadata.is_resourceless_software_draw_with_scroll_or_animation; | 291 frame.metadata.is_resourceless_software_draw_with_scroll_or_animation; |
| 294 if (software_renderer_) { | 292 if (software_renderer_) { |
| 295 software_renderer_->SetDisablePictureQuadImageFiltering( | 293 software_renderer_->SetDisablePictureQuadImageFiltering( |
| 296 disable_image_filtering); | 294 disable_image_filtering); |
| 297 } else { | 295 } else { |
| 298 // This should only be set for software draws in synchronous compositor. | 296 // This should only be set for software draws in synchronous compositor. |
| 299 DCHECK(!disable_image_filtering); | 297 DCHECK(!disable_image_filtering); |
| 300 } | 298 } |
| 301 | 299 |
| 302 renderer_->DecideRenderPassAllocationsForFrame( | 300 renderer_->DecideRenderPassAllocationsForFrame(frame.render_pass_list); |
| 303 frame_data->render_pass_list); | 301 renderer_->DrawFrame(&frame.render_pass_list, device_scale_factor_, |
| 304 renderer_->DrawFrame(&frame_data->render_pass_list, device_scale_factor_, | |
| 305 device_color_space_, current_surface_size_); | 302 device_color_space_, current_surface_size_); |
| 306 } else { | 303 } else { |
| 307 TRACE_EVENT_INSTANT0("cc", "Draw skipped.", TRACE_EVENT_SCOPE_THREAD); | 304 TRACE_EVENT_INSTANT0("cc", "Draw skipped.", TRACE_EVENT_SCOPE_THREAD); |
| 308 } | 305 } |
| 309 | 306 |
| 310 bool should_swap = should_draw && size_matches; | 307 bool should_swap = should_draw && size_matches; |
| 311 if (should_swap) { | 308 if (should_swap) { |
| 312 swapped_since_resize_ = true; | 309 swapped_since_resize_ = true; |
| 313 for (auto& latency : frame.metadata.latency_info) { | 310 for (auto& latency : frame.metadata.latency_info) { |
| 314 TRACE_EVENT_WITH_FLOW1( | 311 TRACE_EVENT_WITH_FLOW1( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 aggregator_->SetFullDamageForSurface(current_surface_id_); | 352 aggregator_->SetFullDamageForSurface(current_surface_id_); |
| 356 if (scheduler_) | 353 if (scheduler_) |
| 357 scheduler_->SurfaceDamaged(current_surface_id_); | 354 scheduler_->SurfaceDamaged(current_surface_id_); |
| 358 } | 355 } |
| 359 | 356 |
| 360 void Display::OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) { | 357 void Display::OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) { |
| 361 if (aggregator_ && | 358 if (aggregator_ && |
| 362 aggregator_->previous_contained_surfaces().count(surface_id)) { | 359 aggregator_->previous_contained_surfaces().count(surface_id)) { |
| 363 Surface* surface = surface_manager_->GetSurfaceForId(surface_id); | 360 Surface* surface = surface_manager_->GetSurfaceForId(surface_id); |
| 364 if (surface) { | 361 if (surface) { |
| 365 const CompositorFrame& current_frame = surface->GetEligibleFrame(); | 362 if (!surface->HasFrame() || |
| 366 if (!current_frame.delegated_frame_data || | 363 surface->GetEligibleFrame().resource_list.empty()) { |
| 367 current_frame.delegated_frame_data->resource_list.empty()) { | |
| 368 aggregator_->ReleaseResources(surface_id); | 364 aggregator_->ReleaseResources(surface_id); |
| 369 } | 365 } |
| 370 } | 366 } |
| 371 if (scheduler_) | 367 if (scheduler_) |
| 372 scheduler_->SurfaceDamaged(surface_id); | 368 scheduler_->SurfaceDamaged(surface_id); |
| 373 *changed = true; | 369 *changed = true; |
| 374 } else if (surface_id == current_surface_id_) { | 370 } else if (surface_id == current_surface_id_) { |
| 375 if (scheduler_) | 371 if (scheduler_) |
| 376 scheduler_->SurfaceDamaged(surface_id); | 372 scheduler_->SurfaceDamaged(surface_id); |
| 377 *changed = true; | 373 *changed = true; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 388 const SurfaceId& Display::CurrentSurfaceId() { | 384 const SurfaceId& Display::CurrentSurfaceId() { |
| 389 return current_surface_id_; | 385 return current_surface_id_; |
| 390 } | 386 } |
| 391 | 387 |
| 392 void Display::ForceImmediateDrawAndSwapIfPossible() { | 388 void Display::ForceImmediateDrawAndSwapIfPossible() { |
| 393 if (scheduler_) | 389 if (scheduler_) |
| 394 scheduler_->ForceImmediateSwapIfPossible(); | 390 scheduler_->ForceImmediateSwapIfPossible(); |
| 395 } | 391 } |
| 396 | 392 |
| 397 } // namespace cc | 393 } // namespace cc |
| OLD | NEW |