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