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