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 #include "platform/graphics/GraphicsLayer.h" 29 30 #include "SkImageFilter.h" 31 #include "SkMatrix44.h" 32 #include "platform/geometry/FloatRect.h" 33 #include "platform/geometry/LayoutRect.h" 34 #include "platform/graphics/GraphicsContext.h" 35 #include "platform/graphics/GraphicsLayerFactory.h" 36 #include "platform/graphics/filters/SkiaImageFilterBuilder.h" 37 #include "platform/graphics/skia/NativeImageSkia.h" 38 #include "platform/scroll/ScrollableArea.h" 39 #include "platform/text/TextStream.h" 40 #include "public/platform/Platform.h" 41 #include "public/platform/WebAnimation.h" 42 #include "public/platform/WebCompositorSupport.h" 43 #include "public/platform/WebFilterOperations.h" 44 #include "public/platform/WebFloatPoint.h" 45 #include "public/platform/WebFloatRect.h" 46 #include "public/platform/WebGraphicsLayerDebugInfo.h" 47 #include "public/platform/WebLayer.h" 48 #include "public/platform/WebPoint.h" 49 #include "public/platform/WebSize.h" 50 #include "wtf/CurrentTime.h" 51 #include "wtf/HashMap.h" 52 #include "wtf/HashSet.h" 53 #include "wtf/text/WTFString.h" 54 55 #ifndef NDEBUG 56 #include <stdio.h> 57 #endif 58 59 using blink::Platform; 60 using blink::WebAnimation; 61 using blink::WebFilterOperations; 62 using blink::WebLayer; 63 using blink::WebPoint; 64 65 namespace WebCore { 66 67 typedef HashMap<const GraphicsLayer*, Vector<FloatRect> > RepaintMap; 68 static RepaintMap& repaintRectMap() 69 { 70 DEFINE_STATIC_LOCAL(RepaintMap, map, ()); 71 return map; 72 } 73 74 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client) 75 { 76 return factory->createGraphicsLayer(client); 77 } 78 79 GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client) 80 : m_client(client) 81 , m_anchorPoint(0.5f, 0.5f, 0) 82 , m_opacity(1) 83 , m_zPosition(0) 84 , m_blendMode(blink::WebBlendModeNormal) 85 , m_contentsOpaque(false) 86 , m_preserves3D(false) 87 , m_backfaceVisibility(true) 88 , m_masksToBounds(false) 89 , m_drawsContent(false) 90 , m_contentsVisible(true) 91 , m_isRootForIsolatedGroup(false) 92 , m_hasScrollParent(false) 93 , m_hasClipParent(false) 94 , m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip) 95 , m_contentsOrientation(CompositingCoordinatesTopDown) 96 , m_parent(0) 97 , m_maskLayer(0) 98 , m_contentsClippingMaskLayer(0) 99 , m_replicaLayer(0) 100 , m_replicatedLayer(0) 101 , m_paintCount(0) 102 , m_contentsLayer(0) 103 , m_contentsLayerId(0) 104 , m_scrollableArea(0) 105 , m_compositingReasons(blink::CompositingReasonUnknown) 106 , m_debugInfo(0) 107 { 108 #ifndef NDEBUG 109 if (m_client) 110 m_client->verifyNotPainting(); 111 #endif 112 113 m_opaqueRectTrackingContentLayerDelegate = adoptPtr(new OpaqueRectTrackingContentLayerDelegate(this)); 114 m_layer = adoptPtr(Platform::current()->compositorSupport()->createContentLayer(m_opaqueRectTrackingContentLayerDelegate.get())); 115 m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible); 116 m_layer->layer()->setWebLayerClient(this); 117 m_layer->setAutomaticallyComputeRasterScale(true); 118 } 119 120 GraphicsLayer::~GraphicsLayer() 121 { 122 for (size_t i = 0; i < m_linkHighlights.size(); ++i) 123 m_linkHighlights[i]->clearCurrentGraphicsLayer(); 124 m_linkHighlights.clear(); 125 126 #ifndef NDEBUG 127 if (m_client) 128 m_client->verifyNotPainting(); 129 #endif 130 131 if (m_replicaLayer) 132 m_replicaLayer->setReplicatedLayer(0); 133 134 if (m_replicatedLayer) 135 m_replicatedLayer->setReplicatedByLayer(0); 136 137 removeAllChildren(); 138 removeFromParent(); 139 140 resetTrackedRepaints(); 141 ASSERT(!m_parent); 142 } 143 144 void GraphicsLayer::setParent(GraphicsLayer* layer) 145 { 146 ASSERT(!layer || !layer->hasAncestor(this)); 147 m_parent = layer; 148 } 149 150 bool GraphicsLayer::hasAncestor(GraphicsLayer* ancestor) const 151 { 152 for (GraphicsLayer* curr = parent(); curr; curr = curr->parent()) { 153 if (curr == ancestor) 154 return true; 155 } 156 157 return false; 158 } 159 160 bool GraphicsLayer::setChildren(const Vector<GraphicsLayer*>& newChildren) 161 { 162 // If the contents of the arrays are the same, nothing to do. 163 if (newChildren == m_children) 164 return false; 165 166 removeAllChildren(); 167 168 size_t listSize = newChildren.size(); 169 for (size_t i = 0; i < listSize; ++i) 170 addChildInternal(newChildren[i]); 171 172 updateChildList(); 173 174 return true; 175 } 176 177 void GraphicsLayer::addChildInternal(GraphicsLayer* childLayer) 178 { 179 ASSERT(childLayer != this); 180 181 if (childLayer->parent()) 182 childLayer->removeFromParent(); 183 184 childLayer->setParent(this); 185 m_children.append(childLayer); 186 187 // Don't call updateChildList here, this function is used in cases where it 188 // should not be called until all children are processed. 189 } 190 191 void GraphicsLayer::addChild(GraphicsLayer* childLayer) 192 { 193 addChildInternal(childLayer); 194 updateChildList(); 195 } 196 197 void GraphicsLayer::addChildAtIndex(GraphicsLayer* childLayer, int index) 198 { 199 ASSERT(childLayer != this); 200 201 if (childLayer->parent()) 202 childLayer->removeFromParent(); 203 204 childLayer->setParent(this); 205 m_children.insert(index, childLayer); 206 207 updateChildList(); 208 } 209 210 void GraphicsLayer::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling) 211 { 212 ASSERT(childLayer != this); 213 childLayer->removeFromParent(); 214 215 bool found = false; 216 for (unsigned i = 0; i < m_children.size(); i++) { 217 if (sibling == m_children[i]) { 218 m_children.insert(i, childLayer); 219 found = true; 220 break; 221 } 222 } 223 224 childLayer->setParent(this); 225 226 if (!found) 227 m_children.append(childLayer); 228 229 updateChildList(); 230 } 231 232 void GraphicsLayer::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling) 233 { 234 childLayer->removeFromParent(); 235 ASSERT(childLayer != this); 236 237 bool found = false; 238 for (unsigned i = 0; i < m_children.size(); i++) { 239 if (sibling == m_children[i]) { 240 m_children.insert(i+1, childLayer); 241 found = true; 242 break; 243 } 244 } 245 246 childLayer->setParent(this); 247 248 if (!found) 249 m_children.append(childLayer); 250 251 updateChildList(); 252 } 253 254 bool GraphicsLayer::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild) 255 { 256 ASSERT(!newChild->parent()); 257 bool found = false; 258 for (unsigned i = 0; i < m_children.size(); i++) { 259 if (oldChild == m_children[i]) { 260 m_children[i] = newChild; 261 found = true; 262 break; 263 } 264 } 265 266 if (found) { 267 oldChild->setParent(0); 268 269 newChild->removeFromParent(); 270 newChild->setParent(this); 271 272 updateChildList(); 273 return true; 274 } 275 276 return false; 277 } 278 279 void GraphicsLayer::removeAllChildren() 280 { 281 while (m_children.size()) { 282 GraphicsLayer* curLayer = m_children[0]; 283 ASSERT(curLayer->parent()); 284 curLayer->removeFromParent(); 285 } 286 } 287 288 void GraphicsLayer::removeFromParent() 289 { 290 if (m_parent) { 291 unsigned i; 292 for (i = 0; i < m_parent->m_children.size(); i++) { 293 if (this == m_parent->m_children[i]) { 294 m_parent->m_children.remove(i); 295 break; 296 } 297 } 298 299 setParent(0); 300 } 301 302 platformLayer()->removeFromParent(); 303 } 304 305 void GraphicsLayer::setReplicatedByLayer(GraphicsLayer* layer) 306 { 307 // FIXME: this could probably be a full early exit. 308 if (m_replicaLayer != layer) { 309 if (m_replicaLayer) 310 m_replicaLayer->setReplicatedLayer(0); 311 312 if (layer) 313 layer->setReplicatedLayer(this); 314 315 m_replicaLayer = layer; 316 } 317 318 WebLayer* webReplicaLayer = layer ? layer->platformLayer() : 0; 319 platformLayer()->setReplicaLayer(webReplicaLayer); 320 } 321 322 void GraphicsLayer::setOffsetFromRenderer(const IntSize& offset, ShouldSetNeedsDisplay shouldSetNeedsDisplay) 323 { 324 if (offset == m_offsetFromRenderer) 325 return; 326 327 m_offsetFromRenderer = offset; 328 329 // If the compositing layer offset changes, we need to repaint. 330 if (shouldSetNeedsDisplay == SetNeedsDisplay) 331 setNeedsDisplay(); 332 } 333 334 void GraphicsLayer::paintGraphicsLayerContents(GraphicsContext& context, const IntRect& clip) 335 { 336 if (!m_client) 337 return; 338 incrementPaintCount(); 339 m_client->paintContents(this, context, m_paintingPhase, clip); 340 } 341 342 void GraphicsLayer::setZPosition(float position) 343 { 344 m_zPosition = position; 345 } 346 347 float GraphicsLayer::accumulatedOpacity() const 348 { 349 if (!preserves3D()) 350 return 1; 351 352 return m_opacity * (parent() ? parent()->accumulatedOpacity() : 1); 353 } 354 355 void GraphicsLayer::distributeOpacity(float accumulatedOpacity) 356 { 357 // If this is a transform layer we need to distribute our opacity to all our children 358 359 // Incoming accumulatedOpacity is the contribution from our parent(s). We mutiply this by our own 360 // opacity to get the total contribution 361 accumulatedOpacity *= m_opacity; 362 363 if (preserves3D()) { 364 size_t numChildren = children().size(); 365 for (size_t i = 0; i < numChildren; ++i) 366 children()[i]->distributeOpacity(accumulatedOpacity); 367 } 368 } 369 370 void GraphicsLayer::updateChildList() 371 { 372 WebLayer* childHost = m_layer->layer(); 373 childHost->removeAllChildren(); 374 375 clearContentsLayerIfUnregistered(); 376 377 if (m_contentsLayer) { 378 // FIXME: add the contents layer in the correct order with negative z-order children. 379 // This does not cause visible rendering issues because currently contents layers are only used 380 // for replaced elements that don't have children. 381 childHost->addChild(m_contentsLayer); 382 } 383 384 const Vector<GraphicsLayer*>& childLayers = children(); 385 size_t numChildren = childLayers.size(); 386 for (size_t i = 0; i < numChildren; ++i) { 387 GraphicsLayer* curChild = childLayers[i]; 388 389 childHost->addChild(curChild->platformLayer()); 390 } 391 392 for (size_t i = 0; i < m_linkHighlights.size(); ++i) 393 childHost->addChild(m_linkHighlights[i]->layer()); 394 } 395 396 void GraphicsLayer::updateLayerIsDrawable() 397 { 398 // For the rest of the accelerated compositor code, there is no reason to make a 399 // distinction between drawsContent and contentsVisible. So, for m_layer->layer(), these two 400 // flags are combined here. m_contentsLayer shouldn't receive the drawsContent flag 401 // so it is only given contentsVisible. 402 403 m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible); 404 if (WebLayer* contentsLayer = contentsLayerIfRegistered()) 405 contentsLayer->setDrawsContent(m_contentsVisible); 406 407 if (m_drawsContent) { 408 m_layer->layer()->invalidate(); 409 for (size_t i = 0; i < m_linkHighlights.size(); ++i) 410 m_linkHighlights[i]->invalidate(); 411 } 412 } 413 414 void GraphicsLayer::updateContentsRect() 415 { 416 WebLayer* contentsLayer = contentsLayerIfRegistered(); 417 if (!contentsLayer) 418 return; 419 420 contentsLayer->setPosition(FloatPoint(m_contentsRect.x(), m_contentsRect.y())); 421 contentsLayer->setBounds(IntSize(m_contentsRect.width(), m_contentsRect.height())); 422 423 if (m_contentsClippingMaskLayer) { 424 if (m_contentsClippingMaskLayer->size() != m_contentsRect.size()) { 425 m_contentsClippingMaskLayer->setSize(m_contentsRect.size()); 426 m_contentsClippingMaskLayer->setNeedsDisplay(); 427 } 428 m_contentsClippingMaskLayer->setPosition(FloatPoint()); 429 m_contentsClippingMaskLayer->setOffsetFromRenderer(offsetFromRenderer() + IntSize(m_contentsRect.location().x(), m_contentsRect.location().y())); 430 } 431 } 432 433 static HashSet<int>* s_registeredLayerSet; 434 435 void GraphicsLayer::registerContentsLayer(WebLayer* layer) 436 { 437 if (!s_registeredLayerSet) 438 s_registeredLayerSet = new HashSet<int>; 439 if (s_registeredLayerSet->contains(layer->id())) 440 CRASH(); 441 s_registeredLayerSet->add(layer->id()); 442 } 443 444 void GraphicsLayer::unregisterContentsLayer(WebLayer* layer) 445 { 446 ASSERT(s_registeredLayerSet); 447 if (!s_registeredLayerSet->contains(layer->id())) 448 CRASH(); 449 s_registeredLayerSet->remove(layer->id()); 450 } 451 452 void GraphicsLayer::setContentsTo(WebLayer* layer) 453 { 454 bool childrenChanged = false; 455 if (layer) { 456 ASSERT(s_registeredLayerSet); 457 if (!s_registeredLayerSet->contains(layer->id())) 458 CRASH(); 459 if (m_contentsLayerId != layer->id()) { 460 setupContentsLayer(layer); 461 childrenChanged = true; 462 } 463 updateContentsRect(); 464 } else { 465 if (m_contentsLayer) { 466 childrenChanged = true; 467 468 // The old contents layer will be removed via updateChildList. 469 m_contentsLayer = 0; 470 m_contentsLayerId = 0; 471 } 472 } 473 474 if (childrenChanged) 475 updateChildList(); 476 } 477 478 void GraphicsLayer::setupContentsLayer(WebLayer* contentsLayer) 479 { 480 ASSERT(contentsLayer); 481 m_contentsLayer = contentsLayer; 482 m_contentsLayerId = m_contentsLayer->id(); 483 484 m_contentsLayer->setWebLayerClient(this); 485 m_contentsLayer->setAnchorPoint(FloatPoint(0, 0)); 486 m_contentsLayer->setUseParentBackfaceVisibility(true); 487 488 // It is necessary to call setDrawsContent as soon as we receive the new contentsLayer, for 489 // the correctness of early exit conditions in setDrawsContent() and setContentsVisible(). 490 m_contentsLayer->setDrawsContent(m_contentsVisible); 491 492 // Insert the content layer first. Video elements require this, because they have 493 // shadow content that must display in front of the video. 494 m_layer->layer()->insertChild(m_contentsLayer, 0); 495 WebLayer* borderWebLayer = m_contentsClippingMaskLayer ? m_contentsClippingMaskLayer->platformLayer() : 0; 496 m_contentsLayer->setMaskLayer(borderWebLayer); 497 } 498 499 void GraphicsLayer::clearContentsLayerIfUnregistered() 500 { 501 if (!m_contentsLayerId || s_registeredLayerSet->contains(m_contentsLayerId)) 502 return; 503 504 m_contentsLayer = 0; 505 m_contentsLayerId = 0; 506 } 507 508 void GraphicsLayer::setDebugInfo(blink::WebGraphicsLayerDebugInfo* debugInfo) 509 { 510 if (m_debugInfo) 511 delete m_debugInfo; 512 m_debugInfo = debugInfo; 513 } 514 515 blink::WebGraphicsLayerDebugInfo* GraphicsLayer::takeDebugInfo() 516 { 517 blink::WebGraphicsLayerDebugInfo* tempDebugInfo = m_debugInfo; 518 m_debugInfo = 0; 519 return tempDebugInfo; 520 } 521 522 WebLayer* GraphicsLayer::contentsLayerIfRegistered() 523 { 524 clearContentsLayerIfUnregistered(); 525 return m_contentsLayer; 526 } 527 528 double GraphicsLayer::backingStoreMemoryEstimate() const 529 { 530 if (!drawsContent()) 531 return 0; 532 533 // Effects of page and device scale are ignored; subclasses should override to take these into account. 534 return static_cast<double>(4 * size().width()) * size().height(); 535 } 536 537 void GraphicsLayer::resetTrackedRepaints() 538 { 539 repaintRectMap().remove(this); 540 } 541 542 void GraphicsLayer::addRepaintRect(const FloatRect& repaintRect) 543 { 544 if (m_client->isTrackingRepaints()) { 545 FloatRect largestRepaintRect(FloatPoint(), m_size); 546 largestRepaintRect.intersect(repaintRect); 547 RepaintMap::iterator repaintIt = repaintRectMap().find(this); 548 if (repaintIt == repaintRectMap().end()) { 549 Vector<FloatRect> repaintRects; 550 repaintRects.append(largestRepaintRect); 551 repaintRectMap().set(this, repaintRects); 552 } else { 553 Vector<FloatRect>& repaintRects = repaintIt->value; 554 repaintRects.append(largestRepaintRect); 555 } 556 } 557 } 558 559 void GraphicsLayer::collectTrackedRepaintRects(Vector<FloatRect>& rects) const 560 { 561 if (!m_client->isTrackingRepaints()) 562 return; 563 564 RepaintMap::iterator repaintIt = repaintRectMap().find(this); 565 if (repaintIt != repaintRectMap().end()) 566 rects.append(repaintIt->value); 567 } 568 569 void GraphicsLayer::dumpLayer(TextStream& ts, int indent, LayerTreeFlags flags) const 570 { 571 writeIndent(ts, indent); 572 ts << "(" << "GraphicsLayer"; 573 574 if (flags & LayerTreeIncludesDebugInfo) { 575 ts << " " << static_cast<void*>(const_cast<GraphicsLayer*>(this)); 576 ts << " \"" << m_client->debugName(this) << "\""; 577 } 578 579 ts << "\n"; 580 dumpProperties(ts, indent, flags); 581 writeIndent(ts, indent); 582 ts << ")\n"; 583 } 584 585 void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeFlags flags) const 586 { 587 if (m_position != FloatPoint()) { 588 writeIndent(ts, indent + 1); 589 ts << "(position " << m_position.x() << " " << m_position.y() << ")\n"; 590 } 591 592 if (m_boundsOrigin != FloatPoint()) { 593 writeIndent(ts, indent + 1); 594 ts << "(bounds origin " << m_boundsOrigin.x() << " " << m_boundsOrigin.y() << ")\n"; 595 } 596 597 if (m_anchorPoint != FloatPoint3D(0.5f, 0.5f, 0)) { 598 writeIndent(ts, indent + 1); 599 ts << "(anchor " << m_anchorPoint.x() << " " << m_anchorPoint.y() << ")\n"; 600 } 601 602 if (m_size != IntSize()) { 603 writeIndent(ts, indent + 1); 604 ts << "(bounds " << m_size.width() << " " << m_size.height() << ")\n"; 605 } 606 607 if (m_opacity != 1) { 608 writeIndent(ts, indent + 1); 609 ts << "(opacity " << m_opacity << ")\n"; 610 } 611 612 if (m_blendMode != blink::WebBlendModeNormal) { 613 writeIndent(ts, indent + 1); 614 ts << "(blendMode " << compositeOperatorName(CompositeSourceOver, m_blendMode) << ")\n"; 615 } 616 617 if (m_isRootForIsolatedGroup) { 618 writeIndent(ts, indent + 1); 619 ts << "(isolate " << m_isRootForIsolatedGroup << ")\n"; 620 } 621 622 if (m_contentsOpaque) { 623 writeIndent(ts, indent + 1); 624 ts << "(contentsOpaque " << m_contentsOpaque << ")\n"; 625 } 626 627 if (m_preserves3D) { 628 writeIndent(ts, indent + 1); 629 ts << "(preserves3D " << m_preserves3D << ")\n"; 630 } 631 632 if (m_drawsContent) { 633 writeIndent(ts, indent + 1); 634 ts << "(drawsContent " << m_drawsContent << ")\n"; 635 } 636 637 if (!m_contentsVisible) { 638 writeIndent(ts, indent + 1); 639 ts << "(contentsVisible " << m_contentsVisible << ")\n"; 640 } 641 642 if (!m_backfaceVisibility) { 643 writeIndent(ts, indent + 1); 644 ts << "(backfaceVisibility " << (m_backfaceVisibility ? "visible" : "hidden") << ")\n"; 645 } 646 647 if (flags & LayerTreeIncludesDebugInfo) { 648 writeIndent(ts, indent + 1); 649 ts << "("; 650 if (m_client) 651 ts << "client " << static_cast<void*>(m_client); 652 else 653 ts << "no client"; 654 ts << ")\n"; 655 } 656 657 if (m_backgroundColor.isValid() && m_backgroundColor != Color::transparent) { 658 writeIndent(ts, indent + 1); 659 ts << "(backgroundColor " << m_backgroundColor.nameForRenderTreeAsText() << ")\n"; 660 } 661 662 if (!m_transform.isIdentity()) { 663 writeIndent(ts, indent + 1); 664 ts << "(transform "; 665 ts << "[" << m_transform.m11() << " " << m_transform.m12() << " " << m_transform.m13() << " " << m_transform.m14() << "] "; 666 ts << "[" << m_transform.m21() << " " << m_transform.m22() << " " << m_transform.m23() << " " << m_transform.m24() << "] "; 667 ts << "[" << m_transform.m31() << " " << m_transform.m32() << " " << m_transform.m33() << " " << m_transform.m34() << "] "; 668 ts << "[" << m_transform.m41() << " " << m_transform.m42() << " " << m_transform.m43() << " " << m_transform.m44() << "])\n"; 669 } 670 671 // Avoid dumping the sublayer transform on the root layer, because it's used for geometry flipping, whose behavior 672 // differs between platforms. 673 if (parent() && !m_childrenTransform.isIdentity()) { 674 writeIndent(ts, indent + 1); 675 ts << "(childrenTransform "; 676 ts << "[" << m_childrenTransform.m11() << " " << m_childrenTransform.m12() << " " << m_childrenTransform.m13() << " " << m_childrenTransform.m14() << "] "; 677 ts << "[" << m_childrenTransform.m21() << " " << m_childrenTransform.m22() << " " << m_childrenTransform.m23() << " " << m_childrenTransform.m24() << "] "; 678 ts << "[" << m_childrenTransform.m31() << " " << m_childrenTransform.m32() << " " << m_childrenTransform.m33() << " " << m_childrenTransform.m34() << "] "; 679 ts << "[" << m_childrenTransform.m41() << " " << m_childrenTransform.m42() << " " << m_childrenTransform.m43() << " " << m_childrenTransform.m44() << "])\n"; 680 } 681 682 if (m_replicaLayer) { 683 writeIndent(ts, indent + 1); 684 ts << "(replica layer"; 685 if (flags & LayerTreeIncludesDebugInfo) 686 ts << " " << m_replicaLayer; 687 ts << ")\n"; 688 m_replicaLayer->dumpLayer(ts, indent + 2, flags); 689 } 690 691 if (m_replicatedLayer) { 692 writeIndent(ts, indent + 1); 693 ts << "(replicated layer"; 694 if (flags & LayerTreeIncludesDebugInfo) 695 ts << " " << m_replicatedLayer; 696 ts << ")\n"; 697 } 698 699 if ((flags & LayerTreeIncludesRepaintRects) && repaintRectMap().contains(this) && !repaintRectMap().get(this).isEmpty()) { 700 writeIndent(ts, indent + 1); 701 ts << "(repaint rects\n"; 702 for (size_t i = 0; i < repaintRectMap().get(this).size(); ++i) { 703 if (repaintRectMap().get(this)[i].isEmpty()) 704 continue; 705 writeIndent(ts, indent + 2); 706 ts << "(rect "; 707 ts << repaintRectMap().get(this)[i].x() << " "; 708 ts << repaintRectMap().get(this)[i].y() << " "; 709 ts << repaintRectMap().get(this)[i].width() << " "; 710 ts << repaintRectMap().get(this)[i].height(); 711 ts << ")\n"; 712 } 713 writeIndent(ts, indent + 1); 714 ts << ")\n"; 715 } 716 717 if ((flags & LayerTreeIncludesPaintingPhases) && paintingPhase()) { 718 writeIndent(ts, indent + 1); 719 ts << "(paintingPhases\n"; 720 if (paintingPhase() & GraphicsLayerPaintBackground) { 721 writeIndent(ts, indent + 2); 722 ts << "GraphicsLayerPaintBackground\n"; 723 } 724 if (paintingPhase() & GraphicsLayerPaintForeground) { 725 writeIndent(ts, indent + 2); 726 ts << "GraphicsLayerPaintForeground\n"; 727 } 728 if (paintingPhase() & GraphicsLayerPaintMask) { 729 writeIndent(ts, indent + 2); 730 ts << "GraphicsLayerPaintMask\n"; 731 } 732 if (paintingPhase() & GraphicsLayerPaintChildClippingMask) { 733 writeIndent(ts, indent + 2); 734 ts << "GraphicsLayerPaintChildClippingMask\n"; 735 } 736 if (paintingPhase() & GraphicsLayerPaintOverflowContents) { 737 writeIndent(ts, indent + 2); 738 ts << "GraphicsLayerPaintOverflowContents\n"; 739 } 740 if (paintingPhase() & GraphicsLayerPaintCompositedScroll) { 741 writeIndent(ts, indent + 2); 742 ts << "GraphicsLayerPaintCompositedScroll\n"; 743 } 744 writeIndent(ts, indent + 1); 745 ts << ")\n"; 746 } 747 748 if (flags & LayerTreeIncludesClipAndScrollParents) { 749 if (m_hasScrollParent) { 750 writeIndent(ts, indent + 1); 751 ts << "(hasScrollParent 1)\n"; 752 } 753 if (m_hasClipParent) { 754 writeIndent(ts, indent + 1); 755 ts << "(hasClipParent 1)\n"; 756 } 757 } 758 759 if (m_children.size()) { 760 writeIndent(ts, indent + 1); 761 ts << "(children " << m_children.size() << "\n"; 762 763 unsigned i; 764 for (i = 0; i < m_children.size(); i++) 765 m_children[i]->dumpLayer(ts, indent + 2, flags); 766 writeIndent(ts, indent + 1); 767 ts << ")\n"; 768 } 769 } 770 771 String GraphicsLayer::layerTreeAsText(LayerTreeFlags flags) const 772 { 773 TextStream ts; 774 775 dumpLayer(ts, 0, flags); 776 return ts.release(); 777 } 778 779 blink::WebString GraphicsLayer::debugName(blink::WebLayer* webLayer) 780 { 781 String name; 782 if (!m_client) 783 return name; 784 785 String highlightDebugName; 786 for (size_t i = 0; i < m_linkHighlights.size(); ++i) { 787 if (webLayer == m_linkHighlights[i]->layer()) { 788 highlightDebugName = "LinkHighlight[" + String::number(i) + "] for " + m_client->debugName(this); 789 break; 790 } 791 } 792 793 if (webLayer == m_contentsLayer) { 794 name = "ContentsLayer for " + m_client->debugName(this); 795 } else if (!highlightDebugName.isEmpty()) { 796 name = highlightDebugName; 797 } else if (webLayer == m_layer->layer()) { 798 name = m_client->debugName(this); 799 } else { 800 ASSERT_NOT_REACHED(); 801 } 802 return name; 803 } 804 805 void GraphicsLayer::setCompositingReasons(blink::WebCompositingReasons reasons) 806 { 807 m_compositingReasons = reasons; 808 m_layer->layer()->setCompositingReasons(reasons); 809 } 810 811 void GraphicsLayer::setPosition(const FloatPoint& point) 812 { 813 m_position = point; 814 platformLayer()->setPosition(m_position); 815 } 816 817 void GraphicsLayer::setAnchorPoint(const FloatPoint3D& point) 818 { 819 m_anchorPoint = point; 820 platformLayer()->setAnchorPoint(FloatPoint(m_anchorPoint.x(), m_anchorPoint.y())); 821 platformLayer()->setAnchorPointZ(m_anchorPoint.z()); 822 } 823 824 void GraphicsLayer::setSize(const FloatSize& size) 825 { 826 // We are receiving negative sizes here that cause assertions to fail in the compositor. Clamp them to 0 to 827 // avoid those assertions. 828 // FIXME: This should be an ASSERT instead, as negative sizes should not exist in WebCore. 829 FloatSize clampedSize = size; 830 if (clampedSize.width() < 0 || clampedSize.height() < 0) 831 clampedSize = FloatSize(); 832 833 if (clampedSize == m_size) 834 return; 835 836 m_size = clampedSize; 837 838 m_layer->layer()->setBounds(flooredIntSize(m_size)); 839 // Note that we don't resize m_contentsLayer. It's up the caller to do that. 840 } 841 842 void GraphicsLayer::setTransform(const TransformationMatrix& transform) 843 { 844 m_transform = transform; 845 platformLayer()->setTransform(TransformationMatrix::toSkMatrix44(m_transform)); 846 } 847 848 void GraphicsLayer::setChildrenTransform(const TransformationMatrix& transform) 849 { 850 m_childrenTransform = transform; 851 platformLayer()->setSublayerTransform(TransformationMatrix::toSkMatrix44(m_childrenTransform)); 852 } 853 854 void GraphicsLayer::setPreserves3D(bool preserves3D) 855 { 856 if (preserves3D == m_preserves3D) 857 return; 858 859 m_preserves3D = preserves3D; 860 m_layer->layer()->setPreserves3D(m_preserves3D); 861 } 862 863 void GraphicsLayer::setMasksToBounds(bool masksToBounds) 864 { 865 m_masksToBounds = masksToBounds; 866 m_layer->layer()->setMasksToBounds(m_masksToBounds); 867 } 868 869 void GraphicsLayer::setDrawsContent(bool drawsContent) 870 { 871 // Note carefully this early-exit is only correct because we also properly call 872 // WebLayer::setDrawsContent whenever m_contentsLayer is set to a new layer in setupContentsLayer(). 873 if (drawsContent == m_drawsContent) 874 return; 875 876 m_drawsContent = drawsContent; 877 updateLayerIsDrawable(); 878 } 879 880 void GraphicsLayer::setContentsVisible(bool contentsVisible) 881 { 882 // Note carefully this early-exit is only correct because we also properly call 883 // WebLayer::setDrawsContent whenever m_contentsLayer is set to a new layer in setupContentsLayer(). 884 if (contentsVisible == m_contentsVisible) 885 return; 886 887 m_contentsVisible = contentsVisible; 888 updateLayerIsDrawable(); 889 } 890 891 void GraphicsLayer::setClipParent(blink::WebLayer* parent) 892 { 893 m_hasClipParent = !!parent; 894 m_layer->layer()->setClipParent(parent); 895 } 896 897 void GraphicsLayer::setScrollParent(blink::WebLayer* parent) 898 { 899 m_hasScrollParent = !!parent; 900 m_layer->layer()->setScrollParent(parent); 901 } 902 903 void GraphicsLayer::setBackgroundColor(const Color& color) 904 { 905 if (color == m_backgroundColor) 906 return; 907 908 m_backgroundColor = color; 909 m_layer->layer()->setBackgroundColor(m_backgroundColor.rgb()); 910 } 911 912 void GraphicsLayer::setContentsOpaque(bool opaque) 913 { 914 m_contentsOpaque = opaque; 915 m_layer->layer()->setOpaque(m_contentsOpaque); 916 m_opaqueRectTrackingContentLayerDelegate->setOpaque(m_contentsOpaque); 917 } 918 919 void GraphicsLayer::setMaskLayer(GraphicsLayer* maskLayer) 920 { 921 if (maskLayer == m_maskLayer) 922 return; 923 924 m_maskLayer = maskLayer; 925 WebLayer* maskWebLayer = m_maskLayer ? m_maskLayer->platformLayer() : 0; 926 m_layer->layer()->setMaskLayer(maskWebLayer); 927 } 928 929 void GraphicsLayer::setContentsClippingMaskLayer(GraphicsLayer* contentsClippingMaskLayer) 930 { 931 if (contentsClippingMaskLayer == m_contentsClippingMaskLayer) 932 return; 933 934 m_contentsClippingMaskLayer = contentsClippingMaskLayer; 935 WebLayer* contentsLayer = contentsLayerIfRegistered(); 936 if (!contentsLayer) 937 return; 938 WebLayer* contentsClippingMaskWebLayer = m_contentsClippingMaskLayer ? m_contentsClippingMaskLayer->platformLayer() : 0; 939 contentsLayer->setMaskLayer(contentsClippingMaskWebLayer); 940 updateContentsRect(); 941 } 942 943 void GraphicsLayer::setBackfaceVisibility(bool visible) 944 { 945 m_backfaceVisibility = visible; 946 m_layer->setDoubleSided(m_backfaceVisibility); 947 } 948 949 void GraphicsLayer::setOpacity(float opacity) 950 { 951 float clampedOpacity = std::max(std::min(opacity, 1.0f), 0.0f); 952 m_opacity = clampedOpacity; 953 platformLayer()->setOpacity(opacity); 954 } 955 956 void GraphicsLayer::setBlendMode(blink::WebBlendMode blendMode) 957 { 958 if (m_blendMode == blendMode) 959 return; 960 m_blendMode = blendMode; 961 platformLayer()->setBlendMode(blink::WebBlendMode(blendMode)); 962 } 963 964 void GraphicsLayer::setIsRootForIsolatedGroup(bool isolated) 965 { 966 if (m_isRootForIsolatedGroup == isolated) 967 return; 968 m_isRootForIsolatedGroup = isolated; 969 platformLayer()->setIsRootForIsolatedGroup(isolated); 970 } 971 972 void GraphicsLayer::setContentsNeedsDisplay() 973 { 974 if (WebLayer* contentsLayer = contentsLayerIfRegistered()) { 975 contentsLayer->invalidate(); 976 addRepaintRect(contentsRect()); 977 } 978 } 979 980 void GraphicsLayer::setNeedsDisplay() 981 { 982 if (drawsContent()) { 983 m_layer->layer()->invalidate(); 984 addRepaintRect(FloatRect(FloatPoint(), m_size)); 985 for (size_t i = 0; i < m_linkHighlights.size(); ++i) 986 m_linkHighlights[i]->invalidate(); 987 } 988 } 989 990 void GraphicsLayer::setNeedsDisplayInRect(const FloatRect& rect) 991 { 992 if (drawsContent()) { 993 m_layer->layer()->invalidateRect(rect); 994 addRepaintRect(rect); 995 for (size_t i = 0; i < m_linkHighlights.size(); ++i) 996 m_linkHighlights[i]->invalidate(); 997 } 998 } 999 1000 void GraphicsLayer::setContentsRect(const IntRect& rect) 1001 { 1002 if (rect == m_contentsRect) 1003 return; 1004 1005 m_contentsRect = rect; 1006 updateContentsRect(); 1007 } 1008 1009 void GraphicsLayer::setContentsToImage(Image* image) 1010 { 1011 RefPtr<NativeImageSkia> nativeImage = image ? image->nativeImageForCurrentFrame() : 0; 1012 if (nativeImage) { 1013 if (!m_imageLayer) { 1014 m_imageLayer = adoptPtr(Platform::current()->compositorSupport()->createImageLayer()); 1015 registerContentsLayer(m_imageLayer->layer()); 1016 } 1017 m_imageLayer->setBitmap(nativeImage->bitmap()); 1018 m_imageLayer->layer()->setOpaque(image->currentFrameKnownToBeOpaque()); 1019 updateContentsRect(); 1020 } else { 1021 if (m_imageLayer) { 1022 unregisterContentsLayer(m_imageLayer->layer()); 1023 m_imageLayer.clear(); 1024 } 1025 } 1026 1027 setContentsTo(m_imageLayer ? m_imageLayer->layer() : 0); 1028 } 1029 1030 void GraphicsLayer::setContentsToNinePatch(Image* image, const IntRect& aperture) 1031 { 1032 if (m_ninePatchLayer) { 1033 unregisterContentsLayer(m_ninePatchLayer->layer()); 1034 m_ninePatchLayer.clear(); 1035 } 1036 RefPtr<NativeImageSkia> nativeImage = image ? image->nativeImageForCurrentFrame() : 0; 1037 if (nativeImage) { 1038 m_ninePatchLayer = adoptPtr(Platform::current()->compositorSupport()->createNinePatchLayer()); 1039 m_ninePatchLayer->setBitmap(nativeImage->bitmap(), aperture); 1040 m_ninePatchLayer->layer()->setOpaque(image->currentFrameKnownToBeOpaque()); 1041 registerContentsLayer(m_ninePatchLayer->layer()); 1042 } 1043 setContentsTo(m_ninePatchLayer ? m_ninePatchLayer->layer() : 0); 1044 } 1045 1046 void GraphicsLayer::setContentsToSolidColor(const Color& color) 1047 { 1048 if (color == m_contentsSolidColor) 1049 return; 1050 1051 m_contentsSolidColor = color; 1052 if (color.isValid() && color.alpha()) { 1053 if (!m_solidColorLayer) { 1054 m_solidColorLayer = adoptPtr(Platform::current()->compositorSupport()->createSolidColorLayer()); 1055 registerContentsLayer(m_solidColorLayer->layer()); 1056 } 1057 m_solidColorLayer->setBackgroundColor(color.rgb()); 1058 } else { 1059 if (!m_solidColorLayer) 1060 return; 1061 unregisterContentsLayer(m_solidColorLayer->layer()); 1062 m_solidColorLayer.clear(); 1063 } 1064 setContentsTo(m_solidColorLayer ? m_solidColorLayer->layer() : 0); 1065 } 1066 1067 bool GraphicsLayer::addAnimation(PassOwnPtr<WebAnimation> popAnimation) 1068 { 1069 OwnPtr<WebAnimation> animation(popAnimation); 1070 ASSERT(animation); 1071 platformLayer()->setAnimationDelegate(this); 1072 1073 // Remove any existing animations with the same animation id and target property. 1074 platformLayer()->removeAnimation(animation->id(), animation->targetProperty()); 1075 return platformLayer()->addAnimation(animation.leakPtr()); 1076 } 1077 1078 void GraphicsLayer::pauseAnimation(int animationId, double timeOffset) 1079 { 1080 platformLayer()->pauseAnimation(animationId, timeOffset); 1081 } 1082 1083 void GraphicsLayer::removeAnimation(int animationId) 1084 { 1085 platformLayer()->removeAnimation(animationId); 1086 } 1087 1088 WebLayer* GraphicsLayer::platformLayer() const 1089 { 1090 return m_layer->layer(); 1091 } 1092 1093 static bool copyWebCoreFilterOperationsToWebFilterOperations(const FilterOperations& filters, WebFilterOperations& webFilters) 1094 { 1095 for (size_t i = 0; i < filters.size(); ++i) { 1096 const FilterOperation& op = *filters.at(i); 1097 switch (op.type()) { 1098 case FilterOperation::REFERENCE: 1099 return false; // Not supported. 1100 case FilterOperation::GRAYSCALE: 1101 case FilterOperation::SEPIA: 1102 case FilterOperation::SATURATE: 1103 case FilterOperation::HUE_ROTATE: { 1104 float amount = toBasicColorMatrixFilterOperation(op).amount(); 1105 switch (op.type()) { 1106 case FilterOperation::GRAYSCALE: 1107 webFilters.appendGrayscaleFilter(amount); 1108 break; 1109 case FilterOperation::SEPIA: 1110 webFilters.appendSepiaFilter(amount); 1111 break; 1112 case FilterOperation::SATURATE: 1113 webFilters.appendSaturateFilter(amount); 1114 break; 1115 case FilterOperation::HUE_ROTATE: 1116 webFilters.appendHueRotateFilter(amount); 1117 break; 1118 default: 1119 ASSERT_NOT_REACHED(); 1120 } 1121 break; 1122 } 1123 case FilterOperation::INVERT: 1124 case FilterOperation::OPACITY: 1125 case FilterOperation::BRIGHTNESS: 1126 case FilterOperation::CONTRAST: { 1127 float amount = toBasicComponentTransferFilterOperation(op).amount(); 1128 switch (op.type()) { 1129 case FilterOperation::INVERT: 1130 webFilters.appendInvertFilter(amount); 1131 break; 1132 case FilterOperation::OPACITY: 1133 webFilters.appendOpacityFilter(amount); 1134 break; 1135 case FilterOperation::BRIGHTNESS: 1136 webFilters.appendBrightnessFilter(amount); 1137 break; 1138 case FilterOperation::CONTRAST: 1139 webFilters.appendContrastFilter(amount); 1140 break; 1141 default: 1142 ASSERT_NOT_REACHED(); 1143 } 1144 break; 1145 } 1146 case FilterOperation::BLUR: { 1147 float pixelRadius = toBlurFilterOperation(op).stdDeviation().getFloatValue(); 1148 webFilters.appendBlurFilter(pixelRadius); 1149 break; 1150 } 1151 case FilterOperation::DROP_SHADOW: { 1152 const DropShadowFilterOperation& dropShadowOp = toDropShadowFilterOperation(op); 1153 webFilters.appendDropShadowFilter(WebPoint(dropShadowOp.x(), dropShadowOp.y()), dropShadowOp.stdDeviation(), dropShadowOp.color().rgb()); 1154 break; 1155 } 1156 case FilterOperation::CUSTOM: 1157 case FilterOperation::VALIDATED_CUSTOM: 1158 return false; // Not supported. 1159 case FilterOperation::NONE: 1160 break; 1161 } 1162 } 1163 return true; 1164 } 1165 1166 bool GraphicsLayer::setFilters(const FilterOperations& filters) 1167 { 1168 SkiaImageFilterBuilder builder; 1169 OwnPtr<WebFilterOperations> webFilters = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations()); 1170 FilterOutsets outsets = filters.outsets(); 1171 builder.setCropOffset(FloatSize(outsets.left(), outsets.top())); 1172 if (!builder.buildFilterOperations(filters, webFilters.get())) { 1173 // Make sure the filters are removed from the platform layer, as they are 1174 // going to fallback to software mode. 1175 webFilters->clear(); 1176 m_layer->layer()->setFilters(*webFilters); 1177 m_filters = FilterOperations(); 1178 return false; 1179 } 1180 1181 m_layer->layer()->setFilters(*webFilters); 1182 m_filters = filters; 1183 return true; 1184 } 1185 1186 void GraphicsLayer::setBackgroundFilters(const FilterOperations& filters) 1187 { 1188 OwnPtr<WebFilterOperations> webFilters = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations()); 1189 if (!copyWebCoreFilterOperationsToWebFilterOperations(filters, *webFilters)) 1190 return; 1191 m_layer->layer()->setBackgroundFilters(*webFilters); 1192 } 1193 1194 void GraphicsLayer::addLinkHighlight(LinkHighlightClient* linkHighlight) 1195 { 1196 ASSERT(linkHighlight && !m_linkHighlights.contains(linkHighlight)); 1197 m_linkHighlights.append(linkHighlight); 1198 linkHighlight->layer()->setWebLayerClient(this); 1199 updateChildList(); 1200 } 1201 1202 void GraphicsLayer::removeLinkHighlight(LinkHighlightClient* linkHighlight) 1203 { 1204 m_linkHighlights.remove(m_linkHighlights.find(linkHighlight)); 1205 updateChildList(); 1206 } 1207 1208 void GraphicsLayer::setScrollableArea(ScrollableArea* scrollableArea, bool isMainFrame) 1209 { 1210 if (m_scrollableArea == scrollableArea) 1211 return; 1212 1213 m_scrollableArea = scrollableArea; 1214 1215 // Main frame scrolling may involve pinch zoom and gets routed through 1216 // WebViewImpl explicitly rather than via GraphicsLayer::didScroll. 1217 if (isMainFrame) 1218 m_layer->layer()->setScrollClient(0); 1219 else 1220 m_layer->layer()->setScrollClient(this); 1221 } 1222 1223 void GraphicsLayer::paint(GraphicsContext& context, const IntRect& clip) 1224 { 1225 paintGraphicsLayerContents(context, clip); 1226 } 1227 1228 1229 void GraphicsLayer::notifyAnimationStarted(double wallClockTime, double monotonicTime, WebAnimation::TargetProperty) 1230 { 1231 if (m_client) 1232 m_client->notifyAnimationStarted(this, wallClockTime, monotonicTime); 1233 } 1234 1235 void GraphicsLayer::notifyAnimationFinished(double, double, WebAnimation::TargetProperty) 1236 { 1237 // Do nothing. 1238 } 1239 1240 void GraphicsLayer::didScroll() 1241 { 1242 if (m_scrollableArea) 1243 m_scrollableArea->scrollToOffsetWithoutAnimation(m_scrollableArea->minimumScrollPosition() + toIntSize(m_layer->layer()->scrollPosition())); 1244 } 1245 1246 } // namespace WebCore 1247 1248 #ifndef NDEBUG 1249 void showGraphicsLayerTree(const WebCore::GraphicsLayer* layer) 1250 { 1251 if (!layer) 1252 return; 1253 1254 String output = layer->layerTreeAsText(WebCore::LayerTreeIncludesDebugInfo); 1255 fprintf(stderr, "%s\n", output.utf8().data()); 1256 } 1257 #endif 1258