| 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 "sky/engine/config.h" | |
| 27 | |
| 28 #include "sky/engine/platform/graphics/GraphicsLayer.h" | |
| 29 | |
| 30 #include "sky/engine/platform/geometry/FloatRect.h" | |
| 31 #include "sky/engine/platform/geometry/LayoutRect.h" | |
| 32 #include "sky/engine/platform/graphics/GraphicsLayerFactory.h" | |
| 33 #include "sky/engine/platform/graphics/Image.h" | |
| 34 #include "sky/engine/platform/graphics/filters/SkiaImageFilterBuilder.h" | |
| 35 #include "sky/engine/platform/graphics/skia/NativeImageSkia.h" | |
| 36 #include "sky/engine/platform/scroll/ScrollableArea.h" | |
| 37 #include "sky/engine/platform/text/TextStream.h" | |
| 38 #include "sky/engine/public/platform/Platform.h" | |
| 39 #include "sky/engine/public/platform/WebCompositorAnimation.h" | |
| 40 #include "sky/engine/public/platform/WebCompositorSupport.h" | |
| 41 #include "sky/engine/public/platform/WebFilterOperations.h" | |
| 42 #include "sky/engine/public/platform/WebFloatPoint.h" | |
| 43 #include "sky/engine/public/platform/WebFloatRect.h" | |
| 44 #include "sky/engine/public/platform/WebGraphicsLayerDebugInfo.h" | |
| 45 #include "sky/engine/public/platform/WebLayer.h" | |
| 46 #include "sky/engine/public/platform/WebPoint.h" | |
| 47 #include "sky/engine/public/platform/WebSize.h" | |
| 48 #include "sky/engine/wtf/CurrentTime.h" | |
| 49 #include "sky/engine/wtf/HashMap.h" | |
| 50 #include "sky/engine/wtf/HashSet.h" | |
| 51 #include "sky/engine/wtf/text/WTFString.h" | |
| 52 #include "third_party/skia/include/core/SkImageFilter.h" | |
| 53 #include "third_party/skia/include/utils/SkMatrix44.h" | |
| 54 | |
| 55 #include <algorithm> | |
| 56 | |
| 57 #ifndef NDEBUG | |
| 58 #include <stdio.h> | |
| 59 #endif | |
| 60 | |
| 61 using blink::Platform; | |
| 62 using blink::WebCompositorAnimation; | |
| 63 using blink::WebFilterOperations; | |
| 64 using blink::WebLayer; | |
| 65 using blink::WebPoint; | |
| 66 | |
| 67 namespace blink { | |
| 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, G
raphicsLayerClient* 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(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_hasScrollParent(false) | |
| 94 , m_hasClipParent(false) | |
| 95 , m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip) | |
| 96 , m_parent(0) | |
| 97 , m_maskLayer(0) | |
| 98 , m_contentsClippingMaskLayer(0) | |
| 99 , m_paintCount(0) | |
| 100 , m_contentsLayer(0) | |
| 101 , m_contentsLayerId(0) | |
| 102 , m_scrollableArea(0) | |
| 103 , m_3dRenderingContext(0) | |
| 104 { | |
| 105 #if ENABLE(ASSERT) | |
| 106 if (m_client) | |
| 107 m_client->verifyNotPainting(); | |
| 108 #endif | |
| 109 | |
| 110 m_opaqueRectTrackingContentLayerDelegate = adoptPtr(new OpaqueRectTrackingCo
ntentLayerDelegate(this)); | |
| 111 m_layer = adoptPtr(Platform::current()->compositorSupport()->createContentLa
yer(m_opaqueRectTrackingContentLayerDelegate.get())); | |
| 112 m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible); | |
| 113 m_layer->layer()->setWebLayerClient(this); | |
| 114 m_layer->setAutomaticallyComputeRasterScale(true); | |
| 115 } | |
| 116 | |
| 117 GraphicsLayer::~GraphicsLayer() | |
| 118 { | |
| 119 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | |
| 120 m_linkHighlights[i]->clearCurrentGraphicsLayer(); | |
| 121 m_linkHighlights.clear(); | |
| 122 | |
| 123 #if ENABLE(ASSERT) | |
| 124 if (m_client) | |
| 125 m_client->verifyNotPainting(); | |
| 126 #endif | |
| 127 | |
| 128 removeAllChildren(); | |
| 129 removeFromParent(); | |
| 130 | |
| 131 resetTrackedPaintInvalidations(); | |
| 132 ASSERT(!m_parent); | |
| 133 } | |
| 134 | |
| 135 void GraphicsLayer::setParent(GraphicsLayer* layer) | |
| 136 { | |
| 137 ASSERT(!layer || !layer->hasAncestor(this)); | |
| 138 m_parent = layer; | |
| 139 } | |
| 140 | |
| 141 #if ENABLE(ASSERT) | |
| 142 | |
| 143 bool GraphicsLayer::hasAncestor(GraphicsLayer* ancestor) const | |
| 144 { | |
| 145 for (GraphicsLayer* curr = parent(); curr; curr = curr->parent()) { | |
| 146 if (curr == ancestor) | |
| 147 return true; | |
| 148 } | |
| 149 | |
| 150 return false; | |
| 151 } | |
| 152 | |
| 153 #endif | |
| 154 | |
| 155 bool GraphicsLayer::setChildren(const GraphicsLayerVector& newChildren) | |
| 156 { | |
| 157 // If the contents of the arrays are the same, nothing to do. | |
| 158 if (newChildren == m_children) | |
| 159 return false; | |
| 160 | |
| 161 removeAllChildren(); | |
| 162 | |
| 163 size_t listSize = newChildren.size(); | |
| 164 for (size_t i = 0; i < listSize; ++i) | |
| 165 addChildInternal(newChildren[i]); | |
| 166 | |
| 167 updateChildList(); | |
| 168 | |
| 169 return true; | |
| 170 } | |
| 171 | |
| 172 void GraphicsLayer::addChildInternal(GraphicsLayer* childLayer) | |
| 173 { | |
| 174 ASSERT(childLayer != this); | |
| 175 | |
| 176 if (childLayer->parent()) | |
| 177 childLayer->removeFromParent(); | |
| 178 | |
| 179 childLayer->setParent(this); | |
| 180 m_children.append(childLayer); | |
| 181 | |
| 182 // Don't call updateChildList here, this function is used in cases where it | |
| 183 // should not be called until all children are processed. | |
| 184 } | |
| 185 | |
| 186 void GraphicsLayer::addChild(GraphicsLayer* childLayer) | |
| 187 { | |
| 188 addChildInternal(childLayer); | |
| 189 updateChildList(); | |
| 190 } | |
| 191 | |
| 192 void GraphicsLayer::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibl
ing) | |
| 193 { | |
| 194 ASSERT(childLayer != this); | |
| 195 childLayer->removeFromParent(); | |
| 196 | |
| 197 bool found = false; | |
| 198 for (unsigned i = 0; i < m_children.size(); i++) { | |
| 199 if (sibling == m_children[i]) { | |
| 200 m_children.insert(i, childLayer); | |
| 201 found = true; | |
| 202 break; | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 childLayer->setParent(this); | |
| 207 | |
| 208 if (!found) | |
| 209 m_children.append(childLayer); | |
| 210 | |
| 211 updateChildList(); | |
| 212 } | |
| 213 | |
| 214 void GraphicsLayer::removeAllChildren() | |
| 215 { | |
| 216 while (!m_children.isEmpty()) { | |
| 217 GraphicsLayer* curLayer = m_children.last(); | |
| 218 ASSERT(curLayer->parent()); | |
| 219 curLayer->removeFromParent(); | |
| 220 } | |
| 221 } | |
| 222 | |
| 223 void GraphicsLayer::removeFromParent() | |
| 224 { | |
| 225 if (m_parent) { | |
| 226 // We use reverseFind so that removeAllChildren() isn't n^2. | |
| 227 m_parent->m_children.remove(m_parent->m_children.reverseFind(this)); | |
| 228 setParent(0); | |
| 229 } | |
| 230 | |
| 231 platformLayer()->removeFromParent(); | |
| 232 } | |
| 233 | |
| 234 void GraphicsLayer::setOffsetFromRenderer(const IntSize& offset, ShouldSetNeedsD
isplay shouldSetNeedsDisplay) | |
| 235 { | |
| 236 if (offset == m_offsetFromRenderer) | |
| 237 return; | |
| 238 | |
| 239 m_offsetFromRenderer = offset; | |
| 240 | |
| 241 // If the compositing layer offset changes, we need to repaint. | |
| 242 if (shouldSetNeedsDisplay == SetNeedsDisplay) | |
| 243 setNeedsDisplay(); | |
| 244 } | |
| 245 | |
| 246 void GraphicsLayer::paintGraphicsLayerContents(GraphicsContext& context, const I
ntRect& clip) | |
| 247 { | |
| 248 if (!m_client) | |
| 249 return; | |
| 250 incrementPaintCount(); | |
| 251 m_client->paintContents(this, context, m_paintingPhase, clip); | |
| 252 } | |
| 253 | |
| 254 void GraphicsLayer::updateChildList() | |
| 255 { | |
| 256 WebLayer* childHost = m_layer->layer(); | |
| 257 childHost->removeAllChildren(); | |
| 258 | |
| 259 clearContentsLayerIfUnregistered(); | |
| 260 | |
| 261 if (m_contentsLayer) { | |
| 262 // FIXME: add the contents layer in the correct order with negative z-or
der children. | |
| 263 // This does not cause visible rendering issues because currently conten
ts layers are only used | |
| 264 // for replaced elements that don't have children. | |
| 265 childHost->addChild(m_contentsLayer); | |
| 266 } | |
| 267 | |
| 268 for (size_t i = 0; i < m_children.size(); ++i) | |
| 269 childHost->addChild(m_children[i]->platformLayer()); | |
| 270 | |
| 271 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | |
| 272 childHost->addChild(m_linkHighlights[i]->layer()); | |
| 273 } | |
| 274 | |
| 275 void GraphicsLayer::updateLayerIsDrawable() | |
| 276 { | |
| 277 // For the rest of the accelerated compositor code, there is no reason to ma
ke a | |
| 278 // distinction between drawsContent and contentsVisible. So, for m_layer->la
yer(), these two | |
| 279 // flags are combined here. m_contentsLayer shouldn't receive the drawsConte
nt flag | |
| 280 // so it is only given contentsVisible. | |
| 281 | |
| 282 m_layer->layer()->setDrawsContent(m_drawsContent && m_contentsVisible); | |
| 283 if (WebLayer* contentsLayer = contentsLayerIfRegistered()) | |
| 284 contentsLayer->setDrawsContent(m_contentsVisible); | |
| 285 | |
| 286 if (m_drawsContent) { | |
| 287 m_layer->layer()->invalidate(); | |
| 288 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | |
| 289 m_linkHighlights[i]->invalidate(); | |
| 290 } | |
| 291 } | |
| 292 | |
| 293 void GraphicsLayer::updateContentsRect() | |
| 294 { | |
| 295 WebLayer* contentsLayer = contentsLayerIfRegistered(); | |
| 296 if (!contentsLayer) | |
| 297 return; | |
| 298 | |
| 299 contentsLayer->setPosition(FloatPoint(m_contentsRect.x(), m_contentsRect.y()
)); | |
| 300 contentsLayer->setBounds(IntSize(m_contentsRect.width(), m_contentsRect.heig
ht())); | |
| 301 | |
| 302 if (m_contentsClippingMaskLayer) { | |
| 303 if (m_contentsClippingMaskLayer->size() != m_contentsRect.size()) { | |
| 304 m_contentsClippingMaskLayer->setSize(m_contentsRect.size()); | |
| 305 m_contentsClippingMaskLayer->setNeedsDisplay(); | |
| 306 } | |
| 307 m_contentsClippingMaskLayer->setPosition(FloatPoint()); | |
| 308 m_contentsClippingMaskLayer->setOffsetFromRenderer(offsetFromRenderer()
+ IntSize(m_contentsRect.location().x(), m_contentsRect.location().y())); | |
| 309 } | |
| 310 } | |
| 311 | |
| 312 static HashSet<int>* s_registeredLayerSet; | |
| 313 | |
| 314 void GraphicsLayer::registerContentsLayer(WebLayer* layer) | |
| 315 { | |
| 316 if (!s_registeredLayerSet) | |
| 317 s_registeredLayerSet = new HashSet<int>; | |
| 318 if (s_registeredLayerSet->contains(layer->id())) | |
| 319 CRASH(); | |
| 320 s_registeredLayerSet->add(layer->id()); | |
| 321 } | |
| 322 | |
| 323 void GraphicsLayer::unregisterContentsLayer(WebLayer* layer) | |
| 324 { | |
| 325 ASSERT(s_registeredLayerSet); | |
| 326 if (!s_registeredLayerSet->contains(layer->id())) | |
| 327 CRASH(); | |
| 328 s_registeredLayerSet->remove(layer->id()); | |
| 329 } | |
| 330 | |
| 331 void GraphicsLayer::setContentsTo(WebLayer* layer) | |
| 332 { | |
| 333 bool childrenChanged = false; | |
| 334 if (layer) { | |
| 335 ASSERT(s_registeredLayerSet); | |
| 336 if (!s_registeredLayerSet->contains(layer->id())) | |
| 337 CRASH(); | |
| 338 if (m_contentsLayerId != layer->id()) { | |
| 339 setupContentsLayer(layer); | |
| 340 childrenChanged = true; | |
| 341 } | |
| 342 updateContentsRect(); | |
| 343 } else { | |
| 344 if (m_contentsLayer) { | |
| 345 childrenChanged = true; | |
| 346 | |
| 347 // The old contents layer will be removed via updateChildList. | |
| 348 m_contentsLayer = 0; | |
| 349 m_contentsLayerId = 0; | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 if (childrenChanged) | |
| 354 updateChildList(); | |
| 355 } | |
| 356 | |
| 357 void GraphicsLayer::setupContentsLayer(WebLayer* contentsLayer) | |
| 358 { | |
| 359 ASSERT(contentsLayer); | |
| 360 m_contentsLayer = contentsLayer; | |
| 361 m_contentsLayerId = m_contentsLayer->id(); | |
| 362 | |
| 363 m_contentsLayer->setWebLayerClient(this); | |
| 364 m_contentsLayer->setTransformOrigin(FloatPoint3D()); | |
| 365 m_contentsLayer->setUseParentBackfaceVisibility(true); | |
| 366 | |
| 367 // It is necessary to call setDrawsContent as soon as we receive the new con
tentsLayer, for | |
| 368 // the correctness of early exit conditions in setDrawsContent() and setCont
entsVisible(). | |
| 369 m_contentsLayer->setDrawsContent(m_contentsVisible); | |
| 370 | |
| 371 // Insert the content layer first. Video elements require this, because they
have | |
| 372 // shadow content that must display in front of the video. | |
| 373 m_layer->layer()->insertChild(m_contentsLayer, 0); | |
| 374 WebLayer* borderWebLayer = m_contentsClippingMaskLayer ? m_contentsClippingM
askLayer->platformLayer() : 0; | |
| 375 m_contentsLayer->setMaskLayer(borderWebLayer); | |
| 376 | |
| 377 m_contentsLayer->setRenderingContext(m_3dRenderingContext); | |
| 378 } | |
| 379 | |
| 380 void GraphicsLayer::clearContentsLayerIfUnregistered() | |
| 381 { | |
| 382 if (!m_contentsLayerId || s_registeredLayerSet->contains(m_contentsLayerId)) | |
| 383 return; | |
| 384 | |
| 385 m_contentsLayer = 0; | |
| 386 m_contentsLayerId = 0; | |
| 387 } | |
| 388 | |
| 389 GraphicsLayerDebugInfo& GraphicsLayer::debugInfo() | |
| 390 { | |
| 391 return m_debugInfo; | |
| 392 } | |
| 393 | |
| 394 WebGraphicsLayerDebugInfo* GraphicsLayer::takeDebugInfoFor(WebLayer* layer) | |
| 395 { | |
| 396 GraphicsLayerDebugInfo* clone = m_debugInfo.clone(); | |
| 397 clone->setDebugName(debugName(layer)); | |
| 398 return clone; | |
| 399 } | |
| 400 | |
| 401 WebLayer* GraphicsLayer::contentsLayerIfRegistered() | |
| 402 { | |
| 403 clearContentsLayerIfUnregistered(); | |
| 404 return m_contentsLayer; | |
| 405 } | |
| 406 | |
| 407 void GraphicsLayer::resetTrackedPaintInvalidations() | |
| 408 { | |
| 409 repaintRectMap().remove(this); | |
| 410 } | |
| 411 | |
| 412 void GraphicsLayer::addRepaintRect(const FloatRect& repaintRect) | |
| 413 { | |
| 414 if (m_client->isTrackingPaintInvalidations()) { | |
| 415 FloatRect largestRepaintRect(FloatPoint(), m_size); | |
| 416 largestRepaintRect.intersect(repaintRect); | |
| 417 RepaintMap::iterator repaintIt = repaintRectMap().find(this); | |
| 418 if (repaintIt == repaintRectMap().end()) { | |
| 419 Vector<FloatRect> repaintRects; | |
| 420 repaintRects.append(largestRepaintRect); | |
| 421 repaintRectMap().set(this, repaintRects); | |
| 422 } else { | |
| 423 Vector<FloatRect>& repaintRects = repaintIt->value; | |
| 424 repaintRects.append(largestRepaintRect); | |
| 425 } | |
| 426 } | |
| 427 } | |
| 428 | |
| 429 String GraphicsLayer::debugName(WebLayer* webLayer) const | |
| 430 { | |
| 431 String name; | |
| 432 if (!m_client) | |
| 433 return name; | |
| 434 | |
| 435 String highlightDebugName; | |
| 436 for (size_t i = 0; i < m_linkHighlights.size(); ++i) { | |
| 437 if (webLayer == m_linkHighlights[i]->layer()) { | |
| 438 highlightDebugName = "LinkHighlight[" + String::number(i) + "] for "
+ m_client->debugName(this); | |
| 439 break; | |
| 440 } | |
| 441 } | |
| 442 | |
| 443 if (webLayer == m_contentsLayer) { | |
| 444 name = "ContentsLayer for " + m_client->debugName(this); | |
| 445 } else if (!highlightDebugName.isEmpty()) { | |
| 446 name = highlightDebugName; | |
| 447 } else if (webLayer == m_layer->layer()) { | |
| 448 name = m_client->debugName(this); | |
| 449 } else { | |
| 450 ASSERT_NOT_REACHED(); | |
| 451 } | |
| 452 return name; | |
| 453 } | |
| 454 | |
| 455 void GraphicsLayer::setCompositingReasons(CompositingReasons reasons) | |
| 456 { | |
| 457 m_debugInfo.setCompositingReasons(reasons); | |
| 458 } | |
| 459 | |
| 460 void GraphicsLayer::setOwnerNodeId(int nodeId) | |
| 461 { | |
| 462 m_debugInfo.setOwnerNodeId(nodeId); | |
| 463 } | |
| 464 | |
| 465 void GraphicsLayer::setPosition(const FloatPoint& point) | |
| 466 { | |
| 467 m_position = point; | |
| 468 platformLayer()->setPosition(m_position); | |
| 469 } | |
| 470 | |
| 471 void GraphicsLayer::setSize(const FloatSize& size) | |
| 472 { | |
| 473 // We are receiving negative sizes here that cause assertions to fail in the
compositor. Clamp them to 0 to | |
| 474 // avoid those assertions. | |
| 475 // FIXME: This should be an ASSERT instead, as negative sizes should not exi
st in WebCore. | |
| 476 FloatSize clampedSize = size; | |
| 477 if (clampedSize.width() < 0 || clampedSize.height() < 0) | |
| 478 clampedSize = FloatSize(); | |
| 479 | |
| 480 if (clampedSize == m_size) | |
| 481 return; | |
| 482 | |
| 483 m_size = clampedSize; | |
| 484 | |
| 485 m_layer->layer()->setBounds(flooredIntSize(m_size)); | |
| 486 // Note that we don't resize m_contentsLayer. It's up the caller to do that. | |
| 487 } | |
| 488 | |
| 489 void GraphicsLayer::setTransform(const TransformationMatrix& transform) | |
| 490 { | |
| 491 m_transform = transform; | |
| 492 platformLayer()->setTransform(TransformationMatrix::toSkMatrix44(m_transform
)); | |
| 493 } | |
| 494 | |
| 495 void GraphicsLayer::setTransformOrigin(const FloatPoint3D& transformOrigin) | |
| 496 { | |
| 497 m_hasTransformOrigin = true; | |
| 498 m_transformOrigin = transformOrigin; | |
| 499 platformLayer()->setTransformOrigin(transformOrigin); | |
| 500 } | |
| 501 | |
| 502 void GraphicsLayer::setShouldFlattenTransform(bool shouldFlatten) | |
| 503 { | |
| 504 if (shouldFlatten == m_shouldFlattenTransform) | |
| 505 return; | |
| 506 | |
| 507 m_shouldFlattenTransform = shouldFlatten; | |
| 508 | |
| 509 m_layer->layer()->setShouldFlattenTransform(shouldFlatten); | |
| 510 } | |
| 511 | |
| 512 void GraphicsLayer::setRenderingContext(int context) | |
| 513 { | |
| 514 if (m_3dRenderingContext == context) | |
| 515 return; | |
| 516 | |
| 517 m_3dRenderingContext = context; | |
| 518 m_layer->layer()->setRenderingContext(context); | |
| 519 | |
| 520 if (m_contentsLayer) | |
| 521 m_contentsLayer->setRenderingContext(m_3dRenderingContext); | |
| 522 } | |
| 523 | |
| 524 void GraphicsLayer::setMasksToBounds(bool masksToBounds) | |
| 525 { | |
| 526 m_masksToBounds = masksToBounds; | |
| 527 m_layer->layer()->setMasksToBounds(m_masksToBounds); | |
| 528 } | |
| 529 | |
| 530 void GraphicsLayer::setDrawsContent(bool drawsContent) | |
| 531 { | |
| 532 // Note carefully this early-exit is only correct because we also properly c
all | |
| 533 // WebLayer::setDrawsContent whenever m_contentsLayer is set to a new layer
in setupContentsLayer(). | |
| 534 if (drawsContent == m_drawsContent) | |
| 535 return; | |
| 536 | |
| 537 m_drawsContent = drawsContent; | |
| 538 updateLayerIsDrawable(); | |
| 539 } | |
| 540 | |
| 541 void GraphicsLayer::setContentsVisible(bool contentsVisible) | |
| 542 { | |
| 543 // Note carefully this early-exit is only correct because we also properly c
all | |
| 544 // WebLayer::setDrawsContent whenever m_contentsLayer is set to a new layer
in setupContentsLayer(). | |
| 545 if (contentsVisible == m_contentsVisible) | |
| 546 return; | |
| 547 | |
| 548 m_contentsVisible = contentsVisible; | |
| 549 updateLayerIsDrawable(); | |
| 550 } | |
| 551 | |
| 552 void GraphicsLayer::setClipParent(WebLayer* parent) | |
| 553 { | |
| 554 m_hasClipParent = !!parent; | |
| 555 m_layer->layer()->setClipParent(parent); | |
| 556 } | |
| 557 | |
| 558 void GraphicsLayer::setScrollParent(WebLayer* parent) | |
| 559 { | |
| 560 m_hasScrollParent = !!parent; | |
| 561 m_layer->layer()->setScrollParent(parent); | |
| 562 } | |
| 563 | |
| 564 void GraphicsLayer::setBackgroundColor(const Color& color) | |
| 565 { | |
| 566 if (color == m_backgroundColor) | |
| 567 return; | |
| 568 | |
| 569 m_backgroundColor = color; | |
| 570 m_layer->layer()->setBackgroundColor(m_backgroundColor.rgb()); | |
| 571 } | |
| 572 | |
| 573 void GraphicsLayer::setContentsOpaque(bool opaque) | |
| 574 { | |
| 575 m_contentsOpaque = opaque; | |
| 576 m_layer->layer()->setOpaque(m_contentsOpaque); | |
| 577 m_opaqueRectTrackingContentLayerDelegate->setOpaque(m_contentsOpaque); | |
| 578 clearContentsLayerIfUnregistered(); | |
| 579 if (m_contentsLayer) | |
| 580 m_contentsLayer->setOpaque(opaque); | |
| 581 } | |
| 582 | |
| 583 void GraphicsLayer::setMaskLayer(GraphicsLayer* maskLayer) | |
| 584 { | |
| 585 if (maskLayer == m_maskLayer) | |
| 586 return; | |
| 587 | |
| 588 m_maskLayer = maskLayer; | |
| 589 WebLayer* maskWebLayer = m_maskLayer ? m_maskLayer->platformLayer() : 0; | |
| 590 m_layer->layer()->setMaskLayer(maskWebLayer); | |
| 591 } | |
| 592 | |
| 593 void GraphicsLayer::setContentsClippingMaskLayer(GraphicsLayer* contentsClipping
MaskLayer) | |
| 594 { | |
| 595 if (contentsClippingMaskLayer == m_contentsClippingMaskLayer) | |
| 596 return; | |
| 597 | |
| 598 m_contentsClippingMaskLayer = contentsClippingMaskLayer; | |
| 599 WebLayer* contentsLayer = contentsLayerIfRegistered(); | |
| 600 if (!contentsLayer) | |
| 601 return; | |
| 602 WebLayer* contentsClippingMaskWebLayer = m_contentsClippingMaskLayer ? m_con
tentsClippingMaskLayer->platformLayer() : 0; | |
| 603 contentsLayer->setMaskLayer(contentsClippingMaskWebLayer); | |
| 604 updateContentsRect(); | |
| 605 } | |
| 606 | |
| 607 void GraphicsLayer::setBackfaceVisibility(bool visible) | |
| 608 { | |
| 609 m_backfaceVisibility = visible; | |
| 610 m_layer->setDoubleSided(m_backfaceVisibility); | |
| 611 } | |
| 612 | |
| 613 void GraphicsLayer::setOpacity(float opacity) | |
| 614 { | |
| 615 float clampedOpacity = std::max(std::min(opacity, 1.0f), 0.0f); | |
| 616 m_opacity = clampedOpacity; | |
| 617 platformLayer()->setOpacity(opacity); | |
| 618 } | |
| 619 | |
| 620 void GraphicsLayer::setBlendMode(WebBlendMode blendMode) | |
| 621 { | |
| 622 if (m_blendMode == blendMode) | |
| 623 return; | |
| 624 m_blendMode = blendMode; | |
| 625 platformLayer()->setBlendMode(WebBlendMode(blendMode)); | |
| 626 } | |
| 627 | |
| 628 void GraphicsLayer::setContentsNeedsDisplay() | |
| 629 { | |
| 630 if (WebLayer* contentsLayer = contentsLayerIfRegistered()) { | |
| 631 contentsLayer->invalidate(); | |
| 632 addRepaintRect(m_contentsRect); | |
| 633 } | |
| 634 } | |
| 635 | |
| 636 void GraphicsLayer::setNeedsDisplay() | |
| 637 { | |
| 638 if (drawsContent()) { | |
| 639 m_layer->layer()->invalidate(); | |
| 640 addRepaintRect(FloatRect(FloatPoint(), m_size)); | |
| 641 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | |
| 642 m_linkHighlights[i]->invalidate(); | |
| 643 } | |
| 644 } | |
| 645 | |
| 646 void GraphicsLayer::setNeedsDisplayInRect(const FloatRect& rect) | |
| 647 { | |
| 648 if (drawsContent()) { | |
| 649 m_layer->layer()->invalidateRect(rect); | |
| 650 addRepaintRect(rect); | |
| 651 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | |
| 652 m_linkHighlights[i]->invalidate(); | |
| 653 } | |
| 654 } | |
| 655 | |
| 656 void GraphicsLayer::setContentsRect(const IntRect& rect) | |
| 657 { | |
| 658 if (rect == m_contentsRect) | |
| 659 return; | |
| 660 | |
| 661 m_contentsRect = rect; | |
| 662 updateContentsRect(); | |
| 663 } | |
| 664 | |
| 665 void GraphicsLayer::setContentsToImage(Image* image) | |
| 666 { | |
| 667 RefPtr<NativeImageSkia> nativeImage = image ? image->nativeImageForCurrentFr
ame() : nullptr; | |
| 668 if (nativeImage) { | |
| 669 if (!m_imageLayer) { | |
| 670 m_imageLayer = adoptPtr(Platform::current()->compositorSupport()->cr
eateImageLayer()); | |
| 671 registerContentsLayer(m_imageLayer->layer()); | |
| 672 } | |
| 673 m_imageLayer->setBitmap(nativeImage->bitmap()); | |
| 674 m_imageLayer->layer()->setOpaque(image->currentFrameKnownToBeOpaque()); | |
| 675 updateContentsRect(); | |
| 676 } else { | |
| 677 if (m_imageLayer) { | |
| 678 unregisterContentsLayer(m_imageLayer->layer()); | |
| 679 m_imageLayer.clear(); | |
| 680 } | |
| 681 } | |
| 682 | |
| 683 setContentsTo(m_imageLayer ? m_imageLayer->layer() : 0); | |
| 684 } | |
| 685 | |
| 686 bool GraphicsLayer::addAnimation(PassOwnPtr<WebCompositorAnimation> popAnimation
) | |
| 687 { | |
| 688 OwnPtr<WebCompositorAnimation> animation(popAnimation); | |
| 689 ASSERT(animation); | |
| 690 platformLayer()->setAnimationDelegate(this); | |
| 691 | |
| 692 // Remove any existing animations with the same animation id and target prop
erty. | |
| 693 platformLayer()->removeAnimation(animation->id(), animation->targetProperty(
)); | |
| 694 return platformLayer()->addAnimation(animation.leakPtr()); | |
| 695 } | |
| 696 | |
| 697 void GraphicsLayer::pauseAnimation(int animationId, double timeOffset) | |
| 698 { | |
| 699 platformLayer()->pauseAnimation(animationId, timeOffset); | |
| 700 } | |
| 701 | |
| 702 void GraphicsLayer::removeAnimation(int animationId) | |
| 703 { | |
| 704 platformLayer()->removeAnimation(animationId); | |
| 705 } | |
| 706 | |
| 707 WebLayer* GraphicsLayer::platformLayer() const | |
| 708 { | |
| 709 return m_layer->layer(); | |
| 710 } | |
| 711 | |
| 712 void GraphicsLayer::setFilters(const FilterOperations& filters) | |
| 713 { | |
| 714 SkiaImageFilterBuilder builder; | |
| 715 OwnPtr<WebFilterOperations> webFilters = adoptPtr(Platform::current()->compo
sitorSupport()->createFilterOperations()); | |
| 716 FilterOutsets outsets = filters.outsets(); | |
| 717 builder.setCropOffset(FloatSize(outsets.left(), outsets.top())); | |
| 718 builder.buildFilterOperations(filters, webFilters.get()); | |
| 719 m_layer->layer()->setFilters(*webFilters); | |
| 720 } | |
| 721 | |
| 722 void GraphicsLayer::setPaintingPhase(GraphicsLayerPaintingPhase phase) | |
| 723 { | |
| 724 if (m_paintingPhase == phase) | |
| 725 return; | |
| 726 m_paintingPhase = phase; | |
| 727 setNeedsDisplay(); | |
| 728 } | |
| 729 | |
| 730 void GraphicsLayer::addLinkHighlight(LinkHighlightClient* linkHighlight) | |
| 731 { | |
| 732 ASSERT(linkHighlight && !m_linkHighlights.contains(linkHighlight)); | |
| 733 m_linkHighlights.append(linkHighlight); | |
| 734 linkHighlight->layer()->setWebLayerClient(this); | |
| 735 updateChildList(); | |
| 736 } | |
| 737 | |
| 738 void GraphicsLayer::removeLinkHighlight(LinkHighlightClient* linkHighlight) | |
| 739 { | |
| 740 m_linkHighlights.remove(m_linkHighlights.find(linkHighlight)); | |
| 741 updateChildList(); | |
| 742 } | |
| 743 | |
| 744 void GraphicsLayer::setScrollableArea(ScrollableArea* scrollableArea) | |
| 745 { | |
| 746 if (m_scrollableArea == scrollableArea) | |
| 747 return; | |
| 748 | |
| 749 m_scrollableArea = scrollableArea; | |
| 750 | |
| 751 // Main frame scrolling may involve pinch zoom and gets routed through | |
| 752 // WebViewImpl explicitly rather than via GraphicsLayer::didScroll. | |
| 753 // TODO(bokan): With pinch virtual viewport the special case will no | |
| 754 // longer be needed, remove once old-style pinch is gone. | |
| 755 m_layer->layer()->setScrollClient(0); | |
| 756 } | |
| 757 | |
| 758 void GraphicsLayer::paint(GraphicsContext& context, const IntRect& clip) | |
| 759 { | |
| 760 paintGraphicsLayerContents(context, clip); | |
| 761 } | |
| 762 | |
| 763 | |
| 764 void GraphicsLayer::notifyAnimationStarted(double monotonicTime, WebCompositorAn
imation::TargetProperty) | |
| 765 { | |
| 766 if (m_client) | |
| 767 m_client->notifyAnimationStarted(this, monotonicTime); | |
| 768 } | |
| 769 | |
| 770 void GraphicsLayer::notifyAnimationFinished(double, WebCompositorAnimation::Targ
etProperty) | |
| 771 { | |
| 772 // Do nothing. | |
| 773 } | |
| 774 | |
| 775 void GraphicsLayer::didScroll() | |
| 776 { | |
| 777 if (m_scrollableArea) | |
| 778 m_scrollableArea->scrollToOffsetWithoutAnimation(m_scrollableArea->minim
umScrollPosition() + toIntSize(m_layer->layer()->scrollPosition())); | |
| 779 } | |
| 780 | |
| 781 } // namespace blink | |
| OLD | NEW |