Unreviewed, rolling out r154989.
[WebKit-https.git] / Source / WebCore / platform / graphics / texmap / coordinated / CoordinatedGraphicsLayer.cpp
1 /*
2  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3  Copyright (C) 2010 Apple Inc. All rights reserved.
4  Copyright (C) 2012 Company 100, Inc.
5  Copyright (C) 2012 Intel Corporation. All rights reserved.
6
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  Library General Public License for more details.
16
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB.  If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21  */
22
23 #include "config.h"
24
25 #if USE(COORDINATED_GRAPHICS)
26 #include "CoordinatedGraphicsLayer.h"
27
28 #include "CoordinatedTile.h"
29 #include "FloatQuad.h"
30 #include "Frame.h"
31 #include "FrameView.h"
32 #include "GraphicsContext.h"
33 #include "GraphicsLayer.h"
34 #include "Page.h"
35 #include "ScrollableArea.h"
36 #include "TextureMapperPlatformLayer.h"
37 #include <wtf/CurrentTime.h>
38 #include <wtf/HashMap.h>
39 #ifndef NDEBUG
40 #include <wtf/TemporaryChange.h>
41 #endif
42 #include <wtf/text/CString.h>
43
44 namespace WebCore {
45
46 static CoordinatedLayerID toCoordinatedLayerID(GraphicsLayer* layer)
47 {
48     return layer ? toCoordinatedGraphicsLayer(layer)->id() : 0;
49 }
50
51 void CoordinatedGraphicsLayer::didChangeLayerState()
52 {
53     m_shouldSyncLayerState = true;
54     if (client())
55         client()->notifyFlushRequired(this);
56 }
57
58 void CoordinatedGraphicsLayer::didChangeAnimations()
59 {
60     m_shouldSyncAnimations = true;
61     if (client())
62         client()->notifyFlushRequired(this);
63 }
64
65 void CoordinatedGraphicsLayer::didChangeChildren()
66 {
67     m_shouldSyncChildren = true;
68     if (client())
69         client()->notifyFlushRequired(this);
70 }
71
72 #if ENABLE(CSS_FILTERS)
73 void CoordinatedGraphicsLayer::didChangeFilters()
74 {
75     m_shouldSyncFilters = true;
76     if (client())
77         client()->notifyFlushRequired(this);
78 }
79 #endif
80
81 void CoordinatedGraphicsLayer::didChangeImageBacking()
82 {
83     m_shouldSyncImageBacking = true;
84     if (client())
85         client()->notifyFlushRequired(this);
86 }
87
88 void CoordinatedGraphicsLayer::setShouldUpdateVisibleRect()
89 {
90     m_shouldUpdateVisibleRect = true;
91     for (size_t i = 0; i < children().size(); ++i)
92         toCoordinatedGraphicsLayer(children()[i])->setShouldUpdateVisibleRect();
93     if (replicaLayer())
94         toCoordinatedGraphicsLayer(replicaLayer())->setShouldUpdateVisibleRect();
95 }
96
97 void CoordinatedGraphicsLayer::didChangeGeometry()
98 {
99     didChangeLayerState();
100     setShouldUpdateVisibleRect();
101 }
102
103 CoordinatedGraphicsLayer::CoordinatedGraphicsLayer(GraphicsLayerClient* client)
104     : GraphicsLayer(client)
105 #ifndef NDEBUG
106     , m_isPurging(false)
107 #endif
108     , m_shouldUpdateVisibleRect(true)
109     , m_shouldSyncLayerState(true)
110     , m_shouldSyncChildren(true)
111     , m_shouldSyncFilters(true)
112     , m_shouldSyncImageBacking(true)
113     , m_shouldSyncAnimations(true)
114     , m_fixedToViewport(false)
115     , m_movingVisibleRect(false)
116     , m_pendingContentsScaleAdjustment(false)
117     , m_pendingVisibleRectAdjustment(false)
118 #if USE(GRAPHICS_SURFACE)
119     , m_isValidCanvas(false)
120     , m_pendingCanvasOperation(None)
121 #endif
122     , m_coordinator(0)
123     , m_compositedNativeImagePtr(0)
124     , m_canvasPlatformLayer(0)
125     , m_animationStartedTimer(this, &CoordinatedGraphicsLayer::animationStartedTimerFired)
126     , m_scrollableArea(0)
127 {
128     static CoordinatedLayerID nextLayerID = 1;
129     m_id = nextLayerID++;
130 }
131
132 CoordinatedGraphicsLayer::~CoordinatedGraphicsLayer()
133 {
134     if (m_coordinator) {
135         purgeBackingStores();
136         m_coordinator->detachLayer(this);
137     }
138     ASSERT(!m_coordinatedImageBacking);
139     ASSERT(!m_mainBackingStore);
140     willBeDestroyed();
141 }
142
143 bool CoordinatedGraphicsLayer::setChildren(const Vector<GraphicsLayer*>& children)
144 {
145     bool ok = GraphicsLayer::setChildren(children);
146     if (!ok)
147         return false;
148     didChangeChildren();
149     return true;
150 }
151
152 void CoordinatedGraphicsLayer::addChild(GraphicsLayer* layer)
153 {
154     GraphicsLayer::addChild(layer);
155     didChangeChildren();
156 }
157
158 void CoordinatedGraphicsLayer::addChildAtIndex(GraphicsLayer* layer, int index)
159 {
160     GraphicsLayer::addChildAtIndex(layer, index);
161     didChangeChildren();
162 }
163
164 void CoordinatedGraphicsLayer::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling)
165 {
166     GraphicsLayer::addChildAbove(layer, sibling);
167     didChangeChildren();
168 }
169
170 void CoordinatedGraphicsLayer::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling)
171 {
172     GraphicsLayer::addChildBelow(layer, sibling);
173     didChangeChildren();
174 }
175
176 bool CoordinatedGraphicsLayer::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
177 {
178     bool ok = GraphicsLayer::replaceChild(oldChild, newChild);
179     if (!ok)
180         return false;
181     didChangeChildren();
182     return true;
183 }
184
185 void CoordinatedGraphicsLayer::removeFromParent()
186 {
187     if (CoordinatedGraphicsLayer* parentLayer = toCoordinatedGraphicsLayer(parent()))
188         parentLayer->didChangeChildren();
189     GraphicsLayer::removeFromParent();
190 }
191
192 void CoordinatedGraphicsLayer::setPosition(const FloatPoint& p)
193 {
194     if (position() == p)
195         return;
196
197     GraphicsLayer::setPosition(p);
198     m_layerState.positionChanged = true;
199     didChangeGeometry();
200 }
201
202 void CoordinatedGraphicsLayer::setAnchorPoint(const FloatPoint3D& p)
203 {
204     if (anchorPoint() == p)
205         return;
206
207     GraphicsLayer::setAnchorPoint(p);
208     m_layerState.anchorPointChanged = true;
209     didChangeGeometry();
210 }
211
212 void CoordinatedGraphicsLayer::setSize(const FloatSize& size)
213 {
214     if (this->size() == size)
215         return;
216
217     GraphicsLayer::setSize(size);
218     m_layerState.sizeChanged = true;
219
220     if (maskLayer())
221         maskLayer()->setSize(size);
222     didChangeGeometry();
223 }
224
225 void CoordinatedGraphicsLayer::setTransform(const TransformationMatrix& t)
226 {
227     if (transform() == t)
228         return;
229
230     GraphicsLayer::setTransform(t);
231     m_layerState.transformChanged = true;
232
233     didChangeGeometry();
234 }
235
236 void CoordinatedGraphicsLayer::setChildrenTransform(const TransformationMatrix& t)
237 {
238     if (childrenTransform() == t)
239         return;
240
241     GraphicsLayer::setChildrenTransform(t);
242     m_layerState.childrenTransformChanged = true;
243
244     didChangeGeometry();
245 }
246
247 void CoordinatedGraphicsLayer::setPreserves3D(bool b)
248 {
249     if (preserves3D() == b)
250         return;
251
252     GraphicsLayer::setPreserves3D(b);
253     m_layerState.preserves3D = b;
254     m_layerState.flagsChanged = true;
255
256     didChangeGeometry();
257 }
258
259 void CoordinatedGraphicsLayer::setMasksToBounds(bool b)
260 {
261     if (masksToBounds() == b)
262         return;
263     GraphicsLayer::setMasksToBounds(b);
264     m_layerState.masksToBounds = b;
265     m_layerState.flagsChanged = true;
266
267     didChangeGeometry();
268 }
269
270 void CoordinatedGraphicsLayer::setDrawsContent(bool b)
271 {
272     if (drawsContent() == b)
273         return;
274     GraphicsLayer::setDrawsContent(b);
275     m_layerState.drawsContent = b;
276     m_layerState.flagsChanged = true;
277
278     didChangeLayerState();
279 }
280
281 void CoordinatedGraphicsLayer::setContentsVisible(bool b)
282 {
283     if (contentsAreVisible() == b)
284         return;
285     GraphicsLayer::setContentsVisible(b);
286     m_layerState.contentsVisible = b;
287     m_layerState.flagsChanged = true;
288
289     if (maskLayer())
290         maskLayer()->setContentsVisible(b);
291
292     didChangeLayerState();
293 }
294
295 void CoordinatedGraphicsLayer::setContentsOpaque(bool b)
296 {
297     if (contentsOpaque() == b)
298         return;
299     if (m_mainBackingStore)
300         m_mainBackingStore->setSupportsAlpha(!b);
301     GraphicsLayer::setContentsOpaque(b);
302     m_layerState.contentsOpaque = b;
303     m_layerState.flagsChanged = true;
304
305     didChangeLayerState();
306 }
307
308 void CoordinatedGraphicsLayer::setBackfaceVisibility(bool b)
309 {
310     if (backfaceVisibility() == b)
311         return;
312
313     GraphicsLayer::setBackfaceVisibility(b);
314     m_layerState.backfaceVisible = b;
315     m_layerState.flagsChanged = true;
316
317     didChangeLayerState();
318 }
319
320 void CoordinatedGraphicsLayer::setOpacity(float opacity)
321 {
322     if (this->opacity() == opacity)
323         return;
324
325     GraphicsLayer::setOpacity(opacity);
326     m_layerState.opacity = opacity;
327     m_layerState.opacityChanged = true;
328
329     didChangeLayerState();
330 }
331
332 void CoordinatedGraphicsLayer::setContentsRect(const IntRect& r)
333 {
334     if (contentsRect() == r)
335         return;
336
337     GraphicsLayer::setContentsRect(r);
338     m_layerState.contentsRect = r;
339     m_layerState.contentsRectChanged = true;
340
341     didChangeLayerState();
342 }
343
344 void CoordinatedGraphicsLayer::setContentsTileSize(const IntSize& s)
345 {
346     if (contentsTileSize() == s)
347         return;
348
349     GraphicsLayer::setContentsTileSize(s);
350     m_layerState.contentsTileSize = s;
351     m_layerState.contentsTilingChanged = true;
352     didChangeLayerState();
353 }
354
355 void CoordinatedGraphicsLayer::setContentsTilePhase(const IntPoint& p)
356 {
357     if (contentsTilePhase() == p)
358         return;
359
360     GraphicsLayer::setContentsTilePhase(p);
361     m_layerState.contentsTilePhase = p;
362     m_layerState.contentsTilingChanged = true;
363     didChangeLayerState();
364 }
365
366 static bool s_shouldSupportContentsTiling = false;
367
368 void CoordinatedGraphicsLayer::setShouldSupportContentsTiling(bool s)
369 {
370     s_shouldSupportContentsTiling = s;
371 }
372
373 bool GraphicsLayer::supportsContentsTiling()
374 {
375     return s_shouldSupportContentsTiling;
376 }
377
378 void CoordinatedGraphicsLayer::setContentsNeedsDisplay()
379 {
380 #if USE(GRAPHICS_SURFACE)
381     if (m_canvasPlatformLayer)
382         m_pendingCanvasOperation |= SyncCanvas;
383 #endif
384
385     if (client())
386         client()->notifyFlushRequired(this);
387
388     addRepaintRect(contentsRect());
389 }
390
391 void CoordinatedGraphicsLayer::setContentsToCanvas(PlatformLayer* platformLayer)
392 {
393 #if USE(GRAPHICS_SURFACE)
394     if (m_canvasPlatformLayer) {
395         ASSERT(m_canvasToken.isValid());
396         if (!platformLayer) {
397             m_pendingCanvasOperation |= DestroyCanvas;
398             m_pendingCanvasOperation &= ~CreateCanvas;
399         }  else if ((m_canvasSize != platformLayer->platformLayerSize()) || (m_canvasToken != platformLayer->graphicsSurfaceToken())) {
400             // m_canvasToken can be different to platformLayer->graphicsSurfaceToken(), even if m_canvasPlatformLayer equals platformLayer.
401             m_pendingCanvasOperation |= RecreateCanvas;
402         }
403     } else {
404         if (platformLayer)
405             m_pendingCanvasOperation |= CreateAndSyncCanvas;
406     }
407
408     m_canvasPlatformLayer = platformLayer;
409     // m_canvasToken is updated only here. In detail, when GraphicsContext3D is changed or reshaped, m_canvasToken is changed and setContentsToCanvas() is always called.
410     m_canvasSize = m_canvasPlatformLayer ? m_canvasPlatformLayer->platformLayerSize() : IntSize();
411     m_canvasToken = m_canvasPlatformLayer ? m_canvasPlatformLayer->graphicsSurfaceToken() : GraphicsSurfaceToken();
412     ASSERT(!(!m_canvasToken.isValid() && m_canvasPlatformLayer));
413
414     if (client())
415         client()->notifyFlushRequired(this);
416 #else
417     UNUSED_PARAM(platformLayer);
418 #endif
419 }
420
421 #if ENABLE(CSS_FILTERS)
422 bool CoordinatedGraphicsLayer::setFilters(const FilterOperations& newFilters)
423 {
424     if (filters() == newFilters)
425         return true;
426
427     if (!GraphicsLayer::setFilters(newFilters))
428         return false;
429
430     didChangeFilters();
431     return true;
432 }
433 #endif
434
435 void CoordinatedGraphicsLayer::setContentsToSolidColor(const Color& color)
436 {
437     if (m_layerState.solidColor == color)
438         return;
439
440     m_layerState.solidColor = color;
441     m_layerState.solidColorChanged = true;
442
443     didChangeLayerState();
444 }
445
446 void CoordinatedGraphicsLayer::setShowDebugBorder(bool show)
447 {
448     if (isShowingDebugBorder() == show)
449         return;
450
451     GraphicsLayer::setShowDebugBorder(show);
452     m_layerState.showDebugBorders = true;
453     m_layerState.flagsChanged = true;
454
455     didChangeLayerState();
456 }
457
458 void CoordinatedGraphicsLayer::setShowRepaintCounter(bool show)
459 {
460     if (isShowingRepaintCounter() == show)
461         return;
462
463     GraphicsLayer::setShowRepaintCounter(show);
464     m_layerState.showRepaintCounter = true;
465     m_layerState.flagsChanged = true;
466
467     didChangeLayerState();
468 }
469
470 void CoordinatedGraphicsLayer::setContentsToImage(Image* image)
471 {
472     NativeImagePtr newNativeImagePtr = image ? image->nativeImageForCurrentFrame() : 0;
473     if (newNativeImagePtr) {
474         // This code makes the assumption that pointer equality on a NativeImagePtr is a valid way to tell if the image is changed.
475         // This assumption is true in Qt, GTK and EFL.
476         if (newNativeImagePtr == m_compositedNativeImagePtr)
477             return;
478
479         m_compositedImage = image;
480         m_compositedNativeImagePtr = newNativeImagePtr;
481     } else {
482         m_compositedImage = 0;
483         m_compositedNativeImagePtr = 0;
484     }
485
486     GraphicsLayer::setContentsToImage(image);
487     didChangeImageBacking();
488 }
489
490 void CoordinatedGraphicsLayer::setMaskLayer(GraphicsLayer* layer)
491 {
492     if (layer == maskLayer())
493         return;
494
495     GraphicsLayer::setMaskLayer(layer);
496
497     if (!layer)
498         return;
499
500     layer->setSize(size());
501     layer->setContentsVisible(contentsAreVisible());
502     CoordinatedGraphicsLayer* coordinatedLayer = toCoordinatedGraphicsLayer(layer);
503     coordinatedLayer->didChangeLayerState();
504
505     m_layerState.mask = coordinatedLayer->id();
506     m_layerState.maskChanged = true;
507
508     didChangeLayerState();
509 }
510
511 bool CoordinatedGraphicsLayer::shouldDirectlyCompositeImage(Image* image) const
512 {
513     if (!image || !image->isBitmapImage())
514         return false;
515
516     enum { MaxDimenstionForDirectCompositing = 2000 };
517     if (image->width() > MaxDimenstionForDirectCompositing || image->height() > MaxDimenstionForDirectCompositing)
518         return false;
519
520     return true;
521 }
522
523 void CoordinatedGraphicsLayer::setReplicatedByLayer(GraphicsLayer* layer)
524 {
525     if (layer == replicaLayer())
526         return;
527
528     GraphicsLayer::setReplicatedByLayer(layer);
529     m_layerState.replica = toCoordinatedLayerID(layer);
530     m_layerState.replicaChanged = true;
531     didChangeLayerState();
532 }
533
534 void CoordinatedGraphicsLayer::setNeedsDisplay()
535 {
536     setNeedsDisplayInRect(FloatRect(FloatPoint(), size()));
537 }
538
539 void CoordinatedGraphicsLayer::setNeedsDisplayInRect(const FloatRect& rect)
540 {
541     if (m_mainBackingStore)
542         m_mainBackingStore->invalidate(IntRect(rect));
543
544     didChangeLayerState();
545
546     addRepaintRect(rect);
547 }
548
549 CoordinatedLayerID CoordinatedGraphicsLayer::id() const
550 {
551     return m_id;
552 }
553
554 void CoordinatedGraphicsLayer::setScrollableArea(ScrollableArea* scrollableArea)
555 {
556     bool oldScrollable = isScrollable();
557     m_scrollableArea = scrollableArea;
558     if (oldScrollable == isScrollable())
559         return;
560
561     m_layerState.isScrollable = isScrollable();
562     m_layerState.flagsChanged = true;
563     didChangeLayerState();
564 }
565
566 void CoordinatedGraphicsLayer::commitScrollOffset(const IntSize& offset)
567 {
568     if (!isScrollable() || offset.isZero())
569         return;
570
571     m_scrollableArea->notifyScrollPositionChanged(m_scrollableArea->scrollPosition() + offset);
572     m_layerState.committedScrollOffset += offset;
573     m_layerState.committedScrollOffsetChanged = true;
574     didChangeLayerState();
575 }
576
577 void CoordinatedGraphicsLayer::setFixedToViewport(bool isFixed)
578 {
579     if (m_fixedToViewport == isFixed)
580         return;
581
582     m_fixedToViewport = isFixed;
583     m_layerState.fixedToViewport = isFixed;
584     m_layerState.flagsChanged = true;
585
586     didChangeLayerState();
587 }
588
589 void CoordinatedGraphicsLayer::flushCompositingState(const FloatRect& rect)
590 {
591     if (!m_coordinator->isFlushingLayerChanges()) {
592         if (client())
593             client()->notifyFlushRequired(this);
594         return;
595     }
596
597     if (CoordinatedGraphicsLayer* mask = toCoordinatedGraphicsLayer(maskLayer()))
598         mask->flushCompositingStateForThisLayerOnly();
599
600     if (CoordinatedGraphicsLayer* replica = toCoordinatedGraphicsLayer(replicaLayer()))
601         replica->flushCompositingStateForThisLayerOnly();
602
603     flushCompositingStateForThisLayerOnly();
604
605     for (size_t i = 0; i < children().size(); ++i)
606         children()[i]->flushCompositingState(rect);
607 }
608
609 CoordinatedGraphicsLayer* toCoordinatedGraphicsLayer(GraphicsLayer* layer)
610 {
611     return static_cast<CoordinatedGraphicsLayer*>(layer);
612 }
613
614 void CoordinatedGraphicsLayer::syncChildren()
615 {
616     if (!m_shouldSyncChildren)
617         return;
618     m_shouldSyncChildren = false;
619     m_layerState.childrenChanged = true;
620     m_layerState.children.clear();
621     for (size_t i = 0; i < children().size(); ++i)
622         m_layerState.children.append(toCoordinatedLayerID(children()[i]));
623 }
624
625 #if ENABLE(CSS_FILTERS)
626 void CoordinatedGraphicsLayer::syncFilters()
627 {
628     if (!m_shouldSyncFilters)
629         return;
630     m_shouldSyncFilters = false;
631
632     m_layerState.filters = GraphicsLayer::filters();
633     m_layerState.filtersChanged = true;
634 }
635 #endif
636
637 void CoordinatedGraphicsLayer::syncImageBacking()
638 {
639     if (!m_shouldSyncImageBacking)
640         return;
641     m_shouldSyncImageBacking = false;
642
643     if (m_compositedNativeImagePtr) {
644         ASSERT(!shouldHaveBackingStore());
645         ASSERT(m_compositedImage);
646
647         bool imageInstanceReplaced = m_coordinatedImageBacking && (m_coordinatedImageBacking->id() != CoordinatedImageBacking::getCoordinatedImageBackingID(m_compositedImage.get()));
648         if (imageInstanceReplaced)
649             releaseImageBackingIfNeeded();
650
651         if (!m_coordinatedImageBacking) {
652             m_coordinatedImageBacking = m_coordinator->createImageBackingIfNeeded(m_compositedImage.get());
653             m_coordinatedImageBacking->addHost(this);
654             m_layerState.imageID = m_coordinatedImageBacking->id();
655         }
656
657         m_coordinatedImageBacking->markDirty();
658         m_layerState.imageChanged = true;
659     } else
660         releaseImageBackingIfNeeded();
661
662     // syncImageBacking() changed m_layerState.imageID.
663     didChangeLayerState();
664 }
665
666 void CoordinatedGraphicsLayer::syncLayerState()
667 {
668     if (!m_shouldSyncLayerState)
669         return;
670     m_shouldSyncLayerState = false;
671
672     m_layerState.childrenTransform = childrenTransform();
673     m_layerState.contentsRect = contentsRect();
674     m_layerState.mask = toCoordinatedLayerID(maskLayer());
675     m_layerState.opacity = opacity();
676     m_layerState.replica = toCoordinatedLayerID(replicaLayer());
677     m_layerState.transform = transform();
678
679     m_layerState.anchorPoint = m_adjustedAnchorPoint;
680     m_layerState.pos = m_adjustedPosition;
681     m_layerState.size = m_adjustedSize;
682
683     if (m_layerState.flagsChanged) {
684         m_layerState.drawsContent = drawsContent();
685         m_layerState.contentsVisible = contentsAreVisible();
686         m_layerState.backfaceVisible = backfaceVisibility();
687         m_layerState.masksToBounds = masksToBounds();
688         m_layerState.preserves3D = preserves3D();
689         m_layerState.fixedToViewport = fixedToViewport();
690         m_layerState.showDebugBorders = isShowingDebugBorder();
691         m_layerState.showRepaintCounter = isShowingRepaintCounter();
692         m_layerState.isScrollable = isScrollable();
693     }
694
695     if (m_layerState.showDebugBorders)
696         updateDebugIndicators();
697 }
698
699 void CoordinatedGraphicsLayer::setDebugBorder(const Color& color, float width)
700 {
701     ASSERT(m_layerState.showDebugBorders);
702     if (m_layerState.debugBorderColor != color) {
703         m_layerState.debugBorderColor = color;
704         m_layerState.debugBorderColorChanged = true;
705     }
706
707     if (m_layerState.debugBorderWidth != width) {
708         m_layerState.debugBorderWidth = width;
709         m_layerState.debugBorderWidthChanged = true;
710     }
711 }
712
713 void CoordinatedGraphicsLayer::syncAnimations()
714 {
715     if (!m_shouldSyncAnimations)
716         return;
717
718     m_shouldSyncAnimations = false;
719     m_layerState.animations = m_animations.getActiveAnimations();
720     m_layerState.animationsChanged = true;
721 }
722
723 #if USE(GRAPHICS_SURFACE)
724 void CoordinatedGraphicsLayer::syncCanvas()
725 {
726     destroyCanvasIfNeeded();
727     createCanvasIfNeeded();
728
729     if (!(m_pendingCanvasOperation & SyncCanvas))
730         return;
731
732     m_pendingCanvasOperation &= ~SyncCanvas;
733
734     if (!m_isValidCanvas)
735         return;
736
737     ASSERT(m_canvasPlatformLayer);
738     m_layerState.canvasFrontBuffer = m_canvasPlatformLayer->copyToGraphicsSurface();
739     m_layerState.canvasShouldSwapBuffers = true;
740 }
741
742 void CoordinatedGraphicsLayer::destroyCanvasIfNeeded()
743 {
744     if (!(m_pendingCanvasOperation & DestroyCanvas))
745         return;
746
747     if (m_isValidCanvas) {
748         m_isValidCanvas = false;
749         m_layerState.canvasToken = GraphicsSurfaceToken();
750         m_layerState.canvasChanged = true;
751     }
752
753     m_pendingCanvasOperation &= ~DestroyCanvas;
754 }
755
756 void CoordinatedGraphicsLayer::createCanvasIfNeeded()
757 {
758     if (!(m_pendingCanvasOperation & CreateCanvas))
759         return;
760
761     ASSERT(m_canvasPlatformLayer);
762     if (!m_isValidCanvas) {
763         m_layerState.canvasSize = m_canvasPlatformLayer->platformLayerSize();
764         m_layerState.canvasToken = m_canvasPlatformLayer->graphicsSurfaceToken();
765         m_layerState.canvasSurfaceFlags = m_canvasPlatformLayer->graphicsSurfaceFlags();
766         m_layerState.canvasChanged = true;
767         m_isValidCanvas = true;
768     }
769
770     m_pendingCanvasOperation &= ~CreateCanvas;
771 }
772 #endif
773
774 void CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly()
775 {
776     ASSERT(m_coordinator->isFlushingLayerChanges());
777
778     // When we have a transform animation, we need to update visible rect every frame to adjust the visible rect of a backing store.
779     bool hasActiveTransformAnimation = selfOrAncestorHasActiveTransformAnimation();
780     if (hasActiveTransformAnimation)
781         m_movingVisibleRect = true;
782
783     // Sets the values.
784     computePixelAlignment(m_adjustedPosition, m_adjustedSize, m_adjustedAnchorPoint, m_pixelAlignmentOffset);
785
786     syncImageBacking();
787     syncLayerState();
788     syncAnimations();
789     computeTransformedVisibleRect();
790     syncChildren();
791 #if ENABLE(CSS_FILTERS)
792     syncFilters();
793 #endif
794 #if USE(GRAPHICS_SURFACE)
795     syncCanvas();
796 #endif
797
798     // Only unset m_movingVisibleRect after we have updated the visible rect after the animation stopped.
799     if (!hasActiveTransformAnimation)
800         m_movingVisibleRect = false;
801 }
802
803 void CoordinatedGraphicsLayer::syncPendingStateChangesIncludingSubLayers()
804 {
805     if (m_layerState.hasPendingChanges()) {
806         m_coordinator->syncLayerState(m_id, m_layerState);
807         resetLayerState();
808     }
809
810     for (size_t i = 0; i < children().size(); ++i)
811         toCoordinatedGraphicsLayer(children()[i])->syncPendingStateChangesIncludingSubLayers();
812 }
813
814 void CoordinatedGraphicsLayer::resetLayerState()
815 {
816     m_layerState.changeMask = 0;
817     m_layerState.tilesToCreate.clear();
818     m_layerState.tilesToRemove.clear();
819     m_layerState.tilesToUpdate.clear();
820     m_layerState.committedScrollOffset = IntSize();
821 }
822
823 bool CoordinatedGraphicsLayer::imageBackingVisible()
824 {
825     ASSERT(m_coordinatedImageBacking);
826     return tiledBackingStoreVisibleRect().intersects(contentsRect());
827 }
828
829 void CoordinatedGraphicsLayer::releaseImageBackingIfNeeded()
830 {
831     if (!m_coordinatedImageBacking)
832         return;
833
834     ASSERT(m_coordinator);
835     m_coordinatedImageBacking->removeHost(this);
836     m_coordinatedImageBacking.clear();
837     m_layerState.imageID = InvalidCoordinatedImageBackingID;
838     m_layerState.imageChanged = true;
839 }
840
841 void CoordinatedGraphicsLayer::tiledBackingStorePaintBegin()
842 {
843 }
844
845 CoordinatedGraphicsLayer* CoordinatedGraphicsLayer::findFirstDescendantWithContentsRecursively()
846 {
847     if (shouldHaveBackingStore())
848         return this;
849
850     for (size_t i = 0; i < children().size(); ++i) {
851         CoordinatedGraphicsLayer* layer = toCoordinatedGraphicsLayer(children()[i])->findFirstDescendantWithContentsRecursively();
852         if (layer)
853             return layer;
854     }
855
856     return 0;
857 }
858
859 void CoordinatedGraphicsLayer::setVisibleContentRectTrajectoryVector(const FloatPoint& trajectoryVector)
860 {
861     if (!m_mainBackingStore)
862         return;
863
864     m_mainBackingStore->setTrajectoryVector(trajectoryVector);
865     setNeedsVisibleRectAdjustment();
866 }
867
868 void CoordinatedGraphicsLayer::deviceOrPageScaleFactorChanged()
869 {
870     if (shouldHaveBackingStore())
871         m_pendingContentsScaleAdjustment = true;
872 }
873
874 float CoordinatedGraphicsLayer::effectiveContentsScale()
875 {
876     return selfOrAncestorHaveNonAffineTransforms() ? 1 : deviceScaleFactor() * pageScaleFactor();
877 }
878
879 void CoordinatedGraphicsLayer::adjustContentsScale()
880 {
881     ASSERT(shouldHaveBackingStore());
882     if (!m_mainBackingStore || m_mainBackingStore->contentsScale() == effectiveContentsScale())
883         return;
884
885     // Between creating the new backing store and painting the content,
886     // we do not want to drop the previous one as that might result in
887     // briefly seeing flickering as the old tiles may be dropped before
888     // something replaces them.
889     m_previousBackingStore = m_mainBackingStore.release();
890
891     // No reason to save the previous backing store for non-visible areas.
892     m_previousBackingStore->removeAllNonVisibleTiles();
893 }
894
895 void CoordinatedGraphicsLayer::createBackingStore()
896 {
897     m_mainBackingStore = adoptPtr(new TiledBackingStore(this, CoordinatedTileBackend::create(this)));
898     m_mainBackingStore->setSupportsAlpha(!contentsOpaque());
899     m_mainBackingStore->setContentsScale(effectiveContentsScale());
900 }
901
902 void CoordinatedGraphicsLayer::tiledBackingStorePaint(GraphicsContext* context, const IntRect& rect)
903 {
904     if (rect.isEmpty())
905         return;
906     paintGraphicsLayerContents(*context, rect);
907 }
908
909 void CoordinatedGraphicsLayer::tiledBackingStorePaintEnd(const Vector<IntRect>& updatedRects)
910 {
911     if (!isShowingRepaintCounter() || updatedRects.isEmpty())
912         return;
913
914     m_layerState.repaintCount = incrementRepaintCount();
915     m_layerState.repaintCountChanged = true;
916 }
917
918 void CoordinatedGraphicsLayer::tiledBackingStoreHasPendingTileCreation()
919 {
920     setNeedsVisibleRectAdjustment();
921     if (client())
922         client()->notifyFlushRequired(this);
923 }
924
925 IntRect CoordinatedGraphicsLayer::tiledBackingStoreContentsRect()
926 {
927     return IntRect(0, 0, size().width(), size().height());
928 }
929
930 static void clampToContentsRectIfRectIsInfinite(FloatRect& rect, const IntRect& contentsRect)
931 {
932     if (rect.width() >= LayoutUnit::nearlyMax() || rect.width() <= LayoutUnit::nearlyMin()) {
933         rect.setX(contentsRect.x());
934         rect.setWidth(contentsRect.width());
935     }
936
937     if (rect.height() >= LayoutUnit::nearlyMax() || rect.height() <= LayoutUnit::nearlyMin()) {
938         rect.setY(contentsRect.y());
939         rect.setHeight(contentsRect.height());
940     }
941 }
942
943 IntRect CoordinatedGraphicsLayer::tiledBackingStoreVisibleRect()
944 {
945     // Non-invertible layers are not visible.
946     if (!m_layerTransform.combined().isInvertible())
947         return IntRect();
948
949     // Return a projection of the visible rect (surface coordinates) onto the layer's plane (layer coordinates).
950     // The resulting quad might be squewed and the visible rect is the bounding box of this quad,
951     // so it might spread further than the real visible area (and then even more amplified by the cover rect multiplier).
952     ASSERT(m_cachedInverseTransform == m_layerTransform.combined().inverse());
953     FloatRect rect = m_cachedInverseTransform.clampedBoundsOfProjectedQuad(FloatQuad(m_coordinator->visibleContentsRect()));
954     clampToContentsRectIfRectIsInfinite(rect, tiledBackingStoreContentsRect());
955     return enclosingIntRect(rect);
956 }
957
958 Color CoordinatedGraphicsLayer::tiledBackingStoreBackgroundColor() const
959 {
960     return contentsOpaque() ? Color::white : Color::transparent;
961 }
962
963 bool CoordinatedGraphicsLayer::paintToSurface(const IntSize& size, uint32_t& atlas, IntPoint& offset, CoordinatedSurface::Client* client)
964 {
965     ASSERT(m_coordinator);
966     ASSERT(m_coordinator->isFlushingLayerChanges());
967     return m_coordinator->paintToSurface(size, contentsOpaque() ? CoordinatedSurface::NoFlags : CoordinatedSurface::SupportsAlpha, atlas, offset, client);
968 }
969
970 void CoordinatedGraphicsLayer::createTile(uint32_t tileID, const SurfaceUpdateInfo& updateInfo, const IntRect& tileRect)
971 {
972     ASSERT(m_coordinator);
973     ASSERT(m_coordinator->isFlushingLayerChanges());
974
975     TileCreationInfo creationInfo;
976     creationInfo.tileID = tileID;
977     creationInfo.scale = updateInfo.scaleFactor;
978
979     m_layerState.tilesToCreate.append(creationInfo);
980     updateTile(tileID, updateInfo, tileRect);
981 }
982
983 void CoordinatedGraphicsLayer::updateTile(uint32_t tileID, const SurfaceUpdateInfo& updateInfo, const IntRect& tileRect)
984 {
985     ASSERT(m_coordinator);
986     ASSERT(m_coordinator->isFlushingLayerChanges());
987
988     TileUpdateInfo tileUpdateInfo;
989     tileUpdateInfo.tileID = tileID;
990     tileUpdateInfo.tileRect = tileRect;
991     tileUpdateInfo.updateInfo = updateInfo;
992     m_layerState.tilesToUpdate.append(tileUpdateInfo);
993 }
994
995 void CoordinatedGraphicsLayer::removeTile(uint32_t tileID)
996 {
997     ASSERT(m_coordinator);
998     ASSERT(m_coordinator->isFlushingLayerChanges() || m_isPurging);
999     m_layerState.tilesToRemove.append(tileID);
1000 }
1001
1002 void CoordinatedGraphicsLayer::updateContentBuffersIncludingSubLayers()
1003 {
1004     if (CoordinatedGraphicsLayer* mask = toCoordinatedGraphicsLayer(maskLayer()))
1005         mask->updateContentBuffers();
1006
1007     if (CoordinatedGraphicsLayer* replica = toCoordinatedGraphicsLayer(replicaLayer()))
1008         replica->updateContentBuffers();
1009
1010     updateContentBuffers();
1011
1012     for (size_t i = 0; i < children().size(); ++i)
1013         toCoordinatedGraphicsLayer(children()[i])->updateContentBuffersIncludingSubLayers();
1014 }
1015
1016 void CoordinatedGraphicsLayer::updateContentBuffers()
1017 {
1018     if (!shouldHaveBackingStore()) {
1019         m_mainBackingStore.clear();
1020         m_previousBackingStore.clear();
1021         return;
1022     }
1023
1024     if (m_pendingContentsScaleAdjustment) {
1025         adjustContentsScale();
1026         m_pendingContentsScaleAdjustment = false;
1027     }
1028
1029     // This is the only place we (re)create the main tiled backing store, once we
1030     // have a remote client and we are ready to send our data to the UI process.
1031     if (!m_mainBackingStore)
1032         createBackingStore();
1033
1034     if (m_pendingVisibleRectAdjustment) {
1035         m_pendingVisibleRectAdjustment = false;
1036         m_mainBackingStore->coverWithTilesIfNeeded();
1037     }
1038
1039     m_mainBackingStore->updateTileBuffers();
1040
1041     // The previous backing store is kept around to avoid flickering between
1042     // removing the existing tiles and painting the new ones. The first time
1043     // the visibleRect is full painted we remove the previous backing store.
1044     if (m_mainBackingStore->visibleAreaIsCovered())
1045         m_previousBackingStore.clear();
1046 }
1047
1048 void CoordinatedGraphicsLayer::purgeBackingStores()
1049 {
1050 #ifndef NDEBUG
1051     TemporaryChange<bool> updateModeProtector(m_isPurging, true);
1052 #endif
1053     m_mainBackingStore.clear();
1054     m_previousBackingStore.clear();
1055
1056     releaseImageBackingIfNeeded();
1057
1058     didChangeLayerState();
1059 }
1060
1061 void CoordinatedGraphicsLayer::setCoordinator(CoordinatedGraphicsLayerClient* coordinator)
1062 {
1063     m_coordinator = coordinator;
1064 }
1065
1066 void CoordinatedGraphicsLayer::setNeedsVisibleRectAdjustment()
1067 {
1068     if (shouldHaveBackingStore())
1069         m_pendingVisibleRectAdjustment = true;
1070 }
1071
1072 bool CoordinatedGraphicsLayer::hasPendingVisibleChanges()
1073 {
1074     if (opacity() < 0.01 && !m_animations.hasActiveAnimationsOfType(AnimatedPropertyOpacity))
1075         return false;
1076
1077     for (size_t i = 0; i < children().size(); ++i) {
1078         if (toCoordinatedGraphicsLayer(children()[i])->hasPendingVisibleChanges())
1079             return true;
1080     }
1081
1082     bool shouldSyncCanvas = false;
1083 #if USE(GRAPHICS_SURFACE)
1084     shouldSyncCanvas = m_pendingCanvasOperation & SyncCanvas;
1085 #endif
1086
1087     if (!m_shouldSyncLayerState && !m_shouldSyncChildren && !m_shouldSyncFilters && !m_shouldSyncImageBacking && !m_shouldSyncAnimations && !shouldSyncCanvas)
1088         return false;
1089
1090     return tiledBackingStoreVisibleRect().intersects(tiledBackingStoreContentsRect());
1091 }
1092
1093 static inline bool isIntegral(float value)
1094 {
1095     return static_cast<int>(value) == value;
1096 }
1097
1098 FloatPoint CoordinatedGraphicsLayer::computePositionRelativeToBase()
1099 {
1100     FloatPoint offset;
1101     for (const GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent())
1102         offset += currLayer->position();
1103
1104     return offset;
1105 }
1106
1107 void CoordinatedGraphicsLayer::computePixelAlignment(FloatPoint& position, FloatSize& size, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset)
1108 {
1109     if (isIntegral(effectiveContentsScale())) {
1110         position = m_position;
1111         size = m_size;
1112         anchorPoint = m_anchorPoint;
1113         alignmentOffset = FloatSize();
1114         return;
1115     }
1116
1117     FloatPoint positionRelativeToBase = computePositionRelativeToBase();
1118
1119     FloatRect baseRelativeBounds(positionRelativeToBase, m_size);
1120     FloatRect scaledBounds = baseRelativeBounds;
1121
1122     // Scale by the effective scale factor to compute the screen-relative bounds.
1123     scaledBounds.scale(effectiveContentsScale());
1124
1125     // Round to integer boundaries.
1126     // NOTE: When using enclosingIntRect (as mac) it will have different sizes depending on position.
1127     FloatRect alignedBounds = roundedIntRect(scaledBounds);
1128
1129     // Convert back to layer coordinates.
1130     alignedBounds.scale(1 / effectiveContentsScale());
1131
1132     // Convert back to layer coordinates.
1133     alignmentOffset = baseRelativeBounds.location() - alignedBounds.location();
1134
1135     position = m_position - alignmentOffset;
1136     size = alignedBounds.size();
1137
1138     // Now we have to compute a new anchor point which compensates for rounding.
1139     float anchorPointX = m_anchorPoint.x();
1140     float anchorPointY = m_anchorPoint.y();
1141
1142     if (alignedBounds.width())
1143         anchorPointX = (baseRelativeBounds.width() * anchorPointX + alignmentOffset.width()) / alignedBounds.width();
1144
1145     if (alignedBounds.height())
1146         anchorPointY = (baseRelativeBounds.height() * anchorPointY + alignmentOffset.height()) / alignedBounds.height();
1147
1148     anchorPoint = FloatPoint3D(anchorPointX, anchorPointY, m_anchorPoint.z() * effectiveContentsScale());
1149 }
1150
1151 void CoordinatedGraphicsLayer::computeTransformedVisibleRect()
1152 {
1153     if (!m_shouldUpdateVisibleRect && !m_movingVisibleRect)
1154         return;
1155
1156     m_shouldUpdateVisibleRect = false;
1157     TransformationMatrix currentTransform = transform();
1158     if (m_movingVisibleRect)
1159         client()->getCurrentTransform(this, currentTransform);
1160     m_layerTransform.setLocalTransform(currentTransform);
1161
1162     m_layerTransform.setAnchorPoint(m_adjustedAnchorPoint);
1163     m_layerTransform.setPosition(m_adjustedPosition);
1164     m_layerTransform.setSize(m_adjustedSize);
1165
1166     m_layerTransform.setFlattening(!preserves3D());
1167     m_layerTransform.setChildrenTransform(childrenTransform());
1168     m_layerTransform.combineTransforms(parent() ? toCoordinatedGraphicsLayer(parent())->m_layerTransform.combinedForChildren() : TransformationMatrix());
1169
1170     m_cachedInverseTransform = m_layerTransform.combined().inverse();
1171
1172     // The combined transform will be used in tiledBackingStoreVisibleRect.
1173     setNeedsVisibleRectAdjustment();
1174 }
1175
1176 bool CoordinatedGraphicsLayer::shouldHaveBackingStore() const
1177 {
1178     return drawsContent() && contentsAreVisible() && !m_size.isEmpty();
1179 }
1180
1181 bool CoordinatedGraphicsLayer::selfOrAncestorHasActiveTransformAnimation() const
1182 {
1183     if (m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitTransform))
1184         return true;
1185
1186     if (!parent())
1187         return false;
1188
1189     return toCoordinatedGraphicsLayer(parent())->selfOrAncestorHasActiveTransformAnimation();
1190 }
1191
1192 bool CoordinatedGraphicsLayer::selfOrAncestorHaveNonAffineTransforms()
1193 {
1194     if (m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitTransform))
1195         return true;
1196
1197     if (!m_layerTransform.combined().isAffine())
1198         return true;
1199
1200     if (!parent())
1201         return false;
1202
1203     return toCoordinatedGraphicsLayer(parent())->selfOrAncestorHaveNonAffineTransforms();
1204 }
1205
1206 bool CoordinatedGraphicsLayer::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double delayAsNegativeTimeOffset)
1207 {
1208     ASSERT(!keyframesName.isEmpty());
1209
1210     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2 || (valueList.property() != AnimatedPropertyWebkitTransform && valueList.property() != AnimatedPropertyOpacity && valueList.property() != AnimatedPropertyWebkitFilter))
1211         return false;
1212
1213     bool listsMatch = false;
1214     bool ignoredHasBigRotation;
1215
1216     if (valueList.property() == AnimatedPropertyWebkitTransform)
1217         listsMatch = validateTransformOperations(valueList, ignoredHasBigRotation) >= 0;
1218
1219     m_lastAnimationStartTime = monotonicallyIncreasingTime() - delayAsNegativeTimeOffset;
1220     m_animations.add(GraphicsLayerAnimation(keyframesName, valueList, boxSize, anim, m_lastAnimationStartTime, listsMatch));
1221     m_animationStartedTimer.startOneShot(0);
1222     didChangeAnimations();
1223     return true;
1224 }
1225
1226 void CoordinatedGraphicsLayer::pauseAnimation(const String& animationName, double time)
1227 {
1228     m_animations.pause(animationName, time);
1229     didChangeAnimations();
1230 }
1231
1232 void CoordinatedGraphicsLayer::removeAnimation(const String& animationName)
1233 {
1234     m_animations.remove(animationName);
1235     didChangeAnimations();
1236 }
1237
1238 void CoordinatedGraphicsLayer::suspendAnimations(double time)
1239 {
1240     m_animations.suspend(time);
1241     didChangeAnimations();
1242 }
1243
1244 void CoordinatedGraphicsLayer::resumeAnimations()
1245 {
1246     m_animations.resume();
1247     didChangeAnimations();
1248 }
1249
1250 void CoordinatedGraphicsLayer::animationStartedTimerFired(Timer<CoordinatedGraphicsLayer>*)
1251 {
1252     client()->notifyAnimationStarted(this, m_lastAnimationStartTime);
1253 }
1254 } // namespace WebCore
1255 #endif // USE(COORDINATED_GRAPHICS)