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