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 
28 #if USE(ACCELERATED_COMPOSITING)
29 
30 #include "GraphicsLayerCACF.h"
31 
32 #include "FloatConversion.h"
33 #include "FloatRect.h"
34 #include "Font.h"
35 #include "FontSelector.h"
36 #include "Image.h"
37 #include "PlatformString.h"
38 #include "SystemTime.h"
39 #include "WebLayer.h"
40 #include "WebTiledLayer.h"
41 #include <wtf/CurrentTime.h>
42 #include <wtf/StringExtras.h>
43 #include <wtf/text/CString.h>
44 
45 using namespace std;
46 
47 namespace WebCore {
48 
49 // The threshold width or height above which a tiled layer will be used. This should be
50 // large enough to avoid tiled layers for most GraphicsLayers, but less than the D3D
51 // texture size limit on all supported hardware.
52 static const int cMaxPixelDimension = 2000;
53 
54 // The width and height of a single tile in a tiled layer. Should be large enough to
55 // avoid lots of small tiles (and therefore lots of drawing callbacks), but small enough
56 // to keep the overall tile cost low.
57 static const int cTiledLayerTileSize = 512;
58 
copyTransform(CATransform3D & toT3D,const TransformationMatrix & t)59 static inline void copyTransform(CATransform3D& toT3D, const TransformationMatrix& t)
60 {
61     toT3D.m11 = narrowPrecisionToFloat(t.m11());
62     toT3D.m12 = narrowPrecisionToFloat(t.m12());
63     toT3D.m13 = narrowPrecisionToFloat(t.m13());
64     toT3D.m14 = narrowPrecisionToFloat(t.m14());
65     toT3D.m21 = narrowPrecisionToFloat(t.m21());
66     toT3D.m22 = narrowPrecisionToFloat(t.m22());
67     toT3D.m23 = narrowPrecisionToFloat(t.m23());
68     toT3D.m24 = narrowPrecisionToFloat(t.m24());
69     toT3D.m31 = narrowPrecisionToFloat(t.m31());
70     toT3D.m32 = narrowPrecisionToFloat(t.m32());
71     toT3D.m33 = narrowPrecisionToFloat(t.m33());
72     toT3D.m34 = narrowPrecisionToFloat(t.m34());
73     toT3D.m41 = narrowPrecisionToFloat(t.m41());
74     toT3D.m42 = narrowPrecisionToFloat(t.m42());
75     toT3D.m43 = narrowPrecisionToFloat(t.m43());
76     toT3D.m44 = narrowPrecisionToFloat(t.m44());
77 }
78 
CAToTransform3D(const CATransform3D & fromT3D)79 TransformationMatrix CAToTransform3D(const CATransform3D& fromT3D)
80 {
81     return TransformationMatrix(
82         fromT3D.m11,
83         fromT3D.m12,
84         fromT3D.m13,
85         fromT3D.m14,
86         fromT3D.m21,
87         fromT3D.m22,
88         fromT3D.m23,
89         fromT3D.m24,
90         fromT3D.m31,
91         fromT3D.m32,
92         fromT3D.m33,
93         fromT3D.m34,
94         fromT3D.m41,
95         fromT3D.m42,
96         fromT3D.m43,
97         fromT3D.m44);
98 }
99 
setLayerBorderColor(WKCACFLayer * layer,const Color & color)100 static void setLayerBorderColor(WKCACFLayer* layer, const Color& color)
101 {
102     layer->setBorderColor(cachedCGColor(color, ColorSpaceDeviceRGB));
103 }
104 
clearBorderColor(WKCACFLayer * layer)105 static void clearBorderColor(WKCACFLayer* layer)
106 {
107     layer->setBorderColor(0);
108 }
109 
setLayerBackgroundColor(WKCACFLayer * layer,const Color & color)110 static void setLayerBackgroundColor(WKCACFLayer* layer, const Color& color)
111 {
112     layer->setBackgroundColor(cachedCGColor(color, ColorSpaceDeviceRGB));
113 }
114 
clearLayerBackgroundColor(WKCACFLayer * layer)115 static void clearLayerBackgroundColor(WKCACFLayer* layer)
116 {
117     layer->setBackgroundColor(0);
118 }
119 
create(GraphicsLayerClient * client)120 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
121 {
122     return new GraphicsLayerCACF(client);
123 }
124 
GraphicsLayerCACF(GraphicsLayerClient * client)125 GraphicsLayerCACF::GraphicsLayerCACF(GraphicsLayerClient* client)
126     : GraphicsLayer(client)
127     , m_contentsLayerPurpose(NoContentsLayer)
128     , m_contentsLayerHasBackgroundColor(false)
129 {
130     m_layer = WebLayer::create(WKCACFLayer::Layer, this);
131 
132     updateDebugIndicators();
133 }
134 
~GraphicsLayerCACF()135 GraphicsLayerCACF::~GraphicsLayerCACF()
136 {
137     // clean up the WK layer
138     if (m_layer)
139         m_layer->removeFromSuperlayer();
140 
141     if (m_contentsLayer)
142         m_contentsLayer->removeFromSuperlayer();
143 
144     if (m_transformLayer)
145         m_transformLayer->removeFromSuperlayer();
146 }
147 
setName(const String & name)148 void GraphicsLayerCACF::setName(const String& name)
149 {
150     String longName = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + name;
151     GraphicsLayer::setName(longName);
152 
153     m_layer->setName(longName);
154 }
155 
setChildren(const Vector<GraphicsLayer * > & children)156 bool GraphicsLayerCACF::setChildren(const Vector<GraphicsLayer*>& children)
157 {
158     bool childrenChanged = GraphicsLayer::setChildren(children);
159     // FIXME: GraphicsLayer::setChildren calls addChild() for each sublayer, which
160     // will end up calling updateSublayerList() N times.
161     if (childrenChanged)
162         updateSublayerList();
163 
164     return childrenChanged;
165 }
166 
addChild(GraphicsLayer * childLayer)167 void GraphicsLayerCACF::addChild(GraphicsLayer* childLayer)
168 {
169     GraphicsLayer::addChild(childLayer);
170     updateSublayerList();
171 }
172 
addChildAtIndex(GraphicsLayer * childLayer,int index)173 void GraphicsLayerCACF::addChildAtIndex(GraphicsLayer* childLayer, int index)
174 {
175     GraphicsLayer::addChildAtIndex(childLayer, index);
176     updateSublayerList();
177 }
178 
addChildBelow(GraphicsLayer * childLayer,GraphicsLayer * sibling)179 void GraphicsLayerCACF::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
180 {
181     GraphicsLayer::addChildBelow(childLayer, sibling);
182     updateSublayerList();
183 }
184 
addChildAbove(GraphicsLayer * childLayer,GraphicsLayer * sibling)185 void GraphicsLayerCACF::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer *sibling)
186 {
187     GraphicsLayer::addChildAbove(childLayer, sibling);
188     updateSublayerList();
189 }
190 
replaceChild(GraphicsLayer * oldChild,GraphicsLayer * newChild)191 bool GraphicsLayerCACF::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
192 {
193     if (GraphicsLayer::replaceChild(oldChild, newChild)) {
194         updateSublayerList();
195         return true;
196     }
197     return false;
198 }
199 
removeFromParent()200 void GraphicsLayerCACF::removeFromParent()
201 {
202     GraphicsLayer::removeFromParent();
203     layerForSuperlayer()->removeFromSuperlayer();
204 }
205 
setPosition(const FloatPoint & point)206 void GraphicsLayerCACF::setPosition(const FloatPoint& point)
207 {
208     GraphicsLayer::setPosition(point);
209     updateLayerPosition();
210 }
211 
setAnchorPoint(const FloatPoint3D & point)212 void GraphicsLayerCACF::setAnchorPoint(const FloatPoint3D& point)
213 {
214     if (point == m_anchorPoint)
215         return;
216 
217     GraphicsLayer::setAnchorPoint(point);
218     updateAnchorPoint();
219 }
220 
setSize(const FloatSize & size)221 void GraphicsLayerCACF::setSize(const FloatSize& size)
222 {
223     if (size == m_size)
224         return;
225 
226     GraphicsLayer::setSize(size);
227     updateLayerSize();
228 }
229 
setTransform(const TransformationMatrix & t)230 void GraphicsLayerCACF::setTransform(const TransformationMatrix& t)
231 {
232     if (t == m_transform)
233         return;
234 
235     GraphicsLayer::setTransform(t);
236     updateTransform();
237 }
238 
setChildrenTransform(const TransformationMatrix & t)239 void GraphicsLayerCACF::setChildrenTransform(const TransformationMatrix& t)
240 {
241     if (t == m_childrenTransform)
242         return;
243 
244     GraphicsLayer::setChildrenTransform(t);
245     updateChildrenTransform();
246 }
247 
setPreserves3D(bool preserves3D)248 void GraphicsLayerCACF::setPreserves3D(bool preserves3D)
249 {
250     if (preserves3D == m_preserves3D)
251         return;
252 
253     GraphicsLayer::setPreserves3D(preserves3D);
254     updateLayerPreserves3D();
255 }
256 
setMasksToBounds(bool masksToBounds)257 void GraphicsLayerCACF::setMasksToBounds(bool masksToBounds)
258 {
259     if (masksToBounds == m_masksToBounds)
260         return;
261 
262     GraphicsLayer::setMasksToBounds(masksToBounds);
263     updateMasksToBounds();
264 }
265 
setDrawsContent(bool drawsContent)266 void GraphicsLayerCACF::setDrawsContent(bool drawsContent)
267 {
268     if (drawsContent == m_drawsContent)
269         return;
270 
271     GraphicsLayer::setDrawsContent(drawsContent);
272     updateLayerDrawsContent();
273 }
274 
setBackgroundColor(const Color & color)275 void GraphicsLayerCACF::setBackgroundColor(const Color& color)
276 {
277     if (m_backgroundColorSet && m_backgroundColor == color)
278         return;
279 
280     GraphicsLayer::setBackgroundColor(color);
281 
282     m_contentsLayerHasBackgroundColor = true;
283     updateLayerBackgroundColor();
284 }
285 
clearBackgroundColor()286 void GraphicsLayerCACF::clearBackgroundColor()
287 {
288     if (!m_backgroundColorSet)
289         return;
290 
291     GraphicsLayer::clearBackgroundColor();
292     clearLayerBackgroundColor(m_contentsLayer.get());
293 }
294 
setContentsOpaque(bool opaque)295 void GraphicsLayerCACF::setContentsOpaque(bool opaque)
296 {
297     if (m_contentsOpaque == opaque)
298         return;
299 
300     GraphicsLayer::setContentsOpaque(opaque);
301     updateContentsOpaque();
302 }
303 
setBackfaceVisibility(bool visible)304 void GraphicsLayerCACF::setBackfaceVisibility(bool visible)
305 {
306     if (m_backfaceVisibility == visible)
307         return;
308 
309     GraphicsLayer::setBackfaceVisibility(visible);
310     updateBackfaceVisibility();
311 }
312 
setOpacity(float opacity)313 void GraphicsLayerCACF::setOpacity(float opacity)
314 {
315     float clampedOpacity = max(min(opacity, 1.0f), 0.0f);
316 
317     if (m_opacity == clampedOpacity)
318         return;
319 
320     GraphicsLayer::setOpacity(clampedOpacity);
321     primaryLayer()->setOpacity(opacity);
322 }
323 
setNeedsDisplay()324 void GraphicsLayerCACF::setNeedsDisplay()
325 {
326     if (drawsContent())
327         m_layer->setNeedsDisplay();
328 }
329 
setNeedsDisplayInRect(const FloatRect & rect)330 void GraphicsLayerCACF::setNeedsDisplayInRect(const FloatRect& rect)
331 {
332     if (drawsContent()) {
333         CGRect cgRect = rect;
334         m_layer->setNeedsDisplay(&cgRect);
335     }
336 }
337 
setContentsRect(const IntRect & rect)338 void GraphicsLayerCACF::setContentsRect(const IntRect& rect)
339 {
340     if (rect == m_contentsRect)
341         return;
342 
343     GraphicsLayer::setContentsRect(rect);
344     updateContentsRect();
345 }
346 
setContentsToImage(Image * image)347 void GraphicsLayerCACF::setContentsToImage(Image* image)
348 {
349     bool childrenChanged = false;
350 
351     if (image) {
352         m_pendingContentsImage = image->nativeImageForCurrentFrame();
353         m_contentsLayerPurpose = ContentsLayerForImage;
354         if (!m_contentsLayer)
355             childrenChanged = true;
356     } else {
357         m_pendingContentsImage = 0;
358         m_contentsLayerPurpose = NoContentsLayer;
359         if (m_contentsLayer)
360             childrenChanged = true;
361     }
362 
363     updateContentsImage();
364 
365     // This has to happen after updateContentsImage
366     if (childrenChanged)
367         updateSublayerList();
368 }
369 
setContentsToMedia(PlatformLayer * mediaLayer)370 void GraphicsLayerCACF::setContentsToMedia(PlatformLayer* mediaLayer)
371 {
372     if (mediaLayer == m_contentsLayer)
373         return;
374 
375     m_contentsLayer = mediaLayer;
376     m_contentsLayerPurpose = mediaLayer ? ContentsLayerForMedia : NoContentsLayer;
377 
378     updateContentsMedia();
379 
380     // This has to happen after updateContentsMedia
381     updateSublayerList();
382 }
383 
hostLayerForSublayers() const384 PlatformLayer* GraphicsLayerCACF::hostLayerForSublayers() const
385 {
386     return m_transformLayer ? m_transformLayer.get() : m_layer.get();
387 }
388 
layerForSuperlayer() const389 PlatformLayer* GraphicsLayerCACF::layerForSuperlayer() const
390 {
391     return m_transformLayer ? m_transformLayer.get() : m_layer.get();
392 }
393 
platformLayer() const394 PlatformLayer* GraphicsLayerCACF::platformLayer() const
395 {
396     return primaryLayer();
397 }
398 
setDebugBackgroundColor(const Color & color)399 void GraphicsLayerCACF::setDebugBackgroundColor(const Color& color)
400 {
401     if (color.isValid())
402         setLayerBackgroundColor(m_layer.get(), color);
403     else
404         clearLayerBackgroundColor(m_layer.get());
405 }
406 
setDebugBorder(const Color & color,float borderWidth)407 void GraphicsLayerCACF::setDebugBorder(const Color& color, float borderWidth)
408 {
409     if (color.isValid()) {
410         setLayerBorderColor(m_layer.get(), color);
411         m_layer->setBorderWidth(borderWidth);
412     } else {
413         clearBorderColor(m_layer.get());
414         m_layer->setBorderWidth(0);
415     }
416 }
417 
requiresTiledLayer(const FloatSize & size) const418 bool GraphicsLayerCACF::requiresTiledLayer(const FloatSize& size) const
419 {
420     if (!m_drawsContent)
421         return false;
422 
423     // FIXME: catch zero-size height or width here (or earlier)?
424     return size.width() > cMaxPixelDimension || size.height() > cMaxPixelDimension;
425 }
426 
swapFromOrToTiledLayer(bool useTiledLayer)427 void GraphicsLayerCACF::swapFromOrToTiledLayer(bool useTiledLayer)
428 {
429     if (useTiledLayer == m_usingTiledLayer)
430         return;
431 
432     CGSize tileSize = CGSizeMake(cTiledLayerTileSize, cTiledLayerTileSize);
433 
434     RefPtr<WKCACFLayer> oldLayer = m_layer;
435     if (useTiledLayer)
436         m_layer = WebTiledLayer::create(tileSize, this);
437     else
438         m_layer = WebLayer::create(WKCACFLayer::Layer, this);
439 
440     m_usingTiledLayer = useTiledLayer;
441 
442     m_layer->adoptSublayers(oldLayer.get());
443     if (oldLayer->superlayer())
444         oldLayer->superlayer()->replaceSublayer(oldLayer.get(), m_layer.get());
445 
446     updateLayerPosition();
447     updateLayerSize();
448     updateAnchorPoint();
449     updateTransform();
450     updateChildrenTransform();
451     updateMasksToBounds();
452     updateContentsOpaque();
453     updateBackfaceVisibility();
454     updateLayerBackgroundColor();
455 
456     updateOpacityOnLayer();
457 
458 #ifndef NDEBUG
459     String name = String::format("CALayer(%p) GraphicsLayer(%p) %s", m_layer.get(), this, m_usingTiledLayer ? "[Tiled Layer] " : "") + m_name;
460     m_layer->setName(name);
461 #endif
462 
463     // need to tell new layer to draw itself
464     setNeedsDisplay();
465 
466     updateDebugIndicators();
467 }
468 
defaultContentsOrientation() const469 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerCACF::defaultContentsOrientation() const
470 {
471     return CompositingCoordinatesTopDown;
472 }
473 
updateSublayerList()474 void GraphicsLayerCACF::updateSublayerList()
475 {
476     Vector<RefPtr<WKCACFLayer> > newSublayers;
477 
478     if (m_transformLayer) {
479         // Add the primary layer first. Even if we have negative z-order children, the primary layer always comes behind.
480         newSublayers.append(m_layer.get());
481     } else if (m_contentsLayer) {
482         // FIXME: add the contents layer in the correct order with negative z-order children.
483         // This does not cause visible rendering issues because currently contents layers are only used
484         // for replaced elements that don't have children.
485         newSublayers.append(m_contentsLayer.get());
486     }
487 
488     const Vector<GraphicsLayer*>& childLayers = children();
489     size_t numChildren = childLayers.size();
490     for (size_t i = 0; i < numChildren; ++i) {
491         GraphicsLayerCACF* curChild = static_cast<GraphicsLayerCACF*>(childLayers[i]);
492 
493         WKCACFLayer* childLayer = curChild->layerForSuperlayer();
494         newSublayers.append(childLayer);
495     }
496 
497     for (int i = 0; i < newSublayers.size(); ++i)
498         newSublayers[i]->removeFromSuperlayer();
499 
500     if (m_transformLayer) {
501         m_transformLayer->setSublayers(newSublayers);
502 
503         if (m_contentsLayer) {
504             // If we have a transform layer, then the contents layer is parented in the
505             // primary layer (which is itself a child of the transform layer).
506             m_layer->removeAllSublayers();
507             m_layer->addSublayer(m_contentsLayer);
508         }
509     } else
510         m_layer->setSublayers(newSublayers);
511 }
512 
updateLayerPosition()513 void GraphicsLayerCACF::updateLayerPosition()
514 {
515     // Position is offset on the layer by the layer anchor point.
516     CGPoint posPoint = CGPointMake(m_position.x() + m_anchorPoint.x() * m_size.width(),
517                                    m_position.y() + m_anchorPoint.y() * m_size.height());
518 
519     primaryLayer()->setPosition(posPoint);
520 }
521 
updateLayerSize()522 void GraphicsLayerCACF::updateLayerSize()
523 {
524     CGRect rect = CGRectMake(0, 0, m_size.width(), m_size.height());
525     if (m_transformLayer) {
526         m_transformLayer->setBounds(rect);
527         // The anchor of the contents layer is always at 0.5, 0.5, so the position is center-relative.
528         CGPoint centerPoint = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
529         m_layer->setPosition(centerPoint);
530     }
531 
532     bool needTiledLayer = requiresTiledLayer(m_size);
533     if (needTiledLayer != m_usingTiledLayer)
534         swapFromOrToTiledLayer(needTiledLayer);
535 
536     m_layer->setBounds(rect);
537 
538     // Note that we don't resize m_contentsLayer. It's up the caller to do that.
539 
540     // if we've changed the bounds, we need to recalculate the position
541     // of the layer, taking anchor point into account.
542     updateLayerPosition();
543 }
544 
updateAnchorPoint()545 void GraphicsLayerCACF::updateAnchorPoint()
546 {
547     primaryLayer()->setAnchorPoint(FloatPoint(m_anchorPoint.x(), m_anchorPoint.y()));
548     primaryLayer()->setAnchorPointZ(m_anchorPoint.z());
549     updateLayerPosition();
550 }
551 
updateTransform()552 void GraphicsLayerCACF::updateTransform()
553 {
554     CATransform3D transform;
555     copyTransform(transform, m_transform);
556     primaryLayer()->setTransform(transform);
557 }
558 
updateChildrenTransform()559 void GraphicsLayerCACF::updateChildrenTransform()
560 {
561     CATransform3D transform;
562     copyTransform(transform, m_childrenTransform);
563     primaryLayer()->setSublayerTransform(transform);
564 }
565 
updateMasksToBounds()566 void GraphicsLayerCACF::updateMasksToBounds()
567 {
568     m_layer->setMasksToBounds(m_masksToBounds);
569     updateDebugIndicators();
570 }
571 
updateContentsOpaque()572 void GraphicsLayerCACF::updateContentsOpaque()
573 {
574     m_layer->setOpaque(m_contentsOpaque);
575 }
576 
updateBackfaceVisibility()577 void GraphicsLayerCACF::updateBackfaceVisibility()
578 {
579     m_layer->setDoubleSided(m_backfaceVisibility);
580 }
581 
updateLayerPreserves3D()582 void GraphicsLayerCACF::updateLayerPreserves3D()
583 {
584     if (m_preserves3D && !m_transformLayer) {
585         // Create the transform layer.
586         m_transformLayer = WebLayer::create(WKCACFLayer::TransformLayer, this);
587 
588 #ifndef NDEBUG
589         m_transformLayer->setName(String().format("Transform Layer CATransformLayer(%p) GraphicsLayer(%p)", m_transformLayer.get(), this));
590 #endif
591         // Copy the position from this layer.
592         updateLayerPosition();
593         updateLayerSize();
594         updateAnchorPoint();
595         updateTransform();
596         updateChildrenTransform();
597 
598         CGPoint point = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
599         m_layer->setPosition(point);
600 
601         m_layer->setAnchorPoint(CGPointMake(0.5f, 0.5f));
602         m_layer->setTransform(CATransform3DIdentity);
603 
604         // Set the old layer to opacity of 1. Further down we will set the opacity on the transform layer.
605         m_layer->setOpacity(1);
606 
607         // Move this layer to be a child of the transform layer.
608         if (m_layer->superlayer())
609             m_layer->superlayer()->replaceSublayer(m_layer.get(), m_transformLayer.get());
610         m_transformLayer->addSublayer(m_layer.get());
611 
612         updateSublayerList();
613     } else if (!m_preserves3D && m_transformLayer) {
614         // Relace the transformLayer in the parent with this layer.
615         m_layer->removeFromSuperlayer();
616         m_transformLayer->superlayer()->replaceSublayer(m_transformLayer.get(), m_layer.get());
617 
618         // Release the transform layer.
619         m_transformLayer = 0;
620 
621         updateLayerPosition();
622         updateLayerSize();
623         updateAnchorPoint();
624         updateTransform();
625         updateChildrenTransform();
626 
627         updateSublayerList();
628     }
629 
630     updateOpacityOnLayer();
631 }
632 
updateLayerDrawsContent()633 void GraphicsLayerCACF::updateLayerDrawsContent()
634 {
635     bool needTiledLayer = requiresTiledLayer(m_size);
636     if (needTiledLayer != m_usingTiledLayer)
637         swapFromOrToTiledLayer(needTiledLayer);
638 
639     if (m_drawsContent)
640         m_layer->setNeedsDisplay();
641     else
642         m_layer->setContents(0);
643 
644     updateDebugIndicators();
645 }
646 
updateLayerBackgroundColor()647 void GraphicsLayerCACF::updateLayerBackgroundColor()
648 {
649     if (!m_contentsLayer)
650         return;
651 
652     // We never create the contents layer just for background color yet.
653     if (m_backgroundColorSet)
654         setLayerBackgroundColor(m_contentsLayer.get(), m_backgroundColor);
655     else
656         clearLayerBackgroundColor(m_contentsLayer.get());
657 }
658 
updateContentsImage()659 void GraphicsLayerCACF::updateContentsImage()
660 {
661     if (m_pendingContentsImage) {
662         if (!m_contentsLayer.get()) {
663             RefPtr<WKCACFLayer> imageLayer = WebLayer::create(WKCACFLayer::Layer, this);
664 #ifndef NDEBUG
665             imageLayer->setName("Image Layer");
666 #endif
667             setupContentsLayer(imageLayer.get());
668             m_contentsLayer = imageLayer;
669             // m_contentsLayer will be parented by updateSublayerList
670         }
671 
672         // FIXME: maybe only do trilinear if the image is being scaled down,
673         // but then what if the layer size changes?
674         m_contentsLayer->setMinificationFilter(WKCACFLayer::Trilinear);
675         m_contentsLayer->setContents(m_pendingContentsImage.get());
676         m_pendingContentsImage = 0;
677 
678         updateContentsRect();
679     } else {
680         // No image.
681         // m_contentsLayer will be removed via updateSublayerList.
682         m_contentsLayer = 0;
683     }
684 }
685 
updateContentsMedia()686 void GraphicsLayerCACF::updateContentsMedia()
687 {
688     // Media layer was set as m_contentsLayer, and will get parented in updateSublayerList().
689     if (m_contentsLayer) {
690         setupContentsLayer(m_contentsLayer.get());
691         updateContentsRect();
692     }
693 }
694 
updateContentsRect()695 void GraphicsLayerCACF::updateContentsRect()
696 {
697     if (!m_contentsLayer)
698         return;
699 
700     CGPoint point = CGPointMake(m_contentsRect.x(),
701                                 m_contentsRect.y());
702     CGRect rect = CGRectMake(0.0f,
703                              0.0f,
704                              m_contentsRect.width(),
705                              m_contentsRect.height());
706 
707     m_contentsLayer->setPosition(point);
708     m_contentsLayer->setBounds(rect);
709 }
710 
setupContentsLayer(WKCACFLayer * contentsLayer)711 void GraphicsLayerCACF::setupContentsLayer(WKCACFLayer* contentsLayer)
712 {
713     if (contentsLayer == m_contentsLayer)
714         return;
715 
716     if (m_contentsLayer) {
717         m_contentsLayer->removeFromSuperlayer();
718         m_contentsLayer = 0;
719     }
720 
721     if (contentsLayer) {
722         m_contentsLayer = contentsLayer;
723 
724         if (defaultContentsOrientation() == CompositingCoordinatesBottomUp) {
725             CATransform3D flipper = {
726                 1.0f, 0.0f, 0.0f, 0.0f,
727                 0.0f, -1.0f, 0.0f, 0.0f,
728                 0.0f, 0.0f, 1.0f, 0.0f,
729                 0.0f, 0.0f, 0.0f, 1.0f};
730             m_contentsLayer->setTransform(flipper);
731             m_contentsLayer->setAnchorPoint(CGPointMake(0.0f, 1.0f));
732         } else
733             m_contentsLayer->setAnchorPoint(CGPointMake(0.0f, 0.0f));
734 
735         // Insert the content layer first. Video elements require this, because they have
736         // shadow content that must display in front of the video.
737         m_layer->insertSublayer(m_contentsLayer.get(), 0);
738 
739         updateContentsRect();
740 
741         if (showDebugBorders()) {
742             setLayerBorderColor(m_contentsLayer.get(), Color(0, 0, 128, 180));
743             m_contentsLayer->setBorderWidth(1.0f);
744         }
745     }
746     updateDebugIndicators();
747 }
748 
749 // This function simply mimics the operation of GraphicsLayerCA
updateOpacityOnLayer()750 void GraphicsLayerCACF::updateOpacityOnLayer()
751 {
752     primaryLayer()->setOpacity(m_opacity);
753 }
754 
755 } // namespace WebCore
756 
757 #endif // USE(ACCELERATED_COMPOSITING)
758