8013ec412537105bbd52cf419cb17d591922080b
[WebKit-https.git] / 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 "GraphicsContext.h"
24 #include "GraphicsLayerAnimation.h"
25 #include "GraphicsLayerFactory.h"
26 #include "ImageBuffer.h"
27 #include <wtf/CurrentTime.h>
28
29 namespace WebCore {
30
31 TextureMapperLayer* toTextureMapperLayer(GraphicsLayer* layer)
32 {
33     return layer ? toGraphicsLayerTextureMapper(layer)->layer() : 0;
34 }
35
36 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client)
37 {
38     if (!factory)
39         return adoptPtr(new GraphicsLayerTextureMapper(client));
40
41     return factory->createGraphicsLayer(client);
42 }
43
44 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
45 {
46     return adoptPtr(new GraphicsLayerTextureMapper(client));
47 }
48
49 GraphicsLayerTextureMapper::GraphicsLayerTextureMapper(GraphicsLayerClient* client)
50     : GraphicsLayer(client)
51     , m_layer(adoptPtr(new TextureMapperLayer()))
52     , m_compositedNativeImagePtr(0)
53     , m_changeMask(NoChanges)
54     , m_needsDisplay(false)
55     , m_hasOwnBackingStore(true)
56     , m_fixedToViewport(false)
57     , m_debugBorderWidth(0)
58     , m_contentsLayer(0)
59     , m_animationStartTime(0)
60 {
61 }
62
63 void GraphicsLayerTextureMapper::notifyChange(ChangeMask changeMask)
64 {
65     m_changeMask |= changeMask;
66     if (!client())
67         return;
68     client()->notifyFlushRequired(this);
69 }
70
71 void GraphicsLayerTextureMapper::setName(const String& name)
72 {
73     GraphicsLayer::setName(name);
74 }
75
76 GraphicsLayerTextureMapper::~GraphicsLayerTextureMapper()
77 {
78     willBeDestroyed();
79 }
80
81 void GraphicsLayerTextureMapper::willBeDestroyed()
82 {
83     GraphicsLayer::willBeDestroyed();
84 }
85
86 /* \reimp (GraphicsLayer.h): The current size might change, thus we need to update the whole display.
87 */
88 void GraphicsLayerTextureMapper::setNeedsDisplay()
89 {
90     if (!drawsContent() || !m_hasOwnBackingStore)
91         return;
92
93     m_needsDisplay = true;
94     notifyChange(DisplayChange);
95     addRepaintRect(FloatRect(FloatPoint(), m_size));
96 }
97
98 /* \reimp (GraphicsLayer.h)
99 */
100 void GraphicsLayerTextureMapper::setContentsNeedsDisplay()
101 {
102     notifyChange(DisplayChange);
103     addRepaintRect(contentsRect());
104 }
105
106 /* \reimp (GraphicsLayer.h)
107 */
108 void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect)
109 {
110     if (!drawsContent() || !m_hasOwnBackingStore)
111         return;
112
113     if (m_needsDisplay)
114         return;
115     m_needsDisplayRect.unite(rect);
116     notifyChange(DisplayChange);
117     addRepaintRect(rect);
118 }
119
120 /* \reimp (GraphicsLayer.h)
121 */
122 bool GraphicsLayerTextureMapper::setChildren(const Vector<GraphicsLayer*>& children)
123 {
124     if (GraphicsLayer::setChildren(children)) {
125         notifyChange(ChildrenChange);
126         return true;
127     }
128     return false;
129 }
130
131 /* \reimp (GraphicsLayer.h)
132 */
133 void GraphicsLayerTextureMapper::addChild(GraphicsLayer* layer)
134 {
135     notifyChange(ChildrenChange);
136     GraphicsLayer::addChild(layer);
137 }
138
139 /* \reimp (GraphicsLayer.h)
140 */
141 void GraphicsLayerTextureMapper::addChildAtIndex(GraphicsLayer* layer, int index)
142 {
143     GraphicsLayer::addChildAtIndex(layer, index);
144     notifyChange(ChildrenChange);
145 }
146
147 /* \reimp (GraphicsLayer.h)
148 */
149 void GraphicsLayerTextureMapper::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling)
150 {
151     GraphicsLayer::addChildAbove(layer, sibling);
152     notifyChange(ChildrenChange);
153 }
154
155 /* \reimp (GraphicsLayer.h)
156 */
157 void GraphicsLayerTextureMapper::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling)
158 {
159     GraphicsLayer::addChildBelow(layer, sibling);
160     notifyChange(ChildrenChange);
161 }
162
163 /* \reimp (GraphicsLayer.h)
164 */
165 bool GraphicsLayerTextureMapper::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
166 {
167     if (GraphicsLayer::replaceChild(oldChild, newChild)) {
168         notifyChange(ChildrenChange);
169         return true;
170     }
171     return false;
172 }
173
174 /* \reimp (GraphicsLayer.h)
175 */
176 void GraphicsLayerTextureMapper::setMaskLayer(GraphicsLayer* value)
177 {
178     if (value == maskLayer())
179         return;
180     GraphicsLayer::setMaskLayer(value);
181     notifyChange(MaskLayerChange);
182
183     if (!value)
184         return;
185     value->setSize(size());
186     value->setContentsVisible(contentsAreVisible());
187 }
188
189
190 /* \reimp (GraphicsLayer.h)
191 */
192 void GraphicsLayerTextureMapper::setReplicatedByLayer(GraphicsLayer* value)
193 {
194     if (value == replicaLayer())
195         return;
196     GraphicsLayer::setReplicatedByLayer(value);
197     notifyChange(ReplicaLayerChange);
198 }
199
200 /* \reimp (GraphicsLayer.h)
201 */
202 void GraphicsLayerTextureMapper::setPosition(const FloatPoint& value)
203 {
204     if (value == position())
205         return;
206     GraphicsLayer::setPosition(value);
207     notifyChange(PositionChange);
208 }
209
210 /* \reimp (GraphicsLayer.h)
211 */
212 void GraphicsLayerTextureMapper::setAnchorPoint(const FloatPoint3D& value)
213 {
214     if (value == anchorPoint())
215         return;
216     GraphicsLayer::setAnchorPoint(value);
217     notifyChange(AnchorPointChange);
218 }
219
220 /* \reimp (GraphicsLayer.h)
221 */
222 void GraphicsLayerTextureMapper::setSize(const FloatSize& value)
223 {
224     if (value == size())
225         return;
226
227     GraphicsLayer::setSize(value);
228     if (maskLayer())
229         maskLayer()->setSize(value);
230     notifyChange(SizeChange);
231 }
232
233 /* \reimp (GraphicsLayer.h)
234 */
235 void GraphicsLayerTextureMapper::setTransform(const TransformationMatrix& value)
236 {
237     if (value == transform())
238         return;
239
240     GraphicsLayer::setTransform(value);
241     notifyChange(TransformChange);
242 }
243
244 /* \reimp (GraphicsLayer.h)
245 */
246 void GraphicsLayerTextureMapper::setChildrenTransform(const TransformationMatrix& value)
247 {
248     if (value == childrenTransform())
249         return;
250     GraphicsLayer::setChildrenTransform(value);
251     notifyChange(ChildrenTransformChange);
252 }
253
254 /* \reimp (GraphicsLayer.h)
255 */
256 void GraphicsLayerTextureMapper::setPreserves3D(bool value)
257 {
258     if (value == preserves3D())
259         return;
260     GraphicsLayer::setPreserves3D(value);
261     notifyChange(Preserves3DChange);
262 }
263
264 /* \reimp (GraphicsLayer.h)
265 */
266 void GraphicsLayerTextureMapper::setMasksToBounds(bool value)
267 {
268     if (value == masksToBounds())
269         return;
270     GraphicsLayer::setMasksToBounds(value);
271     notifyChange(MasksToBoundsChange);
272 }
273
274 /* \reimp (GraphicsLayer.h)
275 */
276 void GraphicsLayerTextureMapper::setDrawsContent(bool value)
277 {
278     if (value == drawsContent())
279         return;
280     GraphicsLayer::setDrawsContent(value);
281     notifyChange(DrawsContentChange);
282
283     if (value && m_hasOwnBackingStore)
284         setNeedsDisplay();
285 }
286
287 /* \reimp (GraphicsLayer.h)
288 */
289 void GraphicsLayerTextureMapper::setContentsVisible(bool value)
290 {
291     if (value == contentsAreVisible())
292         return;
293     notifyChange(ContentsVisibleChange);
294     GraphicsLayer::setContentsVisible(value);
295     if (maskLayer())
296         maskLayer()->setContentsVisible(value);
297 }
298
299 /* \reimp (GraphicsLayer.h)
300 */
301 void GraphicsLayerTextureMapper::setContentsOpaque(bool value)
302 {
303     if (value == contentsOpaque())
304         return;
305     notifyChange(ContentsOpaqueChange);
306     GraphicsLayer::setContentsOpaque(value);
307 }
308
309 /* \reimp (GraphicsLayer.h)
310 */
311 void GraphicsLayerTextureMapper::setBackfaceVisibility(bool value)
312 {
313     if (value == backfaceVisibility())
314         return;
315     GraphicsLayer::setBackfaceVisibility(value);
316     notifyChange(BackfaceVisibilityChange);
317 }
318
319 /* \reimp (GraphicsLayer.h)
320 */
321 void GraphicsLayerTextureMapper::setOpacity(float value)
322 {
323     if (value == opacity())
324         return;
325     GraphicsLayer::setOpacity(value);
326     notifyChange(OpacityChange);
327 }
328
329 /* \reimp (GraphicsLayer.h)
330 */
331 void GraphicsLayerTextureMapper::setContentsRect(const IntRect& value)
332 {
333     if (value == contentsRect())
334         return;
335     GraphicsLayer::setContentsRect(value);
336     notifyChange(ContentsRectChange);
337 }
338
339 void GraphicsLayerTextureMapper::setContentsToSolidColor(const Color& color)
340 {
341     if (color == m_solidColor)
342         return;
343
344     m_solidColor = color;
345     notifyChange(BackgroundColorChange);
346 }
347
348
349 /* \reimp (GraphicsLayer.h)
350 */
351 void GraphicsLayerTextureMapper::setContentsToImage(Image* image)
352 {
353     if (image) {
354         // Make the decision about whether the image has changed.
355         // This code makes the assumption that pointer equality on a NativeImagePtr is a valid way to tell if the image is changed.
356         // This assumption is true in Qt, GTK and EFL.
357         NativeImagePtr newNativeImagePtr = image->nativeImageForCurrentFrame();
358         if (!newNativeImagePtr)
359             return;
360
361         if (newNativeImagePtr == m_compositedNativeImagePtr)
362             return;
363
364         m_compositedNativeImagePtr = newNativeImagePtr;
365         if (!m_compositedImage)
366             m_compositedImage = TextureMapperTiledBackingStore::create();
367         m_compositedImage->setContentsToImage(image);
368     } else {
369         m_compositedNativeImagePtr = 0;
370         m_compositedImage = 0;
371     }
372
373     setContentsToMedia(m_compositedImage.get());
374     notifyChange(ContentChange);
375     GraphicsLayer::setContentsToImage(image);
376 }
377
378 void GraphicsLayerTextureMapper::setContentsToMedia(TextureMapperPlatformLayer* media)
379 {
380     if (media == m_contentsLayer)
381         return;
382
383     GraphicsLayer::setContentsToMedia(media);
384     notifyChange(ContentChange);
385     m_contentsLayer = media;
386 }
387
388 void GraphicsLayerTextureMapper::setShowDebugBorder(bool show)
389 {
390     if (isShowingDebugBorder() == show)
391         return;
392
393     GraphicsLayer::setShowDebugBorder(show);
394     notifyChange(DebugVisualsChange);
395 }
396
397 void GraphicsLayerTextureMapper::setShowRepaintCounter(bool show)
398 {
399     if (isShowingRepaintCounter() == show)
400         return;
401
402     GraphicsLayer::setShowRepaintCounter(show);
403     notifyChange(DebugVisualsChange);
404 }
405
406 /* \reimp (GraphicsLayer.h)
407 */
408 void GraphicsLayerTextureMapper::flushCompositingStateForThisLayerOnly()
409 {
410     prepareBackingStoreIfNeeded();
411     commitLayerChanges();
412     m_layer->syncAnimations();
413     updateBackingStoreIfNeeded();
414 }
415
416 void GraphicsLayerTextureMapper::prepareBackingStoreIfNeeded()
417 {
418     if (!m_hasOwnBackingStore)
419         return;
420     if (!shouldHaveBackingStore()) {
421         m_backingStore.clear();
422         m_changeMask |= BackingStoreChange;
423     } else {
424         if (!m_backingStore) {
425             m_backingStore = TextureMapperTiledBackingStore::create();
426             m_changeMask |= BackingStoreChange;
427         }
428     }
429
430     updateDebugBorderAndRepaintCount();
431 }
432
433 void GraphicsLayerTextureMapper::updateDebugBorderAndRepaintCount()
434 {
435     ASSERT(m_hasOwnBackingStore);
436     if (isShowingDebugBorder())
437         updateDebugIndicators();
438
439     // When this has its own backing store (e.g. Qt WK1), update the repaint count before calling TextureMapperLayer::flushCompositingStateForThisLayerOnly().
440     bool needsToRepaint = shouldHaveBackingStore() && (m_needsDisplay || !m_needsDisplayRect.isEmpty());
441     if (isShowingRepaintCounter() && needsToRepaint) {
442         incrementRepaintCount();
443         m_changeMask |= RepaintCountChange;
444     }
445 }
446
447 void GraphicsLayerTextureMapper::setDebugBorder(const Color& color, float width)
448 {
449     m_debugBorderColor = color;
450     m_debugBorderWidth = width;
451     m_changeMask |= DebugVisualsChange;
452 }
453
454 static void toTextureMapperLayerVector(const Vector<GraphicsLayer*>& layers, Vector<TextureMapperLayer*>& texmapLayers)
455 {
456     texmapLayers.reserveCapacity(layers.size());
457     for (size_t i = 0; i < layers.size(); ++i)
458         texmapLayers.append(toTextureMapperLayer(layers[i]));
459 }
460
461 void GraphicsLayerTextureMapper::commitLayerChanges()
462 {
463     if (m_changeMask == NoChanges)
464         return;
465
466     if (m_changeMask & ChildrenChange) {
467         Vector<TextureMapperLayer*> textureMapperLayerChildren;
468         toTextureMapperLayerVector(children(), textureMapperLayerChildren);
469         m_layer->setChildren(textureMapperLayerChildren);
470     }
471
472     if (m_changeMask & MaskLayerChange)
473         m_layer->setMaskLayer(toTextureMapperLayer(maskLayer()));
474
475     if (m_changeMask & ReplicaLayerChange)
476         m_layer->setReplicaLayer(toTextureMapperLayer(replicaLayer()));
477
478     if (m_changeMask & PositionChange)
479         m_layer->setPosition(position());
480
481     if (m_changeMask & AnchorPointChange)
482         m_layer->setAnchorPoint(anchorPoint());
483
484     if (m_changeMask & SizeChange)
485         m_layer->setSize(size());
486
487     if (m_changeMask & TransformChange)
488         m_layer->setTransform(transform());
489
490     if (m_changeMask & ChildrenTransformChange)
491         m_layer->setChildrenTransform(childrenTransform());
492
493     if (m_changeMask & Preserves3DChange)
494         m_layer->setPreserves3D(preserves3D());
495
496     if (m_changeMask & ContentsRectChange)
497         m_layer->setContentsRect(contentsRect());
498
499     if (m_changeMask & MasksToBoundsChange)
500         m_layer->setMasksToBounds(masksToBounds());
501
502     if (m_changeMask & DrawsContentChange)
503         m_layer->setDrawsContent(drawsContent());
504
505     if (m_changeMask & ContentsVisibleChange)
506         m_layer->setContentsVisible(contentsAreVisible());
507
508     if (m_changeMask & ContentsOpaqueChange)
509         m_layer->setContentsOpaque(contentsOpaque());
510
511     if (m_changeMask & BackfaceVisibilityChange)
512         m_layer->setBackfaceVisibility(backfaceVisibility());
513
514     if (m_changeMask & OpacityChange)
515         m_layer->setOpacity(opacity());
516
517     if (m_changeMask & BackgroundColorChange)
518         m_layer->setSolidColor(solidColor());
519
520 #if ENABLE(CSS_FILTERS)
521     if (m_changeMask & FilterChange)
522         m_layer->setFilters(filters());
523 #endif
524
525     if (m_changeMask & BackingStoreChange)
526         m_layer->setBackingStore(m_backingStore);
527
528     if (m_changeMask & DebugVisualsChange)
529         m_layer->setDebugVisuals(isShowingDebugBorder(), debugBorderColor(), debugBorderWidth(), isShowingRepaintCounter());
530
531     if (m_changeMask & RepaintCountChange)
532         m_layer->setRepaintCount(repaintCount());
533
534     if (m_changeMask & ContentChange)
535         m_layer->setContentsLayer(platformLayer());
536
537     if (m_changeMask & AnimationChange)
538         m_layer->setAnimations(m_animations);
539
540     if (m_changeMask & AnimationStarted)
541         client()->notifyAnimationStarted(this, m_animationStartTime);
542
543     if (m_changeMask & FixedToViewporChange)
544         m_layer->setFixedToViewport(fixedToViewport());
545
546     m_changeMask = NoChanges;
547 }
548
549 /* \reimp (GraphicsLayer.h)
550 */
551 void GraphicsLayerTextureMapper::flushCompositingState(const FloatRect& rect)
552 {
553     if (!m_layer->textureMapper())
554         return;
555
556     flushCompositingStateForThisLayerOnly();
557
558     if (maskLayer())
559         maskLayer()->flushCompositingState(rect);
560     if (replicaLayer())
561         replicaLayer()->flushCompositingState(rect);
562     for (size_t i = 0; i < children().size(); ++i)
563         children()[i]->flushCompositingState(rect);
564 }
565
566 void GraphicsLayerTextureMapper::updateBackingStoreIfNeeded()
567 {
568     if (!m_hasOwnBackingStore)
569         return;
570
571     TextureMapper* textureMapper = m_layer->textureMapper();
572     if (!textureMapper)
573         return;
574
575     if (!shouldHaveBackingStore()) {
576         ASSERT(!m_backingStore);
577         return;
578     }
579     ASSERT(m_backingStore);
580
581     IntRect dirtyRect = enclosingIntRect(FloatRect(FloatPoint::zero(), m_size));
582     if (!m_needsDisplay)
583         dirtyRect.intersect(enclosingIntRect(m_needsDisplayRect));
584     if (dirtyRect.isEmpty())
585         return;
586
587 #if PLATFORM(QT) && !defined(QT_NO_DYNAMIC_CAST)
588     ASSERT(dynamic_cast<TextureMapperTiledBackingStore*>(m_backingStore.get()));
589 #endif
590     TextureMapperTiledBackingStore* backingStore = static_cast<TextureMapperTiledBackingStore*>(m_backingStore.get());
591
592     backingStore->updateContents(textureMapper, this, m_size, dirtyRect, BitmapTexture::UpdateCanModifyOriginalImageData);
593
594     m_needsDisplay = false;
595     m_needsDisplayRect = IntRect();
596 }
597
598 bool GraphicsLayerTextureMapper::shouldHaveBackingStore() const
599 {
600     return drawsContent() && contentsAreVisible() && !m_size.isEmpty();
601 }
602
603 bool GraphicsLayerTextureMapper::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
604 {
605     ASSERT(!keyframesName.isEmpty());
606
607     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2 || (valueList.property() != AnimatedPropertyWebkitTransform && valueList.property() != AnimatedPropertyOpacity))
608         return false;
609
610     bool listsMatch = false;
611     bool hasBigRotation;
612
613     if (valueList.property() == AnimatedPropertyWebkitTransform)
614         listsMatch = validateTransformOperations(valueList, hasBigRotation) >= 0;
615
616     const double currentTime = WTF::currentTime();
617     m_animations.add(GraphicsLayerAnimation(keyframesName, valueList, boxSize, anim, currentTime - timeOffset, listsMatch));
618     // m_animationStartTime is the time of the first real frame of animation, now or delayed by a negative offset.
619     if (timeOffset > 0)
620         m_animationStartTime = currentTime;
621     else
622         m_animationStartTime = currentTime - timeOffset;
623     notifyChange(AnimationChange);
624     notifyChange(AnimationStarted);
625     return true;
626 }
627
628 void GraphicsLayerTextureMapper::setAnimations(const GraphicsLayerAnimations& animations)
629 {
630     m_animations = animations;
631     notifyChange(AnimationChange);
632 }
633
634
635 void GraphicsLayerTextureMapper::pauseAnimation(const String& animationName, double timeOffset)
636 {
637     m_animations.pause(animationName, timeOffset);
638 }
639
640 void GraphicsLayerTextureMapper::removeAnimation(const String& animationName)
641 {
642     m_animations.remove(animationName);
643 }
644
645 #if ENABLE(CSS_FILTERS)
646 bool GraphicsLayerTextureMapper::setFilters(const FilterOperations& filters)
647 {
648     notifyChange(FilterChange);
649     return GraphicsLayer::setFilters(filters);
650 }
651 #endif
652
653 void GraphicsLayerTextureMapper::setBackingStore(PassRefPtr<TextureMapperBackingStore> backingStore)
654 {
655     ASSERT(!m_hasOwnBackingStore);
656     if (m_backingStore == backingStore)
657         return;
658
659     m_backingStore = backingStore;
660     notifyChange(BackingStoreChange);
661 }
662
663 void GraphicsLayerTextureMapper::setFixedToViewport(bool fixed)
664 {
665     if (m_fixedToViewport == fixed)
666         return;
667
668     m_fixedToViewport = fixed;
669     notifyChange(FixedToViewporChange);
670 }
671
672 void GraphicsLayerTextureMapper::setRepaintCount(int repaintCount)
673 {
674     m_repaintCount = repaintCount;
675     notifyChange(RepaintCountChange);
676 }
677
678 }