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