Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "platform/graphics/compositing/PaintArtifactCompositor.h" | 5 #include "platform/graphics/compositing/PaintArtifactCompositor.h" |
| 6 | 6 |
| 7 #include "cc/layers/content_layer_client.h" | 7 #include "cc/layers/content_layer_client.h" |
| 8 #include "cc/layers/layer.h" | 8 #include "cc/layers/layer.h" |
| 9 #include "cc/layers/picture_layer.h" | 9 #include "cc/layers/picture_layer.h" |
| 10 #include "cc/paint/display_item_list.h" | 10 #include "cc/paint/display_item_list.h" |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 return false; | 467 return false; |
| 468 if (effect->HasDirectCompositingReasons()) | 468 if (effect->HasDirectCompositingReasons()) |
| 469 return false; | 469 return false; |
| 470 if (!CanUpcastTo(layer.property_tree_state, | 470 if (!CanUpcastTo(layer.property_tree_state, |
| 471 PropertyTreeState(effect->LocalTransformSpace(), | 471 PropertyTreeState(effect->LocalTransformSpace(), |
| 472 effect->OutputClip(), effect))) | 472 effect->OutputClip(), effect))) |
| 473 return false; | 473 return false; |
| 474 return true; | 474 return true; |
| 475 } | 475 } |
| 476 | 476 |
| 477 static bool SkipEffectivelyInvisibleChunks( | |
|
trchen
2017/04/27 00:24:10
I feel this could be confusing because it sounds l
wkorman
2017/04/27 19:42:18
Done.
| |
| 478 const PaintArtifact& paint_artifact, | |
| 479 const EffectPaintPropertyNode& current_group, | |
| 480 Vector<PaintChunk>::const_iterator& chunk_it) { | |
| 481 // The lower bound of visibility is considered to be 0.0004f < 1/2048. With | |
| 482 // 10-bit color channels (only available on the newest Macs as of 2016; | |
| 483 // otherwise it's 8-bit), we see that an alpha of 1/2048 or less leads to a | |
| 484 // color output of less than 0.5 in all channels, hence not visible. | |
| 485 static const float kMinimumVisibleOpacity = 0.0004f; | |
| 486 if (current_group.Opacity() < kMinimumVisibleOpacity && | |
| 487 !current_group.HasDirectCompositingReasons()) { | |
|
trchen
2017/04/27 00:24:10
nit: short branch first. i.e.
if (!current_group.O
wkorman
2017/04/27 19:42:18
Done.
| |
| 488 // Fast-forward to just past the end of the chunk sequence within this | |
| 489 // subgroup. | |
|
trchen
2017/04/27 00:24:10
I feel we should DCHECK the current chunk indeed b
wkorman
2017/04/27 19:42:18
Done, I added a helper function that made this and
| |
| 490 while (++chunk_it != paint_artifact.PaintChunks().end()) { | |
| 491 const EffectPaintPropertyNode* current_effect = | |
| 492 chunk_it->properties.property_tree_state.Effect(); | |
| 493 if (current_effect != ¤t_group && | |
| 494 !StrictChildOfAlongPath(¤t_group, current_effect)) { | |
| 495 break; | |
| 496 } | |
| 497 } | |
| 498 return true; | |
| 499 } | |
| 500 return false; | |
| 501 } | |
| 502 | |
| 477 void PaintArtifactCompositor::LayerizeGroup( | 503 void PaintArtifactCompositor::LayerizeGroup( |
| 478 const PaintArtifact& paint_artifact, | 504 const PaintArtifact& paint_artifact, |
| 479 Vector<PendingLayer>& pending_layers, | 505 Vector<PendingLayer>& pending_layers, |
| 480 const EffectPaintPropertyNode& current_group, | 506 const EffectPaintPropertyNode& current_group, |
| 481 Vector<PaintChunk>::const_iterator& chunk_it) { | 507 Vector<PaintChunk>::const_iterator& chunk_it) { |
| 508 // Skip paint chunks that are effectively invisible due to opacity and don't | |
| 509 // have a direct compositing reason. | |
| 510 if (SkipEffectivelyInvisibleChunks(paint_artifact, current_group, chunk_it)) | |
|
wkorman
2017/04/27 00:02:32
Revised per in person discussion with trchen@ arou
| |
| 511 return; | |
| 512 | |
| 482 size_t first_layer_in_current_group = pending_layers.size(); | 513 size_t first_layer_in_current_group = pending_layers.size(); |
| 483 // The worst case time complexity of the algorithm is O(pqd), where | 514 // The worst case time complexity of the algorithm is O(pqd), where |
| 484 // p = the number of paint chunks. | 515 // p = the number of paint chunks. |
| 485 // q = average number of trials to find a squash layer or rejected | 516 // q = average number of trials to find a squash layer or rejected |
| 486 // for overlapping. | 517 // for overlapping. |
| 487 // d = (sum of) the depth of property trees. | 518 // d = (sum of) the depth of property trees. |
| 488 // The analysis as follows: | 519 // The analysis as follows: |
| 489 // Every paint chunk will be visited by the main loop below for exactly once, | 520 // Every paint chunk will be visited by the main loop below for exactly once, |
| 490 // except for chunks that enter or exit groups (case B & C below). | 521 // except for chunks that enter or exit groups (case B & C below). |
| 491 // For normal chunk visit (case A), the only cost is determining squash, | 522 // For normal chunk visit (case A), the only cost is determining squash, |
| 492 // which costs O(qd), where d came from "canUpcastTo" and geometry mapping. | 523 // which costs O(qd), where d came from "canUpcastTo" and geometry mapping. |
| 493 // Subtotal: O(pqd) | 524 // Subtotal: O(pqd) |
| 494 // For group entering and exiting, it could cost O(d) for each group, for | 525 // For group entering and exiting, it could cost O(d) for each group, for |
| 495 // searching the shallowest subgroup (strictChildOfAlongPath), thus O(d^2) | 526 // searching the shallowest subgroup (strictChildOfAlongPath), thus O(d^2) |
| 496 // in total. | 527 // in total. |
| 497 // Also when exiting group, the group may be decomposited and squashed to a | 528 // Also when exiting group, the group may be decomposited and squashed to a |
| 498 // previous layer. Again finding the host costs O(qd). Merging would cost O(p) | 529 // previous layer. Again finding the host costs O(qd). Merging would cost O(p) |
| 499 // due to copying the chunk list. Subtotal: O((qd + p)d) = O(qd^2 + pd) | 530 // due to copying the chunk list. Subtotal: O((qd + p)d) = O(qd^2 + pd) |
| 500 // Assuming p > d, the total complexity would be O(pqd + qd^2 + pd) = O(pqd) | 531 // Assuming p > d, the total complexity would be O(pqd + qd^2 + pd) = O(pqd) |
| 501 while (chunk_it != paint_artifact.PaintChunks().end()) { | 532 while (chunk_it != paint_artifact.PaintChunks().end()) { |
| 502 // Look at the effect node of the next chunk. There are 3 possible cases: | 533 // Look at the effect node of the next chunk. There are 3 possible |
| 534 // cases: | |
| 503 // A. The next chunk belongs to the current group but no subgroup. | 535 // A. The next chunk belongs to the current group but no subgroup. |
| 504 // B. The next chunk does not belong to the current group. | 536 // B. The next chunk does not belong to the current group. |
| 505 // C. The next chunk belongs to some subgroup of the current group. | 537 // C. The next chunk belongs to some subgroup of the current group. |
| 506 const EffectPaintPropertyNode* chunk_effect = | 538 const EffectPaintPropertyNode* chunk_effect = |
| 507 chunk_it->properties.property_tree_state.Effect(); | 539 chunk_it->properties.property_tree_state.Effect(); |
| 540 | |
| 508 if (chunk_effect == ¤t_group) { | 541 if (chunk_effect == ¤t_group) { |
| 509 // Case A: The next chunk belongs to the current group but no subgroup. | 542 // Case A: The next chunk belongs to the current group but no subgroup. |
| 510 bool is_foreign = | 543 bool is_foreign = |
| 511 paint_artifact.GetDisplayItemList()[chunk_it->begin_index] | 544 paint_artifact.GetDisplayItemList()[chunk_it->begin_index] |
| 512 .IsForeignLayer(); | 545 .IsForeignLayer(); |
| 513 pending_layers.push_back(PendingLayer(*chunk_it++, is_foreign)); | 546 pending_layers.push_back(PendingLayer(*chunk_it++, is_foreign)); |
| 514 if (is_foreign) | 547 if (is_foreign) |
| 515 continue; | 548 continue; |
| 516 } else { | 549 } else { |
| 517 const EffectPaintPropertyNode* subgroup = | 550 const EffectPaintPropertyNode* subgroup = |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 659 #ifndef NDEBUG | 692 #ifndef NDEBUG |
| 660 void PaintArtifactCompositor::ShowDebugData() { | 693 void PaintArtifactCompositor::ShowDebugData() { |
| 661 LOG(ERROR) << LayersAsJSON(kLayerTreeIncludesDebugInfo) | 694 LOG(ERROR) << LayersAsJSON(kLayerTreeIncludesDebugInfo) |
| 662 ->ToPrettyJSONString() | 695 ->ToPrettyJSONString() |
| 663 .Utf8() | 696 .Utf8() |
| 664 .data(); | 697 .data(); |
| 665 } | 698 } |
| 666 #endif | 699 #endif |
| 667 | 700 |
| 668 } // namespace blink | 701 } // namespace blink |
| OLD | NEW |