Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp

Issue 2833883003: Skip paint chunks with effectively invisible opacity. (Closed)
Patch Set: Updated per discussion. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 != &current_group &&
494 !StrictChildOfAlongPath(&current_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 == &current_group) { 541 if (chunk_effect == &current_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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698