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