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