[chromium] Change WebLayer from a concrete type to a pure virtual interface
[WebKit-https.git] / Source / WebCore / platform / graphics / chromium / GraphicsLayerChromium.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  * Copyright (C) 2009 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32
33 /** FIXME
34  * This file borrows code heavily from platform/graphics/win/GraphicsLayerCACF.cpp
35  * (and hence it includes both copyrights)
36  * Ideally the common code (mostly the code that keeps track of the layer hierarchy)
37  * should be kept separate and shared between platforms. It would be a well worthwhile
38  * effort once the Windows implementation (binaries and headers) of CoreAnimation is
39  * checked in to the WebKit repository. Until then only Apple can make this happen.
40  */
41
42 #include "config.h"
43
44 #if USE(ACCELERATED_COMPOSITING)
45
46 #include "GraphicsLayerChromium.h"
47
48 #include "AnimationIdVendor.h"
49 #include "AnimationTranslationUtil.h"
50 #include "ContentLayerChromium.h"
51 #include "FloatConversion.h"
52 #include "FloatRect.h"
53 #include "GraphicsContext.h"
54 #include "Image.h"
55 #include "NativeImageSkia.h"
56 #include "PlatformContextSkia.h"
57 #include "PlatformString.h"
58 #include "SkMatrix44.h"
59 #include "SystemTime.h"
60
61 #include <public/WebAnimation.h>
62 #include <public/WebFilterOperation.h>
63 #include <public/WebFilterOperations.h>
64 #include <public/WebFloatPoint.h>
65 #include <public/WebFloatRect.h>
66 #include <public/WebImageLayer.h>
67 #include <public/WebSize.h>
68 #include <public/WebTransformationMatrix.h>
69 #include <wtf/CurrentTime.h>
70 #include <wtf/StringExtras.h>
71 #include <wtf/text/CString.h>
72
73 using namespace std;
74 using namespace WebKit;
75
76 namespace WebCore {
77
78 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
79 {
80     return adoptPtr(new GraphicsLayerChromium(client));
81 }
82
83 GraphicsLayerChromium::GraphicsLayerChromium(GraphicsLayerClient* client)
84     : GraphicsLayer(client)
85     , m_contentsLayer(0)
86     , m_contentsLayerId(0)
87     , m_linkHighlight(0)
88     , m_contentsLayerPurpose(NoContentsLayer)
89     , m_contentsLayerHasBackgroundColor(false)
90     , m_inSetChildren(false)
91     , m_pageScaleChanged(false)
92 {
93     m_opaqueRectTrackingContentLayerDelegate = adoptPtr(new OpaqueRectTrackingContentLayerDelegate(this));
94     m_layer = adoptPtr(WebContentLayer::create(m_opaqueRectTrackingContentLayerDelegate.get()));
95     m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible);
96     if (client)
97         deviceOrPageScaleFactorChanged();
98     updateDebugIndicators();
99 }
100
101 GraphicsLayerChromium::~GraphicsLayerChromium()
102 {
103     willBeDestroyed();
104 }
105
106 void GraphicsLayerChromium::willBeDestroyed()
107 {
108     if (m_linkHighlight) {
109         m_linkHighlight->clearCurrentGraphicsLayer();
110         m_linkHighlight = 0;
111     }
112
113     GraphicsLayer::willBeDestroyed();
114 }
115
116 void GraphicsLayerChromium::setName(const String& inName)
117 {
118     m_nameBase = inName;
119     String name = String::format("GraphicsLayer(%p) ", this) + inName;
120     GraphicsLayer::setName(name);
121     updateNames();
122 }
123
124 void GraphicsLayerChromium::updateNames()
125 {
126     String debugName = "Layer for " + m_nameBase;
127     m_layer->layer()->setDebugName(debugName);
128
129     if (m_transformLayer) {
130         String debugName = "TransformLayer for " + m_nameBase;
131         m_transformLayer->setDebugName(debugName);
132     }
133     if (m_contentsLayer) {
134         String debugName = "ContentsLayer for " + m_nameBase;
135         m_contentsLayer->setDebugName(debugName);
136     }
137     if (m_linkHighlight) {
138         String debugName = "LinkHighlight for " + m_nameBase;
139         m_linkHighlight->layer()->setDebugName(debugName);
140     }
141 }
142
143 bool GraphicsLayerChromium::setChildren(const Vector<GraphicsLayer*>& children)
144 {
145     m_inSetChildren = true;
146     bool childrenChanged = GraphicsLayer::setChildren(children);
147
148     if (childrenChanged)
149         updateChildList();
150     m_inSetChildren = false;
151
152     return childrenChanged;
153 }
154
155 void GraphicsLayerChromium::addChild(GraphicsLayer* childLayer)
156 {
157     GraphicsLayer::addChild(childLayer);
158     if (!m_inSetChildren)
159         updateChildList();
160 }
161
162 void GraphicsLayerChromium::addChildAtIndex(GraphicsLayer* childLayer, int index)
163 {
164     GraphicsLayer::addChildAtIndex(childLayer, index);
165     updateChildList();
166 }
167
168 void GraphicsLayerChromium::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
169 {
170     GraphicsLayer::addChildBelow(childLayer, sibling);
171     updateChildList();
172 }
173
174 void GraphicsLayerChromium::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer *sibling)
175 {
176     GraphicsLayer::addChildAbove(childLayer, sibling);
177     updateChildList();
178 }
179
180 bool GraphicsLayerChromium::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
181 {
182     if (GraphicsLayer::replaceChild(oldChild, newChild)) {
183         updateChildList();
184         return true;
185     }
186     return false;
187 }
188
189 void GraphicsLayerChromium::removeFromParent()
190 {
191     GraphicsLayer::removeFromParent();
192     platformLayer()->removeFromParent();
193 }
194
195 void GraphicsLayerChromium::setPosition(const FloatPoint& point)
196 {
197     GraphicsLayer::setPosition(point);
198     updateLayerPosition();
199 }
200
201 void GraphicsLayerChromium::setAnchorPoint(const FloatPoint3D& point)
202 {
203     GraphicsLayer::setAnchorPoint(point);
204     updateAnchorPoint();
205 }
206
207 void GraphicsLayerChromium::setSize(const FloatSize& size)
208 {
209     // We are receiving negative sizes here that cause assertions to fail in the compositor. Clamp them to 0 to
210     // avoid those assertions.
211     // FIXME: This should be an ASSERT instead, as negative sizes should not exist in WebCore.
212     FloatSize clampedSize = size;
213     if (clampedSize.width() < 0 || clampedSize.height() < 0)
214         clampedSize = FloatSize();
215
216     if (clampedSize == m_size)
217         return;
218
219     GraphicsLayer::setSize(clampedSize);
220     updateLayerSize();
221
222     if (m_pageScaleChanged) {
223         m_layer->layer()->invalidate();
224         if (m_linkHighlight)
225             m_linkHighlight->invalidate();
226     }
227     m_pageScaleChanged = false;
228 }
229
230 void GraphicsLayerChromium::setTransform(const TransformationMatrix& transform)
231 {
232     // Call this method first to assign contents scale to our layer so the painter can apply the scale transform.
233     updateContentsScale();
234
235     GraphicsLayer::setTransform(transform);
236     updateTransform();
237 }
238
239 void GraphicsLayerChromium::setChildrenTransform(const TransformationMatrix& transform)
240 {
241     GraphicsLayer::setChildrenTransform(transform);
242     updateChildrenTransform();
243 }
244
245 void GraphicsLayerChromium::setPreserves3D(bool preserves3D)
246 {
247     if (preserves3D == m_preserves3D)
248         return;
249
250     GraphicsLayer::setPreserves3D(preserves3D);
251     updateLayerPreserves3D();
252 }
253
254 void GraphicsLayerChromium::setMasksToBounds(bool masksToBounds)
255 {
256     GraphicsLayer::setMasksToBounds(masksToBounds);
257     updateMasksToBounds();
258 }
259
260 void GraphicsLayerChromium::setDrawsContent(bool drawsContent)
261 {
262     // Note carefully this early-exit is only correct because we also properly call
263     // WebLayer::setDrawsContent whenever m_contentsLayer is set to a new layer in setupContentsLayer().
264     if (drawsContent == m_drawsContent)
265         return;
266
267     GraphicsLayer::setDrawsContent(drawsContent);
268     updateLayerIsDrawable();
269 }
270
271 void GraphicsLayerChromium::setContentsVisible(bool contentsVisible)
272 {
273     // Note carefully this early-exit is only correct because we also properly call
274     // WebLayer::setDrawsContent whenever m_contentsLayer is set to a new layer in setupContentsLayer().
275     if (contentsVisible == m_contentsVisible)
276         return;
277
278     GraphicsLayer::setContentsVisible(contentsVisible);
279     updateLayerIsDrawable();
280 }
281
282 void GraphicsLayerChromium::setBackgroundColor(const Color& color)
283 {
284     GraphicsLayer::setBackgroundColor(color.rgb());
285
286     m_contentsLayerHasBackgroundColor = true;
287     updateLayerBackgroundColor();
288 }
289
290 void GraphicsLayerChromium::clearBackgroundColor()
291 {
292     GraphicsLayer::clearBackgroundColor();
293     m_contentsLayer->setBackgroundColor(static_cast<RGBA32>(0));
294 }
295
296 void GraphicsLayerChromium::setContentsOpaque(bool opaque)
297 {
298     GraphicsLayer::setContentsOpaque(opaque);
299     m_layer->layer()->setOpaque(m_contentsOpaque);
300 }
301
302 static bool copyWebCoreFilterOperationsToWebFilterOperations(const FilterOperations& filters, WebFilterOperations& webFilters)
303 {
304     for (size_t i = 0; i < filters.size(); ++i) {
305         const FilterOperation& op = *filters.at(i);
306         switch (op.getOperationType()) {
307         case FilterOperation::REFERENCE:
308             return false; // Not supported.
309         case FilterOperation::GRAYSCALE:
310         case FilterOperation::SEPIA:
311         case FilterOperation::SATURATE:
312         case FilterOperation::HUE_ROTATE: {
313             float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount();
314             switch (op.getOperationType()) {
315             case FilterOperation::GRAYSCALE:
316                 webFilters.append(WebFilterOperation::createGrayscaleFilter(amount));
317                 break;
318             case FilterOperation::SEPIA:
319                 webFilters.append(WebFilterOperation::createSepiaFilter(amount));
320                 break;
321             case FilterOperation::SATURATE:
322                 webFilters.append(WebFilterOperation::createSaturateFilter(amount));
323                 break;
324             case FilterOperation::HUE_ROTATE:
325                 webFilters.append(WebFilterOperation::createHueRotateFilter(amount));
326                 break;
327             default:
328                 ASSERT_NOT_REACHED();
329             }
330             break;
331         }
332         case FilterOperation::INVERT:
333         case FilterOperation::OPACITY:
334         case FilterOperation::BRIGHTNESS:
335         case FilterOperation::CONTRAST: {
336             float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount();
337             switch (op.getOperationType()) {
338             case FilterOperation::INVERT:
339                 webFilters.append(WebFilterOperation::createInvertFilter(amount));
340                 break;
341             case FilterOperation::OPACITY:
342                 webFilters.append(WebFilterOperation::createOpacityFilter(amount));
343                 break;
344             case FilterOperation::BRIGHTNESS:
345                 webFilters.append(WebFilterOperation::createBrightnessFilter(amount));
346                 break;
347             case FilterOperation::CONTRAST:
348                 webFilters.append(WebFilterOperation::createContrastFilter(amount));
349                 break;
350             default:
351                 ASSERT_NOT_REACHED();
352             }
353             break;
354         }
355         case FilterOperation::BLUR: {
356             float pixelRadius = static_cast<const BlurFilterOperation*>(&op)->stdDeviation().getFloatValue();
357             webFilters.append(WebFilterOperation::createBlurFilter(pixelRadius));
358             break;
359         }
360         case FilterOperation::DROP_SHADOW: {
361             const DropShadowFilterOperation& dropShadowOp = *static_cast<const DropShadowFilterOperation*>(&op);
362             webFilters.append(WebFilterOperation::createDropShadowFilter(WebPoint(dropShadowOp.x(), dropShadowOp.y()), dropShadowOp.stdDeviation(), dropShadowOp.color().rgb()));
363             break;
364         }
365 #if ENABLE(CSS_SHADERS)
366         case FilterOperation::CUSTOM:
367             return false; // Not supported.
368 #endif
369         case FilterOperation::PASSTHROUGH:
370         case FilterOperation::NONE:
371             break;
372         }
373     }
374     return true;
375 }
376
377 bool GraphicsLayerChromium::setFilters(const FilterOperations& filters)
378 {
379     WebFilterOperations webFilters;
380     if (!copyWebCoreFilterOperationsToWebFilterOperations(filters, webFilters)) {
381         // Make sure the filters are removed from the platform layer, as they are
382         // going to fallback to software mode.
383         m_layer->layer()->setFilters(WebFilterOperations());
384         GraphicsLayer::setFilters(FilterOperations());
385         return false;
386     }
387     m_layer->layer()->setFilters(webFilters);
388     return GraphicsLayer::setFilters(filters);
389 }
390
391 void GraphicsLayerChromium::setBackgroundFilters(const FilterOperations& filters)
392 {
393     WebFilterOperations webFilters;
394     if (!copyWebCoreFilterOperationsToWebFilterOperations(filters, webFilters))
395         return;
396     m_layer->layer()->setBackgroundFilters(webFilters);
397 }
398
399 void GraphicsLayerChromium::setMaskLayer(GraphicsLayer* maskLayer)
400 {
401     if (maskLayer == m_maskLayer)
402         return;
403
404     GraphicsLayer::setMaskLayer(maskLayer);
405
406     WebLayer* maskWebLayer = m_maskLayer ? m_maskLayer->platformLayer() : 0;
407     m_layer->layer()->setMaskLayer(maskWebLayer);
408 }
409
410 void GraphicsLayerChromium::setBackfaceVisibility(bool visible)
411 {
412     GraphicsLayer::setBackfaceVisibility(visible);
413     m_layer->setDoubleSided(m_backfaceVisibility);
414 }
415
416 void GraphicsLayerChromium::setOpacity(float opacity)
417 {
418     float clampedOpacity = max(min(opacity, 1.0f), 0.0f);
419     GraphicsLayer::setOpacity(clampedOpacity);
420     platformLayer()->setOpacity(opacity);
421 }
422
423 void GraphicsLayerChromium::setReplicatedByLayer(GraphicsLayer* layer)
424 {
425     GraphicsLayerChromium* layerChromium = static_cast<GraphicsLayerChromium*>(layer);
426     GraphicsLayer::setReplicatedByLayer(layer);
427
428     WebLayer* webReplicaLayer = layerChromium ? layerChromium->platformLayer() : 0;
429     platformLayer()->setReplicaLayer(webReplicaLayer);
430 }
431
432
433 void GraphicsLayerChromium::setContentsNeedsDisplay()
434 {
435     if (m_contentsLayer)
436         m_contentsLayer->invalidate();
437 }
438
439 void GraphicsLayerChromium::setNeedsDisplay()
440 {
441     if (drawsContent()) {
442         m_layer->layer()->invalidate();
443         if (m_linkHighlight)
444             m_linkHighlight->invalidate();
445     }
446 }
447
448 void GraphicsLayerChromium::setNeedsDisplayInRect(const FloatRect& rect)
449 {
450     if (drawsContent()) {
451         m_layer->layer()->invalidateRect(rect);
452         if (m_linkHighlight)
453             m_linkHighlight->invalidate();
454     }
455 }
456
457 void GraphicsLayerChromium::setContentsRect(const IntRect& rect)
458 {
459     if (rect == m_contentsRect)
460         return;
461
462     GraphicsLayer::setContentsRect(rect);
463     updateContentsRect();
464 }
465
466 void GraphicsLayerChromium::setContentsToImage(Image* image)
467 {
468     bool childrenChanged = false;
469     if (image) {
470         if (m_contentsLayerPurpose != ContentsLayerForImage) {
471             m_imageLayer = adoptPtr(WebImageLayer::create());
472             setupContentsLayer(m_imageLayer->layer());
473             m_contentsLayerPurpose = ContentsLayerForImage;
474             childrenChanged = true;
475         }
476         NativeImageSkia* nativeImage = image->nativeImageForCurrentFrame();
477         m_imageLayer->setBitmap(nativeImage->bitmap());
478         m_imageLayer->layer()->setOpaque(image->isBitmapImage() && !image->currentFrameHasAlpha());
479         updateContentsRect();
480     } else {
481         if (m_imageLayer) {
482             childrenChanged = true;
483
484             m_imageLayer.clear();
485         }
486         // The old contents layer will be removed via updateChildList.
487         m_contentsLayer = 0;
488     }
489
490     if (childrenChanged)
491         updateChildList();
492 }
493
494 void GraphicsLayerChromium::setContentsToCanvas(PlatformLayer* layer)
495 {
496     setContentsTo(ContentsLayerForCanvas, layer);
497 }
498
499 void GraphicsLayerChromium::setContentsToMedia(PlatformLayer* layer)
500 {
501     setContentsTo(ContentsLayerForVideo, layer);
502 }
503
504 void GraphicsLayerChromium::setContentsTo(ContentsLayerPurpose purpose, WebKit::WebLayer* layer)
505 {
506     bool childrenChanged = false;
507     if (layer) {
508         if (m_contentsLayerId != layer->id()) {
509             setupContentsLayer(layer);
510             m_contentsLayerPurpose = purpose;
511             childrenChanged = true;
512         }
513         updateContentsRect();
514     } else {
515         if (m_contentsLayer) {
516             childrenChanged = true;
517
518             // The old contents layer will be removed via updateChildList.
519             m_contentsLayer = 0;
520         }
521     }
522
523     if (childrenChanged)
524         updateChildList();
525 }
526
527 bool GraphicsLayerChromium::addAnimation(const KeyframeValueList& values, const IntSize& boxSize, const Animation* animation, const String& animationName, double timeOffset)
528 {
529     platformLayer()->setAnimationDelegate(this);
530
531     int animationId = mapAnimationNameToId(animationName);
532     int groupId = AnimationIdVendor::getNextGroupId();
533
534     OwnPtr<WebKit::WebAnimation> toAdd(createWebAnimation(values, animation, animationId, groupId, timeOffset, boxSize));
535
536     if (toAdd) {
537         // Remove any existing animations with the same animation id and target property.
538         platformLayer()->removeAnimation(animationId, toAdd->targetProperty());
539         return platformLayer()->addAnimation(toAdd.get());
540     }
541
542     return false;
543 }
544
545 void GraphicsLayerChromium::pauseAnimation(const String& animationName, double timeOffset)
546 {
547     platformLayer()->pauseAnimation(mapAnimationNameToId(animationName), timeOffset);
548 }
549
550 void GraphicsLayerChromium::removeAnimation(const String& animationName)
551 {
552     platformLayer()->removeAnimation(mapAnimationNameToId(animationName));
553 }
554
555 void GraphicsLayerChromium::suspendAnimations(double wallClockTime)
556 {
557     // |wallClockTime| is in the wrong time base. Need to convert here.
558     // FIXME: find a more reliable way to do this.
559     double monotonicTime = wallClockTime + monotonicallyIncreasingTime() - currentTime();
560     platformLayer()->suspendAnimations(monotonicTime);
561 }
562
563 void GraphicsLayerChromium::resumeAnimations()
564 {
565     platformLayer()->resumeAnimations(monotonicallyIncreasingTime());
566 }
567
568 void GraphicsLayerChromium::setLinkHighlight(LinkHighlightClient* linkHighlight)
569 {
570     m_linkHighlight = linkHighlight;
571     updateChildList();
572 }
573
574 PlatformLayer* GraphicsLayerChromium::platformLayer() const
575 {
576     return m_transformLayer ? m_transformLayer.get() : m_layer->layer();
577 }
578
579 void GraphicsLayerChromium::setDebugBackgroundColor(const Color& color)
580 {
581     if (color.isValid())
582         m_layer->layer()->setBackgroundColor(color.rgb());
583     else
584         m_layer->layer()->setBackgroundColor(static_cast<RGBA32>(0));
585 }
586
587 void GraphicsLayerChromium::setDebugBorder(const Color& color, float borderWidth)
588 {
589     if (color.isValid()) {
590         m_layer->layer()->setDebugBorderColor(color.rgb());
591         m_layer->layer()->setDebugBorderWidth(borderWidth);
592     } else {
593         m_layer->layer()->setDebugBorderColor(static_cast<RGBA32>(0));
594         m_layer->layer()->setDebugBorderWidth(0);
595     }
596 }
597
598 void GraphicsLayerChromium::updateChildList()
599 {
600     Vector<WebLayer*> newChildren;
601
602     if (m_transformLayer) {
603         // Add the primary layer first. Even if we have negative z-order children, the primary layer always comes behind.
604         newChildren.append(m_layer->layer());
605     } else if (m_contentsLayer) {
606         // FIXME: add the contents layer in the correct order with negative z-order children.
607         // This does not cause visible rendering issues because currently contents layers are only used
608         // for replaced elements that don't have children.
609         newChildren.append(m_contentsLayer);
610     }
611
612     const Vector<GraphicsLayer*>& childLayers = children();
613     size_t numChildren = childLayers.size();
614     for (size_t i = 0; i < numChildren; ++i) {
615         GraphicsLayerChromium* curChild = static_cast<GraphicsLayerChromium*>(childLayers[i]);
616
617         newChildren.append(curChild->platformLayer());
618     }
619
620     if (m_linkHighlight)
621         newChildren.append(m_linkHighlight->layer());
622
623     for (size_t i = 0; i < newChildren.size(); ++i)
624         newChildren[i]->removeFromParent();
625
626     WebVector<WebLayer*> newWebChildren;
627     newWebChildren.assign(newChildren.data(), newChildren.size());
628
629     if (m_transformLayer) {
630         m_transformLayer->setChildren(newWebChildren);
631
632         if (m_contentsLayer) {
633             // If we have a transform layer, then the contents layer is parented in the
634             // primary layer (which is itself a child of the transform layer).
635             m_layer->layer()->removeAllChildren();
636             m_layer->layer()->addChild(m_contentsLayer);
637         }
638     } else
639         m_layer->layer()->setChildren(newWebChildren);
640 }
641
642 void GraphicsLayerChromium::updateLayerPosition()
643 {
644     platformLayer()->setPosition(m_position);
645 }
646
647 void GraphicsLayerChromium::updateLayerSize()
648 {
649     IntSize layerSize(m_size.width(), m_size.height());
650     if (m_transformLayer) {
651         m_transformLayer->setBounds(layerSize);
652         m_layer->layer()->setPosition(FloatPoint());
653     }
654
655     m_layer->layer()->setBounds(layerSize);
656
657     // Note that we don't resize m_contentsLayer-> It's up the caller to do that.
658 }
659
660 void GraphicsLayerChromium::updateAnchorPoint()
661 {
662     platformLayer()->setAnchorPoint(FloatPoint(m_anchorPoint.x(), m_anchorPoint.y()));
663     platformLayer()->setAnchorPointZ(m_anchorPoint.z());
664 }
665
666 void GraphicsLayerChromium::updateTransform()
667 {
668     platformLayer()->setTransform(WebTransformationMatrix(m_transform));
669 }
670
671 void GraphicsLayerChromium::updateChildrenTransform()
672 {
673     platformLayer()->setSublayerTransform(WebTransformationMatrix(m_childrenTransform));
674 }
675
676 void GraphicsLayerChromium::updateMasksToBounds()
677 {
678     m_layer->layer()->setMasksToBounds(m_masksToBounds);
679     updateDebugIndicators();
680 }
681
682 void GraphicsLayerChromium::updateLayerPreserves3D()
683 {
684     if (m_preserves3D && !m_transformLayer) {
685         // Create the transform layer.
686         m_transformLayer = adoptPtr(WebLayer::create());
687         m_transformLayer->setPreserves3D(true);
688         m_transformLayer->setAnimationDelegate(this);
689         m_layer->layer()->transferAnimationsTo(m_transformLayer.get());
690
691         // Copy the position from this layer.
692         updateLayerPosition();
693         updateLayerSize();
694         updateAnchorPoint();
695         updateTransform();
696         updateChildrenTransform();
697
698         m_layer->layer()->setPosition(FloatPoint::zero());
699
700         m_layer->layer()->setAnchorPoint(FloatPoint(0.5f, 0.5f));
701         m_layer->layer()->setTransform(SkMatrix44());
702
703         // Set the old layer to opacity of 1. Further down we will set the opacity on the transform layer.
704         m_layer->layer()->setOpacity(1);
705
706         m_layer->setContentsScale(contentsScale());
707
708         // Move this layer to be a child of the transform layer.
709         if (parent())
710             parent()->platformLayer()->replaceChild(m_layer->layer(), m_transformLayer.get());
711         m_transformLayer->addChild(m_layer->layer());
712
713         updateChildList();
714     } else if (m_preserves3D && !m_transformLayer) {
715         // Relace the transformLayer in the parent with this layer.
716         m_layer->layer()->removeFromParent();
717         if (parent())
718             parent()->platformLayer()->replaceChild(m_transformLayer.get(), m_layer->layer());
719
720         m_layer->layer()->setAnimationDelegate(this);
721         m_transformLayer->transferAnimationsTo(m_layer->layer());
722
723         // Release the transform layer.
724         m_transformLayer->setAnimationDelegate(0);
725         m_transformLayer.clear();
726
727         updateLayerPosition();
728         updateLayerSize();
729         updateAnchorPoint();
730         updateTransform();
731         updateChildrenTransform();
732
733         updateChildList();
734     }
735
736     m_layer->layer()->setPreserves3D(m_preserves3D);
737     platformLayer()->setOpacity(m_opacity);
738     updateNames();
739 }
740
741 void GraphicsLayerChromium::updateLayerIsDrawable()
742 {
743     // For the rest of the accelerated compositor code, there is no reason to make a
744     // distinction between drawsContent and contentsVisible. So, for m_layer->layer(), these two
745     // flags are combined here. m_contentsLayer shouldn't receive the drawsContent flag
746     // so it is only given contentsVisible.
747
748     m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible);
749
750     if (m_contentsLayer)
751         m_contentsLayer->setDrawsContent(m_contentsVisible);
752
753     if (m_drawsContent) {
754         m_layer->layer()->invalidate();
755         if (m_linkHighlight)
756             m_linkHighlight->invalidate();
757     }
758
759     updateDebugIndicators();
760 }
761
762 void GraphicsLayerChromium::updateLayerBackgroundColor()
763 {
764     if (!m_contentsLayer)
765         return;
766
767     // We never create the contents layer just for background color yet.
768     if (m_backgroundColorSet)
769         m_contentsLayer->setBackgroundColor(m_backgroundColor.rgb());
770     else
771         m_contentsLayer->setBackgroundColor(static_cast<RGBA32>(0));
772 }
773
774 void GraphicsLayerChromium::updateContentsVideo()
775 {
776     // FIXME: Implement
777 }
778
779 void GraphicsLayerChromium::updateContentsRect()
780 {
781     if (!m_contentsLayer)
782         return;
783
784     m_contentsLayer->setPosition(FloatPoint(m_contentsRect.x(), m_contentsRect.y()));
785     m_contentsLayer->setBounds(IntSize(m_contentsRect.width(), m_contentsRect.height()));
786 }
787
788 void GraphicsLayerChromium::updateContentsScale()
789 {
790     // If page scale is already applied then there's no need to apply it again.
791     if (appliesPageScale())
792         return;
793
794     m_layer->setContentsScale(contentsScale());
795 }
796
797 void GraphicsLayerChromium::setupContentsLayer(WebLayer* contentsLayer)
798 {
799     m_contentsLayer = contentsLayer;
800     m_contentsLayerId = m_contentsLayer->id();
801
802     if (m_contentsLayer) {
803         m_contentsLayer->setAnchorPoint(FloatPoint(0, 0));
804         m_contentsLayer->setUseParentBackfaceVisibility(true);
805
806         // It is necessary to call setDrawsContent as soon as we receive the new contentsLayer, for
807         // the correctness of early exit conditions in setDrawsContent() and setContentsVisible().
808         m_contentsLayer->setDrawsContent(m_contentsVisible);
809
810         // Insert the content layer first. Video elements require this, because they have
811         // shadow content that must display in front of the video.
812         m_layer->layer()->insertChild(m_contentsLayer, 0);
813
814         if (showDebugBorders()) {
815             m_contentsLayer->setDebugBorderColor(Color(0, 0, 128, 180).rgb());
816             m_contentsLayer->setDebugBorderWidth(1);
817         }
818     }
819     updateDebugIndicators();
820     updateNames();
821 }
822
823 float GraphicsLayerChromium::contentsScale() const
824 {
825     if (!appliesPageScale())
826         return pageScaleFactor() * deviceScaleFactor();
827     return 1;
828 }
829
830 void GraphicsLayerChromium::deviceOrPageScaleFactorChanged()
831 {
832     updateContentsScale();
833     // Invalidations are clamped to the layer's bounds but we receive the scale changed notification before receiving
834     // the new layer bounds. When the scale changes, we really want to invalidate the post-scale layer bounds, so we
835     // remember that the scale has changed and then invalidate the full layer bounds when we receive the new size.
836     m_pageScaleChanged = true;
837 }
838
839 void GraphicsLayerChromium::paint(GraphicsContext& context, const IntRect& clip)
840 {
841     context.platformContext()->setDrawingToImageBuffer(true);
842     paintGraphicsLayerContents(context, clip);
843 }
844
845 int GraphicsLayerChromium::mapAnimationNameToId(const String& animationName)
846 {
847     if (animationName.isEmpty())
848         return 0;
849
850     if (!m_animationIdMap.contains(animationName))
851         m_animationIdMap.add(animationName, AnimationIdVendor::getNextAnimationId());
852
853     return m_animationIdMap.find(animationName)->second;
854 }
855
856 void GraphicsLayerChromium::notifyAnimationStarted(double startTime)
857 {
858     if (m_client)
859         m_client->notifyAnimationStarted(this, startTime);
860 }
861
862 void GraphicsLayerChromium::notifyAnimationFinished(double)
863 {
864     // Do nothing.
865 }
866
867 } // namespace WebCore
868
869 #endif // USE(ACCELERATED_COMPOSITING)