Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / GraphicsLayer.cpp
1 /*
2  * Copyright (C) 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "platform/graphics/GraphicsLayer.h"
28
29 #include "SkImageFilter.h"
30 #include "SkMatrix44.h"
31 #include "platform/TraceEvent.h"
32 #include "platform/geometry/FloatRect.h"
33 #include "platform/geometry/LayoutRect.h"
34 #include "platform/graphics/FirstPaintInvalidationTracking.h"
35 #include "platform/graphics/GraphicsLayerFactory.h"
36 #include "platform/graphics/Image.h"
37 #include "platform/graphics/filters/SkiaImageFilterBuilder.h"
38 #include "platform/graphics/skia/NativeImageSkia.h"
39 #include "platform/scroll/ScrollableArea.h"
40 #include "platform/text/TextStream.h"
41 #include "public/platform/Platform.h"
42 #include "public/platform/WebCompositorAnimation.h"
43 #include "public/platform/WebCompositorSupport.h"
44 #include "public/platform/WebFilterOperations.h"
45 #include "public/platform/WebFloatPoint.h"
46 #include "public/platform/WebFloatRect.h"
47 #include "public/platform/WebGraphicsLayerDebugInfo.h"
48 #include "public/platform/WebLayer.h"
49 #include "public/platform/WebPoint.h"
50 #include "public/platform/WebSize.h"
51 #include "wtf/CurrentTime.h"
52 #include "wtf/HashMap.h"
53 #include "wtf/HashSet.h"
54 #include "wtf/text/WTFString.h"
55 #include <algorithm>
56
57 #ifndef NDEBUG
58 #include <stdio.h>
59 #endif
60
61 namespace blink {
62
63 typedef HashMap<const GraphicsLayer*, Vector<FloatRect> > RepaintMap;
64 static RepaintMap& repaintRectMap()
65 {
66     DEFINE_STATIC_LOCAL(RepaintMap, map, ());
67     return map;
68 }
69
70 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client)
71 {
72     return factory->createGraphicsLayer(client);
73 }
74
75 GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
76     : m_client(client)
77     , m_backgroundColor(Color::transparent)
78     , m_opacity(1)
79     , m_blendMode(WebBlendModeNormal)
80     , m_hasTransformOrigin(false)
81     , m_contentsOpaque(false)
82     , m_shouldFlattenTransform(true)
83     , m_backfaceVisibility(true)
84     , m_masksToBounds(false)
85     , m_drawsContent(false)
86     , m_contentsVisible(true)
87     , m_isRootForIsolatedGroup(false)
88     , m_hasScrollParent(false)
89     , m_hasClipParent(false)
90     , m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip)
91     , m_parent(0)
92     , m_maskLayer(0)
93     , m_contentsClippingMaskLayer(0)
94     , m_replicaLayer(0)
95     , m_replicatedLayer(0)
96     , m_paintCount(0)
97     , m_contentsLayer(0)
98     , m_contentsLayerId(0)
99     , m_scrollableArea(0)
100     , m_3dRenderingContext(0)
101 {
102 #if ENABLE(ASSERT)
103     if (m_client)
104         m_client->verifyNotPainting();
105 #endif
106
107     m_contentLayerDelegate = adoptPtr(new ContentLayerDelegate(this));
108     m_layer = adoptPtr(Platform::current()->compositorSupport()->createContentLayer(m_contentLayerDelegate.get()));
109     m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible);
110     m_layer->layer()->setWebLayerClient(this);
111     m_layer->setAutomaticallyComputeRasterScale(true);
112 }
113
114 GraphicsLayer::~GraphicsLayer()
115 {
116     for (size_t i = 0; i < m_linkHighlights.size(); ++i)
117         m_linkHighlights[i]->clearCurrentGraphicsLayer();
118     m_linkHighlights.clear();
119
120 #if ENABLE(ASSERT)
121     if (m_client)
122         m_client->verifyNotPainting();
123 #endif
124
125     if (m_replicaLayer)
126         m_replicaLayer->setReplicatedLayer(0);
127
128     if (m_replicatedLayer)
129         m_replicatedLayer->setReplicatedByLayer(0);
130
131     removeAllChildren();
132     removeFromParent();
133
134     resetTrackedPaintInvalidations();
135     ASSERT(!m_parent);
136 }
137
138 void GraphicsLayer::setParent(GraphicsLayer* layer)
139 {
140     ASSERT(!layer || !layer->hasAncestor(this));
141     m_parent = layer;
142 }
143
144 #if ENABLE(ASSERT)
145
146 bool GraphicsLayer::hasAncestor(GraphicsLayer* ancestor) const
147 {
148     for (GraphicsLayer* curr = parent(); curr; curr = curr->parent()) {
149         if (curr == ancestor)
150             return true;
151     }
152
153     return false;
154 }
155
156 #endif
157
158 bool GraphicsLayer::setChildren(const GraphicsLayerVector& newChildren)
159 {
160     // If the contents of the arrays are the same, nothing to do.
161     if (newChildren == m_children)
162         return false;
163
164     removeAllChildren();
165
166     size_t listSize = newChildren.size();
167     for (size_t i = 0; i < listSize; ++i)
168         addChildInternal(newChildren[i]);
169
170     updateChildList();
171
172     return true;
173 }
174
175 void GraphicsLayer::addChildInternal(GraphicsLayer* childLayer)
176 {
177     ASSERT(childLayer != this);
178
179     if (childLayer->parent())
180         childLayer->removeFromParent();
181
182     childLayer->setParent(this);
183     m_children.append(childLayer);
184
185     // Don't call updateChildList here, this function is used in cases where it
186     // should not be called until all children are processed.
187 }
188
189 void GraphicsLayer::addChild(GraphicsLayer* childLayer)
190 {
191     addChildInternal(childLayer);
192     updateChildList();
193 }
194
195 void GraphicsLayer::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
196 {
197     ASSERT(childLayer != this);
198     childLayer->removeFromParent();
199
200     bool found = false;
201     for (unsigned i = 0; i < m_children.size(); i++) {
202         if (sibling == m_children[i]) {
203             m_children.insert(i, childLayer);
204             found = true;
205             break;
206         }
207     }
208
209     childLayer->setParent(this);
210
211     if (!found)
212         m_children.append(childLayer);
213
214     updateChildList();
215 }
216
217 void GraphicsLayer::removeAllChildren()
218 {
219     while (!m_children.isEmpty()) {
220         GraphicsLayer* curLayer = m_children.last();
221         ASSERT(curLayer->parent());
222         curLayer->removeFromParent();
223     }
224 }
225
226 void GraphicsLayer::removeFromParent()
227 {
228     if (m_parent) {
229         // We use reverseFind so that removeAllChildren() isn't n^2.
230         m_parent->m_children.remove(m_parent->m_children.reverseFind(this));
231         setParent(0);
232     }
233
234     platformLayer()->removeFromParent();
235 }
236
237 void GraphicsLayer::setReplicatedByLayer(GraphicsLayer* layer)
238 {
239     // FIXME: this could probably be a full early exit.
240     if (m_replicaLayer != layer) {
241         if (m_replicaLayer)
242             m_replicaLayer->setReplicatedLayer(0);
243
244         if (layer)
245             layer->setReplicatedLayer(this);
246
247         m_replicaLayer = layer;
248     }
249
250     WebLayer* webReplicaLayer = layer ? layer->platformLayer() : 0;
251     platformLayer()->setReplicaLayer(webReplicaLayer);
252 }
253
254 void GraphicsLayer::setOffsetFromRenderer(const IntSize& offset, ShouldSetNeedsDisplay shouldSetNeedsDisplay)
255 {
256     if (offset == m_offsetFromRenderer)
257         return;
258
259     m_offsetFromRenderer = offset;
260
261     // If the compositing layer offset changes, we need to repaint.
262     if (shouldSetNeedsDisplay == SetNeedsDisplay)
263         setNeedsDisplay();
264 }
265
266 void GraphicsLayer::paintGraphicsLayerContents(GraphicsContext& context, const IntRect& clip)
267 {
268     if (!m_client)
269         return;
270     if (firstPaintInvalidationTrackingEnabled())
271         m_debugInfo.clearAnnotatedInvalidateRects();
272     incrementPaintCount();
273     m_client->paintContents(this, context, m_paintingPhase, clip);
274 }
275
276 void GraphicsLayer::updateChildList()
277 {
278     WebLayer* childHost = m_layer->layer();
279     childHost->removeAllChildren();
280
281     clearContentsLayerIfUnregistered();
282
283     if (m_contentsLayer) {
284         // FIXME: add the contents layer in the correct order with negative z-order children.
285         // This does not cause visible rendering issues because currently contents layers are only used
286         // for replaced elements that don't have children.
287         childHost->addChild(m_contentsLayer);
288     }
289
290     for (size_t i = 0; i < m_children.size(); ++i)
291         childHost->addChild(m_children[i]->platformLayer());
292
293     for (size_t i = 0; i < m_linkHighlights.size(); ++i)
294         childHost->addChild(m_linkHighlights[i]->layer());
295 }
296
297 void GraphicsLayer::updateLayerIsDrawable()
298 {
299     // For the rest of the accelerated compositor code, there is no reason to make a
300     // distinction between drawsContent and contentsVisible. So, for m_layer->layer(), these two
301     // flags are combined here. m_contentsLayer shouldn't receive the drawsContent flag
302     // so it is only given contentsVisible.
303
304     m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible);
305     if (WebLayer* contentsLayer = contentsLayerIfRegistered())
306         contentsLayer->setDrawsContent(m_contentsVisible);
307
308     if (m_drawsContent) {
309         m_layer->layer()->invalidate();
310         for (size_t i = 0; i < m_linkHighlights.size(); ++i)
311             m_linkHighlights[i]->invalidate();
312     }
313 }
314
315 void GraphicsLayer::updateContentsRect()
316 {
317     WebLayer* contentsLayer = contentsLayerIfRegistered();
318     if (!contentsLayer)
319         return;
320
321     contentsLayer->setPosition(FloatPoint(m_contentsRect.x(), m_contentsRect.y()));
322     contentsLayer->setBounds(IntSize(m_contentsRect.width(), m_contentsRect.height()));
323
324     if (m_contentsClippingMaskLayer) {
325         if (m_contentsClippingMaskLayer->size() != m_contentsRect.size()) {
326             m_contentsClippingMaskLayer->setSize(m_contentsRect.size());
327             m_contentsClippingMaskLayer->setNeedsDisplay();
328         }
329         m_contentsClippingMaskLayer->setPosition(FloatPoint());
330         m_contentsClippingMaskLayer->setOffsetFromRenderer(offsetFromRenderer() + IntSize(m_contentsRect.location().x(), m_contentsRect.location().y()));
331     }
332 }
333
334 static HashSet<int>* s_registeredLayerSet;
335
336 void GraphicsLayer::registerContentsLayer(WebLayer* layer)
337 {
338     if (!s_registeredLayerSet)
339         s_registeredLayerSet = new HashSet<int>;
340     if (s_registeredLayerSet->contains(layer->id()))
341         CRASH();
342     s_registeredLayerSet->add(layer->id());
343 }
344
345 void GraphicsLayer::unregisterContentsLayer(WebLayer* layer)
346 {
347     ASSERT(s_registeredLayerSet);
348     if (!s_registeredLayerSet->contains(layer->id()))
349         CRASH();
350     s_registeredLayerSet->remove(layer->id());
351 }
352
353 void GraphicsLayer::setContentsTo(WebLayer* layer)
354 {
355     bool childrenChanged = false;
356     if (layer) {
357         ASSERT(s_registeredLayerSet);
358         if (!s_registeredLayerSet->contains(layer->id()))
359             CRASH();
360         if (m_contentsLayerId != layer->id()) {
361             setupContentsLayer(layer);
362             childrenChanged = true;
363         }
364         updateContentsRect();
365     } else {
366         if (m_contentsLayer) {
367             childrenChanged = true;
368
369             // The old contents layer will be removed via updateChildList.
370             m_contentsLayer = 0;
371             m_contentsLayerId = 0;
372         }
373     }
374
375     if (childrenChanged)
376         updateChildList();
377 }
378
379 void GraphicsLayer::setupContentsLayer(WebLayer* contentsLayer)
380 {
381     ASSERT(contentsLayer);
382     m_contentsLayer = contentsLayer;
383     m_contentsLayerId = m_contentsLayer->id();
384
385     m_contentsLayer->setWebLayerClient(this);
386     m_contentsLayer->setTransformOrigin(FloatPoint3D());
387     m_contentsLayer->setUseParentBackfaceVisibility(true);
388
389     // It is necessary to call setDrawsContent as soon as we receive the new contentsLayer, for
390     // the correctness of early exit conditions in setDrawsContent() and setContentsVisible().
391     m_contentsLayer->setDrawsContent(m_contentsVisible);
392
393     // Insert the content layer first. Video elements require this, because they have
394     // shadow content that must display in front of the video.
395     m_layer->layer()->insertChild(m_contentsLayer, 0);
396     WebLayer* borderWebLayer = m_contentsClippingMaskLayer ? m_contentsClippingMaskLayer->platformLayer() : 0;
397     m_contentsLayer->setMaskLayer(borderWebLayer);
398
399     m_contentsLayer->setRenderingContext(m_3dRenderingContext);
400 }
401
402 void GraphicsLayer::clearContentsLayerIfUnregistered()
403 {
404     if (!m_contentsLayerId || s_registeredLayerSet->contains(m_contentsLayerId))
405         return;
406
407     m_contentsLayer = 0;
408     m_contentsLayerId = 0;
409 }
410
411 GraphicsLayerDebugInfo& GraphicsLayer::debugInfo()
412 {
413     return m_debugInfo;
414 }
415
416 WebGraphicsLayerDebugInfo* GraphicsLayer::takeDebugInfoFor(WebLayer* layer)
417 {
418     GraphicsLayerDebugInfo* clone = m_debugInfo.clone();
419     clone->setDebugName(debugName(layer));
420     return clone;
421 }
422
423 WebLayer* GraphicsLayer::contentsLayerIfRegistered()
424 {
425     clearContentsLayerIfUnregistered();
426     return m_contentsLayer;
427 }
428
429 void GraphicsLayer::resetTrackedPaintInvalidations()
430 {
431     repaintRectMap().remove(this);
432 }
433
434 void GraphicsLayer::addRepaintRect(const FloatRect& repaintRect)
435 {
436     if (m_client->isTrackingPaintInvalidations()) {
437         RepaintMap::iterator repaintIt = repaintRectMap().find(this);
438         if (repaintIt == repaintRectMap().end()) {
439             Vector<FloatRect> repaintRects;
440             repaintRects.append(repaintRect);
441             repaintRectMap().set(this, repaintRects);
442         } else {
443             Vector<FloatRect>& repaintRects = repaintIt->value;
444             repaintRects.append(repaintRect);
445         }
446     }
447 }
448
449 static bool compareFloatRects(const FloatRect& a, const FloatRect& b)
450 {
451     if (a.x() != b.x())
452         return a.x() > b.x();
453     if (a.y() != b.y())
454         return a.y() > b.y();
455     if (a.width() != b.width())
456         return a.width() > b.width();
457     return a.height() > b.height();
458 }
459
460 template <typename T>
461 static PassRefPtr<JSONArray> pointAsJSONArray(const T& point)
462 {
463     RefPtr<JSONArray> array = adoptRef(new JSONArray);
464     array->pushNumber(point.x());
465     array->pushNumber(point.y());
466     return array;
467 }
468
469 template <typename T>
470 static PassRefPtr<JSONArray> sizeAsJSONArray(const T& size)
471 {
472     RefPtr<JSONArray> array = adoptRef(new JSONArray);
473     array->pushNumber(size.width());
474     array->pushNumber(size.height());
475     return array;
476 }
477
478 template <typename T>
479 static PassRefPtr<JSONArray> rectAsJSONArray(const T& rect)
480 {
481     RefPtr<JSONArray> array = adoptRef(new JSONArray);
482     array->pushNumber(rect.x());
483     array->pushNumber(rect.y());
484     array->pushNumber(rect.width());
485     array->pushNumber(rect.height());
486     return array;
487 }
488
489 static double roundCloseToZero(double number)
490 {
491     return std::abs(number) < 1e-7 ? 0 : number;
492 }
493
494 static PassRefPtr<JSONArray> transformAsJSONArray(const TransformationMatrix& t)
495 {
496     RefPtr<JSONArray> array = adoptRef(new JSONArray);
497     {
498         RefPtr<JSONArray> row = adoptRef(new JSONArray);
499         row->pushNumber(roundCloseToZero(t.m11()));
500         row->pushNumber(roundCloseToZero(t.m12()));
501         row->pushNumber(roundCloseToZero(t.m13()));
502         row->pushNumber(roundCloseToZero(t.m14()));
503         array->pushArray(row);
504     }
505     {
506         RefPtr<JSONArray> row = adoptRef(new JSONArray);
507         row->pushNumber(roundCloseToZero(t.m21()));
508         row->pushNumber(roundCloseToZero(t.m22()));
509         row->pushNumber(roundCloseToZero(t.m23()));
510         row->pushNumber(roundCloseToZero(t.m24()));
511         array->pushArray(row);
512     }
513     {
514         RefPtr<JSONArray> row = adoptRef(new JSONArray);
515         row->pushNumber(roundCloseToZero(t.m31()));
516         row->pushNumber(roundCloseToZero(t.m32()));
517         row->pushNumber(roundCloseToZero(t.m33()));
518         row->pushNumber(roundCloseToZero(t.m34()));
519         array->pushArray(row);
520     }
521     {
522         RefPtr<JSONArray> row = adoptRef(new JSONArray);
523         row->pushNumber(roundCloseToZero(t.m41()));
524         row->pushNumber(roundCloseToZero(t.m42()));
525         row->pushNumber(roundCloseToZero(t.m43()));
526         row->pushNumber(roundCloseToZero(t.m44()));
527         array->pushArray(row);
528     }
529     return array;
530 }
531
532 static String pointerAsString(const void* ptr)
533 {
534     TextStream ts;
535     ts << ptr;
536     return ts.release();
537 }
538
539 PassRefPtr<JSONObject> GraphicsLayer::layerTreeAsJSON(LayerTreeFlags flags, RenderingContextMap& renderingContextMap) const
540 {
541     RefPtr<JSONObject> json = adoptRef(new JSONObject);
542
543     if (flags & LayerTreeIncludesDebugInfo) {
544         json->setString("this", pointerAsString(this));
545         json->setString("debugName", m_client->debugName(this));
546     }
547
548     if (m_position != FloatPoint())
549         json->setArray("position", pointAsJSONArray(m_position));
550
551     if (m_hasTransformOrigin && m_transformOrigin != FloatPoint3D(m_size.width() * 0.5f, m_size.height() * 0.5f, 0))
552         json->setArray("transformOrigin", pointAsJSONArray(m_transformOrigin));
553
554     if (m_size != IntSize())
555         json->setArray("bounds", sizeAsJSONArray(m_size));
556
557     if (m_opacity != 1)
558         json->setNumber("opacity", m_opacity);
559
560     if (m_blendMode != WebBlendModeNormal)
561         json->setString("blendMode", compositeOperatorName(CompositeSourceOver, m_blendMode));
562
563     if (m_isRootForIsolatedGroup)
564         json->setBoolean("isolate", m_isRootForIsolatedGroup);
565
566     if (m_contentsOpaque)
567         json->setBoolean("contentsOpaque", m_contentsOpaque);
568
569     if (!m_shouldFlattenTransform)
570         json->setBoolean("shouldFlattenTransform", m_shouldFlattenTransform);
571
572     if (m_3dRenderingContext) {
573         RenderingContextMap::const_iterator it = renderingContextMap.find(m_3dRenderingContext);
574         int contextId = renderingContextMap.size() + 1;
575         if (it == renderingContextMap.end())
576             renderingContextMap.set(m_3dRenderingContext, contextId);
577         else
578             contextId = it->value;
579
580         json->setNumber("3dRenderingContext", contextId);
581     }
582
583     if (m_drawsContent)
584         json->setBoolean("drawsContent", m_drawsContent);
585
586     if (!m_contentsVisible)
587         json->setBoolean("contentsVisible", m_contentsVisible);
588
589     if (!m_backfaceVisibility)
590         json->setString("backfaceVisibility", m_backfaceVisibility ? "visible" : "hidden");
591
592     if (flags & LayerTreeIncludesDebugInfo)
593         json->setString("client", pointerAsString(m_client));
594
595     if (m_backgroundColor.alpha())
596         json->setString("backgroundColor", m_backgroundColor.nameForRenderTreeAsText());
597
598     if (!m_transform.isIdentity())
599         json->setArray("transform", transformAsJSONArray(m_transform));
600
601     if (m_replicaLayer)
602         json->setObject("replicaLayer", m_replicaLayer->layerTreeAsJSON(flags, renderingContextMap));
603
604     if (m_replicatedLayer)
605         json->setString("replicatedLayer", flags & LayerTreeIncludesDebugInfo ? pointerAsString(m_replicatedLayer) : "");
606
607     if ((flags & LayerTreeIncludesPaintInvalidationRects) && repaintRectMap().contains(this) && !repaintRectMap().get(this).isEmpty()) {
608         Vector<FloatRect> repaintRectsCopy = repaintRectMap().get(this);
609         std::sort(repaintRectsCopy.begin(), repaintRectsCopy.end(), &compareFloatRects);
610         RefPtr<JSONArray> repaintRectsJSON = adoptRef(new JSONArray);
611         for (size_t i = 0; i < repaintRectsCopy.size(); ++i) {
612             if (repaintRectsCopy[i].isEmpty())
613                 continue;
614             repaintRectsJSON->pushArray(rectAsJSONArray(repaintRectsCopy[i]));
615         }
616         json->setArray("repaintRects", repaintRectsJSON);
617     }
618
619     if ((flags & LayerTreeIncludesPaintingPhases) && m_paintingPhase) {
620         RefPtr<JSONArray> paintingPhasesJSON = adoptRef(new JSONArray);
621         if (m_paintingPhase & GraphicsLayerPaintBackground)
622             paintingPhasesJSON->pushString("GraphicsLayerPaintBackground");
623         if (m_paintingPhase & GraphicsLayerPaintForeground)
624             paintingPhasesJSON->pushString("GraphicsLayerPaintForeground");
625         if (m_paintingPhase & GraphicsLayerPaintMask)
626             paintingPhasesJSON->pushString("GraphicsLayerPaintMask");
627         if (m_paintingPhase & GraphicsLayerPaintChildClippingMask)
628             paintingPhasesJSON->pushString("GraphicsLayerPaintChildClippingMask");
629         if (m_paintingPhase & GraphicsLayerPaintOverflowContents)
630             paintingPhasesJSON->pushString("GraphicsLayerPaintOverflowContents");
631         if (m_paintingPhase & GraphicsLayerPaintCompositedScroll)
632             paintingPhasesJSON->pushString("GraphicsLayerPaintCompositedScroll");
633         json->setArray("paintingPhases", paintingPhasesJSON);
634     }
635
636     if (flags & LayerTreeIncludesClipAndScrollParents) {
637         if (m_hasScrollParent)
638             json->setBoolean("hasScrollParent", true);
639         if (m_hasClipParent)
640             json->setBoolean("hasClipParent", true);
641     }
642
643     if (flags & LayerTreeIncludesDebugInfo) {
644         RefPtr<JSONArray> compositingReasonsJSON = adoptRef(new JSONArray);
645         for (size_t i = 0; i < kNumberOfCompositingReasons; ++i) {
646             if (m_debugInfo.compositingReasons() & kCompositingReasonStringMap[i].reason)
647                 compositingReasonsJSON->pushString(kCompositingReasonStringMap[i].description);
648         }
649         json->setArray("compositingReasons", compositingReasonsJSON);
650     }
651
652     if (m_children.size()) {
653         RefPtr<JSONArray> childrenJSON = adoptRef(new JSONArray);
654         for (size_t i = 0; i < m_children.size(); i++)
655             childrenJSON->pushObject(m_children[i]->layerTreeAsJSON(flags, renderingContextMap));
656         json->setArray("children", childrenJSON);
657     }
658
659     return json;
660 }
661
662 String GraphicsLayer::layerTreeAsText(LayerTreeFlags flags) const
663 {
664     RenderingContextMap renderingContextMap;
665     RefPtr<JSONObject> json = layerTreeAsJSON(flags, renderingContextMap);
666     return json->toPrettyJSONString();
667 }
668
669 String GraphicsLayer::debugName(WebLayer* webLayer) const
670 {
671     String name;
672     if (!m_client)
673         return name;
674
675     String highlightDebugName;
676     for (size_t i = 0; i < m_linkHighlights.size(); ++i) {
677         if (webLayer == m_linkHighlights[i]->layer()) {
678             highlightDebugName = "LinkHighlight[" + String::number(i) + "] for " + m_client->debugName(this);
679             break;
680         }
681     }
682
683     if (webLayer == m_contentsLayer) {
684         name = "ContentsLayer for " + m_client->debugName(this);
685     } else if (!highlightDebugName.isEmpty()) {
686         name = highlightDebugName;
687     } else if (webLayer == m_layer->layer()) {
688         name = m_client->debugName(this);
689     } else {
690         ASSERT_NOT_REACHED();
691     }
692     return name;
693 }
694
695 void GraphicsLayer::setCompositingReasons(CompositingReasons reasons)
696 {
697     m_debugInfo.setCompositingReasons(reasons);
698 }
699
700 void GraphicsLayer::setOwnerNodeId(int nodeId)
701 {
702     m_debugInfo.setOwnerNodeId(nodeId);
703 }
704
705 void GraphicsLayer::setPosition(const FloatPoint& point)
706 {
707     m_position = point;
708     platformLayer()->setPosition(m_position);
709 }
710
711 void GraphicsLayer::setSize(const FloatSize& size)
712 {
713     // We are receiving negative sizes here that cause assertions to fail in the compositor. Clamp them to 0 to
714     // avoid those assertions.
715     // FIXME: This should be an ASSERT instead, as negative sizes should not exist in WebCore.
716     FloatSize clampedSize = size;
717     if (clampedSize.width() < 0 || clampedSize.height() < 0)
718         clampedSize = FloatSize();
719
720     if (clampedSize == m_size)
721         return;
722
723     m_size = clampedSize;
724
725     m_layer->layer()->setBounds(flooredIntSize(m_size));
726     // Note that we don't resize m_contentsLayer. It's up the caller to do that.
727 }
728
729 void GraphicsLayer::setTransform(const TransformationMatrix& transform)
730 {
731     m_transform = transform;
732     platformLayer()->setTransform(TransformationMatrix::toSkMatrix44(m_transform));
733 }
734
735 void GraphicsLayer::setTransformOrigin(const FloatPoint3D& transformOrigin)
736 {
737     m_hasTransformOrigin = true;
738     m_transformOrigin = transformOrigin;
739     platformLayer()->setTransformOrigin(transformOrigin);
740 }
741
742 void GraphicsLayer::setShouldFlattenTransform(bool shouldFlatten)
743 {
744     if (shouldFlatten == m_shouldFlattenTransform)
745         return;
746
747     m_shouldFlattenTransform = shouldFlatten;
748
749     m_layer->layer()->setShouldFlattenTransform(shouldFlatten);
750 }
751
752 void GraphicsLayer::setRenderingContext(int context)
753 {
754     if (m_3dRenderingContext == context)
755         return;
756
757     m_3dRenderingContext = context;
758     m_layer->layer()->setRenderingContext(context);
759
760     if (m_contentsLayer)
761         m_contentsLayer->setRenderingContext(m_3dRenderingContext);
762 }
763
764 void GraphicsLayer::setMasksToBounds(bool masksToBounds)
765 {
766     m_masksToBounds = masksToBounds;
767     m_layer->layer()->setMasksToBounds(m_masksToBounds);
768 }
769
770 void GraphicsLayer::setDrawsContent(bool drawsContent)
771 {
772     // Note carefully this early-exit is only correct because we also properly call
773     // WebLayer::setDrawsContent whenever m_contentsLayer is set to a new layer in setupContentsLayer().
774     if (drawsContent == m_drawsContent)
775         return;
776
777     m_drawsContent = drawsContent;
778     updateLayerIsDrawable();
779 }
780
781 void GraphicsLayer::setContentsVisible(bool contentsVisible)
782 {
783     // Note carefully this early-exit is only correct because we also properly call
784     // WebLayer::setDrawsContent whenever m_contentsLayer is set to a new layer in setupContentsLayer().
785     if (contentsVisible == m_contentsVisible)
786         return;
787
788     m_contentsVisible = contentsVisible;
789     updateLayerIsDrawable();
790 }
791
792 void GraphicsLayer::setClipParent(WebLayer* parent)
793 {
794     m_hasClipParent = !!parent;
795     m_layer->layer()->setClipParent(parent);
796 }
797
798 void GraphicsLayer::setScrollParent(WebLayer* parent)
799 {
800     m_hasScrollParent = !!parent;
801     m_layer->layer()->setScrollParent(parent);
802 }
803
804 void GraphicsLayer::setBackgroundColor(const Color& color)
805 {
806     if (color == m_backgroundColor)
807         return;
808
809     m_backgroundColor = color;
810     m_layer->layer()->setBackgroundColor(m_backgroundColor.rgb());
811 }
812
813 void GraphicsLayer::setContentsOpaque(bool opaque)
814 {
815     m_contentsOpaque = opaque;
816     m_layer->layer()->setOpaque(m_contentsOpaque);
817     m_contentLayerDelegate->setOpaque(m_contentsOpaque);
818     clearContentsLayerIfUnregistered();
819     if (m_contentsLayer)
820         m_contentsLayer->setOpaque(opaque);
821 }
822
823 void GraphicsLayer::setMaskLayer(GraphicsLayer* maskLayer)
824 {
825     if (maskLayer == m_maskLayer)
826         return;
827
828     m_maskLayer = maskLayer;
829     WebLayer* maskWebLayer = m_maskLayer ? m_maskLayer->platformLayer() : 0;
830     m_layer->layer()->setMaskLayer(maskWebLayer);
831 }
832
833 void GraphicsLayer::setContentsClippingMaskLayer(GraphicsLayer* contentsClippingMaskLayer)
834 {
835     if (contentsClippingMaskLayer == m_contentsClippingMaskLayer)
836         return;
837
838     m_contentsClippingMaskLayer = contentsClippingMaskLayer;
839     WebLayer* contentsLayer = contentsLayerIfRegistered();
840     if (!contentsLayer)
841         return;
842     WebLayer* contentsClippingMaskWebLayer = m_contentsClippingMaskLayer ? m_contentsClippingMaskLayer->platformLayer() : 0;
843     contentsLayer->setMaskLayer(contentsClippingMaskWebLayer);
844     updateContentsRect();
845 }
846
847 void GraphicsLayer::setBackfaceVisibility(bool visible)
848 {
849     m_backfaceVisibility = visible;
850     m_layer->setDoubleSided(m_backfaceVisibility);
851 }
852
853 void GraphicsLayer::setOpacity(float opacity)
854 {
855     float clampedOpacity = std::max(std::min(opacity, 1.0f), 0.0f);
856     m_opacity = clampedOpacity;
857     platformLayer()->setOpacity(opacity);
858 }
859
860 void GraphicsLayer::setBlendMode(WebBlendMode blendMode)
861 {
862     if (m_blendMode == blendMode)
863         return;
864     m_blendMode = blendMode;
865     platformLayer()->setBlendMode(WebBlendMode(blendMode));
866 }
867
868 void GraphicsLayer::setIsRootForIsolatedGroup(bool isolated)
869 {
870     if (m_isRootForIsolatedGroup == isolated)
871         return;
872     m_isRootForIsolatedGroup = isolated;
873     platformLayer()->setIsRootForIsolatedGroup(isolated);
874 }
875
876 void GraphicsLayer::setContentsNeedsDisplay()
877 {
878     if (WebLayer* contentsLayer = contentsLayerIfRegistered()) {
879         contentsLayer->invalidate();
880         addRepaintRect(m_contentsRect);
881     }
882 }
883
884 void GraphicsLayer::setNeedsDisplay()
885 {
886     if (drawsContent()) {
887         m_layer->layer()->invalidate();
888         addRepaintRect(FloatRect(FloatPoint(), m_size));
889         for (size_t i = 0; i < m_linkHighlights.size(); ++i)
890             m_linkHighlights[i]->invalidate();
891     }
892 }
893
894 void GraphicsLayer::setNeedsDisplayInRect(const IntRect& rect, PaintInvalidationReason invalidationReason)
895 {
896     if (drawsContent()) {
897         m_layer->layer()->invalidateRect(rect);
898         if (firstPaintInvalidationTrackingEnabled())
899             m_debugInfo.appendAnnotatedInvalidateRect(rect, invalidationReason);
900         addRepaintRect(rect);
901         for (size_t i = 0; i < m_linkHighlights.size(); ++i)
902             m_linkHighlights[i]->invalidate();
903     }
904 }
905
906 void GraphicsLayer::setContentsRect(const IntRect& rect)
907 {
908     if (rect == m_contentsRect)
909         return;
910
911     m_contentsRect = rect;
912     updateContentsRect();
913 }
914
915 void GraphicsLayer::setContentsToImage(Image* image)
916 {
917     RefPtr<NativeImageSkia> nativeImage = image ? image->nativeImageForCurrentFrame() : nullptr;
918     if (nativeImage) {
919         if (!m_imageLayer) {
920             m_imageLayer = adoptPtr(Platform::current()->compositorSupport()->createImageLayer());
921             registerContentsLayer(m_imageLayer->layer());
922         }
923         m_imageLayer->setImageBitmap(nativeImage->bitmap());
924         m_imageLayer->layer()->setOpaque(image->currentFrameKnownToBeOpaque());
925         updateContentsRect();
926     } else {
927         if (m_imageLayer) {
928             unregisterContentsLayer(m_imageLayer->layer());
929             m_imageLayer.clear();
930         }
931     }
932
933     setContentsTo(m_imageLayer ? m_imageLayer->layer() : 0);
934 }
935
936 void GraphicsLayer::setContentsToNinePatch(Image* image, const IntRect& aperture)
937 {
938     if (m_ninePatchLayer) {
939         unregisterContentsLayer(m_ninePatchLayer->layer());
940         m_ninePatchLayer.clear();
941     }
942     RefPtr<NativeImageSkia> nativeImage = image ? image->nativeImageForCurrentFrame() : nullptr;
943     if (nativeImage) {
944         m_ninePatchLayer = adoptPtr(Platform::current()->compositorSupport()->createNinePatchLayer());
945         const SkBitmap& bitmap = nativeImage->bitmap();
946         int borderWidth = bitmap.width() - aperture.width();
947         int borderHeight = bitmap.height() - aperture.height();
948         WebRect border(aperture.x(), aperture.y(), borderWidth, borderHeight);
949
950         m_ninePatchLayer->setBitmap(bitmap);
951         m_ninePatchLayer->setAperture(aperture);
952         m_ninePatchLayer->setBorder(border);
953
954         m_ninePatchLayer->layer()->setOpaque(image->currentFrameKnownToBeOpaque());
955         registerContentsLayer(m_ninePatchLayer->layer());
956     }
957     setContentsTo(m_ninePatchLayer ? m_ninePatchLayer->layer() : 0);
958 }
959
960 bool GraphicsLayer::addAnimation(PassOwnPtr<WebCompositorAnimation> popAnimation)
961 {
962     OwnPtr<WebCompositorAnimation> animation(popAnimation);
963     ASSERT(animation);
964     platformLayer()->setAnimationDelegate(this);
965
966     // Remove any existing animations with the same animation id and target property.
967     platformLayer()->removeAnimation(animation->id(), animation->targetProperty());
968     return platformLayer()->addAnimation(animation.leakPtr());
969 }
970
971 void GraphicsLayer::pauseAnimation(int animationId, double timeOffset)
972 {
973     platformLayer()->pauseAnimation(animationId, timeOffset);
974 }
975
976 void GraphicsLayer::removeAnimation(int animationId)
977 {
978     platformLayer()->removeAnimation(animationId);
979 }
980
981 WebLayer* GraphicsLayer::platformLayer() const
982 {
983     return m_layer->layer();
984 }
985
986 void GraphicsLayer::setFilters(const FilterOperations& filters)
987 {
988     SkiaImageFilterBuilder builder;
989     OwnPtr<WebFilterOperations> webFilters = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations());
990     FilterOutsets outsets = filters.outsets();
991     builder.setCropOffset(FloatSize(outsets.left(), outsets.top()));
992     builder.buildFilterOperations(filters, webFilters.get());
993     m_layer->layer()->setFilters(*webFilters);
994 }
995
996 void GraphicsLayer::setPaintingPhase(GraphicsLayerPaintingPhase phase)
997 {
998     if (m_paintingPhase == phase)
999         return;
1000     m_paintingPhase = phase;
1001     setNeedsDisplay();
1002 }
1003
1004 void GraphicsLayer::addLinkHighlight(LinkHighlightClient* linkHighlight)
1005 {
1006     ASSERT(linkHighlight && !m_linkHighlights.contains(linkHighlight));
1007     m_linkHighlights.append(linkHighlight);
1008     linkHighlight->layer()->setWebLayerClient(this);
1009     updateChildList();
1010 }
1011
1012 void GraphicsLayer::removeLinkHighlight(LinkHighlightClient* linkHighlight)
1013 {
1014     m_linkHighlights.remove(m_linkHighlights.find(linkHighlight));
1015     updateChildList();
1016 }
1017
1018 void GraphicsLayer::setScrollableArea(ScrollableArea* scrollableArea, bool isViewport)
1019 {
1020     if (m_scrollableArea == scrollableArea)
1021         return;
1022
1023     m_scrollableArea = scrollableArea;
1024
1025     // Viewport scrolling may involve pinch zoom and gets routed through
1026     // WebViewImpl explicitly rather than via GraphicsLayer::didScroll.
1027     if (isViewport)
1028         m_layer->layer()->setScrollClient(0);
1029     else
1030         m_layer->layer()->setScrollClient(this);
1031 }
1032
1033 void GraphicsLayer::paint(GraphicsContext& context, const IntRect& clip)
1034 {
1035     paintGraphicsLayerContents(context, clip);
1036 }
1037
1038
1039 void GraphicsLayer::notifyAnimationStarted(double monotonicTime, int group)
1040 {
1041     if (m_client)
1042         m_client->notifyAnimationStarted(this, monotonicTime, group);
1043 }
1044
1045 void GraphicsLayer::notifyAnimationFinished(double, int)
1046 {
1047 }
1048
1049 void GraphicsLayer::didScroll()
1050 {
1051     if (m_scrollableArea) {
1052         DoublePoint newPosition = m_scrollableArea->minimumScrollPosition() + toDoubleSize(m_layer->layer()->scrollPositionDouble());
1053         // FIXME: Remove the toFloatPoint(). crbug.com/414283.
1054         m_scrollableArea->scrollToOffsetWithoutAnimation(toFloatPoint(newPosition));
1055     }
1056 }
1057
1058 } // namespace blink
1059
1060 #ifndef NDEBUG
1061 void showGraphicsLayerTree(const blink::GraphicsLayer* layer)
1062 {
1063     if (!layer)
1064         return;
1065
1066     String output = layer->layerTreeAsText(blink::LayerTreeIncludesDebugInfo);
1067     fprintf(stderr, "%s\n", output.utf8().data());
1068 }
1069 #endif