OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/CompositorMutatorClient.h" | 5 #include "platform/graphics/CompositorMutatorClient.h" |
6 | 6 |
7 #include <memory> | |
8 | |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/callback.h" | 10 #include "base/callback.h" |
9 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
10 #include "cc/trees/layer_tree_impl.h" | 12 #include "cc/trees/layer_tree_impl.h" |
13 #include "cc/trees/scroll_node.h" | |
14 #include "platform/graphics/CompositorElementId.h" | |
11 #include "platform/graphics/CompositorMutableStateProvider.h" | 15 #include "platform/graphics/CompositorMutableStateProvider.h" |
12 #include "platform/graphics/CompositorMutation.h" | 16 #include "platform/graphics/CompositorMutation.h" |
13 #include "platform/graphics/CompositorMutationsTarget.h" | 17 #include "platform/graphics/CompositorMutationsTarget.h" |
14 #include "platform/graphics/CompositorMutator.h" | 18 #include "platform/graphics/CompositorMutator.h" |
15 #include "wtf/PtrUtil.h" | 19 #include "wtf/PtrUtil.h" |
16 #include <memory> | |
17 | 20 |
18 namespace blink { | 21 namespace blink { |
22 namespace { | |
23 void updateLayerTree(cc::LayerTreeImpl* treeImpl, | |
24 uint64_t elementId, | |
25 const CompositorMutation* mutation) { | |
26 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
| |
27 createCompositorElementId(elementId, CompositorSubElementId::Primary)); | |
28 if (layer) { | |
29 if (mutation->isOpacityMutated()) { | |
30 treeImpl->property_trees()->effect_tree.OnOpacityAnimated( | |
31 mutation->opacity(), layer->effect_tree_index(), treeImpl); | |
32 } | |
33 if (mutation->isTransformMutated()) { | |
34 treeImpl->property_trees()->transform_tree.OnTransformAnimated( | |
35 gfx::Transform(mutation->transform()), layer->transform_tree_index(), | |
36 treeImpl); | |
37 } | |
38 } | |
39 | |
40 cc::LayerImpl* scrollLayer = treeImpl->LayerByElementId( | |
41 createCompositorElementId(elementId, CompositorSubElementId::Scroll)); | |
42 if (scrollLayer) { | |
43 gfx::ScrollOffset offset = scrollLayer->CurrentScrollOffset(); | |
44 if (mutation->isScrollLeftMutated()) { | |
45 offset.set_x(mutation->scrollLeft()); | |
46 } | |
47 if (mutation->isScrollTopMutated()) { | |
48 offset.set_y(mutation->scrollTop()); | |
49 } | |
50 if (mutation->isScrollLeftMutated() || mutation->isScrollTopMutated()) { | |
51 treeImpl->property_trees()->scroll_tree.OnScrollOffsetAnimated( | |
52 scrollLayer->id(), scrollLayer->scroll_tree_index(), offset, | |
53 treeImpl); | |
54 } | |
55 } | |
56 } | |
57 } // namespace | |
19 | 58 |
20 CompositorMutatorClient::CompositorMutatorClient( | 59 CompositorMutatorClient::CompositorMutatorClient( |
21 CompositorMutator* mutator, | 60 CompositorMutator* mutator, |
22 CompositorMutationsTarget* mutationsTarget) | 61 CompositorMutationsTarget* mutationsTarget) |
23 : m_client(nullptr), | 62 : m_client(nullptr), |
24 m_mutationsTarget(mutationsTarget), | 63 m_mutationsTarget(mutationsTarget), |
25 m_mutator(mutator), | 64 m_mutator(mutator), |
26 m_mutations(nullptr) { | 65 m_mutations(nullptr) { |
27 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), | 66 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), |
28 "CompositorMutatorClient::CompositorMutatorClient"); | 67 "CompositorMutatorClient::CompositorMutatorClient"); |
29 } | 68 } |
30 | 69 |
31 CompositorMutatorClient::~CompositorMutatorClient() { | 70 CompositorMutatorClient::~CompositorMutatorClient() { |
32 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), | 71 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), |
33 "CompositorMutatorClient::~CompositorMutatorClient"); | 72 "CompositorMutatorClient::~CompositorMutatorClient"); |
34 } | 73 } |
35 | 74 |
36 bool CompositorMutatorClient::Mutate(base::TimeTicks monotonicTime, | 75 bool CompositorMutatorClient::Mutate(base::TimeTicks monotonicTime, |
37 cc::LayerTreeImpl* treeImpl) { | 76 cc::LayerTreeImpl* treeImpl) { |
38 TRACE_EVENT0("compositor-worker", "CompositorMutatorClient::Mutate"); | 77 TRACE_EVENT0("compositor-worker", "CompositorMutatorClient::Mutate"); |
39 double monotonicTimeNow = (monotonicTime - base::TimeTicks()).InSecondsF(); | 78 double monotonicTimeNow = (monotonicTime - base::TimeTicks()).InSecondsF(); |
40 if (!m_mutations) | 79 if (!m_mutations) |
41 m_mutations = WTF::wrapUnique(new CompositorMutations); | 80 m_mutations = WTF::wrapUnique(new CompositorMutations); |
42 CompositorMutableStateProvider compositorState(treeImpl, m_mutations.get()); | 81 |
82 ProxyCompositorMutablePropertiesMap inputPropertiesMap; | |
83 snapshotLayerTree(treeImpl, &inputPropertiesMap); | |
84 | |
85 CompositorMutations newMutations; | |
86 CompositorMutableStateProvider compositorState(&inputPropertiesMap, | |
87 &newMutations); | |
43 bool shouldReinvoke = m_mutator->mutate(monotonicTimeNow, &compositorState); | 88 bool shouldReinvoke = m_mutator->mutate(monotonicTimeNow, &compositorState); |
89 | |
90 for (const auto& entry : newMutations.map) { | |
91 updateLayerTree(treeImpl, entry.key, entry.value.get()); | |
92 } | |
93 | |
94 // Currently ScrollTree:OnScrollOffsetAnimated triggers a main frame begin | |
95 // synchronously, which will call TakeMutations causing m_mutations to be | |
96 // released. Make sure m_mutations is not null before calling updateMutations. | |
97 // TODO(smcgruer): Find a way to avoid triggering a main frame begin here. | |
98 if (!m_mutations) | |
99 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
| |
100 | |
101 // CompositorMutation objects are moved to updateMutations rather than copied | |
102 // to reduce the number of allocated objects. | |
103 for (auto& entry : newMutations.map) { | |
104 updateMutations(entry.key, std::move(entry.value)); | |
105 } | |
106 | |
44 return shouldReinvoke; | 107 return shouldReinvoke; |
45 } | 108 } |
46 | 109 |
47 void CompositorMutatorClient::SetClient(cc::LayerTreeMutatorClient* client) { | 110 void CompositorMutatorClient::SetClient(cc::LayerTreeMutatorClient* client) { |
48 TRACE_EVENT0("compositor-worker", "CompositorMutatorClient::SetClient"); | 111 TRACE_EVENT0("compositor-worker", "CompositorMutatorClient::SetClient"); |
49 m_client = client; | 112 m_client = client; |
50 setNeedsMutate(); | 113 setNeedsMutate(); |
51 } | 114 } |
52 | 115 |
53 base::Closure CompositorMutatorClient::TakeMutations() { | 116 base::Closure CompositorMutatorClient::TakeMutations() { |
54 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), | 117 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("compositor-worker"), |
55 "CompositorMutatorClient::TakeMutations"); | 118 "CompositorMutatorClient::TakeMutations"); |
56 if (!m_mutations) | 119 if (!m_mutations) |
57 return base::Closure(); | 120 return base::Closure(); |
58 | |
59 return base::Bind(&CompositorMutationsTarget::applyMutations, | 121 return base::Bind(&CompositorMutationsTarget::applyMutations, |
60 base::Unretained(m_mutationsTarget), | 122 base::Unretained(m_mutationsTarget), |
61 base::Owned(m_mutations.release())); | 123 base::Owned(m_mutations.release())); |
62 } | 124 } |
63 | 125 |
64 void CompositorMutatorClient::setNeedsMutate() { | 126 void CompositorMutatorClient::setNeedsMutate() { |
65 TRACE_EVENT0("compositor-worker", "CompositorMutatorClient::setNeedsMutate"); | 127 TRACE_EVENT0("compositor-worker", "CompositorMutatorClient::setNeedsMutate"); |
66 m_client->SetNeedsMutate(); | 128 m_client->SetNeedsMutate(); |
67 } | 129 } |
68 | 130 |
131 void CompositorMutatorClient::registerCompositorProxy( | |
132 uint64_t proxyId, | |
133 uint64_t elementId, | |
134 uint32_t mutableProperties) { | |
135 TRACE_EVENT0("compositor-worker", | |
136 "CompositorMutatorClient::registerCompositorProxy"); | |
137 m_inputProperties[proxyId] = std::make_pair(elementId, mutableProperties); | |
138 } | |
139 | |
140 void CompositorMutatorClient::unregisterCompositorProxy(uint64_t proxyId) { | |
141 TRACE_EVENT0("compositor-worker", | |
142 "CompositorMutatorClient::unregisterCompositorProxy"); | |
143 DCHECK(m_inputProperties.find(proxyId) != m_inputProperties.end()); | |
144 m_inputProperties.erase(proxyId); | |
145 } | |
146 | |
69 void CompositorMutatorClient::setMutationsForTesting( | 147 void CompositorMutatorClient::setMutationsForTesting( |
70 std::unique_ptr<CompositorMutations> mutations) { | 148 std::unique_ptr<CompositorMutations> mutations) { |
71 m_mutations = std::move(mutations); | 149 m_mutations = std::move(mutations); |
72 } | 150 } |
73 | 151 |
152 void CompositorMutatorClient::snapshotLayerTree( | |
153 const cc::LayerTreeImpl* treeImpl, | |
154 ProxyCompositorMutablePropertiesMap* inputMap) const { | |
155 for (const auto& it : m_inputProperties) { | |
156 uint64_t proxyId = it.first; | |
157 const std::pair<uint64_t, uint32_t>& value = it.second; | |
158 uint64_t elementId = value.first; | |
159 uint32_t properties = value.second; | |
160 | |
161 cc::LayerImpl* layer = treeImpl->LayerByElementId( | |
162 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
| |
163 cc::LayerImpl* scrollLayer = treeImpl->LayerByElementId( | |
164 createCompositorElementId(elementId, CompositorSubElementId::Scroll)); | |
165 if (!layer && !scrollLayer) | |
166 continue; | |
167 | |
168 (*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.
| |
169 (*inputMap)[proxyId].transform = SkMatrix44::I(); | |
170 if (layer) { | |
171 if (properties & CompositorMutableProperty::kOpacity) { | |
172 (*inputMap)[proxyId].opacity = layer->Opacity(); | |
173 } | |
174 if (properties & CompositorMutableProperty::kTransform) { | |
175 (*inputMap)[proxyId].transform = layer->Transform().matrix(); | |
176 } | |
177 } | |
178 if (scrollLayer) { | |
179 if (properties & CompositorMutableProperty::kScrollLeft) { | |
180 (*inputMap)[proxyId].scrollLeft = | |
181 scrollLayer->CurrentScrollOffset().x(); | |
182 } | |
183 if (properties & CompositorMutableProperty::kScrollTop) { | |
184 (*inputMap)[proxyId].scrollTop = scrollLayer->CurrentScrollOffset().y(); | |
185 } | |
186 } | |
187 } | |
188 } | |
189 | |
190 void CompositorMutatorClient::updateMutations( | |
191 uint64_t elementId, | |
192 std::unique_ptr<CompositorMutation> mutation) { | |
193 if (!m_mutations->map.contains(elementId)) { | |
194 m_mutations->map.set(elementId, std::move(mutation)); | |
195 return; | |
196 } | |
197 | |
198 CompositorMutation* existingMutation = m_mutations->map.at(elementId); | |
199 if (mutation->isOpacityMutated()) { | |
200 existingMutation->setOpacity(mutation->opacity()); | |
201 } | |
202 if (mutation->isTransformMutated()) { | |
203 existingMutation->setTransform(mutation->transform()); | |
204 } | |
205 if (mutation->isScrollTopMutated()) { | |
206 existingMutation->setScrollTop(mutation->scrollTop()); | |
207 } | |
208 if (mutation->isScrollLeftMutated()) { | |
209 existingMutation->setScrollLeft(mutation->scrollLeft()); | |
210 } | |
211 } | |
212 | |
74 } // namespace blink | 213 } // namespace blink |
OLD | NEW |