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