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