OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2010, Google Inc. All rights reserved. |
| 3 * Copyright (C) 2009 Apple Inc. All rights reserved. |
| 4 * |
| 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are |
| 7 * met: |
| 8 * |
| 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. |
| 11 * * Redistributions in binary form must reproduce the above |
| 12 * copyright notice, this list of conditions and the following disclaimer |
| 13 * in the documentation and/or other materials provided with the |
| 14 * distribution. |
| 15 * * Neither the name of Google Inc. nor the names of its |
| 16 * contributors may be used to endorse or promote products derived from |
| 17 * this software without specific prior written permission. |
| 18 * |
| 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 */ |
| 31 |
| 32 |
| 33 /** TODO(Vangelis) |
| 34 * This file borrows code heavily from platform/graphics/win/GraphicsLayerCACF.c
pp |
| 35 * (and hence it includes both copyrights) |
| 36 * Ideally the common code (e.g. the code that keeps track of the layer hierarch
y |
| 37 * should be kept separate and shared between platforms. |
| 38 */ |
| 39 |
| 40 #include "config.h" |
| 41 |
| 42 #if USE(ACCELERATED_COMPOSITING) |
| 43 |
| 44 #include "GraphicsLayerSkia.h" |
| 45 |
| 46 #include "CString.h" |
| 47 #include "FloatConversion.h" |
| 48 #include "FloatRect.h" |
| 49 #include "Image.h" |
| 50 #include "PlatformString.h" |
| 51 #include "SystemTime.h" |
| 52 #include "LayerSkia.h" |
| 53 #include <wtf/CurrentTime.h> |
| 54 #include <wtf/StringExtras.h> |
| 55 |
| 56 using namespace std; |
| 57 |
| 58 namespace WebCore { |
| 59 |
| 60 |
| 61 static void setLayerBorderColor(LayerSkia* layer, const Color& color) |
| 62 { |
| 63 layer->setBorderColor(color); |
| 64 } |
| 65 |
| 66 static void clearBorderColor(LayerSkia* layer) |
| 67 { |
| 68 layer->setBorderColor(Color(0, 0, 0, 0)); |
| 69 } |
| 70 |
| 71 static void setLayerBackgroundColor(LayerSkia* layer, const Color& color) |
| 72 { |
| 73 layer->setBackgroundColor(color); |
| 74 } |
| 75 |
| 76 static void clearLayerBackgroundColor(LayerSkia* layer) |
| 77 { |
| 78 layer->setBackgroundColor(0); |
| 79 } |
| 80 |
| 81 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoord
inatesOrientation() |
| 82 { |
| 83 return CompositingCoordinatesBottomUp; |
| 84 } |
| 85 |
| 86 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client) |
| 87 { |
| 88 return new GraphicsLayerSkia(client); |
| 89 } |
| 90 |
| 91 GraphicsLayerSkia::GraphicsLayerSkia(GraphicsLayerClient* client) |
| 92 : GraphicsLayer(client) |
| 93 , m_contentsLayerPurpose(NoContentsLayer) |
| 94 , m_contentsLayerHasBackgroundColor(false) |
| 95 { |
| 96 m_layer = LayerSkia::create(LayerSkia::Layer, this); |
| 97 |
| 98 updateDebugIndicators(); |
| 99 } |
| 100 |
| 101 GraphicsLayerSkia::~GraphicsLayerSkia() |
| 102 { |
| 103 // clean up the Skia layer |
| 104 if (m_layer) |
| 105 m_layer->removeFromSuperlayer(); |
| 106 |
| 107 if (m_transformLayer) |
| 108 m_transformLayer->removeFromSuperlayer(); |
| 109 } |
| 110 |
| 111 void GraphicsLayerSkia::setName(const String& inName) |
| 112 { |
| 113 String name = String::format("GraphicsLayerSkia(%p) GraphicsLayer(%p) ", m_l
ayer.get(), this) + inName; |
| 114 GraphicsLayer::setName(name); |
| 115 } |
| 116 |
| 117 NativeLayer GraphicsLayerSkia::nativeLayer() const |
| 118 { |
| 119 return m_layer.get(); |
| 120 } |
| 121 |
| 122 bool GraphicsLayerSkia::setChildren(const Vector<GraphicsLayer*>& children) |
| 123 { |
| 124 bool childrenChanged = GraphicsLayer::setChildren(children); |
| 125 // FIXME: GraphicsLayer::setChildren calls addChild() for each sublayer, whi
ch |
| 126 // will end up calling updateSublayerList() N times. |
| 127 if (childrenChanged) |
| 128 updateSublayerList(); |
| 129 |
| 130 return childrenChanged; |
| 131 } |
| 132 |
| 133 void GraphicsLayerSkia::addChild(GraphicsLayer* childLayer) |
| 134 { |
| 135 GraphicsLayer::addChild(childLayer); |
| 136 updateSublayerList(); |
| 137 } |
| 138 |
| 139 void GraphicsLayerSkia::addChildAtIndex(GraphicsLayer* childLayer, int index) |
| 140 { |
| 141 GraphicsLayer::addChildAtIndex(childLayer, index); |
| 142 updateSublayerList(); |
| 143 } |
| 144 |
| 145 void GraphicsLayerSkia::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer*
sibling) |
| 146 { |
| 147 GraphicsLayer::addChildBelow(childLayer, sibling); |
| 148 updateSublayerList(); |
| 149 } |
| 150 |
| 151 void GraphicsLayerSkia::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer *
sibling) |
| 152 { |
| 153 GraphicsLayer::addChildAbove(childLayer, sibling); |
| 154 updateSublayerList(); |
| 155 } |
| 156 |
| 157 bool GraphicsLayerSkia::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* new
Child) |
| 158 { |
| 159 if (GraphicsLayer::replaceChild(oldChild, newChild)) { |
| 160 updateSublayerList(); |
| 161 return true; |
| 162 } |
| 163 return false; |
| 164 } |
| 165 |
| 166 void GraphicsLayerSkia::removeFromParent() |
| 167 { |
| 168 GraphicsLayer::removeFromParent(); |
| 169 layerForSuperlayer()->removeFromSuperlayer(); |
| 170 } |
| 171 |
| 172 void GraphicsLayerSkia::setPosition(const FloatPoint& point) |
| 173 { |
| 174 GraphicsLayer::setPosition(point); |
| 175 updateLayerPosition(); |
| 176 } |
| 177 |
| 178 void GraphicsLayerSkia::setAnchorPoint(const FloatPoint3D& point) |
| 179 { |
| 180 if (point == m_anchorPoint) |
| 181 return; |
| 182 |
| 183 GraphicsLayer::setAnchorPoint(point); |
| 184 updateAnchorPoint(); |
| 185 } |
| 186 |
| 187 void GraphicsLayerSkia::setSize(const FloatSize& size) |
| 188 { |
| 189 if (size == m_size) |
| 190 return; |
| 191 |
| 192 GraphicsLayer::setSize(size); |
| 193 updateLayerSize(); |
| 194 } |
| 195 |
| 196 void GraphicsLayerSkia::setTransform(const TransformationMatrix& t) |
| 197 { |
| 198 if (t == m_transform) |
| 199 return; |
| 200 |
| 201 GraphicsLayer::setTransform(t); |
| 202 updateTransform(); |
| 203 } |
| 204 |
| 205 void GraphicsLayerSkia::setChildrenTransform(const TransformationMatrix& t) |
| 206 { |
| 207 if (t == m_childrenTransform) |
| 208 return; |
| 209 |
| 210 GraphicsLayer::setChildrenTransform(t); |
| 211 updateChildrenTransform(); |
| 212 } |
| 213 |
| 214 void GraphicsLayerSkia::setPreserves3D(bool preserves3D) |
| 215 { |
| 216 if (preserves3D == m_preserves3D) |
| 217 return; |
| 218 |
| 219 GraphicsLayer::setPreserves3D(preserves3D); |
| 220 updateLayerPreserves3D(); |
| 221 } |
| 222 |
| 223 void GraphicsLayerSkia::setMasksToBounds(bool masksToBounds) |
| 224 { |
| 225 if (masksToBounds == m_masksToBounds) |
| 226 return; |
| 227 |
| 228 GraphicsLayer::setMasksToBounds(masksToBounds); |
| 229 updateMasksToBounds(); |
| 230 } |
| 231 |
| 232 void GraphicsLayerSkia::setDrawsContent(bool drawsContent) |
| 233 { |
| 234 if (drawsContent == m_drawsContent) |
| 235 return; |
| 236 |
| 237 GraphicsLayer::setDrawsContent(drawsContent); |
| 238 updateLayerDrawsContent(); |
| 239 } |
| 240 |
| 241 void GraphicsLayerSkia::setBackgroundColor(const Color& color) |
| 242 { |
| 243 if (m_backgroundColorSet && m_backgroundColor == color) |
| 244 return; |
| 245 |
| 246 GraphicsLayer::setBackgroundColor(color); |
| 247 |
| 248 m_contentsLayerHasBackgroundColor = true; |
| 249 updateLayerBackgroundColor(); |
| 250 } |
| 251 |
| 252 void GraphicsLayerSkia::clearBackgroundColor() |
| 253 { |
| 254 if (!m_backgroundColorSet) |
| 255 return; |
| 256 |
| 257 GraphicsLayer::clearBackgroundColor(); |
| 258 clearLayerBackgroundColor(m_contentsLayer.get()); |
| 259 } |
| 260 |
| 261 void GraphicsLayerSkia::setContentsOpaque(bool opaque) |
| 262 { |
| 263 if (m_contentsOpaque == opaque) |
| 264 return; |
| 265 |
| 266 GraphicsLayer::setContentsOpaque(opaque); |
| 267 updateContentsOpaque(); |
| 268 } |
| 269 |
| 270 void GraphicsLayerSkia::setBackfaceVisibility(bool visible) |
| 271 { |
| 272 if (m_backfaceVisibility == visible) |
| 273 return; |
| 274 |
| 275 GraphicsLayer::setBackfaceVisibility(visible); |
| 276 updateBackfaceVisibility(); |
| 277 } |
| 278 |
| 279 void GraphicsLayerSkia::setOpacity(float opacity) |
| 280 { |
| 281 float clampedOpacity = max(min(opacity, 1.0f), 0.0f); |
| 282 |
| 283 if (m_opacity == clampedOpacity) |
| 284 return; |
| 285 |
| 286 GraphicsLayer::setOpacity(clampedOpacity); |
| 287 primaryLayer()->setOpacity(opacity); |
| 288 } |
| 289 |
| 290 void GraphicsLayerSkia::setNeedsDisplay() |
| 291 { |
| 292 if (drawsContent()) |
| 293 m_layer->setNeedsDisplay(); |
| 294 } |
| 295 |
| 296 void GraphicsLayerSkia::setNeedsDisplayInRect(const FloatRect& rect) |
| 297 { |
| 298 if (drawsContent()) |
| 299 m_layer->setNeedsDisplay(rect); |
| 300 } |
| 301 |
| 302 void GraphicsLayerSkia::setContentsRect(const IntRect& rect) |
| 303 { |
| 304 if (rect == m_contentsRect) |
| 305 return; |
| 306 |
| 307 GraphicsLayer::setContentsRect(rect); |
| 308 updateContentsRect(); |
| 309 } |
| 310 |
| 311 void GraphicsLayerSkia::setContentsToImage(Image* image) |
| 312 { |
| 313 // TODO(vangelis): Implement |
| 314 } |
| 315 |
| 316 void GraphicsLayerSkia::setContentsToVideo(PlatformLayer* videoLayer) |
| 317 { |
| 318 // TODO(vangelis): Implement |
| 319 } |
| 320 |
| 321 void GraphicsLayerSkia::setGeometryOrientation(CompositingCoordinatesOrientation
orientation) |
| 322 { |
| 323 if (orientation == m_geometryOrientation) |
| 324 return; |
| 325 |
| 326 GraphicsLayer::setGeometryOrientation(orientation); |
| 327 updateGeometryOrientation(); |
| 328 } |
| 329 |
| 330 PlatformLayer* GraphicsLayerSkia::hostLayerForSublayers() const |
| 331 { |
| 332 return m_transformLayer ? m_transformLayer.get() : m_layer.get(); |
| 333 } |
| 334 |
| 335 PlatformLayer* GraphicsLayerSkia::layerForSuperlayer() const |
| 336 { |
| 337 return m_transformLayer ? m_transformLayer.get() : m_layer.get(); |
| 338 } |
| 339 |
| 340 PlatformLayer* GraphicsLayerSkia::platformLayer() const |
| 341 { |
| 342 return primaryLayer(); |
| 343 } |
| 344 |
| 345 void GraphicsLayerSkia::setDebugBackgroundColor(const Color& color) |
| 346 { |
| 347 if (color.isValid()) |
| 348 setLayerBackgroundColor(m_layer.get(), color); |
| 349 else |
| 350 clearLayerBackgroundColor(m_layer.get()); |
| 351 } |
| 352 |
| 353 void GraphicsLayerSkia::setDebugBorder(const Color& color, float borderWidth) |
| 354 { |
| 355 if (color.isValid()) { |
| 356 setLayerBorderColor(m_layer.get(), color); |
| 357 m_layer->setBorderWidth(borderWidth); |
| 358 } else { |
| 359 clearBorderColor(m_layer.get()); |
| 360 m_layer->setBorderWidth(0); |
| 361 } |
| 362 } |
| 363 |
| 364 GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerSkia::defaultConte
ntsOrientation() const |
| 365 { |
| 366 return CompositingCoordinatesTopDown; |
| 367 } |
| 368 |
| 369 void GraphicsLayerSkia::updateSublayerList() |
| 370 { |
| 371 Vector<RefPtr<LayerSkia> > newSublayers; |
| 372 |
| 373 if (m_transformLayer) { |
| 374 // Add the primary layer first. Even if we have negative z-order childre
n, the primary layer always comes behind. |
| 375 newSublayers.append(m_layer.get()); |
| 376 } else if (m_contentsLayer) { |
| 377 // FIXME: add the contents layer in the correct order with negative z-or
der children. |
| 378 // This does not cause visible rendering issues because currently conten
ts layers are only used |
| 379 // for replaced elements that don't have children. |
| 380 newSublayers.append(m_contentsLayer.get()); |
| 381 } |
| 382 |
| 383 const Vector<GraphicsLayer*>& childLayers = children(); |
| 384 size_t numChildren = childLayers.size(); |
| 385 for (size_t i = 0; i < numChildren; ++i) { |
| 386 GraphicsLayerSkia* curChild = static_cast<GraphicsLayerSkia*>(childLayer
s[i]); |
| 387 |
| 388 LayerSkia* childLayer = curChild->layerForSuperlayer(); |
| 389 newSublayers.append(childLayer); |
| 390 } |
| 391 |
| 392 for (size_t i = 0; i < newSublayers.size(); ++i) |
| 393 newSublayers[i]->removeFromSuperlayer(); |
| 394 |
| 395 if (m_transformLayer) { |
| 396 m_transformLayer->setSublayers(newSublayers); |
| 397 |
| 398 if (m_contentsLayer) { |
| 399 // If we have a transform layer, then the contents layer is parented
in the |
| 400 // primary layer (which is itself a child of the transform layer). |
| 401 m_layer->removeAllSublayers(); |
| 402 m_layer->addSublayer(m_contentsLayer); |
| 403 } |
| 404 } else |
| 405 m_layer->setSublayers(newSublayers); |
| 406 } |
| 407 |
| 408 void GraphicsLayerSkia::updateLayerPosition() |
| 409 { |
| 410 // Position is offset on the layer by the layer anchor point. |
| 411 SkPoint posPoint; |
| 412 posPoint.set(m_position.x() + m_anchorPoint.x() * m_size.width(), |
| 413 posPoint.fY = m_position.y() + m_anchorPoint.y() * m_size.heigh
t()); |
| 414 |
| 415 primaryLayer()->setPosition(posPoint); |
| 416 } |
| 417 |
| 418 void GraphicsLayerSkia::updateLayerSize() |
| 419 { |
| 420 SkIRect rect; |
| 421 rect.set(0, 0, m_size.width(), m_size.height()); |
| 422 if (m_transformLayer) { |
| 423 m_transformLayer->setBounds(rect); |
| 424 // The anchor of the contents layer is always at 0.5, 0.5, so the positi
on is center-relative. |
| 425 SkPoint centerPoint; |
| 426 centerPoint.set(m_size.width() / 2.0f, m_size.height() / 2.0f); |
| 427 m_layer->setPosition(centerPoint); |
| 428 } |
| 429 |
| 430 m_layer->setBounds(rect); |
| 431 |
| 432 // Note that we don't resize m_contentsLayer. It's up the caller to do that. |
| 433 |
| 434 // if we've changed the bounds, we need to recalculate the position |
| 435 // of the layer, taking anchor point into account. |
| 436 updateLayerPosition(); |
| 437 } |
| 438 |
| 439 void GraphicsLayerSkia::updateAnchorPoint() |
| 440 { |
| 441 SkPoint anchorPoint; |
| 442 anchorPoint.set(m_anchorPoint.x(), m_anchorPoint.y()); |
| 443 primaryLayer()->setAnchorPoint(anchorPoint); |
| 444 primaryLayer()->setAnchorPointZ(m_anchorPoint.z()); |
| 445 updateLayerPosition(); |
| 446 } |
| 447 |
| 448 void GraphicsLayerSkia::updateTransform() |
| 449 { |
| 450 primaryLayer()->setTransform(m_transform.toAffineTransform()); |
| 451 } |
| 452 |
| 453 void GraphicsLayerSkia::updateChildrenTransform() |
| 454 { |
| 455 primaryLayer()->setSublayerTransform(m_childrenTransform); |
| 456 } |
| 457 |
| 458 void GraphicsLayerSkia::updateMasksToBounds() |
| 459 { |
| 460 m_layer->setMasksToBounds(m_masksToBounds); |
| 461 updateDebugIndicators(); |
| 462 } |
| 463 |
| 464 void GraphicsLayerSkia::updateContentsOpaque() |
| 465 { |
| 466 m_layer->setOpaque(m_contentsOpaque); |
| 467 } |
| 468 |
| 469 void GraphicsLayerSkia::updateBackfaceVisibility() |
| 470 { |
| 471 m_layer->setDoubleSided(m_backfaceVisibility); |
| 472 } |
| 473 |
| 474 void GraphicsLayerSkia::updateLayerPreserves3D() |
| 475 { |
| 476 // TODO(vangelis): implement |
| 477 } |
| 478 |
| 479 void GraphicsLayerSkia::updateLayerDrawsContent() |
| 480 { |
| 481 if (m_drawsContent) |
| 482 m_layer->setNeedsDisplay(); |
| 483 |
| 484 updateDebugIndicators(); |
| 485 } |
| 486 |
| 487 void GraphicsLayerSkia::updateLayerBackgroundColor() |
| 488 { |
| 489 if (!m_contentsLayer) |
| 490 return; |
| 491 |
| 492 // We never create the contents layer just for background color yet. |
| 493 if (m_backgroundColorSet) |
| 494 setLayerBackgroundColor(m_contentsLayer.get(), m_backgroundColor); |
| 495 else |
| 496 clearLayerBackgroundColor(m_contentsLayer.get()); |
| 497 } |
| 498 |
| 499 void GraphicsLayerSkia::updateContentsImage() |
| 500 { |
| 501 // TODO(vangelis): Implement |
| 502 } |
| 503 |
| 504 void GraphicsLayerSkia::updateContentsVideo() |
| 505 { |
| 506 // TODO(vangelis): Implement |
| 507 } |
| 508 |
| 509 void GraphicsLayerSkia::updateContentsRect() |
| 510 { |
| 511 if (!m_contentsLayer) |
| 512 return; |
| 513 |
| 514 SkPoint point; |
| 515 point.set(m_contentsRect.x(), m_contentsRect.y()); |
| 516 SkIRect rect; |
| 517 rect.set(0, |
| 518 0, |
| 519 m_contentsRect.width(), |
| 520 m_contentsRect.height()); |
| 521 |
| 522 m_contentsLayer->setPosition(point); |
| 523 m_contentsLayer->setBounds(rect); |
| 524 } |
| 525 |
| 526 void GraphicsLayerSkia::updateGeometryOrientation() |
| 527 { |
| 528 switch (geometryOrientation()) { |
| 529 case CompositingCoordinatesTopDown: |
| 530 m_layer->setGeometryFlipped(false); |
| 531 break; |
| 532 |
| 533 case CompositingCoordinatesBottomUp: |
| 534 m_layer->setGeometryFlipped(true); |
| 535 break; |
| 536 } |
| 537 // Geometry orientation is mapped onto children transform in older QuartzCor
es, |
| 538 // so is handled via setGeometryOrientation(). |
| 539 } |
| 540 |
| 541 void GraphicsLayerSkia::setupContentsLayer(LayerSkia* contentsLayer) |
| 542 { |
| 543 if (contentsLayer == m_contentsLayer) |
| 544 return; |
| 545 |
| 546 if (m_contentsLayer) { |
| 547 m_contentsLayer->removeFromSuperlayer(); |
| 548 m_contentsLayer = 0; |
| 549 } |
| 550 |
| 551 if (contentsLayer) { |
| 552 m_contentsLayer = contentsLayer; |
| 553 |
| 554 if (defaultContentsOrientation() == CompositingCoordinatesBottomUp) { |
| 555 SkPoint anchorPoint; |
| 556 anchorPoint.set(0.0f, 1.0f); |
| 557 m_contentsLayer->setAnchorPoint(anchorPoint); |
| 558 } else { |
| 559 SkPoint anchorPoint; |
| 560 anchorPoint.set(0.0f, 0.0f); |
| 561 m_contentsLayer->setAnchorPoint(anchorPoint); |
| 562 } |
| 563 |
| 564 // Insert the content layer first. Video elements require this, because
they have |
| 565 // shadow content that must display in front of the video. |
| 566 m_layer->insertSublayer(m_contentsLayer.get(), 0); |
| 567 |
| 568 updateContentsRect(); |
| 569 |
| 570 if (showDebugBorders()) { |
| 571 setLayerBorderColor(m_contentsLayer.get(), Color(0, 0, 128, 180)); |
| 572 m_contentsLayer->setBorderWidth(1.0f); |
| 573 } |
| 574 } |
| 575 updateDebugIndicators(); |
| 576 } |
| 577 |
| 578 // This function simply mimics the operation of GraphicsLayerCA |
| 579 void GraphicsLayerSkia::updateOpacityOnLayer() |
| 580 { |
| 581 primaryLayer()->setOpacity(m_opacity); |
| 582 } |
| 583 |
| 584 } // namespace WebCore |
| 585 |
| 586 #endif // USE(ACCELERATED_COMPOSITING) |
OLD | NEW |