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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 ResourceId id) { | 136 ResourceId id) { |
137 ResourceProvider::ResourceIdMap::const_iterator it = | 137 ResourceProvider::ResourceIdMap::const_iterator it = |
138 child_to_parent_map.find(id); | 138 child_to_parent_map.find(id); |
139 DCHECK(it != child_to_parent_map.end()); | 139 DCHECK(it != child_to_parent_map.end()); |
140 | 140 |
141 DCHECK_EQ(it->first, id); | 141 DCHECK_EQ(it->first, id); |
142 ResourceId remapped_id = it->second; | 142 ResourceId remapped_id = it->second; |
143 return remapped_id; | 143 return remapped_id; |
144 } | 144 } |
145 | 145 |
146 static ResourceId ValidateResourceHelper( | |
147 bool* invalid_frame, | |
148 const ResourceProvider::ResourceIdMap& child_to_parent_map, | |
149 ResourceProvider::ResourceIdSet* resources_in_frame, | |
150 ResourceId id) { | |
151 ResourceProvider::ResourceIdMap::const_iterator it = | |
152 child_to_parent_map.find(id); | |
153 if (it == child_to_parent_map.end()) { | |
154 *invalid_frame = true; | |
155 return id; | |
156 } | |
157 resources_in_frame->insert(id); | |
158 return id; | |
159 } | |
160 | |
161 bool SurfaceAggregator::ValidateResources( | 146 bool SurfaceAggregator::ValidateResources( |
162 Surface* surface, | 147 Surface* surface, |
163 const DelegatedFrameData* frame_data) { | 148 const DelegatedFrameData* frame_data) { |
164 if (!provider_) // TODO(jamesr): hack for unit tests that don't set up rp | 149 if (!provider_) // TODO(jamesr): hack for unit tests that don't set up rp |
165 return false; | 150 return false; |
166 | 151 |
167 int child_id = ChildIdForSurface(surface); | 152 int child_id = ChildIdForSurface(surface); |
168 if (surface->factory()) | 153 if (surface->factory()) |
169 surface->factory()->RefResources(frame_data->resource_list); | 154 surface->factory()->RefResources(frame_data->resource_list); |
170 provider_->ReceiveFromChild(child_id, frame_data->resource_list); | 155 provider_->ReceiveFromChild(child_id, frame_data->resource_list); |
171 | 156 |
172 ResourceProvider::ResourceIdSet referenced_resources; | 157 ResourceProvider::ResourceIdSet referenced_resources; |
173 size_t reserve_size = frame_data->resource_list.size(); | 158 size_t reserve_size = frame_data->resource_list.size(); |
174 #if defined(COMPILER_MSVC) | 159 #if defined(COMPILER_MSVC) |
175 referenced_resources.reserve(reserve_size); | 160 referenced_resources.reserve(reserve_size); |
176 #elif defined(COMPILER_GCC) | 161 #elif defined(COMPILER_GCC) |
177 // Pre-standard hash-tables only implement resize, which behaves similarly | 162 // Pre-standard hash-tables only implement resize, which behaves similarly |
178 // to reserve for these keys. Resizing to 0 may also be broken (particularly | 163 // to reserve for these keys. Resizing to 0 may also be broken (particularly |
179 // on stlport). | 164 // on stlport). |
180 // TODO(jbauman): Replace with reserve when C++11 is supported everywhere. | 165 // TODO(jbauman): Replace with reserve when C++11 is supported everywhere. |
181 if (reserve_size) | 166 if (reserve_size) |
182 referenced_resources.resize(reserve_size); | 167 referenced_resources.resize(reserve_size); |
183 #endif | 168 #endif |
184 | 169 |
185 bool invalid_frame = false; | 170 bool invalid_frame = false; |
186 DrawQuad::ResourceIteratorCallback remap = | 171 const ResourceProvider::ResourceIdMap& child_to_parent_map = |
187 base::Bind(&ValidateResourceHelper, &invalid_frame, | 172 provider_->GetChildToParentMap(child_id); |
188 base::ConstRef(provider_->GetChildToParentMap(child_id)), | |
189 &referenced_resources); | |
190 for (const auto& render_pass : frame_data->render_pass_list) { | 173 for (const auto& render_pass : frame_data->render_pass_list) { |
191 for (const auto& quad : render_pass->quad_list) | 174 for (const auto& quad : render_pass->quad_list) { |
192 quad->IterateResources(remap); | 175 for (const ResourceId& resource_id : quad->resources) { |
piman
2015/05/28 19:35:46
nit: ResourceId instead of const ResourceId&
vmpstr
2015/05/28 22:37:00
Done.
| |
176 ResourceProvider::ResourceIdMap::const_iterator it = | |
177 child_to_parent_map.find(resource_id); | |
178 if (it == child_to_parent_map.end()) { | |
179 invalid_frame = true; | |
180 continue; | |
piman
2015/05/28 19:35:46
nit: break
vmpstr
2015/05/28 22:37:00
Done.
| |
181 } | |
182 referenced_resources.insert(resource_id); | |
183 } | |
184 } | |
193 } | 185 } |
194 | 186 |
195 if (!invalid_frame) | 187 if (!invalid_frame) |
196 provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); | 188 provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources); |
197 | 189 |
198 return invalid_frame; | 190 return invalid_frame; |
199 } | 191 } |
200 | 192 |
201 gfx::Rect SurfaceAggregator::DamageRectForSurface(const Surface* surface, | 193 gfx::Rect SurfaceAggregator::DamageRectForSurface(const Surface* surface, |
202 const RenderPass& source, | 194 const RenderPass& source, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 bool invalid_frame = ValidateResources(surface, frame_data); | 231 bool invalid_frame = ValidateResources(surface, frame_data); |
240 if (invalid_frame) { | 232 if (invalid_frame) { |
241 for (auto& request : copy_requests) { | 233 for (auto& request : copy_requests) { |
242 request.second->SendEmptyResult(); | 234 request.second->SendEmptyResult(); |
243 delete request.second; | 235 delete request.second; |
244 } | 236 } |
245 return; | 237 return; |
246 } | 238 } |
247 | 239 |
248 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; | 240 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; |
249 DrawQuad::ResourceIteratorCallback remap; | 241 const ResourceProvider::ResourceIdMap& child_to_parent_map = |
250 if (provider_) { | 242 provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface)) |
251 int child_id = ChildIdForSurface(surface); | 243 : ResourceProvider::ResourceIdMap(); |
252 remap = | |
253 base::Bind(&ResourceRemapHelper, | |
254 base::ConstRef(provider_->GetChildToParentMap(child_id))); | |
255 } | |
256 | |
257 bool merge_pass = surface_quad->opacity() == 1.f && copy_requests.empty(); | 244 bool merge_pass = surface_quad->opacity() == 1.f && copy_requests.empty(); |
258 | 245 |
259 gfx::Rect surface_damage = DamageRectForSurface( | 246 gfx::Rect surface_damage = DamageRectForSurface( |
260 surface, *render_pass_list.back(), surface_quad->visible_rect); | 247 surface, *render_pass_list.back(), surface_quad->visible_rect); |
261 const RenderPassList& referenced_passes = render_pass_list; | 248 const RenderPassList& referenced_passes = render_pass_list; |
262 size_t passes_to_copy = | 249 size_t passes_to_copy = |
263 merge_pass ? referenced_passes.size() - 1 : referenced_passes.size(); | 250 merge_pass ? referenced_passes.size() - 1 : referenced_passes.size(); |
264 for (size_t j = 0; j < passes_to_copy; ++j) { | 251 for (size_t j = 0; j < passes_to_copy; ++j) { |
265 const RenderPass& source = *referenced_passes[j]; | 252 const RenderPass& source = *referenced_passes[j]; |
266 | 253 |
(...skipping 11 matching lines...) Expand all Loading... | |
278 | 265 |
279 // Contributing passes aggregated in to the pass list need to take the | 266 // Contributing passes aggregated in to the pass list need to take the |
280 // transform of the surface quad into account to update their transform to | 267 // transform of the surface quad into account to update their transform to |
281 // the root surface. | 268 // the root surface. |
282 copy_pass->transform_to_root_target.ConcatTransform( | 269 copy_pass->transform_to_root_target.ConcatTransform( |
283 surface_quad->quadTransform()); | 270 surface_quad->quadTransform()); |
284 copy_pass->transform_to_root_target.ConcatTransform(target_transform); | 271 copy_pass->transform_to_root_target.ConcatTransform(target_transform); |
285 copy_pass->transform_to_root_target.ConcatTransform( | 272 copy_pass->transform_to_root_target.ConcatTransform( |
286 dest_pass->transform_to_root_target); | 273 dest_pass->transform_to_root_target); |
287 | 274 |
288 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, remap, | 275 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, |
289 gfx::Transform(), ClipData(), copy_pass.get(), surface_id); | 276 child_to_parent_map, gfx::Transform(), ClipData(), |
277 copy_pass.get(), surface_id); | |
290 | 278 |
291 if (j == referenced_passes.size() - 1) | 279 if (j == referenced_passes.size() - 1) |
292 surface_damage = gfx::UnionRects(surface_damage, copy_pass->damage_rect); | 280 surface_damage = gfx::UnionRects(surface_damage, copy_pass->damage_rect); |
293 | 281 |
294 dest_pass_list_->push_back(copy_pass.Pass()); | 282 dest_pass_list_->push_back(copy_pass.Pass()); |
295 } | 283 } |
296 | 284 |
297 const RenderPass& last_pass = *render_pass_list.back(); | 285 const RenderPass& last_pass = *render_pass_list.back(); |
298 if (merge_pass) { | 286 if (merge_pass) { |
299 // TODO(jamesr): Clean up last pass special casing. | 287 // TODO(jamesr): Clean up last pass special casing. |
300 const QuadList& quads = last_pass.quad_list; | 288 const QuadList& quads = last_pass.quad_list; |
301 | 289 |
302 gfx::Transform surface_transform = surface_quad->quadTransform(); | 290 gfx::Transform surface_transform = surface_quad->quadTransform(); |
303 surface_transform.ConcatTransform(target_transform); | 291 surface_transform.ConcatTransform(target_transform); |
304 | 292 |
305 // Intersect the transformed visible rect and the clip rect to create a | 293 // Intersect the transformed visible rect and the clip rect to create a |
306 // smaller cliprect for the quad. | 294 // smaller cliprect for the quad. |
307 ClipData surface_quad_clip_rect( | 295 ClipData surface_quad_clip_rect( |
308 true, MathUtil::MapEnclosingClippedRect(surface_quad->quadTransform(), | 296 true, MathUtil::MapEnclosingClippedRect(surface_quad->quadTransform(), |
309 surface_quad->visible_rect)); | 297 surface_quad->visible_rect)); |
310 if (surface_quad->isClipped()) | 298 if (surface_quad->isClipped()) |
311 surface_quad_clip_rect.rect.Intersect(surface_quad->clipRect()); | 299 surface_quad_clip_rect.rect.Intersect(surface_quad->clipRect()); |
312 | 300 |
313 ClipData quads_clip = | 301 ClipData quads_clip = |
314 CalculateClipRect(clip_rect, surface_quad_clip_rect, target_transform); | 302 CalculateClipRect(clip_rect, surface_quad_clip_rect, target_transform); |
315 | 303 |
316 CopyQuadsToPass(quads, last_pass.shared_quad_state_list, remap, | 304 CopyQuadsToPass(quads, last_pass.shared_quad_state_list, |
317 surface_transform, quads_clip, dest_pass, surface_id); | 305 child_to_parent_map, surface_transform, quads_clip, |
306 dest_pass, surface_id); | |
318 } else { | 307 } else { |
319 RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id); | 308 RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id); |
320 | 309 |
321 CopySharedQuadState(surface_quad->shared_quad_state, target_transform, | 310 CopySharedQuadState(surface_quad->shared_quad_state, target_transform, |
322 clip_rect, dest_pass); | 311 clip_rect, dest_pass); |
323 | 312 |
324 SharedQuadState* shared_quad_state = | 313 SharedQuadState* shared_quad_state = |
325 dest_pass->shared_quad_state_list.back(); | 314 dest_pass->shared_quad_state_list.back(); |
326 RenderPassDrawQuad* quad = | 315 RenderPassDrawQuad* quad = |
327 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 316 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 ClipData new_clip_rect = CalculateClipRect( | 353 ClipData new_clip_rect = CalculateClipRect( |
365 clip_rect, ClipData(source_sqs->is_clipped, source_sqs->clip_rect), | 354 clip_rect, ClipData(source_sqs->is_clipped, source_sqs->clip_rect), |
366 target_transform); | 355 target_transform); |
367 copy_shared_quad_state->is_clipped = new_clip_rect.is_clipped; | 356 copy_shared_quad_state->is_clipped = new_clip_rect.is_clipped; |
368 copy_shared_quad_state->clip_rect = new_clip_rect.rect; | 357 copy_shared_quad_state->clip_rect = new_clip_rect.rect; |
369 } | 358 } |
370 | 359 |
371 void SurfaceAggregator::CopyQuadsToPass( | 360 void SurfaceAggregator::CopyQuadsToPass( |
372 const QuadList& source_quad_list, | 361 const QuadList& source_quad_list, |
373 const SharedQuadStateList& source_shared_quad_state_list, | 362 const SharedQuadStateList& source_shared_quad_state_list, |
374 const DrawQuad::ResourceIteratorCallback& remap, | 363 const ResourceProvider::ResourceIdMap& child_to_parent_map, |
375 const gfx::Transform& target_transform, | 364 const gfx::Transform& target_transform, |
376 const ClipData& clip_rect, | 365 const ClipData& clip_rect, |
377 RenderPass* dest_pass, | 366 RenderPass* dest_pass, |
378 SurfaceId surface_id) { | 367 SurfaceId surface_id) { |
379 const SharedQuadState* last_copied_source_shared_quad_state = NULL; | 368 const SharedQuadState* last_copied_source_shared_quad_state = NULL; |
380 | 369 |
381 SharedQuadStateList::ConstIterator sqs_iter = | 370 SharedQuadStateList::ConstIterator sqs_iter = |
382 source_shared_quad_state_list.begin(); | 371 source_shared_quad_state_list.begin(); |
383 for (const auto& quad : source_quad_list) { | 372 for (const auto& quad : source_quad_list) { |
384 while (quad->shared_quad_state != *sqs_iter) { | 373 while (quad->shared_quad_state != *sqs_iter) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 pass_quad, dest_pass->shared_quad_state_list.back(), | 405 pass_quad, dest_pass->shared_quad_state_list.back(), |
417 remapped_pass_id); | 406 remapped_pass_id); |
418 dest_pass->damage_rect = | 407 dest_pass->damage_rect = |
419 gfx::UnionRects(dest_pass->damage_rect, | 408 gfx::UnionRects(dest_pass->damage_rect, |
420 MathUtil::MapEnclosingClippedRect( | 409 MathUtil::MapEnclosingClippedRect( |
421 dest_quad->quadTransform(), pass_damage)); | 410 dest_quad->quadTransform(), pass_damage)); |
422 } else { | 411 } else { |
423 dest_quad = dest_pass->CopyFromAndAppendDrawQuad( | 412 dest_quad = dest_pass->CopyFromAndAppendDrawQuad( |
424 quad, dest_pass->shared_quad_state_list.back()); | 413 quad, dest_pass->shared_quad_state_list.back()); |
425 } | 414 } |
426 if (!remap.is_null()) | 415 if (!child_to_parent_map.empty()) { |
427 dest_quad->IterateResources(remap); | 416 for (size_t i = 0; i < dest_quad->resources.count; ++i) { |
piman
2015/05/28 19:35:46
You can use range for loop here too:
for (Resource
vmpstr
2015/05/28 22:36:59
Oops, missed this one. Thanks
| |
417 dest_quad->resources.ids[i] = ResourceRemapHelper( | |
418 child_to_parent_map, dest_quad->resources.ids[i]); | |
419 } | |
420 } | |
428 } | 421 } |
429 } | 422 } |
430 } | 423 } |
431 | 424 |
432 void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data, | 425 void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data, |
433 Surface* surface) { | 426 Surface* surface) { |
434 // The root surface is allowed to have copy output requests, so grab them | 427 // The root surface is allowed to have copy output requests, so grab them |
435 // off its render passes. | 428 // off its render passes. |
436 std::multimap<RenderPassId, CopyOutputRequest*> copy_requests; | 429 std::multimap<RenderPassId, CopyOutputRequest*> copy_requests; |
437 surface->TakeCopyOutputRequests(©_requests); | 430 surface->TakeCopyOutputRequests(©_requests); |
438 | 431 |
439 const RenderPassList& source_pass_list = frame_data->render_pass_list; | 432 const RenderPassList& source_pass_list = frame_data->render_pass_list; |
440 bool invalid_frame = ValidateResources(surface, frame_data); | 433 bool invalid_frame = ValidateResources(surface, frame_data); |
441 DCHECK(!invalid_frame); | 434 DCHECK(!invalid_frame); |
442 if (invalid_frame) | 435 if (invalid_frame) |
443 return; | 436 return; |
444 | 437 |
445 DrawQuad::ResourceIteratorCallback remap; | 438 const ResourceProvider::ResourceIdMap& child_to_parent_map = |
446 if (provider_) { | 439 provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface)) |
447 int child_id = ChildIdForSurface(surface); | 440 : ResourceProvider::ResourceIdMap(); |
448 remap = | |
449 base::Bind(&ResourceRemapHelper, | |
450 base::ConstRef(provider_->GetChildToParentMap(child_id))); | |
451 } | |
452 | |
453 for (size_t i = 0; i < source_pass_list.size(); ++i) { | 441 for (size_t i = 0; i < source_pass_list.size(); ++i) { |
454 const RenderPass& source = *source_pass_list[i]; | 442 const RenderPass& source = *source_pass_list[i]; |
455 | 443 |
456 size_t sqs_size = source.shared_quad_state_list.size(); | 444 size_t sqs_size = source.shared_quad_state_list.size(); |
457 size_t dq_size = source.quad_list.size(); | 445 size_t dq_size = source.quad_list.size(); |
458 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); | 446 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); |
459 | 447 |
460 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); | 448 MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); |
461 | 449 |
462 RenderPassId remapped_pass_id = | 450 RenderPassId remapped_pass_id = |
463 RemapPassId(source.id, surface->surface_id()); | 451 RemapPassId(source.id, surface->surface_id()); |
464 | 452 |
465 gfx::Rect damage_rect = | 453 gfx::Rect damage_rect = |
466 (i < source_pass_list.size() - 1) | 454 (i < source_pass_list.size() - 1) |
467 ? gfx::Rect() | 455 ? gfx::Rect() |
468 : DamageRectForSurface(surface, source, source.output_rect); | 456 : DamageRectForSurface(surface, source, source.output_rect); |
469 copy_pass->SetAll(remapped_pass_id, source.output_rect, damage_rect, | 457 copy_pass->SetAll(remapped_pass_id, source.output_rect, damage_rect, |
470 source.transform_to_root_target, | 458 source.transform_to_root_target, |
471 source.has_transparent_background); | 459 source.has_transparent_background); |
472 | 460 |
473 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, remap, | 461 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, |
474 gfx::Transform(), ClipData(), copy_pass.get(), | 462 child_to_parent_map, gfx::Transform(), ClipData(), |
475 surface->surface_id()); | 463 copy_pass.get(), surface->surface_id()); |
476 | 464 |
477 dest_pass_list_->push_back(copy_pass.Pass()); | 465 dest_pass_list_->push_back(copy_pass.Pass()); |
478 } | 466 } |
479 } | 467 } |
480 | 468 |
481 void SurfaceAggregator::RemoveUnreferencedChildren() { | 469 void SurfaceAggregator::RemoveUnreferencedChildren() { |
482 for (const auto& surface : previous_contained_surfaces_) { | 470 for (const auto& surface : previous_contained_surfaces_) { |
483 if (!contained_surfaces_.count(surface.first)) { | 471 if (!contained_surfaces_.count(surface.first)) { |
484 SurfaceToResourceChildIdMap::iterator it = | 472 SurfaceToResourceChildIdMap::iterator it = |
485 surface_id_to_resource_child_id_.find(surface.first); | 473 surface_id_to_resource_child_id_.find(surface.first); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 | 540 |
553 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { | 541 void SurfaceAggregator::SetFullDamageForSurface(SurfaceId surface_id) { |
554 auto it = previous_contained_surfaces_.find(surface_id); | 542 auto it = previous_contained_surfaces_.find(surface_id); |
555 if (it == previous_contained_surfaces_.end()) | 543 if (it == previous_contained_surfaces_.end()) |
556 return; | 544 return; |
557 // Set the last drawn index as 0 to ensure full damage next time it's drawn. | 545 // Set the last drawn index as 0 to ensure full damage next time it's drawn. |
558 it->second = 0; | 546 it->second = 0; |
559 } | 547 } |
560 | 548 |
561 } // namespace cc | 549 } // namespace cc |
OLD | NEW |