OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "config.h" | 5 #include "config.h" |
6 #include "core/dom/CompositorProxy.h" | 6 #include "core/dom/CompositorProxy.h" |
7 | 7 |
8 #include "bindings/core/v8/ExceptionMessages.h" | 8 #include "bindings/core/v8/ExceptionMessages.h" |
9 #include "bindings/core/v8/ExceptionState.h" | 9 #include "bindings/core/v8/ExceptionState.h" |
10 #include "core/dom/DOMNodeIds.h" | 10 #include "core/dom/DOMNodeIds.h" |
11 #include "core/dom/ExceptionCode.h" | 11 #include "core/dom/ExceptionCode.h" |
12 #include "core/dom/ExecutionContext.h" | 12 #include "core/dom/ExecutionContext.h" |
13 #include "platform/ThreadSafeFunctional.h" | 13 #include "platform/ThreadSafeFunctional.h" |
14 #include "public/platform/Platform.h" | 14 #include "public/platform/Platform.h" |
15 #include "public/platform/WebCompositorMutableProperties.h" | |
15 #include "public/platform/WebTraceLocation.h" | 16 #include "public/platform/WebTraceLocation.h" |
16 | 17 |
17 namespace blink { | 18 namespace blink { |
18 | 19 |
19 struct AttributeFlagMapping { | 20 struct MutablePropertyMapping { |
20 const char* name; | 21 const char* name; |
21 unsigned length; | 22 unsigned length; |
22 CompositorProxy::Attributes attribute; | 23 WebCompositorMutableProperty compositorMutableProperty; |
esprehn
2015/12/02 03:28:48
I would just call this "property"
| |
23 }; | 24 }; |
24 | 25 |
25 static AttributeFlagMapping allowedAttributes[] = { | 26 static MutablePropertyMapping allowedProperties[] = { |
26 { "opacity", 7, CompositorProxy::Attributes::OPACITY }, | 27 { "opacity", 7, WebCompositorMutablePropertyOpacity }, |
27 { "scrollleft", 10, CompositorProxy::Attributes::SCROLL_LEFT }, | 28 { "scrollleft", 10, WebCompositorMutablePropertyScrollLeft }, |
28 { "scrolltop", 9, CompositorProxy::Attributes::SCROLL_TOP }, | 29 { "scrolltop", 9, WebCompositorMutablePropertyScrollTop }, |
29 { "touch", 5, CompositorProxy::Attributes::TOUCH }, | 30 { "transform", 9, WebCompositorMutablePropertyTransform }, |
30 { "transform", 8, CompositorProxy::Attributes::TRANSFORM }, | |
31 }; | 31 }; |
32 | 32 |
33 static bool CompareAttributeName(const AttributeFlagMapping& attribute, StringIm pl* attributeLower) | 33 static WebCompositorMutableProperty compositorMutablePropertyForName(const Strin g& attributeName) |
34 { | 34 { |
35 ASSERT(attributeLower->is8Bit()); | 35 String attributeLower = attributeName.lower(); |
36 return memcmp(attribute.name, attributeLower->characters8(), std::min(attrib ute.length, attributeLower->length())) < 0; | 36 for (size_t i = 0; i < WTF_ARRAY_LENGTH(allowedProperties); ++i) { |
37 } | 37 const MutablePropertyMapping& mapping = allowedProperties[i]; |
38 | 38 String propertyName(mapping.name, mapping.length); |
esprehn
2015/12/02 03:28:48
this mallocs a string repeatedly as you loop, don'
Ian Vollick
2015/12/03 17:54:43
Done. There was a bug here (crbug.com/531577). I'v
| |
39 static CompositorProxy::Attributes attributeFlagForName(const String& attributeN ame) | 39 if (propertyName == attributeLower) |
40 { | 40 return mapping.compositorMutableProperty; |
41 CompositorProxy::Attributes attributeFlag = CompositorProxy::Attributes::NON E; | |
42 const String attributeLower = attributeName.lower(); | |
43 const AttributeFlagMapping* start = allowedAttributes; | |
44 const AttributeFlagMapping* end = allowedAttributes + WTF_ARRAY_LENGTH(allow edAttributes); | |
45 if (attributeLower.impl()->is8Bit()) { | |
46 const AttributeFlagMapping* match = std::lower_bound(start, end, attribu teLower.impl(), CompareAttributeName); | |
47 if (match != end) | |
48 attributeFlag = match->attribute; | |
49 } | 41 } |
50 return attributeFlag; | 42 return WebCompositorMutablePropertyNone; |
51 } | 43 } |
52 | 44 |
53 static bool isControlThread() | 45 static bool isControlThread() |
54 { | 46 { |
55 return !isMainThread(); | 47 return !isMainThread(); |
56 } | 48 } |
57 | 49 |
58 static bool isCallingCompositorFrameCallback() | 50 static bool isCallingCompositorFrameCallback() |
59 { | 51 { |
60 // TODO(sad): Check that the requestCompositorFrame callbacks are currently being called. | 52 // TODO(sad): Check that the requestCompositorFrame callbacks are currently being called. |
61 return true; | 53 return true; |
62 } | 54 } |
63 | 55 |
64 static void decrementCountForElement(uint64_t elementId) | 56 static void decrementProxiedPropertyCountsForElement(uint64_t elementId, uint32_ t compositorMutableProperties) |
65 { | 57 { |
66 ASSERT(isMainThread()); | 58 ASSERT(isMainThread()); |
67 Node* node = DOMNodeIds::nodeForId(elementId); | 59 Node* node = DOMNodeIds::nodeForId(elementId); |
68 if (!node) | 60 if (!node) |
69 return; | 61 return; |
70 Element* element = toElement(node); | 62 Element* element = toElement(node); |
71 element->decrementProxyCount(); | 63 element->decrementProxiedPropertyCounts(compositorMutableProperties); |
72 } | 64 } |
73 | 65 |
74 static void incrementProxyCountForElement(uint64_t elementId) | 66 static void incrementProxiedPropertyCountsForElement(uint64_t elementId, uint32_ t compositorMutableProperties) |
75 { | 67 { |
76 ASSERT(isMainThread()); | 68 ASSERT(isMainThread()); |
77 Node* node = DOMNodeIds::nodeForId(elementId); | 69 Node* node = DOMNodeIds::nodeForId(elementId); |
78 if (!node) | 70 if (!node) |
79 return; | 71 return; |
80 Element* element = toElement(node); | 72 Element* element = toElement(node); |
81 element->incrementProxyCount(); | 73 element->incrementProxiedPropertyCounts(compositorMutableProperties); |
82 } | 74 } |
83 | 75 |
84 static bool raiseExceptionIfMutationNotAllowed(ExceptionState& exceptionState) | 76 static bool raiseExceptionIfMutationNotAllowed(ExceptionState& exceptionState) |
85 { | 77 { |
86 if (!isControlThread()) { | 78 if (!isControlThread()) { |
87 exceptionState.throwDOMException(NoModificationAllowedError, "Cannot mut ate a proxy attribute from the main page."); | 79 exceptionState.throwDOMException(NoModificationAllowedError, "Cannot mut ate a proxy attribute from the main page."); |
88 return true; | 80 return true; |
89 } | 81 } |
90 if (!isCallingCompositorFrameCallback()) { | 82 if (!isCallingCompositorFrameCallback()) { |
91 exceptionState.throwDOMException(NoModificationAllowedError, "Cannot mut ate a proxy attribute outside of a requestCompositorFrame callback."); | 83 exceptionState.throwDOMException(NoModificationAllowedError, "Cannot mut ate a proxy attribute outside of a requestCompositorFrame callback."); |
92 return true; | 84 return true; |
93 } | 85 } |
94 return false; | 86 return false; |
95 } | 87 } |
96 | 88 |
97 static uint32_t attributesBitfieldFromNames(const Vector<String>& attributeArray ) | 89 static uint32_t compositorMutablePropertiesFromNames(const Vector<String>& attri buteArray) |
98 { | 90 { |
99 uint32_t attributesBitfield = 0; | 91 uint32_t compositorMutableProperties = 0; |
esprehn
2015/12/02 03:28:48
you can name your local vars a lot shorter if you
Ian Vollick
2015/12/03 17:54:43
Done.
| |
100 for (const auto& attribute : attributeArray) { | 92 for (const auto& attribute : attributeArray) { |
101 attributesBitfield |= static_cast<uint32_t>(attributeFlagForName(attribu te)); | 93 compositorMutableProperties |= static_cast<uint32_t>(compositorMutablePr opertyForName(attribute)); |
102 } | 94 } |
103 return attributesBitfield; | 95 return compositorMutableProperties; |
104 } | 96 } |
105 | 97 |
106 #if ENABLE(ASSERT) | 98 #if ENABLE(ASSERT) |
107 static bool sanityCheckAttributeFlags(uint32_t attributeFlags) | 99 static bool sanityCheckMutableProperties(uint32_t compositorMutableProperties) |
108 { | 100 { |
109 uint32_t sanityCheckAttributes = attributeFlags; | 101 // Ensures that we only have bits set for valid mutable properties. |
110 for (unsigned i = 0; i < arraysize(allowedAttributes); ++i) { | 102 uint32_t sanityCheckProperties = compositorMutableProperties; |
111 sanityCheckAttributes &= ~static_cast<uint32_t>(allowedAttributes[i].att ribute); | 103 for (unsigned i = 0; i < arraysize(allowedProperties); ++i) { |
104 sanityCheckProperties &= ~static_cast<uint32_t>(allowedProperties[i].com positorMutableProperty); | |
112 } | 105 } |
113 return !sanityCheckAttributes; | 106 return !sanityCheckProperties; |
114 } | 107 } |
115 #endif | 108 #endif |
116 | 109 |
117 CompositorProxy* CompositorProxy::create(ExecutionContext* context, Element* ele ment, const Vector<String>& attributeArray, ExceptionState& exceptionState) | 110 CompositorProxy* CompositorProxy::create(ExecutionContext* context, Element* ele ment, const Vector<String>& attributeArray, ExceptionState& exceptionState) |
118 { | 111 { |
119 if (!context->isDocument()) { | 112 if (!context->isDocument()) { |
120 exceptionState.throwTypeError(ExceptionMessages::failedToConstruct("Comp ositorProxy", "Can only be created from the main context.")); | 113 exceptionState.throwTypeError(ExceptionMessages::failedToConstruct("Comp ositorProxy", "Can only be created from the main context.")); |
121 exceptionState.throwIfNeeded(); | 114 exceptionState.throwIfNeeded(); |
122 return nullptr; | 115 return nullptr; |
123 } | 116 } |
124 | 117 |
125 return new CompositorProxy(*element, attributeArray); | 118 return new CompositorProxy(*element, attributeArray); |
126 } | 119 } |
127 | 120 |
128 CompositorProxy* CompositorProxy::create(uint64_t elementId, uint32_t attributeF lags) | 121 CompositorProxy* CompositorProxy::create(uint64_t elementId, uint32_t compositor MutableProperties) |
129 { | 122 { |
130 return new CompositorProxy(elementId, attributeFlags); | 123 return new CompositorProxy(elementId, compositorMutableProperties); |
131 } | 124 } |
132 | 125 |
133 CompositorProxy::CompositorProxy(Element& element, const Vector<String>& attribu teArray) | 126 CompositorProxy::CompositorProxy(Element& element, const Vector<String>& attribu teArray) |
134 : m_elementId(DOMNodeIds::idForNode(&element)) | 127 : m_elementId(DOMNodeIds::idForNode(&element)) |
135 , m_bitfieldsSupported(attributesBitfieldFromNames(attributeArray)) | 128 , m_compositorMutableProperties(compositorMutablePropertiesFromNames(attribu teArray)) |
136 { | 129 { |
137 ASSERT(isMainThread()); | 130 ASSERT(isMainThread()); |
138 ASSERT(m_bitfieldsSupported); | 131 ASSERT(m_compositorMutableProperties); |
139 ASSERT(sanityCheckAttributeFlags(m_bitfieldsSupported)); | 132 ASSERT(sanityCheckMutableProperties(m_compositorMutableProperties)); |
140 | 133 |
141 incrementProxyCountForElement(m_elementId); | 134 incrementProxiedPropertyCountsForElement(m_elementId, m_compositorMutablePro perties); |
142 } | 135 } |
143 | 136 |
144 CompositorProxy::CompositorProxy(uint64_t elementId, uint32_t attributeFlags) | 137 CompositorProxy::CompositorProxy(uint64_t elementId, uint32_t compositorMutableP roperties) |
145 : m_elementId(elementId) | 138 : m_elementId(elementId) |
146 , m_bitfieldsSupported(attributeFlags) | 139 , m_compositorMutableProperties(compositorMutableProperties) |
147 { | 140 { |
148 ASSERT(isControlThread()); | 141 ASSERT(isControlThread()); |
149 ASSERT(sanityCheckAttributeFlags(m_bitfieldsSupported)); | 142 ASSERT(sanityCheckMutableProperties(m_compositorMutableProperties)); |
150 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, t hreadSafeBind(&incrementProxyCountForElement, m_elementId)); | 143 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE, t hreadSafeBind(&incrementProxiedPropertyCountsForElement, m_elementId, m_composit orMutableProperties)); |
151 } | 144 } |
152 | 145 |
153 CompositorProxy::~CompositorProxy() | 146 CompositorProxy::~CompositorProxy() |
154 { | 147 { |
155 if (m_connected) | 148 if (m_connected) |
156 disconnect(); | 149 disconnect(); |
157 } | 150 } |
158 | 151 |
159 bool CompositorProxy::supports(const String& attributeName) const | 152 bool CompositorProxy::supports(const String& attributeName) const |
160 { | 153 { |
161 return !!(m_bitfieldsSupported & static_cast<uint32_t>(attributeFlagForName( attributeName))); | 154 return !!(m_compositorMutableProperties & static_cast<uint32_t>(compositorMu tablePropertyForName(attributeName))); |
162 } | 155 } |
163 | 156 |
164 double CompositorProxy::opacity(ExceptionState& exceptionState) const | 157 double CompositorProxy::opacity(ExceptionState& exceptionState) const |
165 { | 158 { |
166 if (raiseExceptionIfMutationNotAllowed(exceptionState)) | 159 if (raiseExceptionIfMutationNotAllowed(exceptionState)) |
167 return 0.0; | 160 return 0.0; |
168 if (raiseExceptionIfNotMutable(Attributes::OPACITY, exceptionState)) | 161 if (raiseExceptionIfNotMutable(static_cast<uint32_t>(WebCompositorMutablePro pertyOpacity), exceptionState)) |
169 return 0.0; | 162 return 0.0; |
170 return m_opacity; | 163 return m_opacity; |
171 } | 164 } |
172 | 165 |
173 double CompositorProxy::scrollLeft(ExceptionState& exceptionState) const | 166 double CompositorProxy::scrollLeft(ExceptionState& exceptionState) const |
174 { | 167 { |
175 if (raiseExceptionIfMutationNotAllowed(exceptionState)) | 168 if (raiseExceptionIfMutationNotAllowed(exceptionState)) |
176 return 0.0; | 169 return 0.0; |
177 if (raiseExceptionIfNotMutable(Attributes::SCROLL_LEFT, exceptionState)) | 170 if (raiseExceptionIfNotMutable(static_cast<uint32_t>(WebCompositorMutablePro pertyScrollLeft), exceptionState)) |
178 return 0.0; | 171 return 0.0; |
179 return m_scrollLeft; | 172 return m_scrollLeft; |
180 } | 173 } |
181 | 174 |
182 double CompositorProxy::scrollTop(ExceptionState& exceptionState) const | 175 double CompositorProxy::scrollTop(ExceptionState& exceptionState) const |
183 { | 176 { |
184 if (raiseExceptionIfMutationNotAllowed(exceptionState)) | 177 if (raiseExceptionIfMutationNotAllowed(exceptionState)) |
185 return 0.0; | 178 return 0.0; |
186 if (raiseExceptionIfNotMutable(Attributes::SCROLL_TOP, exceptionState)) | 179 if (raiseExceptionIfNotMutable(static_cast<uint32_t>(WebCompositorMutablePro pertyScrollTop), exceptionState)) |
187 return 0.0; | 180 return 0.0; |
188 return m_scrollTop; | 181 return m_scrollTop; |
189 } | 182 } |
190 | 183 |
191 DOMMatrix* CompositorProxy::transform(ExceptionState& exceptionState) const | 184 DOMMatrix* CompositorProxy::transform(ExceptionState& exceptionState) const |
192 { | 185 { |
193 if (raiseExceptionIfMutationNotAllowed(exceptionState)) | 186 if (raiseExceptionIfMutationNotAllowed(exceptionState)) |
194 return nullptr; | 187 return nullptr; |
195 if (raiseExceptionIfNotMutable(Attributes::TRANSFORM, exceptionState)) | 188 if (raiseExceptionIfNotMutable(static_cast<uint32_t>(WebCompositorMutablePro pertyTransform), exceptionState)) |
196 return nullptr; | 189 return nullptr; |
197 return m_transform; | 190 return m_transform; |
198 } | 191 } |
199 | 192 |
200 void CompositorProxy::setOpacity(double opacity, ExceptionState& exceptionState) | 193 void CompositorProxy::setOpacity(double opacity, ExceptionState& exceptionState) |
201 { | 194 { |
202 if (raiseExceptionIfMutationNotAllowed(exceptionState)) | 195 if (raiseExceptionIfMutationNotAllowed(exceptionState)) |
203 return; | 196 return; |
204 if (raiseExceptionIfNotMutable(Attributes::OPACITY, exceptionState)) | 197 if (raiseExceptionIfNotMutable(static_cast<uint32_t>(WebCompositorMutablePro pertyOpacity), exceptionState)) |
205 return; | 198 return; |
206 m_opacity = std::min(1., std::max(0., opacity)); | 199 m_opacity = std::min(1., std::max(0., opacity)); |
207 m_mutatedAttributes |= static_cast<uint32_t>(Attributes::OPACITY); | 200 m_mutatedProperties |= static_cast<uint32_t>(WebCompositorMutablePropertyTra nsform); |
208 } | 201 } |
209 | 202 |
210 void CompositorProxy::setScrollLeft(double scrollLeft, ExceptionState& exception State) | 203 void CompositorProxy::setScrollLeft(double scrollLeft, ExceptionState& exception State) |
211 { | 204 { |
212 if (raiseExceptionIfMutationNotAllowed(exceptionState)) | 205 if (raiseExceptionIfMutationNotAllowed(exceptionState)) |
213 return; | 206 return; |
214 if (raiseExceptionIfNotMutable(Attributes::SCROLL_LEFT, exceptionState)) | 207 if (raiseExceptionIfNotMutable(static_cast<uint32_t>(WebCompositorMutablePro pertyScrollLeft), exceptionState)) |
215 return; | 208 return; |
216 m_scrollLeft = scrollLeft; | 209 m_scrollLeft = scrollLeft; |
217 m_mutatedAttributes |= static_cast<uint32_t>(Attributes::SCROLL_LEFT); | 210 m_mutatedProperties |= static_cast<uint32_t>(WebCompositorMutablePropertyScr ollLeft); |
218 } | 211 } |
219 | 212 |
220 void CompositorProxy::setScrollTop(double scrollTop, ExceptionState& exceptionSt ate) | 213 void CompositorProxy::setScrollTop(double scrollTop, ExceptionState& exceptionSt ate) |
221 { | 214 { |
222 if (raiseExceptionIfMutationNotAllowed(exceptionState)) | 215 if (raiseExceptionIfMutationNotAllowed(exceptionState)) |
223 return; | 216 return; |
224 if (raiseExceptionIfNotMutable(Attributes::SCROLL_TOP, exceptionState)) | 217 if (raiseExceptionIfNotMutable(static_cast<uint32_t>(WebCompositorMutablePro pertyScrollTop), exceptionState)) |
225 return; | 218 return; |
226 m_scrollTop = scrollTop; | 219 m_scrollTop = scrollTop; |
227 m_mutatedAttributes |= static_cast<uint32_t>(Attributes::SCROLL_TOP); | 220 m_mutatedProperties |= static_cast<uint32_t>(WebCompositorMutablePropertyScr ollTop); |
228 } | 221 } |
229 | 222 |
230 void CompositorProxy::setTransform(DOMMatrix* transform, ExceptionState& excepti onState) | 223 void CompositorProxy::setTransform(DOMMatrix* transform, ExceptionState& excepti onState) |
231 { | 224 { |
232 if (raiseExceptionIfMutationNotAllowed(exceptionState)) | 225 if (raiseExceptionIfMutationNotAllowed(exceptionState)) |
233 return; | 226 return; |
234 if (raiseExceptionIfNotMutable(Attributes::TRANSFORM, exceptionState)) | 227 if (raiseExceptionIfNotMutable(static_cast<uint32_t>(WebCompositorMutablePro pertyTransform), exceptionState)) |
235 return; | 228 return; |
236 m_transform = transform; | 229 m_transform = transform; |
237 m_mutatedAttributes |= static_cast<uint32_t>(Attributes::TRANSFORM); | 230 m_mutatedProperties |= static_cast<uint32_t>(WebCompositorMutablePropertyTra nsform); |
238 } | 231 } |
239 | 232 |
240 bool CompositorProxy::raiseExceptionIfNotMutable(Attributes attribute, Exception State& exceptionState) const | 233 bool CompositorProxy::raiseExceptionIfNotMutable(uint32_t property, ExceptionSta te& exceptionState) const |
241 { | 234 { |
242 if (m_connected && (m_bitfieldsSupported & static_cast<uint32_t>(attribute)) ) | 235 if (m_connected && (m_compositorMutableProperties & property)) |
243 return false; | 236 return false; |
244 exceptionState.throwDOMException(NoModificationAllowedError, | 237 exceptionState.throwDOMException(NoModificationAllowedError, |
245 m_connected ? "Attempted to mutate non-mutable attribute." : "Attempted to mutate attribute on a disconnected proxy."); | 238 m_connected ? "Attempted to mutate non-mutable attribute." : "Attempted to mutate attribute on a disconnected proxy."); |
246 return true; | 239 return true; |
247 } | 240 } |
248 | 241 |
249 void CompositorProxy::disconnect() | 242 void CompositorProxy::disconnect() |
250 { | 243 { |
251 m_connected = false; | 244 m_connected = false; |
252 if (isMainThread()) | 245 if (isMainThread()) |
253 decrementCountForElement(m_elementId); | 246 decrementProxiedPropertyCountsForElement(m_elementId, m_compositorMutabl eProperties); |
254 else | 247 else |
255 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HER E, threadSafeBind(&decrementCountForElement, m_elementId)); | 248 Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HER E, threadSafeBind(&decrementProxiedPropertyCountsForElement, m_elementId, m_comp ositorMutableProperties)); |
256 } | 249 } |
257 | 250 |
258 } // namespace blink | 251 } // namespace blink |
OLD | NEW |