Index: third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp |
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp |
index 4f4e0b6ebdf40e13698a02cdfb634c2af9d1f15a..adb897f8eb120c0682d2e04bdd81f186c9b7d6e0 100644 |
--- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp |
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp |
@@ -474,11 +474,42 @@ bool PaintArtifactCompositor::CanDecompositeEffect( |
return true; |
} |
+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.
|
+ const PaintArtifact& paint_artifact, |
+ const EffectPaintPropertyNode& current_group, |
+ Vector<PaintChunk>::const_iterator& chunk_it) { |
+ // The lower bound of visibility is considered to be 0.0004f < 1/2048. With |
+ // 10-bit color channels (only available on the newest Macs as of 2016; |
+ // otherwise it's 8-bit), we see that an alpha of 1/2048 or less leads to a |
+ // color output of less than 0.5 in all channels, hence not visible. |
+ static const float kMinimumVisibleOpacity = 0.0004f; |
+ if (current_group.Opacity() < kMinimumVisibleOpacity && |
+ !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.
|
+ // Fast-forward to just past the end of the chunk sequence within this |
+ // 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
|
+ while (++chunk_it != paint_artifact.PaintChunks().end()) { |
+ const EffectPaintPropertyNode* current_effect = |
+ chunk_it->properties.property_tree_state.Effect(); |
+ if (current_effect != ¤t_group && |
+ !StrictChildOfAlongPath(¤t_group, current_effect)) { |
+ break; |
+ } |
+ } |
+ return true; |
+ } |
+ return false; |
+} |
+ |
void PaintArtifactCompositor::LayerizeGroup( |
const PaintArtifact& paint_artifact, |
Vector<PendingLayer>& pending_layers, |
const EffectPaintPropertyNode& current_group, |
Vector<PaintChunk>::const_iterator& chunk_it) { |
+ // Skip paint chunks that are effectively invisible due to opacity and don't |
+ // have a direct compositing reason. |
+ if (SkipEffectivelyInvisibleChunks(paint_artifact, current_group, chunk_it)) |
wkorman
2017/04/27 00:02:32
Revised per in person discussion with trchen@ arou
|
+ return; |
+ |
size_t first_layer_in_current_group = pending_layers.size(); |
// The worst case time complexity of the algorithm is O(pqd), where |
// p = the number of paint chunks. |
@@ -499,12 +530,14 @@ void PaintArtifactCompositor::LayerizeGroup( |
// due to copying the chunk list. Subtotal: O((qd + p)d) = O(qd^2 + pd) |
// Assuming p > d, the total complexity would be O(pqd + qd^2 + pd) = O(pqd) |
while (chunk_it != paint_artifact.PaintChunks().end()) { |
- // Look at the effect node of the next chunk. There are 3 possible cases: |
+ // Look at the effect node of the next chunk. There are 3 possible |
+ // cases: |
// A. The next chunk belongs to the current group but no subgroup. |
// B. The next chunk does not belong to the current group. |
// C. The next chunk belongs to some subgroup of the current group. |
const EffectPaintPropertyNode* chunk_effect = |
chunk_it->properties.property_tree_state.Effect(); |
+ |
if (chunk_effect == ¤t_group) { |
// Case A: The next chunk belongs to the current group but no subgroup. |
bool is_foreign = |