Index: third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.cpp |
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.cpp b/third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.cpp |
index 3909529da4e469c11eaf9e72f110b48a52cb6b26..1b33091563c8adcc44e0dff367d3b974999e117d 100644 |
--- a/third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.cpp |
+++ b/third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.cpp |
@@ -5,10 +5,13 @@ |
#include "platform/graphics/CompositorMutatorClient.h" |
#include <memory> |
+ |
#include "base/bind.h" |
#include "base/callback.h" |
#include "base/trace_event/trace_event.h" |
#include "cc/trees/layer_tree_impl.h" |
+#include "cc/trees/scroll_node.h" |
+#include "platform/graphics/CompositorElementId.h" |
#include "platform/graphics/CompositorMutableStateProvider.h" |
#include "platform/graphics/CompositorMutation.h" |
#include "platform/graphics/CompositorMutationsTarget.h" |
@@ -39,9 +42,26 @@ bool CompositorMutatorClient::Mutate(base::TimeTicks monotonic_time, |
double monotonic_time_now = (monotonic_time - base::TimeTicks()).InSecondsF(); |
if (!mutations_) |
mutations_ = WTF::WrapUnique(new CompositorMutations); |
- CompositorMutableStateProvider compositor_state(tree_impl, mutations_.get()); |
+ |
+ ProxyCompositorMutablePropertiesMap input_properties_map; |
+ SnapshotLayerTree(tree_impl, &input_properties_map); |
+ |
+ CompositorMutations new_mutations; |
+ CompositorMutableStateProvider compositor_state(&input_properties_map, |
+ &new_mutations); |
bool should_reinvoke = |
mutator_->Mutate(monotonic_time_now, &compositor_state); |
+ |
+ for (const auto& entry : new_mutations.map) { |
+ UpdateLayerTree(tree_impl, entry.key, entry.value.get()); |
+ } |
+ |
+ // CompositorMutation objects are moved to updateMutations rather than copied |
+ // to reduce the number of allocated objects. |
+ for (auto& entry : new_mutations.map) { |
+ UpdateMutations(entry.key, std::move(entry.value)); |
+ } |
+ |
return should_reinvoke; |
} |
@@ -67,9 +87,153 @@ void CompositorMutatorClient::SetNeedsMutate() { |
client_->SetNeedsMutate(); |
} |
+void CompositorMutatorClient::RegisterCompositorProxy( |
+ uint64_t proxy_id, |
+ uint64_t element_id, |
+ uint32_t mutable_properties) { |
+ TRACE_EVENT0("compositor-worker", |
+ "CompositorMutatorClient::RegisterCompositorProxy"); |
+ input_properties_[proxy_id] = std::make_pair(element_id, mutable_properties); |
+} |
+ |
+void CompositorMutatorClient::UnregisterCompositorProxy(uint64_t proxy_id) { |
+ TRACE_EVENT0("compositor-worker", |
+ "CompositorMutatorClient::UnregisterCompositorProxy"); |
+ DCHECK(input_properties_.find(proxy_id) != input_properties_.end()); |
+ input_properties_.erase(proxy_id); |
+} |
+ |
void CompositorMutatorClient::SetMutationsForTesting( |
std::unique_ptr<CompositorMutations> mutations) { |
mutations_ = std::move(mutations); |
} |
+void CompositorMutatorClient::SnapshotLayerTree( |
+ const cc::LayerTreeImpl* tree_impl, |
+ ProxyCompositorMutablePropertiesMap* input_map) const { |
+ ProxyCompositorMutablePropertiesMap& input_map_ref = *input_map; |
+ for (const auto& it : input_properties_) { |
+ uint64_t proxy_id = it.first; |
+ const std::pair<uint64_t, uint32_t>& value = it.second; |
+ uint64_t element_id = value.first; |
+ uint32_t properties = value.second; |
+ |
+ // Avoid expensive layer lookups by first checking whether any properties |
+ // are being mutated that require that layer. |
+ cc::LayerImpl* layer = nullptr; |
+ cc::LayerImpl* scrollLayer = nullptr; |
+ if (properties & (CompositorMutableProperty::kOpacity | |
+ CompositorMutableProperty::kTransform)) { |
+ layer = tree_impl->LayerByElementId(CreateCompositorElementId( |
+ element_id, CompositorSubElementId::kPrimary)); |
+ } |
+ if (properties & (CompositorMutableProperty::kScrollLeft | |
+ CompositorMutableProperty::kScrollTop)) { |
+ scrollLayer = tree_impl->LayerByElementId(CreateCompositorElementId( |
+ element_id, CompositorSubElementId::kScroll)); |
+ } |
+ |
+ // If the element no longer exists in the layer tree, there is no point |
+ // creating an entry for it. |
+ // TODO(smcgruer): Should we just create a default entry instead? |
+ if (!layer && !scrollLayer) |
+ continue; |
+ |
+ input_map_ref[proxy_id].element_id = element_id; |
+ input_map_ref[proxy_id].transform = SkMatrix44::I(); |
+ if (layer) { |
+ if (properties & CompositorMutableProperty::kOpacity) { |
+ input_map_ref[proxy_id].opacity = layer->Opacity(); |
+ } |
+ if (properties & CompositorMutableProperty::kTransform) { |
+ input_map_ref[proxy_id].transform = layer->Transform().matrix(); |
+ } |
+ } |
+ if (scrollLayer) { |
+ if (properties & CompositorMutableProperty::kScrollLeft) { |
+ input_map_ref[proxy_id].scroll_left = |
+ scrollLayer->CurrentScrollOffset().x(); |
+ } |
+ if (properties & CompositorMutableProperty::kScrollTop) { |
+ input_map_ref[proxy_id].scroll_top = |
+ scrollLayer->CurrentScrollOffset().y(); |
+ } |
+ } |
+ } |
+} |
+ |
+void CompositorMutatorClient::UpdateLayerTree( |
+ cc::LayerTreeImpl* tree_impl, |
+ uint64_t element_id, |
+ const CompositorMutation* mutation) { |
+ uint32_t mutatedProperties = mutation->mutatedProperties(); |
+ |
+ // Avoid expensive layer lookups by checking first whether any relevant |
+ // properties have been mutated. |
+ if (mutatedProperties & (CompositorMutableProperty::kOpacity | |
+ CompositorMutableProperty::kTransform)) { |
+ cc::ElementId compositor_element_id = |
+ CreateCompositorElementId(element_id, CompositorSubElementId::kPrimary); |
+ cc::LayerImpl* layer = tree_impl->LayerByElementId(compositor_element_id); |
+ if (layer) { |
+ if (mutatedProperties & CompositorMutableProperty::kOpacity) { |
+ tree_impl->SetOpacityMutated(compositor_element_id, |
+ mutation->Opacity()); |
+ } |
+ if (mutatedProperties & CompositorMutableProperty::kTransform) { |
+ tree_impl->SetTransformMutated(compositor_element_id, |
+ gfx::Transform(mutation->Transform())); |
+ } |
+ } |
+ } |
+ |
+ if (mutatedProperties & (CompositorMutableProperty::kScrollLeft | |
+ CompositorMutableProperty::kScrollTop)) { |
+ cc::LayerImpl* scrollLayer = tree_impl->LayerByElementId( |
+ CreateCompositorElementId(element_id, CompositorSubElementId::kScroll)); |
+ if (scrollLayer) { |
+ gfx::ScrollOffset offset = scrollLayer->CurrentScrollOffset(); |
+ if (mutatedProperties & CompositorMutableProperty::kScrollLeft) { |
+ offset.set_x(mutation->ScrollLeft()); |
+ } |
+ if (mutatedProperties & CompositorMutableProperty::kScrollTop) { |
+ offset.set_y(mutation->ScrollTop()); |
+ } |
+ tree_impl->property_trees()->scroll_tree.OnScrollOffsetAnimated( |
+ scrollLayer->id(), scrollLayer->scroll_tree_index(), offset, |
+ tree_impl); |
+ |
+ // ScrollTree:OnScrollOffsetAnimated triggers a synchronous main frame |
+ // begin that calls TakeMutations and causes mutations_ to be released. |
+ // Restore mutations_ for the later call to |updateMutations|. |
+ // TODO(smcgruer): Find a way to avoid triggering a main frame begin here. |
+ DCHECK(!mutations_); |
+ mutations_ = WTF::WrapUnique(new CompositorMutations); |
+ } |
+ } |
+} |
+ |
+void CompositorMutatorClient::UpdateMutations( |
+ uint64_t element_id, |
+ std::unique_ptr<CompositorMutation> mutation) { |
+ if (!mutations_->map.Contains(element_id)) { |
+ mutations_->map.Set(element_id, std::move(mutation)); |
+ return; |
+ } |
+ |
+ CompositorMutation* existingMutation = mutations_->map.at(element_id); |
+ if (mutation->IsOpacityMutated()) { |
+ existingMutation->SetOpacity(mutation->Opacity()); |
+ } |
+ if (mutation->IsTransformMutated()) { |
+ existingMutation->SetTransform(mutation->Transform()); |
+ } |
+ if (mutation->IsScrollTopMutated()) { |
+ existingMutation->SetScrollTop(mutation->ScrollTop()); |
+ } |
+ if (mutation->IsScrollLeftMutated()) { |
+ existingMutation->SetScrollLeft(mutation->ScrollLeft()); |
+ } |
+} |
+ |
} // namespace blink |