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 f0344194d387cffe88dfb9a80c86baf90bcde12d..61a04066ca368fec956f115954ae8d763c1eec9c 100644 |
--- a/third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.cpp |
+++ b/third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.cpp |
@@ -4,18 +4,57 @@ |
#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" |
#include "platform/graphics/CompositorMutator.h" |
#include "wtf/PtrUtil.h" |
-#include <memory> |
namespace blink { |
+namespace { |
+void updateLayerTree(cc::LayerTreeImpl* treeImpl, |
+ uint64_t elementId, |
+ const CompositorMutation* mutation) { |
+ cc::LayerImpl* layer = treeImpl->LayerByElementId( |
flackr
2017/04/03 17:09:19
Since (I'm assuming) the LayerByElementId requires
smcgruer
2017/04/03 19:37:11
Done, but it's real ugly now that we're using bitm
|
+ createCompositorElementId(elementId, CompositorSubElementId::Primary)); |
+ if (layer) { |
+ if (mutation->isOpacityMutated()) { |
+ treeImpl->property_trees()->effect_tree.OnOpacityAnimated( |
+ mutation->opacity(), layer->effect_tree_index(), treeImpl); |
+ } |
+ if (mutation->isTransformMutated()) { |
+ treeImpl->property_trees()->transform_tree.OnTransformAnimated( |
+ gfx::Transform(mutation->transform()), layer->transform_tree_index(), |
+ treeImpl); |
+ } |
+ } |
+ |
+ cc::LayerImpl* scrollLayer = treeImpl->LayerByElementId( |
+ createCompositorElementId(elementId, CompositorSubElementId::Scroll)); |
+ if (scrollLayer) { |
+ gfx::ScrollOffset offset = scrollLayer->CurrentScrollOffset(); |
+ if (mutation->isScrollLeftMutated()) { |
+ offset.set_x(mutation->scrollLeft()); |
+ } |
+ if (mutation->isScrollTopMutated()) { |
+ offset.set_y(mutation->scrollTop()); |
+ } |
+ if (mutation->isScrollLeftMutated() || mutation->isScrollTopMutated()) { |
+ treeImpl->property_trees()->scroll_tree.OnScrollOffsetAnimated( |
+ scrollLayer->id(), scrollLayer->scroll_tree_index(), offset, |
+ treeImpl); |
+ } |
+ } |
+} |
+} // namespace |
CompositorMutatorClient::CompositorMutatorClient( |
CompositorMutator* mutator, |
@@ -39,8 +78,32 @@ bool CompositorMutatorClient::Mutate(base::TimeTicks monotonicTime, |
double monotonicTimeNow = (monotonicTime - base::TimeTicks()).InSecondsF(); |
if (!m_mutations) |
m_mutations = WTF::wrapUnique(new CompositorMutations); |
- CompositorMutableStateProvider compositorState(treeImpl, m_mutations.get()); |
+ |
+ ProxyCompositorMutablePropertiesMap inputPropertiesMap; |
+ snapshotLayerTree(treeImpl, &inputPropertiesMap); |
+ |
+ CompositorMutations newMutations; |
+ CompositorMutableStateProvider compositorState(&inputPropertiesMap, |
+ &newMutations); |
bool shouldReinvoke = m_mutator->mutate(monotonicTimeNow, &compositorState); |
+ |
+ for (const auto& entry : newMutations.map) { |
+ updateLayerTree(treeImpl, entry.key, entry.value.get()); |
+ } |
+ |
+ // Currently ScrollTree:OnScrollOffsetAnimated triggers a main frame begin |
+ // synchronously, which will call TakeMutations causing m_mutations to be |
+ // released. Make sure m_mutations is not null before calling updateMutations. |
+ // TODO(smcgruer): Find a way to avoid triggering a main frame begin here. |
+ if (!m_mutations) |
+ m_mutations = WTF::wrapUnique(new CompositorMutations); |
flackr
2017/04/03 17:09:19
With this patch we could limit this workaround to
smcgruer
2017/04/03 19:37:11
Done
|
+ |
+ // CompositorMutation objects are moved to updateMutations rather than copied |
+ // to reduce the number of allocated objects. |
+ for (auto& entry : newMutations.map) { |
+ updateMutations(entry.key, std::move(entry.value)); |
+ } |
+ |
return shouldReinvoke; |
} |
@@ -55,7 +118,6 @@ base::Closure CompositorMutatorClient::TakeMutations() { |
"CompositorMutatorClient::TakeMutations"); |
if (!m_mutations) |
return base::Closure(); |
- |
return base::Bind(&CompositorMutationsTarget::applyMutations, |
base::Unretained(m_mutationsTarget), |
base::Owned(m_mutations.release())); |
@@ -66,9 +128,86 @@ void CompositorMutatorClient::setNeedsMutate() { |
m_client->SetNeedsMutate(); |
} |
+void CompositorMutatorClient::registerCompositorProxy( |
+ uint64_t proxyId, |
+ uint64_t elementId, |
+ uint32_t mutableProperties) { |
+ TRACE_EVENT0("compositor-worker", |
+ "CompositorMutatorClient::registerCompositorProxy"); |
+ m_inputProperties[proxyId] = std::make_pair(elementId, mutableProperties); |
+} |
+ |
+void CompositorMutatorClient::unregisterCompositorProxy(uint64_t proxyId) { |
+ TRACE_EVENT0("compositor-worker", |
+ "CompositorMutatorClient::unregisterCompositorProxy"); |
+ DCHECK(m_inputProperties.find(proxyId) != m_inputProperties.end()); |
+ m_inputProperties.erase(proxyId); |
+} |
+ |
void CompositorMutatorClient::setMutationsForTesting( |
std::unique_ptr<CompositorMutations> mutations) { |
m_mutations = std::move(mutations); |
} |
+void CompositorMutatorClient::snapshotLayerTree( |
+ const cc::LayerTreeImpl* treeImpl, |
+ ProxyCompositorMutablePropertiesMap* inputMap) const { |
+ for (const auto& it : m_inputProperties) { |
+ uint64_t proxyId = it.first; |
+ const std::pair<uint64_t, uint32_t>& value = it.second; |
+ uint64_t elementId = value.first; |
+ uint32_t properties = value.second; |
+ |
+ cc::LayerImpl* layer = treeImpl->LayerByElementId( |
+ createCompositorElementId(elementId, CompositorSubElementId::Primary)); |
flackr
2017/04/03 17:09:19
Same comment as above.
smcgruer
2017/04/03 19:37:11
Done, though it's a bit ugly to keep the if (!laye
|
+ cc::LayerImpl* scrollLayer = treeImpl->LayerByElementId( |
+ createCompositorElementId(elementId, CompositorSubElementId::Scroll)); |
+ if (!layer && !scrollLayer) |
+ continue; |
+ |
+ (*inputMap)[proxyId].elementId = elementId; |
flackr
2017/04/03 17:09:19
I'm not sure if the repeated calls to (*inputMap)[
smcgruer
2017/04/03 19:37:11
Done, I think.
|
+ (*inputMap)[proxyId].transform = SkMatrix44::I(); |
+ if (layer) { |
+ if (properties & CompositorMutableProperty::kOpacity) { |
+ (*inputMap)[proxyId].opacity = layer->Opacity(); |
+ } |
+ if (properties & CompositorMutableProperty::kTransform) { |
+ (*inputMap)[proxyId].transform = layer->Transform().matrix(); |
+ } |
+ } |
+ if (scrollLayer) { |
+ if (properties & CompositorMutableProperty::kScrollLeft) { |
+ (*inputMap)[proxyId].scrollLeft = |
+ scrollLayer->CurrentScrollOffset().x(); |
+ } |
+ if (properties & CompositorMutableProperty::kScrollTop) { |
+ (*inputMap)[proxyId].scrollTop = scrollLayer->CurrentScrollOffset().y(); |
+ } |
+ } |
+ } |
+} |
+ |
+void CompositorMutatorClient::updateMutations( |
+ uint64_t elementId, |
+ std::unique_ptr<CompositorMutation> mutation) { |
+ if (!m_mutations->map.contains(elementId)) { |
+ m_mutations->map.set(elementId, std::move(mutation)); |
+ return; |
+ } |
+ |
+ CompositorMutation* existingMutation = m_mutations->map.at(elementId); |
+ 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 |