initial import
[vuplus_webkit] / Source / WebCore / platform / graphics / texmap / GraphicsLayerTextureMapper.cpp
1 /*
2     Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
3
4     This library is free software; you can redistribute it and/or
5     modify it under the terms of the GNU Library General Public
6     License as published by the Free Software Foundation; either
7     version 2 of the License, or (at your option) any later version.
8
9     This library is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12     Library General Public License for more details.
13
14     You should have received a copy of the GNU Library General Public License
15     along with this library; see the file COPYING.LIB.  If not, write to
16     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17     Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "GraphicsLayerTextureMapper.h"
22
23 #include "TextureMapperNode.h"
24
25 namespace WebCore {
26
27 GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client)
28     : GraphicsLayer(client)
29     , m_node(adoptPtr(new TextureMapperNode()))
30     , m_changeMask(0)
31     , m_animationStartedTimer(this, &GraphicsLayerTextureMapper::animationStartedTimerFired)
32 {
33 }
34
35 void GraphicsLayerTextureMapper::notifyChange(TextureMapperNode::ChangeMask changeMask)
36 {
37     m_changeMask |= changeMask;
38     if (!client())
39         return;
40     client()->notifySyncRequired(this);
41 }
42
43 void GraphicsLayerTextureMapper::didSynchronize()
44 {
45     m_syncQueued = false;
46     m_changeMask = 0;
47     m_pendingContent.needsDisplay = false;
48     m_pendingContent.needsDisplayRect = IntRect();
49 }
50
51 void GraphicsLayerTextureMapper::setName(const String& name)
52 {
53     GraphicsLayer::setName(name);
54 }
55
56 GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper()
57 {
58 }
59
60 /* \reimp (GraphicsLayer.h): The current size might change, thus we need to update the whole display.
61 */
62 void GraphicsLayerTextureMapper::setNeedsDisplay()
63 {
64     m_pendingContent.needsDisplay = true;
65     notifyChange(TextureMapperNode::DisplayChange);
66 }
67
68 /* \reimp (GraphicsLayer.h)
69 */
70 void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect)
71 {
72     if (m_pendingContent.needsDisplay)
73         return;
74     m_pendingContent.needsDisplayRect.unite(rect);
75     notifyChange(TextureMapperNode::DisplayChange);
76 }
77
78 /* \reimp (GraphicsLayer.h)
79 */
80 void GraphicsLayerTextureMapper::setParent(GraphicsLayer* layer)
81 {
82     notifyChange(TextureMapperNode::ParentChange);
83     GraphicsLayer::setParent(layer);
84 }
85
86 /* \reimp (GraphicsLayer.h)
87 */
88 bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& children)
89 {
90     notifyChange(TextureMapperNode::ChildrenChange);
91     return GraphicsLayer::setChildren(children);
92 }
93
94 /* \reimp (GraphicsLayer.h)
95 */
96 void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer)
97 {
98     notifyChange(TextureMapperNode::ChildrenChange);
99     GraphicsLayer::addChild(layer);
100 }
101
102 /* \reimp (GraphicsLayer.h)
103 */
104 void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index)
105 {
106     GraphicsLayer::addChildAtIndex(layer, index);
107     notifyChange(TextureMapperNode::ChildrenChange);
108 }
109
110 /* \reimp (GraphicsLayer.h)
111 */
112 void GraphicsLayerTextureMapper::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling)
113 {
114      GraphicsLayer::addChildAbove(layer, sibling);
115      notifyChange(TextureMapperNode::ChildrenChange);
116 }
117
118 /* \reimp (GraphicsLayer.h)
119 */
120 void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling)
121 {
122
123     GraphicsLayer::addChildBelow(layer, sibling);
124     notifyChange(TextureMapperNode::ChildrenChange);
125 }
126
127 /* \reimp (GraphicsLayer.h)
128 */
129 bool GraphicsLayerTextureMapper::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
130 {
131     if (GraphicsLayer::replaceChild(oldChild, newChild)) {
132         notifyChange(TextureMapperNode::ChildrenChange);
133         return true;
134     }
135     return false;
136 }
137
138 /* \reimp (GraphicsLayer.h)
139 */
140 void GraphicsLayerTextureMapper::removeFromParent()
141 {
142     if (!parent())
143         return;
144     notifyChange(TextureMapperNode::ParentChange);
145     GraphicsLayer::removeFromParent();
146 }
147
148 /* \reimp (GraphicsLayer.h)
149 */
150 void GraphicsLayerTextureMapper::setMaskLayer(GraphicsLayer* value)
151 {
152     if (value == maskLayer())
153         return;
154     GraphicsLayer::setMaskLayer(value);
155     notifyChange(TextureMapperNode::MaskLayerChange);
156 }
157
158
159 /* \reimp (GraphicsLayer.h)
160 */
161 void GraphicsLayerTextureMapper::setReplicatedByLayer(GraphicsLayer* value)
162 {
163     if (value == replicaLayer())
164         return;
165     GraphicsLayer::setReplicatedByLayer(value);
166     notifyChange(TextureMapperNode::ReplicaLayerChange);
167 }
168
169 /* \reimp (GraphicsLayer.h)
170 */
171 void GraphicsLayerTextureMapper::setPosition(const FloatPoint& value)
172 {
173     if (value == position())
174         return;
175     GraphicsLayer::setPosition(value);
176     notifyChange(TextureMapperNode::PositionChange);
177 }
178
179 /* \reimp (GraphicsLayer.h)
180 */
181 void GraphicsLayerTextureMapper::setAnchorPoint(const FloatPoint3D& value)
182 {
183     if (value == anchorPoint())
184         return;
185     GraphicsLayer::setAnchorPoint(value);
186     notifyChange(TextureMapperNode::AnchorPointChange);
187 }
188
189 /* \reimp (GraphicsLayer.h)
190 */
191 void GraphicsLayerTextureMapper::setSize(const FloatSize& value)
192 {
193     if (value == size())
194         return;
195
196     GraphicsLayer::setSize(value);
197     notifyChange(TextureMapperNode::SizeChange);
198 }
199
200 /* \reimp (GraphicsLayer.h)
201 */
202 void GraphicsLayerTextureMapper::setTransform(const TransformationMatrix& value)
203 {
204     if (value == transform())
205         return;
206
207     GraphicsLayer::setTransform(value);
208     notifyChange(TextureMapperNode::TransformChange);
209 }
210
211 /* \reimp (GraphicsLayer.h)
212 */
213 void GraphicsLayerTextureMapper::setChildrenTransform(const TransformationMatrix& value)
214 {
215     if (value == childrenTransform())
216         return;
217     GraphicsLayer::setChildrenTransform(value);
218     notifyChange(TextureMapperNode::ChildrenTransformChange);
219 }
220
221 /* \reimp (GraphicsLayer.h)
222 */
223 void GraphicsLayerTextureMapper::setPreserves3D(bool value)
224 {
225     if (value == preserves3D())
226         return;
227     GraphicsLayer::setPreserves3D(value);
228     notifyChange(TextureMapperNode::Preserves3DChange);
229 }
230
231 /* \reimp (GraphicsLayer.h)
232 */
233 void GraphicsLayerTextureMapper::setMasksToBounds(bool value)
234 {
235     if (value == masksToBounds())
236         return;
237     GraphicsLayer::setMasksToBounds(value);
238     notifyChange(TextureMapperNode::MasksToBoundsChange);
239 }
240
241 /* \reimp (GraphicsLayer.h)
242 */
243 void GraphicsLayerTextureMapper::setDrawsContent(bool value)
244 {
245     if (value == drawsContent())
246         return;
247     notifyChange(TextureMapperNode::DrawsContentChange);
248     GraphicsLayer::setDrawsContent(value);
249 }
250
251 /* \reimp (GraphicsLayer.h)
252 */
253 void GraphicsLayerTextureMapper::setBackgroundColor(const Color& value)
254 {
255     if (value == m_pendingContent.backgroundColor)
256         return;
257     m_pendingContent.backgroundColor = value;
258     GraphicsLayer::setBackgroundColor(value);
259     notifyChange(TextureMapperNode::BackgroundColorChange);
260 }
261
262 /* \reimp (GraphicsLayer.h)
263 */
264 void GraphicsLayerTextureMapper::clearBackgroundColor()
265 {
266     if (!m_pendingContent.backgroundColor.isValid())
267         return;
268     m_pendingContent.backgroundColor = Color();
269     GraphicsLayer::clearBackgroundColor();
270     notifyChange(TextureMapperNode::BackgroundColorChange);
271 }
272
273 /* \reimp (GraphicsLayer.h)
274 */
275 void GraphicsLayerTextureMapper::setContentsOpaque(bool value)
276 {
277     if (value == contentsOpaque())
278         return;
279     notifyChange(TextureMapperNode::ContentsOpaqueChange);
280     GraphicsLayer::setContentsOpaque(value);
281 }
282
283 /* \reimp (GraphicsLayer.h)
284 */
285 void GraphicsLayerTextureMapper::setBackfaceVisibility(bool value)
286 {
287     if (value == backfaceVisibility())
288         return;
289     GraphicsLayer::setBackfaceVisibility(value);
290     notifyChange(TextureMapperNode::BackfaceVisibilityChange);
291 }
292
293 /* \reimp (GraphicsLayer.h)
294 */
295 void GraphicsLayerTextureMapper::setOpacity(float value)
296 {
297     if (value == opacity())
298         return;
299     GraphicsLayer::setOpacity(value);
300     notifyChange(TextureMapperNode::OpacityChange);
301 }
302
303 /* \reimp (GraphicsLayer.h)
304 */
305 void GraphicsLayerTextureMapper::setContentsRect(const IntRect& value)
306 {
307     if (value == contentsRect())
308         return;
309     GraphicsLayer::setContentsRect(value);
310     notifyChange(TextureMapperNode::ContentsRectChange);
311 }
312
313 /* \reimp (GraphicsLayer.h)
314 */
315 void GraphicsLayerTextureMapper::setContentsToImage(Image* image)
316 {
317     notifyChange(TextureMapperNode::ContentChange);
318     m_pendingContent.contentType = image ? TextureMapperNode::DirectImageContentType : TextureMapperNode::HTMLContentType;
319     m_pendingContent.image = image;
320     GraphicsLayer::setContentsToImage(image);
321 }
322
323 void GraphicsLayerTextureMapper::setContentsToMedia(TextureMapperPlatformLayer* media)
324 {
325     GraphicsLayer::setContentsToMedia(media);
326     notifyChange(TextureMapperNode::ContentChange);
327     m_pendingContent.contentType = media ? TextureMapperNode::MediaContentType : TextureMapperNode::HTMLContentType;
328     m_pendingContent.media = media;
329 }
330
331 /* \reimp (GraphicsLayer.h)
332 */
333 void GraphicsLayerTextureMapper::syncCompositingStateForThisLayerOnly()
334 {
335     m_node->syncCompositingState(this);
336 }
337
338 /* \reimp (GraphicsLayer.h)
339 */
340 void GraphicsLayerTextureMapper::syncCompositingState(const FloatRect&)
341 {
342     m_node->syncCompositingState(this, TextureMapperNode::TraverseDescendants);
343 }
344
345 /* \reimp (GraphicsLayer.h)
346 */
347 PlatformLayer* GraphicsLayerTextureMapper::platformLayer() const
348 {
349     return const_cast<TextureMapperPlatformLayer*>(node()->media());
350 }
351
352 bool GraphicsLayerTextureMapper::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
353 {
354     ASSERT(!keyframesName.isEmpty());
355
356     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2 || (valueList.property() != AnimatedPropertyWebkitTransform && valueList.property() != AnimatedPropertyOpacity))
357         return false;
358
359     for (size_t i = 0; i < m_animations.size(); ++i) {
360         // The same animation name can be used for two animations with different properties.
361         if (m_animations[i]->name != keyframesName || m_animations[i]->keyframes.property() != valueList.property())
362             continue;
363
364         // We already have a copy of this animation, that means that we're resuming it rather than adding it.
365         RefPtr<TextureMapperAnimation>& animation = m_animations[i];
366         animation->animation = Animation::create(anim);
367         animation->paused = false;
368         animation->startTime = WTF::currentTime() - timeOffset;
369         notifyChange(TextureMapperNode::AnimationChange);
370         m_animationStartedTimer.startOneShot(0);
371         return true;
372     }
373
374     RefPtr<TextureMapperAnimation> animation = TextureMapperAnimation::create(valueList);
375     animation->boxSize = boxSize;
376     animation->name = keyframesName;
377     animation->animation = Animation::create(anim);
378     animation->paused = false;
379     animation->startTime = WTF::currentTime() - timeOffset;
380
381     if (valueList.property() == AnimatedPropertyWebkitTransform) {
382         bool hasBigRotation; // Not used, but required as a pointer parameter for the function.
383         fetchTransformOperationList(valueList, animation->functionList, animation->listsMatch, hasBigRotation);
384     }
385
386     m_animations.append(animation);
387     notifyChange(TextureMapperNode::AnimationChange);
388     m_animationStartedTimer.startOneShot(0);
389
390     return true;
391 }
392
393 void GraphicsLayerTextureMapper::pauseAnimation(const String& animationName, double timeOffset)
394 {
395     for (size_t i = 0; i < m_animations.size(); ++i) {
396         if (m_animations[i]->name != animationName)
397             continue;
398         m_animations[i]->paused = true;
399         notifyChange(TextureMapperNode::AnimationChange);
400     }
401 }
402
403 void GraphicsLayerTextureMapper::removeAnimation(const String& animationName)
404 {
405     for (int i = m_animations.size() - 1; i >= 0; --i) {
406         // The same animation name can be used for two animations with different properties. We should remove both.
407         if (m_animations[i]->name != animationName)
408             continue;
409         m_animations.remove(i);
410         notifyChange(TextureMapperNode::AnimationChange);
411     }
412 }
413
414 void GraphicsLayerTextureMapper::animationStartedTimerFired(Timer<GraphicsLayerTextureMapper>*)
415 {
416     client()->notifyAnimationStarted(this, /* DOM time */ WTF::currentTime());
417 }
418
419 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
420 {
421     if (s_graphicsLayerFactory)
422         return (*s_graphicsLayerFactory)(client);
423     return adoptPtr(new GraphicsLayerTextureMapper(client));
424 }
425
426 }