| 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
|
|
|