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