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 /** FIXME |
| 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 (mostly the code that keeps track of the layer hierar
chy) |
| 37 * should be kept separate and shared between platforms. It would be a well wort
hwhile |
| 38 * effort once the Windows implementation (binaries and headers) of CoreAnimatio
n is |
| 39 * checked in to the WebKit repository. Until then only Apple can make this happ
en. |
| 40 */ |
| 41 |
| 42 #include "config.h" |
| 43 |
| 44 #if USE(ACCELERATED_COMPOSITING) |
| 45 |
| 46 #include "GraphicsLayerChromium.h" |
| 47 |
| 48 #include "AnimationIdVendor.h" |
| 49 #include "AnimationTranslationUtil.h" |
| 50 #include "ContentLayerChromium.h" |
| 51 #include "FloatConversion.h" |
| 52 #include "FloatRect.h" |
| 53 #include "GraphicsContext.h" |
| 54 #include "Image.h" |
| 55 #include "LayerChromium.h" |
| 56 #include "LinkHighlight.h" |
| 57 #include "NativeImageSkia.h" |
| 58 #include "PlatformContextSkia.h" |
| 59 #include "PlatformString.h" |
| 60 #include "SkMatrix44.h" |
| 61 #include "SystemTime.h" |
| 62 |
| 63 #include "cc/CCActiveAnimation.h" |
| 64 |
| 65 #include <public/WebFilterOperation.h> |
| 66 #include <public/WebFilterOperations.h> |
| 67 #include <public/WebFloatPoint.h> |
| 68 #include <public/WebFloatRect.h> |
| 69 #include <public/WebImageLayer.h> |
| 70 #include <public/WebSize.h> |
| 71 #include <public/WebTransformationMatrix.h> |
| 72 #include <wtf/CurrentTime.h> |
| 73 #include <wtf/StringExtras.h> |
| 74 #include <wtf/text/CString.h> |
| 75 |
| 76 using namespace std; |
| 77 using namespace WebKit; |
| 78 |
| 79 namespace WebCore { |
| 80 |
| 81 PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client) |
| 82 { |
| 83 return adoptPtr(new GraphicsLayerChromium(client)); |
| 84 } |
| 85 |
| 86 GraphicsLayerChromium::GraphicsLayerChromium(GraphicsLayerClient* client) |
| 87 : GraphicsLayer(client) |
| 88 , m_contentsLayerPurpose(NoContentsLayer) |
| 89 , m_contentsLayerHasBackgroundColor(false) |
| 90 , m_inSetChildren(false) |
| 91 , m_pageScaleChanged(false) |
| 92 { |
| 93 m_opaqueRectTrackingContentLayerDelegate = adoptPtr(new OpaqueRectTrackingCo
ntentLayerDelegate(this)); |
| 94 m_layer = WebContentLayer::create(m_opaqueRectTrackingContentLayerDelegate.g
et()); |
| 95 m_layer.setDrawsContent(m_drawsContent && m_contentsVisible); |
| 96 if (client) |
| 97 deviceOrPageScaleFactorChanged(); |
| 98 updateDebugIndicators(); |
| 99 } |
| 100 |
| 101 GraphicsLayerChromium::~GraphicsLayerChromium() |
| 102 { |
| 103 // Do cleanup while we can still safely call methods on the derived class. |
| 104 willBeDestroyed(); |
| 105 } |
| 106 |
| 107 void GraphicsLayerChromium::willBeDestroyed() |
| 108 { |
| 109 if (!m_layer.isNull()) { |
| 110 m_layer.clearClient(); |
| 111 m_layer.unwrap<LayerChromium>()->clearRenderSurface(); |
| 112 m_layer.unwrap<LayerChromium>()->setLayerAnimationDelegate(0); |
| 113 } |
| 114 |
| 115 if (!m_contentsLayer.isNull()) { |
| 116 m_contentsLayer.unwrap<LayerChromium>()->clearRenderSurface(); |
| 117 m_contentsLayer.unwrap<LayerChromium>()->setLayerAnimationDelegate(0); |
| 118 } |
| 119 |
| 120 if (!m_transformLayer.isNull()) { |
| 121 m_transformLayer.unwrap<LayerChromium>()->clearRenderSurface(); |
| 122 m_transformLayer.unwrap<LayerChromium>()->setLayerAnimationDelegate(0); |
| 123 } |
| 124 |
| 125 if (m_linkHighlight) |
| 126 m_linkHighlight.clear(); |
| 127 |
| 128 GraphicsLayer::willBeDestroyed(); |
| 129 } |
| 130 |
| 131 void GraphicsLayerChromium::setName(const String& inName) |
| 132 { |
| 133 m_nameBase = inName; |
| 134 String name = String::format("GraphicsLayerChromium(%p) GraphicsLayer(%p) ",
m_layer.unwrap<LayerChromium>(), this) + inName; |
| 135 GraphicsLayer::setName(name); |
| 136 updateNames(); |
| 137 } |
| 138 |
| 139 void GraphicsLayerChromium::updateNames() |
| 140 { |
| 141 if (!m_layer.isNull()) |
| 142 m_layer.unwrap<LayerChromium>()->setDebugName("Layer for " + m_nameBase)
; |
| 143 if (!m_transformLayer.isNull()) |
| 144 m_transformLayer.unwrap<LayerChromium>()->setDebugName("TransformLayer f
or " + m_nameBase); |
| 145 if (!m_contentsLayer.isNull()) |
| 146 m_contentsLayer.unwrap<LayerChromium>()->setDebugName("ContentsLayer for
" + m_nameBase); |
| 147 if (m_linkHighlight) |
| 148 m_linkHighlight->contentLayer()->setDebugName("LinkHighlight for " + m_n
ameBase); |
| 149 } |
| 150 |
| 151 bool GraphicsLayerChromium::setChildren(const Vector<GraphicsLayer*>& children) |
| 152 { |
| 153 m_inSetChildren = true; |
| 154 bool childrenChanged = GraphicsLayer::setChildren(children); |
| 155 |
| 156 if (childrenChanged) |
| 157 updateChildList(); |
| 158 m_inSetChildren = false; |
| 159 |
| 160 return childrenChanged; |
| 161 } |
| 162 |
| 163 void GraphicsLayerChromium::addChild(GraphicsLayer* childLayer) |
| 164 { |
| 165 GraphicsLayer::addChild(childLayer); |
| 166 if (!m_inSetChildren) |
| 167 updateChildList(); |
| 168 } |
| 169 |
| 170 void GraphicsLayerChromium::addChildAtIndex(GraphicsLayer* childLayer, int index
) |
| 171 { |
| 172 GraphicsLayer::addChildAtIndex(childLayer, index); |
| 173 updateChildList(); |
| 174 } |
| 175 |
| 176 void GraphicsLayerChromium::addChildBelow(GraphicsLayer* childLayer, GraphicsLay
er* sibling) |
| 177 { |
| 178 GraphicsLayer::addChildBelow(childLayer, sibling); |
| 179 updateChildList(); |
| 180 } |
| 181 |
| 182 void GraphicsLayerChromium::addChildAbove(GraphicsLayer* childLayer, GraphicsLay
er *sibling) |
| 183 { |
| 184 GraphicsLayer::addChildAbove(childLayer, sibling); |
| 185 updateChildList(); |
| 186 } |
| 187 |
| 188 bool GraphicsLayerChromium::replaceChild(GraphicsLayer* oldChild, GraphicsLayer*
newChild) |
| 189 { |
| 190 if (GraphicsLayer::replaceChild(oldChild, newChild)) { |
| 191 updateChildList(); |
| 192 return true; |
| 193 } |
| 194 return false; |
| 195 } |
| 196 |
| 197 void GraphicsLayerChromium::removeFromParent() |
| 198 { |
| 199 GraphicsLayer::removeFromParent(); |
| 200 layerForParent().removeFromParent(); |
| 201 } |
| 202 |
| 203 void GraphicsLayerChromium::setPosition(const FloatPoint& point) |
| 204 { |
| 205 GraphicsLayer::setPosition(point); |
| 206 updateLayerPosition(); |
| 207 } |
| 208 |
| 209 void GraphicsLayerChromium::setAnchorPoint(const FloatPoint3D& point) |
| 210 { |
| 211 GraphicsLayer::setAnchorPoint(point); |
| 212 updateAnchorPoint(); |
| 213 } |
| 214 |
| 215 void GraphicsLayerChromium::setSize(const FloatSize& size) |
| 216 { |
| 217 // We are receiving negative sizes here that cause assertions to fail in the
compositor. Clamp them to 0 to |
| 218 // avoid those assertions. |
| 219 // FIXME: This should be an ASSERT instead, as negative sizes should not exi
st in WebCore. |
| 220 FloatSize clampedSize = size; |
| 221 if (clampedSize.width() < 0 || clampedSize.height() < 0) |
| 222 clampedSize = FloatSize(); |
| 223 |
| 224 if (clampedSize == m_size) |
| 225 return; |
| 226 |
| 227 GraphicsLayer::setSize(clampedSize); |
| 228 updateLayerSize(); |
| 229 |
| 230 if (m_pageScaleChanged && !m_layer.isNull()) |
| 231 m_layer.invalidate(); |
| 232 m_pageScaleChanged = false; |
| 233 } |
| 234 |
| 235 void GraphicsLayerChromium::setTransform(const TransformationMatrix& transform) |
| 236 { |
| 237 // Call this method first to assign contents scale to our layer so the paint
er can apply the scale transform. |
| 238 updateContentsScale(); |
| 239 |
| 240 GraphicsLayer::setTransform(transform); |
| 241 updateTransform(); |
| 242 } |
| 243 |
| 244 void GraphicsLayerChromium::setChildrenTransform(const TransformationMatrix& tra
nsform) |
| 245 { |
| 246 GraphicsLayer::setChildrenTransform(transform); |
| 247 updateChildrenTransform(); |
| 248 } |
| 249 |
| 250 void GraphicsLayerChromium::setPreserves3D(bool preserves3D) |
| 251 { |
| 252 if (preserves3D == m_preserves3D) |
| 253 return; |
| 254 |
| 255 GraphicsLayer::setPreserves3D(preserves3D); |
| 256 updateLayerPreserves3D(); |
| 257 } |
| 258 |
| 259 void GraphicsLayerChromium::setMasksToBounds(bool masksToBounds) |
| 260 { |
| 261 GraphicsLayer::setMasksToBounds(masksToBounds); |
| 262 updateMasksToBounds(); |
| 263 } |
| 264 |
| 265 void GraphicsLayerChromium::setDrawsContent(bool drawsContent) |
| 266 { |
| 267 // Note carefully this early-exit is only correct because we also properly i
nitialize |
| 268 // LayerChromium::m_isDrawable whenever m_contentsLayer is set to a new laye
r in setupContentsLayer(). |
| 269 if (drawsContent == m_drawsContent) |
| 270 return; |
| 271 |
| 272 GraphicsLayer::setDrawsContent(drawsContent); |
| 273 updateLayerIsDrawable(); |
| 274 } |
| 275 |
| 276 void GraphicsLayerChromium::setContentsVisible(bool contentsVisible) |
| 277 { |
| 278 // Note carefully this early-exit is only correct because we also properly i
nitialize |
| 279 // LayerChromium::m_isDrawable whenever m_contentsLayer is set to a new laye
r in setupContentsLayer(). |
| 280 if (contentsVisible == m_contentsVisible) |
| 281 return; |
| 282 |
| 283 GraphicsLayer::setContentsVisible(contentsVisible); |
| 284 updateLayerIsDrawable(); |
| 285 } |
| 286 |
| 287 void GraphicsLayerChromium::setBackgroundColor(const Color& color) |
| 288 { |
| 289 GraphicsLayer::setBackgroundColor(color.rgb()); |
| 290 |
| 291 m_contentsLayerHasBackgroundColor = true; |
| 292 updateLayerBackgroundColor(); |
| 293 } |
| 294 |
| 295 void GraphicsLayerChromium::clearBackgroundColor() |
| 296 { |
| 297 GraphicsLayer::clearBackgroundColor(); |
| 298 m_contentsLayer.setBackgroundColor(static_cast<RGBA32>(0)); |
| 299 } |
| 300 |
| 301 void GraphicsLayerChromium::setContentsOpaque(bool opaque) |
| 302 { |
| 303 GraphicsLayer::setContentsOpaque(opaque); |
| 304 m_layer.setOpaque(m_contentsOpaque); |
| 305 } |
| 306 |
| 307 static bool copyWebCoreFilterOperationsToWebFilterOperations(const FilterOperati
ons& filters, WebFilterOperations& webFilters) |
| 308 { |
| 309 for (size_t i = 0; i < filters.size(); ++i) { |
| 310 const FilterOperation& op = *filters.at(i); |
| 311 switch (op.getOperationType()) { |
| 312 case FilterOperation::REFERENCE: |
| 313 return false; // Not supported. |
| 314 case FilterOperation::GRAYSCALE: |
| 315 case FilterOperation::SEPIA: |
| 316 case FilterOperation::SATURATE: |
| 317 case FilterOperation::HUE_ROTATE: { |
| 318 float amount = static_cast<const BasicColorMatrixFilterOperation*>(&
op)->amount(); |
| 319 switch (op.getOperationType()) { |
| 320 case FilterOperation::GRAYSCALE: |
| 321 webFilters.append(WebFilterOperation::createGrayscaleFilter(amou
nt)); |
| 322 break; |
| 323 case FilterOperation::SEPIA: |
| 324 webFilters.append(WebFilterOperation::createSepiaFilter(amount))
; |
| 325 break; |
| 326 case FilterOperation::SATURATE: |
| 327 webFilters.append(WebFilterOperation::createSaturateFilter(amoun
t)); |
| 328 break; |
| 329 case FilterOperation::HUE_ROTATE: |
| 330 webFilters.append(WebFilterOperation::createHueRotateFilter(amou
nt)); |
| 331 break; |
| 332 default: |
| 333 ASSERT_NOT_REACHED(); |
| 334 } |
| 335 break; |
| 336 } |
| 337 case FilterOperation::INVERT: |
| 338 case FilterOperation::OPACITY: |
| 339 case FilterOperation::BRIGHTNESS: |
| 340 case FilterOperation::CONTRAST: { |
| 341 float amount = static_cast<const BasicComponentTransferFilterOperati
on*>(&op)->amount(); |
| 342 switch (op.getOperationType()) { |
| 343 case FilterOperation::INVERT: |
| 344 webFilters.append(WebFilterOperation::createInvertFilter(amount)
); |
| 345 break; |
| 346 case FilterOperation::OPACITY: |
| 347 webFilters.append(WebFilterOperation::createOpacityFilter(amount
)); |
| 348 break; |
| 349 case FilterOperation::BRIGHTNESS: |
| 350 webFilters.append(WebFilterOperation::createBrightnessFilter(amo
unt)); |
| 351 break; |
| 352 case FilterOperation::CONTRAST: |
| 353 webFilters.append(WebFilterOperation::createContrastFilter(amoun
t)); |
| 354 break; |
| 355 default: |
| 356 ASSERT_NOT_REACHED(); |
| 357 } |
| 358 break; |
| 359 } |
| 360 case FilterOperation::BLUR: { |
| 361 float pixelRadius = static_cast<const BlurFilterOperation*>(&op)->st
dDeviation().getFloatValue(); |
| 362 webFilters.append(WebFilterOperation::createBlurFilter(pixelRadius))
; |
| 363 break; |
| 364 } |
| 365 case FilterOperation::DROP_SHADOW: { |
| 366 const DropShadowFilterOperation& dropShadowOp = *static_cast<const D
ropShadowFilterOperation*>(&op); |
| 367 webFilters.append(WebFilterOperation::createDropShadowFilter(WebPoin
t(dropShadowOp.x(), dropShadowOp.y()), dropShadowOp.stdDeviation(), dropShadowOp
.color().rgb())); |
| 368 break; |
| 369 } |
| 370 #if ENABLE(CSS_SHADERS) |
| 371 case FilterOperation::CUSTOM: |
| 372 return false; // Not supported. |
| 373 #endif |
| 374 case FilterOperation::PASSTHROUGH: |
| 375 case FilterOperation::NONE: |
| 376 break; |
| 377 } |
| 378 } |
| 379 return true; |
| 380 } |
| 381 |
| 382 bool GraphicsLayerChromium::setFilters(const FilterOperations& filters) |
| 383 { |
| 384 WebFilterOperations webFilters; |
| 385 if (!copyWebCoreFilterOperationsToWebFilterOperations(filters, webFilters)) |
| 386 return false; |
| 387 m_layer.setFilters(webFilters); |
| 388 return GraphicsLayer::setFilters(filters); |
| 389 } |
| 390 |
| 391 void GraphicsLayerChromium::setBackgroundFilters(const FilterOperations& filters
) |
| 392 { |
| 393 WebFilterOperations webFilters; |
| 394 if (!copyWebCoreFilterOperationsToWebFilterOperations(filters, webFilters)) |
| 395 return; |
| 396 m_layer.setBackgroundFilters(webFilters); |
| 397 } |
| 398 |
| 399 void GraphicsLayerChromium::setMaskLayer(GraphicsLayer* maskLayer) |
| 400 { |
| 401 if (maskLayer == m_maskLayer) |
| 402 return; |
| 403 |
| 404 GraphicsLayer::setMaskLayer(maskLayer); |
| 405 |
| 406 LayerChromium* maskLayerChromium = m_maskLayer ? m_maskLayer->platformLayer(
) : 0; |
| 407 m_layer.unwrap<LayerChromium>()->setMaskLayer(maskLayerChromium); |
| 408 } |
| 409 |
| 410 void GraphicsLayerChromium::setBackfaceVisibility(bool visible) |
| 411 { |
| 412 GraphicsLayer::setBackfaceVisibility(visible); |
| 413 m_layer.setDoubleSided(m_backfaceVisibility); |
| 414 } |
| 415 |
| 416 void GraphicsLayerChromium::setOpacity(float opacity) |
| 417 { |
| 418 float clampedOpacity = max(min(opacity, 1.0f), 0.0f); |
| 419 GraphicsLayer::setOpacity(clampedOpacity); |
| 420 primaryLayer().setOpacity(opacity); |
| 421 } |
| 422 |
| 423 void GraphicsLayerChromium::setReplicatedByLayer(GraphicsLayer* layer) |
| 424 { |
| 425 GraphicsLayerChromium* layerChromium = static_cast<GraphicsLayerChromium*>(l
ayer); |
| 426 GraphicsLayer::setReplicatedByLayer(layer); |
| 427 LayerChromium* replicaLayer = layerChromium ? layerChromium->primaryLayer().
unwrap<LayerChromium>() : 0; |
| 428 primaryLayer().unwrap<LayerChromium>()->setReplicaLayer(replicaLayer); |
| 429 } |
| 430 |
| 431 |
| 432 void GraphicsLayerChromium::setContentsNeedsDisplay() |
| 433 { |
| 434 if (!m_contentsLayer.isNull()) |
| 435 m_contentsLayer.invalidate(); |
| 436 } |
| 437 |
| 438 void GraphicsLayerChromium::setNeedsDisplay() |
| 439 { |
| 440 if (drawsContent()) |
| 441 m_layer.invalidate(); |
| 442 } |
| 443 |
| 444 void GraphicsLayerChromium::setNeedsDisplayInRect(const FloatRect& rect) |
| 445 { |
| 446 if (drawsContent()) |
| 447 m_layer.invalidateRect(rect); |
| 448 } |
| 449 |
| 450 void GraphicsLayerChromium::setContentsRect(const IntRect& rect) |
| 451 { |
| 452 if (rect == m_contentsRect) |
| 453 return; |
| 454 |
| 455 GraphicsLayer::setContentsRect(rect); |
| 456 updateContentsRect(); |
| 457 } |
| 458 |
| 459 void GraphicsLayerChromium::setContentsToImage(Image* image) |
| 460 { |
| 461 bool childrenChanged = false; |
| 462 if (image) { |
| 463 if (m_contentsLayer.isNull() || m_contentsLayerPurpose != ContentsLayerF
orImage) { |
| 464 WebKit::WebImageLayer imageLayer = WebKit::WebImageLayer::create(); |
| 465 setupContentsLayer(imageLayer.unwrap<LayerChromium>()); |
| 466 m_contentsLayerPurpose = ContentsLayerForImage; |
| 467 childrenChanged = true; |
| 468 } |
| 469 WebKit::WebImageLayer imageLayer = m_contentsLayer.to<WebKit::WebImageLa
yer>(); |
| 470 NativeImageSkia* nativeImage = image->nativeImageForCurrentFrame(); |
| 471 imageLayer.setBitmap(nativeImage->bitmap()); |
| 472 imageLayer.setOpaque(image->isBitmapImage() && !image->currentFrameHasAl
pha()); |
| 473 updateContentsRect(); |
| 474 } else { |
| 475 if (!m_contentsLayer.isNull()) { |
| 476 childrenChanged = true; |
| 477 |
| 478 // The old contents layer will be removed via updateChildList. |
| 479 m_contentsLayer.reset(); |
| 480 } |
| 481 } |
| 482 |
| 483 if (childrenChanged) |
| 484 updateChildList(); |
| 485 } |
| 486 |
| 487 void GraphicsLayerChromium::setContentsToCanvas(PlatformLayer* platformLayer) |
| 488 { |
| 489 bool childrenChanged = false; |
| 490 if (platformLayer) { |
| 491 if (m_contentsLayer.unwrap<LayerChromium>() != platformLayer) { |
| 492 setupContentsLayer(platformLayer); |
| 493 m_contentsLayerPurpose = ContentsLayerForCanvas; |
| 494 childrenChanged = true; |
| 495 } |
| 496 updateContentsRect(); |
| 497 } else { |
| 498 if (!m_contentsLayer.isNull()) { |
| 499 childrenChanged = true; |
| 500 |
| 501 // The old contents layer will be removed via updateChildList. |
| 502 m_contentsLayer.reset(); |
| 503 } |
| 504 } |
| 505 |
| 506 if (childrenChanged) |
| 507 updateChildList(); |
| 508 } |
| 509 |
| 510 bool GraphicsLayerChromium::addAnimation(const KeyframeValueList& values, const
IntSize& boxSize, const Animation* animation, const String& animationName, doubl
e timeOffset) |
| 511 { |
| 512 // Bail early if we have a large rotation. |
| 513 if (values.property() == AnimatedPropertyWebkitTransform) { |
| 514 bool hasRotationOfMoreThan180Degrees = false; |
| 515 validateTransformOperations(values, hasRotationOfMoreThan180Degrees); |
| 516 if (hasRotationOfMoreThan180Degrees) |
| 517 return false; |
| 518 } |
| 519 |
| 520 primaryLayer().unwrap<LayerChromium>()->setLayerAnimationDelegate(this); |
| 521 |
| 522 int animationId = mapAnimationNameToId(animationName); |
| 523 int groupId = AnimationIdVendor::getNextGroupId(); |
| 524 |
| 525 OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(values, animation, ani
mationId, groupId, timeOffset, boxSize)); |
| 526 |
| 527 if (toAdd.get()) { |
| 528 // Remove any existing animations with the same animation id and target
property. |
| 529 primaryLayer().unwrap<LayerChromium>()->layerAnimationController()->remo
veAnimation(toAdd->id(), toAdd->targetProperty()); |
| 530 return primaryLayer().unwrap<LayerChromium>()->addAnimation(toAdd.releas
e()); |
| 531 } |
| 532 |
| 533 return false; |
| 534 } |
| 535 |
| 536 void GraphicsLayerChromium::pauseAnimation(const String& animationName, double t
imeOffset) |
| 537 { |
| 538 primaryLayer().unwrap<LayerChromium>()->pauseAnimation(mapAnimationNameToId(
animationName), timeOffset); |
| 539 } |
| 540 |
| 541 void GraphicsLayerChromium::removeAnimation(const String& animationName) |
| 542 { |
| 543 primaryLayer().unwrap<LayerChromium>()->removeAnimation(mapAnimationNameToId
(animationName)); |
| 544 } |
| 545 |
| 546 void GraphicsLayerChromium::suspendAnimations(double wallClockTime) |
| 547 { |
| 548 // |wallClockTime| is in the wrong time base. Need to convert here. |
| 549 // FIXME: find a more reliable way to do this. |
| 550 double monotonicTime = wallClockTime + monotonicallyIncreasingTime() - curre
ntTime(); |
| 551 primaryLayer().unwrap<LayerChromium>()->suspendAnimations(monotonicTime); |
| 552 } |
| 553 |
| 554 void GraphicsLayerChromium::resumeAnimations() |
| 555 { |
| 556 primaryLayer().unwrap<LayerChromium>()->resumeAnimations(monotonicallyIncrea
singTime()); |
| 557 } |
| 558 |
| 559 void GraphicsLayerChromium::addLinkHighlight(const Path& path) |
| 560 { |
| 561 m_linkHighlight = LinkHighlight::create(this, path, AnimationIdVendor::LinkH
ighlightAnimationId, AnimationIdVendor::getNextGroupId()); |
| 562 updateChildList(); |
| 563 } |
| 564 |
| 565 void GraphicsLayerChromium::didFinishLinkHighlight() |
| 566 { |
| 567 if (m_linkHighlight) |
| 568 m_linkHighlight->contentLayer()->removeFromParent(); |
| 569 |
| 570 m_linkHighlight.clear(); |
| 571 } |
| 572 |
| 573 void GraphicsLayerChromium::setContentsToMedia(PlatformLayer* layer) |
| 574 { |
| 575 bool childrenChanged = false; |
| 576 if (layer) { |
| 577 if (m_contentsLayer.isNull() || m_contentsLayerPurpose != ContentsLayerF
orVideo) { |
| 578 setupContentsLayer(layer); |
| 579 m_contentsLayerPurpose = ContentsLayerForVideo; |
| 580 childrenChanged = true; |
| 581 } |
| 582 updateContentsRect(); |
| 583 } else { |
| 584 if (!m_contentsLayer.isNull()) { |
| 585 childrenChanged = true; |
| 586 |
| 587 // The old contents layer will be removed via updateChildList. |
| 588 m_contentsLayer.reset(); |
| 589 } |
| 590 } |
| 591 |
| 592 if (childrenChanged) |
| 593 updateChildList(); |
| 594 } |
| 595 |
| 596 WebLayer GraphicsLayerChromium::hostLayerForChildren() const |
| 597 { |
| 598 return m_transformLayer.isNull() ? m_layer : m_transformLayer; |
| 599 } |
| 600 |
| 601 WebLayer GraphicsLayerChromium::layerForParent() const |
| 602 { |
| 603 return m_transformLayer.isNull() ? m_layer : m_transformLayer; |
| 604 } |
| 605 |
| 606 PlatformLayer* GraphicsLayerChromium::platformLayer() const |
| 607 { |
| 608 return primaryLayer().unwrap<LayerChromium>(); |
| 609 } |
| 610 |
| 611 void GraphicsLayerChromium::setDebugBackgroundColor(const Color& color) |
| 612 { |
| 613 if (color.isValid()) |
| 614 m_layer.setBackgroundColor(color.rgb()); |
| 615 else |
| 616 m_layer.setBackgroundColor(static_cast<RGBA32>(0)); |
| 617 } |
| 618 |
| 619 void GraphicsLayerChromium::setDebugBorder(const Color& color, float borderWidth
) |
| 620 { |
| 621 if (color.isValid()) { |
| 622 m_layer.setDebugBorderColor(color.rgb()); |
| 623 m_layer.setDebugBorderWidth(borderWidth); |
| 624 } else { |
| 625 m_layer.setDebugBorderColor(static_cast<RGBA32>(0)); |
| 626 m_layer.setDebugBorderWidth(0); |
| 627 } |
| 628 } |
| 629 |
| 630 void GraphicsLayerChromium::updateChildList() |
| 631 { |
| 632 Vector<RefPtr<LayerChromium> > newChildren; |
| 633 |
| 634 if (!m_transformLayer.isNull()) { |
| 635 // Add the primary layer first. Even if we have negative z-order childre
n, the primary layer always comes behind. |
| 636 newChildren.append(m_layer.unwrap<LayerChromium>()); |
| 637 } else if (!m_contentsLayer.isNull()) { |
| 638 // FIXME: add the contents layer in the correct order with negative z-or
der children. |
| 639 // This does not cause visible rendering issues because currently conten
ts layers are only used |
| 640 // for replaced elements that don't have children. |
| 641 newChildren.append(m_contentsLayer.unwrap<LayerChromium>()); |
| 642 } |
| 643 |
| 644 const Vector<GraphicsLayer*>& childLayers = children(); |
| 645 size_t numChildren = childLayers.size(); |
| 646 for (size_t i = 0; i < numChildren; ++i) { |
| 647 GraphicsLayerChromium* curChild = static_cast<GraphicsLayerChromium*>(ch
ildLayers[i]); |
| 648 |
| 649 LayerChromium* childLayer = curChild->layerForParent().unwrap<LayerChrom
ium>(); |
| 650 newChildren.append(childLayer); |
| 651 } |
| 652 |
| 653 if (m_linkHighlight) |
| 654 newChildren.append(m_linkHighlight->contentLayer()); |
| 655 |
| 656 for (size_t i = 0; i < newChildren.size(); ++i) |
| 657 newChildren[i]->removeFromParent(); |
| 658 |
| 659 if (!m_transformLayer.isNull()) { |
| 660 m_transformLayer.unwrap<LayerChromium>()->setChildren(newChildren); |
| 661 |
| 662 if (!m_contentsLayer.isNull()) { |
| 663 // If we have a transform layer, then the contents layer is parented
in the |
| 664 // primary layer (which is itself a child of the transform layer). |
| 665 m_layer.removeAllChildren(); |
| 666 m_layer.addChild(m_contentsLayer); |
| 667 } |
| 668 } else |
| 669 m_layer.unwrap<LayerChromium>()->setChildren(newChildren); |
| 670 } |
| 671 |
| 672 void GraphicsLayerChromium::updateLayerPosition() |
| 673 { |
| 674 // Position is offset on the layer by the layer anchor point. |
| 675 FloatPoint layerPosition(m_position.x() + m_anchorPoint.x() * m_size.width()
, |
| 676 m_position.y() + m_anchorPoint.y() * m_size.height(
)); |
| 677 |
| 678 primaryLayer().setPosition(layerPosition); |
| 679 } |
| 680 |
| 681 void GraphicsLayerChromium::updateLayerSize() |
| 682 { |
| 683 IntSize layerSize(m_size.width(), m_size.height()); |
| 684 if (!m_transformLayer.isNull()) { |
| 685 m_transformLayer.setBounds(layerSize); |
| 686 // The anchor of the contents layer is always at 0.5, 0.5, so the positi
on is center-relative. |
| 687 FloatPoint centerPoint(m_size.width() / 2, m_size.height() / 2); |
| 688 m_layer.setPosition(centerPoint); |
| 689 } |
| 690 |
| 691 m_layer.setBounds(layerSize); |
| 692 |
| 693 // Note that we don't resize m_contentsLayer. It's up the caller to do that. |
| 694 |
| 695 // If we've changed the bounds, we need to recalculate the position |
| 696 // of the layer, taking anchor point into account. |
| 697 updateLayerPosition(); |
| 698 } |
| 699 |
| 700 void GraphicsLayerChromium::updateAnchorPoint() |
| 701 { |
| 702 primaryLayer().setAnchorPoint(FloatPoint(m_anchorPoint.x(), m_anchorPoint.y(
))); |
| 703 primaryLayer().setAnchorPointZ(m_anchorPoint.z()); |
| 704 |
| 705 updateLayerPosition(); |
| 706 } |
| 707 |
| 708 void GraphicsLayerChromium::updateTransform() |
| 709 { |
| 710 primaryLayer().setTransform(WebTransformationMatrix(m_transform)); |
| 711 } |
| 712 |
| 713 void GraphicsLayerChromium::updateChildrenTransform() |
| 714 { |
| 715 primaryLayer().setSublayerTransform(WebTransformationMatrix(m_childrenTransf
orm)); |
| 716 } |
| 717 |
| 718 void GraphicsLayerChromium::updateMasksToBounds() |
| 719 { |
| 720 m_layer.setMasksToBounds(m_masksToBounds); |
| 721 updateDebugIndicators(); |
| 722 } |
| 723 |
| 724 void GraphicsLayerChromium::updateLayerPreserves3D() |
| 725 { |
| 726 if (m_preserves3D && m_transformLayer.isNull()) { |
| 727 // Create the transform layer. |
| 728 m_transformLayer = WebLayer::create(); |
| 729 m_transformLayer.setPreserves3D(true); |
| 730 m_transformLayer.unwrap<LayerChromium>()->setLayerAnimationDelegate(this
); |
| 731 m_transformLayer.unwrap<LayerChromium>()->setLayerAnimationController(m_
layer.unwrap<LayerChromium>()->releaseLayerAnimationController()); |
| 732 |
| 733 // Copy the position from this layer. |
| 734 updateLayerPosition(); |
| 735 updateLayerSize(); |
| 736 updateAnchorPoint(); |
| 737 updateTransform(); |
| 738 updateChildrenTransform(); |
| 739 |
| 740 m_layer.setPosition(FloatPoint(m_size.width() / 2.0f, m_size.height() /
2.0f)); |
| 741 |
| 742 m_layer.setAnchorPoint(FloatPoint(0.5f, 0.5f)); |
| 743 m_layer.setTransform(SkMatrix44()); |
| 744 |
| 745 // Set the old layer to opacity of 1. Further down we will set the opaci
ty on the transform layer. |
| 746 m_layer.setOpacity(1); |
| 747 |
| 748 m_layer.setContentsScale(contentsScale()); |
| 749 |
| 750 // Move this layer to be a child of the transform layer. |
| 751 if (!m_layer.parent().isNull()) |
| 752 m_layer.parent().replaceChild(m_layer, m_transformLayer); |
| 753 m_transformLayer.addChild(m_layer); |
| 754 |
| 755 updateChildList(); |
| 756 } else if (!m_preserves3D && !m_transformLayer.isNull()) { |
| 757 // Relace the transformLayer in the parent with this layer. |
| 758 m_layer.removeFromParent(); |
| 759 if (!m_transformLayer.parent().isNull()) |
| 760 m_transformLayer.parent().replaceChild(m_transformLayer, m_layer); |
| 761 |
| 762 m_layer.unwrap<LayerChromium>()->setLayerAnimationDelegate(this); |
| 763 m_layer.unwrap<LayerChromium>()->setLayerAnimationController(m_transform
Layer.unwrap<LayerChromium>()->releaseLayerAnimationController()); |
| 764 |
| 765 // Release the transform layer. |
| 766 m_transformLayer.unwrap<LayerChromium>()->setLayerAnimationDelegate(0); |
| 767 m_transformLayer.reset(); |
| 768 |
| 769 updateLayerPosition(); |
| 770 updateLayerSize(); |
| 771 updateAnchorPoint(); |
| 772 updateTransform(); |
| 773 updateChildrenTransform(); |
| 774 |
| 775 updateChildList(); |
| 776 } |
| 777 |
| 778 m_layer.setPreserves3D(m_preserves3D); |
| 779 primaryLayer().setOpacity(m_opacity); |
| 780 updateNames(); |
| 781 } |
| 782 |
| 783 void GraphicsLayerChromium::updateLayerIsDrawable() |
| 784 { |
| 785 // For the rest of the accelerated compositor code, there is no reason to ma
ke a |
| 786 // distinction between drawsContent and contentsVisible. So, for m_layer, th
ese two |
| 787 // flags are combined here. m_contentsLayer shouldn't receive the drawsConte
nt flag |
| 788 // so it is only given contentsVisible. |
| 789 |
| 790 m_layer.setDrawsContent(m_drawsContent && m_contentsVisible); |
| 791 |
| 792 if (!m_contentsLayer.isNull()) |
| 793 m_contentsLayer.setDrawsContent(m_contentsVisible); |
| 794 |
| 795 if (m_drawsContent) |
| 796 m_layer.invalidate(); |
| 797 |
| 798 updateDebugIndicators(); |
| 799 } |
| 800 |
| 801 void GraphicsLayerChromium::updateLayerBackgroundColor() |
| 802 { |
| 803 if (m_contentsLayer.isNull()) |
| 804 return; |
| 805 |
| 806 // We never create the contents layer just for background color yet. |
| 807 if (m_backgroundColorSet) |
| 808 m_contentsLayer.setBackgroundColor(m_backgroundColor.rgb()); |
| 809 else |
| 810 m_contentsLayer.setBackgroundColor(static_cast<RGBA32>(0)); |
| 811 } |
| 812 |
| 813 void GraphicsLayerChromium::updateContentsVideo() |
| 814 { |
| 815 // FIXME: Implement |
| 816 } |
| 817 |
| 818 void GraphicsLayerChromium::updateContentsRect() |
| 819 { |
| 820 if (m_contentsLayer.isNull()) |
| 821 return; |
| 822 |
| 823 m_contentsLayer.setPosition(FloatPoint(m_contentsRect.x(), m_contentsRect.y(
))); |
| 824 m_contentsLayer.setBounds(IntSize(m_contentsRect.width(), m_contentsRect.hei
ght())); |
| 825 } |
| 826 |
| 827 void GraphicsLayerChromium::updateContentsScale() |
| 828 { |
| 829 // If page scale is already applied then there's no need to apply it again. |
| 830 if (appliesPageScale() || m_layer.isNull()) |
| 831 return; |
| 832 |
| 833 m_layer.setContentsScale(contentsScale()); |
| 834 } |
| 835 |
| 836 void GraphicsLayerChromium::setupContentsLayer(LayerChromium* contentsLayer) |
| 837 { |
| 838 if (contentsLayer == m_contentsLayer.unwrap<LayerChromium>()) |
| 839 return; |
| 840 |
| 841 if (!m_contentsLayer.isNull()) { |
| 842 m_contentsLayer.setUseParentBackfaceVisibility(false); |
| 843 m_contentsLayer.removeFromParent(); |
| 844 m_contentsLayer.reset(); |
| 845 } |
| 846 |
| 847 if (contentsLayer) { |
| 848 m_contentsLayer = WebLayer(contentsLayer); |
| 849 |
| 850 m_contentsLayer.setAnchorPoint(FloatPoint(0, 0)); |
| 851 m_contentsLayer.setUseParentBackfaceVisibility(true); |
| 852 |
| 853 // It is necessary to call setDrawsContent as soon as we receive the new
contentsLayer, for |
| 854 // the correctness of early exit conditions in setDrawsContent() and set
ContentsVisible(). |
| 855 m_contentsLayer.setDrawsContent(m_contentsVisible); |
| 856 |
| 857 // Insert the content layer first. Video elements require this, because
they have |
| 858 // shadow content that must display in front of the video. |
| 859 m_layer.insertChild(m_contentsLayer, 0); |
| 860 |
| 861 if (showDebugBorders()) { |
| 862 m_contentsLayer.setDebugBorderColor(Color(0, 0, 128, 180).rgb()); |
| 863 m_contentsLayer.setDebugBorderWidth(1); |
| 864 } |
| 865 } |
| 866 updateDebugIndicators(); |
| 867 updateNames(); |
| 868 } |
| 869 |
| 870 float GraphicsLayerChromium::contentsScale() const |
| 871 { |
| 872 if (!appliesPageScale()) |
| 873 return pageScaleFactor() * deviceScaleFactor(); |
| 874 return 1; |
| 875 } |
| 876 |
| 877 void GraphicsLayerChromium::deviceOrPageScaleFactorChanged() |
| 878 { |
| 879 updateContentsScale(); |
| 880 // Invalidations are clamped to the layer's bounds but we receive the scale
changed notification before receiving |
| 881 // the new layer bounds. When the scale changes, we really want to invalidat
e the post-scale layer bounds, so we |
| 882 // remember that the scale has changed and then invalidate the full layer bo
unds when we receive the new size. |
| 883 m_pageScaleChanged = true; |
| 884 } |
| 885 |
| 886 void GraphicsLayerChromium::paint(GraphicsContext& context, const IntRect& clip) |
| 887 { |
| 888 context.platformContext()->setDrawingToImageBuffer(true); |
| 889 paintGraphicsLayerContents(context, clip); |
| 890 } |
| 891 |
| 892 int GraphicsLayerChromium::mapAnimationNameToId(const String& animationName) |
| 893 { |
| 894 if (animationName.isEmpty()) |
| 895 return 0; |
| 896 |
| 897 if (!m_animationIdMap.contains(animationName)) |
| 898 m_animationIdMap.add(animationName, AnimationIdVendor::getNextAnimationI
d()); |
| 899 |
| 900 return m_animationIdMap.find(animationName)->second; |
| 901 } |
| 902 |
| 903 void GraphicsLayerChromium::notifyAnimationStarted(double startTime) |
| 904 { |
| 905 if (m_client) |
| 906 m_client->notifyAnimationStarted(this, startTime); |
| 907 } |
| 908 |
| 909 void GraphicsLayerChromium::notifyAnimationFinished(double) |
| 910 { |
| 911 // Do nothing. |
| 912 } |
| 913 |
| 914 } // namespace WebCore |
| 915 |
| 916 #endif // USE(ACCELERATED_COMPOSITING) |
OLD | NEW |