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/surface_aggregator.h" | 5 #include "cc/surfaces/surface_aggregator.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 124 provider_->SetChildNeedsSyncPoints( | 124 provider_->SetChildNeedsSyncPoints( |
| 125 child_id, surface->factory()->needs_sync_points()); | 125 child_id, surface->factory()->needs_sync_points()); |
| 126 } | 126 } |
| 127 surface_id_to_resource_child_id_[surface->surface_id()] = child_id; | 127 surface_id_to_resource_child_id_[surface->surface_id()] = child_id; |
| 128 return child_id; | 128 return child_id; |
| 129 } else { | 129 } else { |
| 130 return it->second; | 130 return it->second; |
| 131 } | 131 } |
| 132 } | 132 } |
| 133 | 133 |
| 134 bool SurfaceAggregator::ValidateResources( | |
| 135 Surface* surface, | |
| 136 const DelegatedFrameData* frame_data) { | |
| 137 if (!provider_) // TODO(jamesr): hack for unit tests that don't set up rp | |
| 138 return false; | |
| 139 | |
| 140 int child_id = ChildIdForSurface(surface); | |
| 141 if (surface->factory()) | |
| 142 surface->factory()->RefResources(frame_data->resource_list); | |
| 143 provider_->ReceiveFromChild(child_id, frame_data->resource_list); | |
| 144 | |
| 145 ResourceProvider::ResourceIdSet referenced_resources; | |
| 146 size_t reserve_size = frame_data->resource_list.size(); | |
| 147 #if defined(COMPILER_MSVC) | |
| 148 referenced_resources.reserve(reserve_size); | |
| 149 #elif defined(COMPILER_GCC) | |
| 150 // Pre-standard hash-tables only implement resize, which behaves similarly | |
| 151 // to reserve for these keys. Resizing to 0 may also be broken (particularly | |
| 152 // on stlport). | |
| 153 // TODO(jbauman): Replace with reserve when C++11 is supported everywhere. | |
| 154 if (reserve_size) | |
| 155 referenced_resources.resize(reserve_size); | |
| 156 #endif | |
| 157 | |
| 158 bool invalid_frame = false; | |
| 159 const ResourceProvider::ResourceIdMap& child_to_parent_map = | |
| 160 provider_->GetChildToParentMap(child_id); | |
| 161 for (const auto& render_pass : frame_data->render_pass_list) { | |
| 162 for (const auto& quad : render_pass->quad_list) { | |
| 163 for (ResourceId resource_id : quad->resources) { | |
| 164 ResourceProvider::ResourceIdMap::const_iterator it = | |
| 165 child_to_parent_map.find(resource_id); | |
| 166 if (it == child_to_parent_map.end()) { | |
| 167 invalid_frame = true; | |
| 168 break; | |
| 169 } | |
| 170 referenced_resources.insert(resource_id); | |
| 171 } | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 if (!invalid_frame) | |
| 176 provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); | |
| 177 | |
| 178 return invalid_frame; | |
| 179 } | |
| 180 | 134 |
| 181 gfx::Rect SurfaceAggregator::DamageRectForSurface(const Surface* surface, | 135 gfx::Rect SurfaceAggregator::DamageRectForSurface(const Surface* surface, |
| 182 const RenderPass& source, | 136 const RenderPass& source, |
| 183 const gfx::Rect& full_rect) { | 137 const gfx::Rect& full_rect) { |
| 184 int previous_index = previous_contained_surfaces_[surface->surface_id()]; | 138 int previous_index = previous_contained_surfaces_[surface->surface_id()]; |
| 185 if (previous_index == surface->frame_index()) | 139 if (previous_index == surface->frame_index()) |
| 186 return gfx::Rect(); | 140 return gfx::Rect(); |
| 187 else if (previous_index == surface->frame_index() - 1) | 141 else if (previous_index == surface->frame_index() - 1) |
| 188 return source.damage_rect; | 142 return source.damage_rect; |
| 189 return full_rect; | 143 return full_rect; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 209 if (!frame) | 163 if (!frame) |
| 210 return; | 164 return; |
| 211 const DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); | 165 const DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); |
| 212 if (!frame_data) | 166 if (!frame_data) |
| 213 return; | 167 return; |
| 214 | 168 |
| 215 std::multimap<RenderPassId, CopyOutputRequest*> copy_requests; | 169 std::multimap<RenderPassId, CopyOutputRequest*> copy_requests; |
| 216 surface->TakeCopyOutputRequests(©_requests); | 170 surface->TakeCopyOutputRequests(©_requests); |
| 217 | 171 |
| 218 const RenderPassList& render_pass_list = frame_data->render_pass_list; | 172 const RenderPassList& render_pass_list = frame_data->render_pass_list; |
| 219 bool invalid_frame = ValidateResources(surface, frame_data); | 173 if (!surface_validity_[surface->surface_id()]) { |
| 220 if (invalid_frame) { | |
| 221 for (auto& request : copy_requests) { | 174 for (auto& request : copy_requests) { |
| 222 request.second->SendEmptyResult(); | 175 request.second->SendEmptyResult(); |
| 223 delete request.second; | 176 delete request.second; |
| 224 } | 177 } |
| 225 return; | 178 return; |
| 226 } | 179 } |
| 227 | 180 |
| 228 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 181 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
| 229 // TODO(vmpstr): provider check is a hack for unittests that don't set up a | 182 // TODO(vmpstr): provider check is a hack for unittests that don't set up a |
| 230 // resource provider. | 183 // resource provider. |
| 231 ResourceProvider::ResourceIdMap empty_map; | 184 ResourceProvider::ResourceIdMap empty_map; |
| 232 const ResourceProvider::ResourceIdMap& child_to_parent_map = | 185 const ResourceProvider::ResourceIdMap& child_to_parent_map = |
| 233 provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface)) | 186 provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface)) |
| 234 : empty_map; | 187 : empty_map; |
| 235 bool merge_pass = | 188 bool merge_pass = |
| 236 surface_quad->shared_quad_state->opacity == 1.f && copy_requests.empty(); | 189 surface_quad->shared_quad_state->opacity == 1.f && copy_requests.empty(); |
| 237 | 190 |
| 238 gfx::Rect surface_damage = DamageRectForSurface( | |
| 239 surface, *render_pass_list.back(), surface_quad->visible_rect); | |
| 240 const RenderPassList& referenced_passes = render_pass_list; | 191 const RenderPassList& referenced_passes = render_pass_list; |
| 241 size_t passes_to_copy = | 192 size_t passes_to_copy = |
| 242 merge_pass ? referenced_passes.size() - 1 : referenced_passes.size(); | 193 merge_pass ? referenced_passes.size() - 1 : referenced_passes.size(); |
| 243 for (size_t j = 0; j < passes_to_copy; ++j) { | 194 for (size_t j = 0; j < passes_to_copy; ++j) { |
| 244 const RenderPass& source = *referenced_passes[j]; | 195 const RenderPass& source = *referenced_passes[j]; |
| 245 | 196 |
| 246 size_t sqs_size = source.shared_quad_state_list.size(); | 197 size_t sqs_size = source.shared_quad_state_list.size(); |
| 247 size_t dq_size = source.quad_list.size(); | 198 size_t dq_size = source.quad_list.size(); |
| 248 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); | 199 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); |
| 249 | 200 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 261 copy_pass->transform_to_root_target.ConcatTransform( | 212 copy_pass->transform_to_root_target.ConcatTransform( |
| 262 surface_quad->shared_quad_state->quad_to_target_transform); | 213 surface_quad->shared_quad_state->quad_to_target_transform); |
| 263 copy_pass->transform_to_root_target.ConcatTransform(target_transform); | 214 copy_pass->transform_to_root_target.ConcatTransform(target_transform); |
| 264 copy_pass->transform_to_root_target.ConcatTransform( | 215 copy_pass->transform_to_root_target.ConcatTransform( |
| 265 dest_pass->transform_to_root_target); | 216 dest_pass->transform_to_root_target); |
| 266 | 217 |
| 267 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, | 218 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, |
| 268 child_to_parent_map, gfx::Transform(), ClipData(), | 219 child_to_parent_map, gfx::Transform(), ClipData(), |
| 269 copy_pass.get(), surface_id); | 220 copy_pass.get(), surface_id); |
| 270 | 221 |
| 271 if (j == referenced_passes.size() - 1) | |
| 272 surface_damage = gfx::UnionRects(surface_damage, copy_pass->damage_rect); | |
| 273 | |
| 274 dest_pass_list_->push_back(copy_pass.Pass()); | 222 dest_pass_list_->push_back(copy_pass.Pass()); |
| 275 } | 223 } |
| 276 | 224 |
| 277 gfx::Transform surface_transform = | 225 gfx::Transform surface_transform = |
| 278 surface_quad->shared_quad_state->quad_to_target_transform; | 226 surface_quad->shared_quad_state->quad_to_target_transform; |
| 279 surface_transform.ConcatTransform(target_transform); | 227 surface_transform.ConcatTransform(target_transform); |
| 280 | 228 |
| 281 const RenderPass& last_pass = *render_pass_list.back(); | 229 const RenderPass& last_pass = *render_pass_list.back(); |
| 282 if (merge_pass) { | 230 if (merge_pass) { |
| 283 // TODO(jamesr): Clean up last pass special casing. | 231 // TODO(jamesr): Clean up last pass special casing. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 315 surface_quad->visible_rect, | 263 surface_quad->visible_rect, |
| 316 remapped_pass_id, | 264 remapped_pass_id, |
| 317 0, | 265 0, |
| 318 gfx::Vector2dF(), | 266 gfx::Vector2dF(), |
| 319 gfx::Size(), | 267 gfx::Size(), |
| 320 FilterOperations(), | 268 FilterOperations(), |
| 321 gfx::Vector2dF(), | 269 gfx::Vector2dF(), |
| 322 FilterOperations()); | 270 FilterOperations()); |
| 323 } | 271 } |
| 324 | 272 |
| 325 dest_pass->damage_rect = gfx::UnionRects( | |
| 326 dest_pass->damage_rect, | |
| 327 MathUtil::MapEnclosingClippedRect(surface_transform, surface_damage)); | |
| 328 | 273 |
| 329 referenced_surfaces_.erase(it); | 274 referenced_surfaces_.erase(it); |
| 330 } | 275 } |
| 331 | 276 |
| 332 void SurfaceAggregator::CopySharedQuadState( | 277 void SurfaceAggregator::CopySharedQuadState( |
| 333 const SharedQuadState* source_sqs, | 278 const SharedQuadState* source_sqs, |
| 334 const gfx::Transform& target_transform, | 279 const gfx::Transform& target_transform, |
| 335 const ClipData& clip_rect, | 280 const ClipData& clip_rect, |
| 336 RenderPass* dest_render_pass) { | 281 RenderPass* dest_render_pass) { |
| 337 SharedQuadState* copy_shared_quad_state = | 282 SharedQuadState* copy_shared_quad_state = |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 last_copied_source_shared_quad_state = quad->shared_quad_state; | 327 last_copied_source_shared_quad_state = quad->shared_quad_state; |
| 383 } | 328 } |
| 384 DrawQuad* dest_quad; | 329 DrawQuad* dest_quad; |
| 385 if (quad->material == DrawQuad::RENDER_PASS) { | 330 if (quad->material == DrawQuad::RENDER_PASS) { |
| 386 const RenderPassDrawQuad* pass_quad = | 331 const RenderPassDrawQuad* pass_quad = |
| 387 RenderPassDrawQuad::MaterialCast(quad); | 332 RenderPassDrawQuad::MaterialCast(quad); |
| 388 RenderPassId original_pass_id = pass_quad->render_pass_id; | 333 RenderPassId original_pass_id = pass_quad->render_pass_id; |
| 389 RenderPassId remapped_pass_id = | 334 RenderPassId remapped_pass_id = |
| 390 RemapPassId(original_pass_id, surface_id); | 335 RemapPassId(original_pass_id, surface_id); |
| 391 | 336 |
| 392 gfx::Rect pass_damage; | |
| 393 for (const auto* pass : *dest_pass_list_) { | |
| 394 if (pass->id == remapped_pass_id) { | |
| 395 pass_damage = pass->damage_rect; | |
| 396 break; | |
| 397 } | |
| 398 } | |
| 399 | |
| 400 dest_quad = dest_pass->CopyFromAndAppendRenderPassDrawQuad( | 337 dest_quad = dest_pass->CopyFromAndAppendRenderPassDrawQuad( |
| 401 pass_quad, dest_pass->shared_quad_state_list.back(), | 338 pass_quad, dest_pass->shared_quad_state_list.back(), |
| 402 remapped_pass_id); | 339 remapped_pass_id); |
| 403 dest_pass->damage_rect = gfx::UnionRects( | |
| 404 dest_pass->damage_rect, | |
| 405 MathUtil::MapEnclosingClippedRect( | |
| 406 dest_quad->shared_quad_state->quad_to_target_transform, | |
| 407 pass_damage)); | |
| 408 } else { | 340 } else { |
| 409 dest_quad = dest_pass->CopyFromAndAppendDrawQuad( | 341 dest_quad = dest_pass->CopyFromAndAppendDrawQuad( |
| 410 quad, dest_pass->shared_quad_state_list.back()); | 342 quad, dest_pass->shared_quad_state_list.back()); |
| 411 } | 343 } |
| 412 if (!child_to_parent_map.empty()) { | 344 if (!child_to_parent_map.empty()) { |
| 413 for (ResourceId& resource_id : dest_quad->resources) { | 345 for (ResourceId& resource_id : dest_quad->resources) { |
| 414 ResourceProvider::ResourceIdMap::const_iterator it = | 346 ResourceProvider::ResourceIdMap::const_iterator it = |
| 415 child_to_parent_map.find(resource_id); | 347 child_to_parent_map.find(resource_id); |
| 416 DCHECK(it != child_to_parent_map.end()); | 348 DCHECK(it != child_to_parent_map.end()); |
| 417 | 349 |
| 418 DCHECK_EQ(it->first, resource_id); | 350 DCHECK_EQ(it->first, resource_id); |
| 419 ResourceId remapped_id = it->second; | 351 ResourceId remapped_id = it->second; |
| 420 resource_id = remapped_id; | 352 resource_id = remapped_id; |
| 421 } | 353 } |
| 422 } | 354 } |
| 423 } | 355 } |
| 424 } | 356 } |
| 425 } | 357 } |
| 426 | 358 |
| 427 void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data, | 359 void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data, |
| 428 Surface* surface) { | 360 Surface* surface) { |
| 429 // The root surface is allowed to have copy output requests, so grab them | 361 // The root surface is allowed to have copy output requests, so grab them |
| 430 // off its render passes. | 362 // off its render passes. |
| 431 std::multimap<RenderPassId, CopyOutputRequest*> copy_requests; | 363 std::multimap<RenderPassId, CopyOutputRequest*> copy_requests; |
| 432 surface->TakeCopyOutputRequests(©_requests); | 364 surface->TakeCopyOutputRequests(©_requests); |
| 433 | 365 |
| 434 const RenderPassList& source_pass_list = frame_data->render_pass_list; | 366 const RenderPassList& source_pass_list = frame_data->render_pass_list; |
| 435 bool invalid_frame = ValidateResources(surface, frame_data); | 367 DCHECK(surface_validity_[surface->surface_id()]); |
| 436 DCHECK(!invalid_frame); | 368 if (!surface_validity_[surface->surface_id()]) |
| 437 if (invalid_frame) | |
| 438 return; | 369 return; |
| 439 | 370 |
| 440 // TODO(vmpstr): provider check is a hack for unittests that don't set up a | 371 // TODO(vmpstr): provider check is a hack for unittests that don't set up a |
| 441 // resource provider. | 372 // resource provider. |
| 442 ResourceProvider::ResourceIdMap empty_map; | 373 ResourceProvider::ResourceIdMap empty_map; |
| 443 const ResourceProvider::ResourceIdMap& child_to_parent_map = | 374 const ResourceProvider::ResourceIdMap& child_to_parent_map = |
| 444 provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface)) | 375 provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface)) |
| 445 : empty_map; | 376 : empty_map; |
| 446 for (size_t i = 0; i < source_pass_list.size(); ++i) { | 377 for (size_t i = 0; i < source_pass_list.size(); ++i) { |
| 447 const RenderPass& source = *source_pass_list[i]; | 378 const RenderPass& source = *source_pass_list[i]; |
| 448 | 379 |
| 449 size_t sqs_size = source.shared_quad_state_list.size(); | 380 size_t sqs_size = source.shared_quad_state_list.size(); |
| 450 size_t dq_size = source.quad_list.size(); | 381 size_t dq_size = source.quad_list.size(); |
| 451 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); | 382 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); |
| 452 | 383 |
| 453 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); | 384 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); |
| 454 | 385 |
| 455 RenderPassId remapped_pass_id = | 386 RenderPassId remapped_pass_id = |
| 456 RemapPassId(source.id, surface->surface_id()); | 387 RemapPassId(source.id, surface->surface_id()); |
| 457 | 388 |
| 458 gfx::Rect damage_rect = | 389 copy_pass->SetAll(remapped_pass_id, source.output_rect, gfx::Rect(), |
| 459 (i < source_pass_list.size() - 1) | |
| 460 ? gfx::Rect() | |
| 461 : DamageRectForSurface(surface, source, source.output_rect); | |
| 462 copy_pass->SetAll(remapped_pass_id, source.output_rect, damage_rect, | |
| 463 source.transform_to_root_target, | 390 source.transform_to_root_target, |
| 464 source.has_transparent_background); | 391 source.has_transparent_background); |
| 465 | 392 |
| 466 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, | 393 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, |
| 467 child_to_parent_map, gfx::Transform(), ClipData(), | 394 child_to_parent_map, gfx::Transform(), ClipData(), |
| 468 copy_pass.get(), surface->surface_id()); | 395 copy_pass.get(), surface->surface_id()); |
| 469 | 396 |
| 470 dest_pass_list_->push_back(copy_pass.Pass()); | 397 dest_pass_list_->push_back(copy_pass.Pass()); |
| 471 } | 398 } |
| 472 } | 399 } |
| 473 | 400 |
| 474 void SurfaceAggregator::RemoveUnreferencedChildren() { | 401 void SurfaceAggregator::RemoveUnreferencedChildren() { |
| 475 for (const auto& surface : previous_contained_surfaces_) { | 402 for (const auto& surface : previous_contained_surfaces_) { |
| 476 if (!contained_surfaces_.count(surface.first)) { | 403 if (!contained_surfaces_.count(surface.first)) { |
| 477 SurfaceToResourceChildIdMap::iterator it = | 404 SurfaceToResourceChildIdMap::iterator it = |
| 478 surface_id_to_resource_child_id_.find(surface.first); | 405 surface_id_to_resource_child_id_.find(surface.first); |
| 479 if (it != surface_id_to_resource_child_id_.end()) { | 406 if (it != surface_id_to_resource_child_id_.end()) { |
| 480 provider_->DestroyChild(it->second); | 407 provider_->DestroyChild(it->second); |
| 481 surface_id_to_resource_child_id_.erase(it); | 408 surface_id_to_resource_child_id_.erase(it); |
| 482 } | 409 } |
| 483 | 410 |
| 484 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); | 411 Surface* surface_ptr = manager_->GetSurfaceForId(surface.first); |
| 485 if (surface_ptr) | 412 if (surface_ptr) |
| 486 surface_ptr->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); | 413 surface_ptr->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); |
| 487 } | 414 } |
| 488 } | 415 } |
| 489 } | 416 } |
| 490 | 417 |
| 418 // Validate the resources of the current surface and its descendants, and | |
| 419 // calculate their combined damage rect. | |
| 420 gfx::Rect SurfaceAggregator::ValidateAndCalculateDamageRect( | |
| 421 SurfaceId surface_id) { | |
| 422 if (referenced_surfaces_.count(surface_id)) | |
| 423 return gfx::Rect(); | |
| 424 Surface* surface = manager_->GetSurfaceForId(surface_id); | |
| 425 if (!surface) | |
| 426 return gfx::Rect(); | |
| 427 const CompositorFrame* surface_frame = surface->GetEligibleFrame(); | |
| 428 if (!surface_frame) | |
| 429 return gfx::Rect(); | |
| 430 const DelegatedFrameData* frame_data = | |
| 431 surface_frame->delegated_frame_data.get(); | |
| 432 if (!frame_data) | |
| 433 return gfx::Rect(); | |
| 434 SurfaceSet::iterator it = | |
| 435 referenced_surfaces_.insert(surface->surface_id()).first; | |
| 436 | |
| 437 int child_id = 0; | |
| 438 // TODO(jbauman): hack for unit tests that don't set up rp | |
| 439 if (provider_) { | |
| 440 child_id = ChildIdForSurface(surface); | |
| 441 if (surface->factory()) | |
| 442 surface->factory()->RefResources(frame_data->resource_list); | |
| 443 provider_->ReceiveFromChild(child_id, frame_data->resource_list); | |
| 444 } | |
| 445 | |
| 446 ResourceProvider::ResourceIdSet referenced_resources; | |
| 447 size_t reserve_size = frame_data->resource_list.size(); | |
| 448 #if defined(COMPILER_MSVC) | |
| 449 referenced_resources.reserve(reserve_size); | |
| 450 #elif defined(COMPILER_GCC) | |
| 451 // Pre-standard hash-tables only implement resize, which behaves similarly | |
| 452 // to reserve for these keys. Resizing to 0 may also be broken (particularly | |
| 453 // on stlport). | |
| 454 // TODO(jbauman): Replace with reserve when C++11 is supported everywhere. | |
| 455 if (reserve_size) | |
| 456 referenced_resources.resize(reserve_size); | |
| 457 #endif | |
| 458 | |
| 459 bool invalid_frame = false; | |
| 460 ResourceProvider::ResourceIdMap empty_map; | |
| 461 const ResourceProvider::ResourceIdMap& child_to_parent_map = | |
| 462 provider_ ? provider_->GetChildToParentMap(child_id) : empty_map; | |
| 463 | |
| 464 // Each pair in the vector is a child surface and the transform from its | |
| 465 // target to the root target. | |
| 466 std::vector<std::pair<SurfaceId, gfx::Transform>> child_surfaces; | |
| 467 for (const auto& render_pass : frame_data->render_pass_list) { | |
| 468 for (const auto& quad : render_pass->quad_list) { | |
| 469 if (quad->material == DrawQuad::SURFACE_CONTENT) { | |
| 470 const SurfaceDrawQuad* surface_quad = | |
| 471 SurfaceDrawQuad::MaterialCast(quad); | |
| 472 gfx::Transform target_to_root_transform( | |
| 473 surface_quad->shared_quad_state->quad_to_target_transform, | |
| 474 render_pass->transform_to_root_target); | |
| 475 child_surfaces.push_back( | |
| 476 std::make_pair(surface_quad->surface_id, target_to_root_transform)); | |
| 477 } | |
| 478 | |
| 479 if (!provider_) | |
| 480 continue; | |
| 481 for (ResourceId resource_id : quad->resources) { | |
| 482 ResourceProvider::ResourceIdMap::const_iterator it = | |
| 483 child_to_parent_map.find(resource_id); | |
| 484 if (it == child_to_parent_map.end()) { | |
| 485 invalid_frame = true; | |
| 486 break; | |
| 487 } | |
| 488 referenced_resources.insert(resource_id); | |
| 489 } | |
| 490 } | |
| 491 } | |
| 492 | |
| 493 surface_validity_[surface->surface_id()] = !invalid_frame; | |
| 494 if (invalid_frame) { | |
| 495 referenced_surfaces_.erase(it); | |
| 496 return gfx::Rect(); | |
| 497 } | |
| 498 | |
| 499 if (provider_) | |
| 500 provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); | |
| 501 | |
| 502 gfx::Rect damage_rect; | |
| 503 if (!frame_data->render_pass_list.empty()) | |
|
danakj
2015/07/06 22:08:43
{}
jbauman
2015/07/06 23:08:15
Done.
| |
| 504 damage_rect = | |
| 505 DamageRectForSurface(surface, *frame_data->render_pass_list.back(), | |
| 506 frame_data->render_pass_list.back()->output_rect); | |
| 507 | |
| 508 for (const auto& surface_info : child_surfaces) { | |
| 509 gfx::Rect surface_damage = | |
| 510 ValidateAndCalculateDamageRect(surface_info.first); | |
| 511 damage_rect.Union( | |
| 512 MathUtil::MapEnclosingClippedRect(surface_info.second, surface_damage)); | |
|
danakj
2015/07/06 22:08:43
Does this do the right thing with the transform?
jbauman
2015/07/06 23:08:15
The transform in the second is from the quad space
| |
| 513 } | |
| 514 referenced_surfaces_.erase(it); | |
| 515 return damage_rect; | |
| 516 } | |
| 517 | |
| 491 scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { | 518 scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) { |
| 492 Surface* surface = manager_->GetSurfaceForId(surface_id); | 519 Surface* surface = manager_->GetSurfaceForId(surface_id); |
| 493 DCHECK(surface); | 520 DCHECK(surface); |
| 494 contained_surfaces_[surface_id] = surface->frame_index(); | 521 contained_surfaces_[surface_id] = surface->frame_index(); |
| 495 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); | 522 const CompositorFrame* root_surface_frame = surface->GetEligibleFrame(); |
| 496 if (!root_surface_frame) | 523 if (!root_surface_frame) |
| 497 return nullptr; | 524 return nullptr; |
| 498 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); | 525 TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate"); |
| 499 | 526 |
| 500 scoped_ptr<CompositorFrame> frame(new CompositorFrame); | 527 scoped_ptr<CompositorFrame> frame(new CompositorFrame); |
| 501 frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData); | 528 frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData); |
| 502 | 529 |
| 503 DCHECK(root_surface_frame->delegated_frame_data); | 530 DCHECK(root_surface_frame->delegated_frame_data); |
| 504 | 531 |
| 505 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | |
| 506 | |
| 507 dest_resource_list_ = &frame->delegated_frame_data->resource_list; | 532 dest_resource_list_ = &frame->delegated_frame_data->resource_list; |
| 508 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; | 533 dest_pass_list_ = &frame->delegated_frame_data->render_pass_list; |
| 509 | 534 |
| 535 surface_validity_.clear(); | |
| 536 gfx::Rect damage_rect = ValidateAndCalculateDamageRect(surface_id); | |
| 537 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | |
| 538 | |
| 510 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); | 539 CopyPasses(root_surface_frame->delegated_frame_data.get(), surface); |
| 511 | 540 |
| 512 referenced_surfaces_.erase(it); | 541 referenced_surfaces_.erase(it); |
| 513 DCHECK(referenced_surfaces_.empty()); | 542 DCHECK(referenced_surfaces_.empty()); |
| 514 | 543 |
| 515 if (dest_pass_list_->empty()) | 544 if (dest_pass_list_->empty()) |
| 516 return nullptr; | 545 return nullptr; |
| 546 dest_pass_list_->back()->damage_rect = damage_rect; | |
| 517 | 547 |
| 518 dest_pass_list_ = NULL; | 548 dest_pass_list_ = NULL; |
| 519 RemoveUnreferencedChildren(); | 549 RemoveUnreferencedChildren(); |
| 520 contained_surfaces_.swap(previous_contained_surfaces_); | 550 contained_surfaces_.swap(previous_contained_surfaces_); |
| 521 contained_surfaces_.clear(); | 551 contained_surfaces_.clear(); |
| 522 | 552 |
| 523 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); | 553 for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin(); |
| 524 it != previous_contained_surfaces_.end(); | 554 it != previous_contained_surfaces_.end(); |
| 525 ++it) { | 555 ++it) { |
| 526 Surface* surface = manager_->GetSurfaceForId(it->first); | 556 Surface* surface = manager_->GetSurfaceForId(it->first); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 545 | 575 |
| 546 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { | 576 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { |
| 547 auto it = previous_contained_surfaces_.find(surface_id); | 577 auto it = previous_contained_surfaces_.find(surface_id); |
| 548 if (it == previous_contained_surfaces_.end()) | 578 if (it == previous_contained_surfaces_.end()) |
| 549 return; | 579 return; |
| 550 // Set the last drawn index as 0 to ensure full damage next time it's drawn. | 580 // Set the last drawn index as 0 to ensure full damage next time it's drawn. |
| 551 it->second = 0; | 581 it->second = 0; |
| 552 } | 582 } |
| 553 | 583 |
| 554 } // namespace cc | 584 } // namespace cc |
| OLD | NEW |