1/* 2 * Copyright (C) 2011 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#if USE(ACCELERATED_COMPOSITING) 29 30#include "PlatformCALayer.h" 31 32#include "AbstractCACFLayerTreeHost.h" 33#include "Font.h" 34#include "GraphicsContext.h" 35#include "PlatformCALayerWinInternal.h" 36#include <QuartzCore/CoreAnimationCF.h> 37#include <WebKitSystemInterface/WebKitSystemInterface.h> 38#include <wtf/CurrentTime.h> 39#include <wtf/text/CString.h> 40 41using namespace WebCore; 42 43bool PlatformCALayer::isValueFunctionSupported() 44{ 45 return true; 46} 47 48void PlatformCALayer::setOwner(PlatformCALayerClient* owner) 49{ 50 m_owner = owner; 51} 52 53static CFStringRef toCACFLayerType(PlatformCALayer::LayerType type) 54{ 55 return (type == PlatformCALayer::LayerTypeTransformLayer) ? kCACFTransformLayer : kCACFLayer; 56} 57 58static CFStringRef toCACFFilterType(PlatformCALayer::FilterType type) 59{ 60 switch (type) { 61 case PlatformCALayer::Linear: return kCACFFilterLinear; 62 case PlatformCALayer::Nearest: return kCACFFilterNearest; 63 case PlatformCALayer::Trilinear: return kCACFFilterTrilinear; 64 default: return 0; 65 } 66} 67 68static AbstractCACFLayerTreeHost* layerTreeHostForLayer(const PlatformCALayer* layer) 69{ 70 // We need the AbstractCACFLayerTreeHost associated with this layer, which is stored in the UserData of the CACFContext 71 void* userData = wkCACFLayerGetContextUserData(layer->platformLayer()); 72 if (!userData) 73 return 0; 74 75 return static_cast<AbstractCACFLayerTreeHost*>(userData); 76} 77 78static PlatformCALayerWinInternal* intern(const PlatformCALayer* layer) 79{ 80 return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(layer->platformLayer())); 81} 82 83static PlatformCALayerWinInternal* intern(void* layer) 84{ 85 return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(static_cast<CACFLayerRef>(layer))); 86} 87 88PassRefPtr<PlatformCALayer> PlatformCALayer::create(LayerType layerType, PlatformCALayerClient* owner) 89{ 90 return adoptRef(new PlatformCALayer(layerType, 0, owner)); 91} 92 93PassRefPtr<PlatformCALayer> PlatformCALayer::create(void* platformLayer, PlatformCALayerClient* owner) 94{ 95 return adoptRef(new PlatformCALayer(LayerTypeCustom, static_cast<PlatformLayer*>(platformLayer), owner)); 96} 97 98static void displayCallback(CACFLayerRef caLayer, CGContextRef context) 99{ 100 ASSERT_ARG(caLayer, CACFLayerGetUserData(caLayer)); 101 intern(caLayer)->displayCallback(caLayer, context); 102} 103 104static void layoutSublayersProc(CACFLayerRef caLayer) 105{ 106 PlatformCALayer* layer = PlatformCALayer::platformCALayer(caLayer); 107 if (layer && layer->owner()) 108 layer->owner()->platformCALayerLayoutSublayersOfLayer(layer); 109} 110 111PlatformCALayer::PlatformCALayer(LayerType layerType, PlatformLayer* layer, PlatformCALayerClient* owner) 112 : m_owner(owner) 113{ 114 if (layer) { 115 m_layerType = LayerTypeCustom; 116 m_layer = layer; 117 } else { 118 m_layerType = layerType; 119 ASSERT((layerType != LayerTypeTiledBackingLayer) && (layerType != LayerTypePageTiledBackingLayer)); 120 m_layer = adoptCF(CACFLayerCreate(toCACFLayerType(layerType))); 121 122 // Create the PlatformCALayerWinInternal object and point to it in the userdata. 123 PlatformCALayerWinInternal* intern = new PlatformCALayerWinInternal(this); 124 CACFLayerSetUserData(m_layer.get(), intern); 125 126 // Set the display callback 127 CACFLayerSetDisplayCallback(m_layer.get(), displayCallback); 128 CACFLayerSetLayoutCallback(m_layer.get(), layoutSublayersProc); 129 } 130} 131 132PlatformCALayer::~PlatformCALayer() 133{ 134 // Toss all the kids 135 removeAllSublayers(); 136 137 // Get rid of the user data 138 PlatformCALayerWinInternal* layerIntern = intern(this); 139 CACFLayerSetUserData(m_layer.get(), 0); 140 141 // Clear the owner, which also clears it in the delegate to prevent attempts 142 // to use the GraphicsLayerCA after it has been destroyed. 143 setOwner(0); 144 145 CACFLayerRemoveFromSuperlayer(m_layer.get()); 146 147 delete layerIntern; 148} 149 150PlatformCALayer* PlatformCALayer::platformCALayer(void* platformLayer) 151{ 152 if (!platformLayer) 153 return 0; 154 155 PlatformCALayerWinInternal* layerIntern = intern(platformLayer); 156 return layerIntern ? layerIntern->owner() : 0; 157} 158 159PassRefPtr<PlatformCALayer> PlatformCALayer::clone(PlatformCALayerClient* owner) const 160{ 161 PlatformCALayer::LayerType type = (layerType() == PlatformCALayer::LayerTypeTransformLayer) ? 162 PlatformCALayer::LayerTypeTransformLayer : PlatformCALayer::LayerTypeLayer; 163 RefPtr<PlatformCALayer> newLayer = PlatformCALayer::create(type, owner); 164 165 newLayer->setPosition(position()); 166 newLayer->setBounds(bounds()); 167 newLayer->setAnchorPoint(anchorPoint()); 168 newLayer->setTransform(transform()); 169 newLayer->setSublayerTransform(sublayerTransform()); 170 newLayer->setContents(contents()); 171 newLayer->setMasksToBounds(masksToBounds()); 172 newLayer->setDoubleSided(isDoubleSided()); 173 newLayer->setOpaque(isOpaque()); 174 newLayer->setBackgroundColor(backgroundColor()); 175 newLayer->setContentsScale(contentsScale()); 176#if ENABLE(CSS_FILTERS) 177 newLayer->copyFiltersFrom(this); 178#endif 179 180 return newLayer; 181} 182 183PlatformLayer* PlatformCALayer::platformLayer() const 184{ 185 return m_layer.get(); 186} 187 188PlatformCALayer* PlatformCALayer::rootLayer() const 189{ 190 AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this); 191 return host ? host->rootLayer() : 0; 192} 193 194void PlatformCALayer::animationStarted(CFTimeInterval beginTime) 195{ 196 // Update start time for any animation not yet started 197 CFTimeInterval cacfBeginTime = currentTimeToMediaTime(beginTime); 198 199 HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = m_animations.end(); 200 for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = m_animations.begin(); it != end; ++it) 201 it->value->setActualStartTimeIfNeeded(cacfBeginTime); 202 203 if (m_owner) 204 m_owner->platformCALayerAnimationStarted(beginTime); 205} 206 207static void resubmitAllAnimations(PlatformCALayer* layer) 208{ 209 HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = layer->animations().end(); 210 for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = layer->animations().begin(); it != end; ++it) 211 CACFLayerAddAnimation(layer->platformLayer(), it->key.createCFString().get(), it->value->platformAnimation()); 212} 213 214void PlatformCALayer::ensureAnimationsSubmitted() 215{ 216 resubmitAllAnimations(this); 217 218 PlatformCALayerList children; 219 intern(this)->getSublayers(children); 220 for (size_t i = 0; i < children.size(); ++i) 221 children[i]->ensureAnimationsSubmitted(); 222} 223 224void PlatformCALayer::setNeedsDisplay(const FloatRect* dirtyRect) 225{ 226 intern(this)->setNeedsDisplay(dirtyRect); 227} 228 229void PlatformCALayer::setNeedsCommit() 230{ 231 AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this); 232 if (host) 233 host->layerTreeDidChange(); 234} 235 236void PlatformCALayer::setContentsChanged() 237{ 238 // FIXME: There is no equivalent of setContentsChanged in CACF. For now I will 239 // set contents to 0 and then back to its original value to see if that 240 // kicks CACF into redisplaying. 241 RetainPtr<CFTypeRef> contents = CACFLayerGetContents(m_layer.get()); 242 CACFLayerSetContents(m_layer.get(), 0); 243 CACFLayerSetContents(m_layer.get(), contents.get()); 244 setNeedsCommit(); 245} 246 247void PlatformCALayer::setNeedsLayout() 248{ 249 if (!m_owner || !m_owner->platformCALayerRespondsToLayoutChanges()) 250 return; 251 252 CACFLayerSetNeedsLayout(m_layer.get()); 253 setNeedsCommit(); 254} 255 256PlatformCALayer* PlatformCALayer::superlayer() const 257{ 258 return platformCALayer(CACFLayerGetSuperlayer(m_layer.get())); 259} 260 261void PlatformCALayer::removeFromSuperlayer() 262{ 263 CACFLayerRemoveFromSuperlayer(m_layer.get()); 264 setNeedsCommit(); 265} 266 267void PlatformCALayer::setSublayers(const PlatformCALayerList& list) 268{ 269 intern(this)->setSublayers(list); 270} 271 272void PlatformCALayer::removeAllSublayers() 273{ 274 intern(this)->removeAllSublayers(); 275} 276 277void PlatformCALayer::appendSublayer(PlatformCALayer* layer) 278{ 279 // This must be in terms of insertSublayer instead of a direct call so PlatformCALayerInternal can override. 280 insertSublayer(layer, sublayerCount()); 281} 282 283void PlatformCALayer::insertSublayer(PlatformCALayer* layer, size_t index) 284{ 285 intern(this)->insertSublayer(layer, index); 286} 287 288void PlatformCALayer::replaceSublayer(PlatformCALayer* reference, PlatformCALayer* newLayer) 289{ 290 // This must not use direct calls to allow PlatformCALayerInternal to override. 291 ASSERT_ARG(reference, reference); 292 ASSERT_ARG(reference, reference->superlayer() == this); 293 294 if (reference == newLayer) 295 return; 296 297 int referenceIndex = intern(this)->indexOfSublayer(reference); 298 ASSERT(referenceIndex != -1); 299 if (referenceIndex == -1) 300 return; 301 302 reference->removeFromSuperlayer(); 303 304 if (newLayer) { 305 newLayer->removeFromSuperlayer(); 306 insertSublayer(newLayer, referenceIndex); 307 } 308} 309 310size_t PlatformCALayer::sublayerCount() const 311{ 312 return intern(this)->sublayerCount(); 313} 314 315void PlatformCALayer::adoptSublayers(PlatformCALayer* source) 316{ 317 PlatformCALayerList sublayers; 318 intern(source)->getSublayers(sublayers); 319 320 // Use setSublayers() because it properly nulls out the superlayer pointers. 321 setSublayers(sublayers); 322} 323 324void PlatformCALayer::addAnimationForKey(const String& key, PlatformCAAnimation* animation) 325{ 326 // Add it to the animation list 327 m_animations.add(key, animation); 328 329 CACFLayerAddAnimation(m_layer.get(), key.createCFString().get(), animation->platformAnimation()); 330 setNeedsCommit(); 331 332 // Tell the host about it so we can fire the start animation event 333 AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this); 334 if (host) 335 host->addPendingAnimatedLayer(this); 336} 337 338void PlatformCALayer::removeAnimationForKey(const String& key) 339{ 340 // Remove it from the animation list 341 m_animations.remove(key); 342 343 CACFLayerRemoveAnimation(m_layer.get(), key.createCFString().get()); 344 345 // We don't "remove" a layer from AbstractCACFLayerTreeHost when it loses an animation. 346 // There may be other active animations on the layer and if an animation 347 // callback is fired on a layer without any animations no harm is done. 348 349 setNeedsCommit(); 350} 351 352PassRefPtr<PlatformCAAnimation> PlatformCALayer::animationForKey(const String& key) 353{ 354 HashMap<String, RefPtr<PlatformCAAnimation> >::iterator it = m_animations.find(key); 355 if (it == m_animations.end()) 356 return 0; 357 358 return it->value; 359} 360 361PlatformCALayer* PlatformCALayer::mask() const 362{ 363 return platformCALayer(CACFLayerGetMask(m_layer.get())); 364} 365 366void PlatformCALayer::setMask(PlatformCALayer* layer) 367{ 368 CACFLayerSetMask(m_layer.get(), layer ? layer->platformLayer() : 0); 369 setNeedsCommit(); 370} 371 372bool PlatformCALayer::isOpaque() const 373{ 374 return CACFLayerIsOpaque(m_layer.get()); 375} 376 377void PlatformCALayer::setOpaque(bool value) 378{ 379 CACFLayerSetOpaque(m_layer.get(), value); 380 setNeedsCommit(); 381} 382 383FloatRect PlatformCALayer::bounds() const 384{ 385 return CACFLayerGetBounds(m_layer.get()); 386} 387 388void PlatformCALayer::setBounds(const FloatRect& value) 389{ 390 intern(this)->setBounds(value); 391 setNeedsLayout(); 392} 393 394FloatPoint3D PlatformCALayer::position() const 395{ 396 CGPoint point = CACFLayerGetPosition(m_layer.get()); 397 return FloatPoint3D(point.x, point.y, CACFLayerGetZPosition(m_layer.get())); 398} 399 400void PlatformCALayer::setPosition(const FloatPoint3D& value) 401{ 402 CACFLayerSetPosition(m_layer.get(), CGPointMake(value.x(), value.y())); 403 CACFLayerSetZPosition(m_layer.get(), value.z()); 404 setNeedsCommit(); 405} 406 407FloatPoint3D PlatformCALayer::anchorPoint() const 408{ 409 CGPoint point = CACFLayerGetAnchorPoint(m_layer.get()); 410 float z = CACFLayerGetAnchorPointZ(m_layer.get()); 411 return FloatPoint3D(point.x, point.y, z); 412} 413 414void PlatformCALayer::setAnchorPoint(const FloatPoint3D& value) 415{ 416 CACFLayerSetAnchorPoint(m_layer.get(), CGPointMake(value.x(), value.y())); 417 CACFLayerSetAnchorPointZ(m_layer.get(), value.z()); 418 setNeedsCommit(); 419} 420 421TransformationMatrix PlatformCALayer::transform() const 422{ 423 return CACFLayerGetTransform(m_layer.get()); 424} 425 426void PlatformCALayer::setTransform(const TransformationMatrix& value) 427{ 428 CACFLayerSetTransform(m_layer.get(), value); 429 setNeedsCommit(); 430} 431 432TransformationMatrix PlatformCALayer::sublayerTransform() const 433{ 434 return CACFLayerGetSublayerTransform(m_layer.get()); 435} 436 437void PlatformCALayer::setSublayerTransform(const TransformationMatrix& value) 438{ 439 CACFLayerSetSublayerTransform(m_layer.get(), value); 440 setNeedsCommit(); 441} 442 443TransformationMatrix PlatformCALayer::contentsTransform() const 444{ 445 // ContentsTransform is not used 446 return TransformationMatrix(); 447} 448 449void PlatformCALayer::setContentsTransform(const TransformationMatrix&) 450{ 451 // ContentsTransform is not used 452} 453 454bool PlatformCALayer::isHidden() const 455{ 456 return CACFLayerIsHidden(m_layer.get()); 457} 458 459void PlatformCALayer::setHidden(bool value) 460{ 461 CACFLayerSetHidden(m_layer.get(), value); 462 setNeedsCommit(); 463} 464 465bool PlatformCALayer::isGeometryFlipped() const 466{ 467 return CACFLayerIsGeometryFlipped(m_layer.get()); 468} 469 470void PlatformCALayer::setGeometryFlipped(bool value) 471{ 472 CACFLayerSetGeometryFlipped(m_layer.get(), value); 473 setNeedsCommit(); 474} 475 476bool PlatformCALayer::isDoubleSided() const 477{ 478 return CACFLayerIsDoubleSided(m_layer.get()); 479} 480 481void PlatformCALayer::setDoubleSided(bool value) 482{ 483 CACFLayerSetDoubleSided(m_layer.get(), value); 484 setNeedsCommit(); 485} 486 487bool PlatformCALayer::masksToBounds() const 488{ 489 return CACFLayerGetMasksToBounds(m_layer.get()); 490} 491 492void PlatformCALayer::setMasksToBounds(bool value) 493{ 494 CACFLayerSetMasksToBounds(m_layer.get(), value); 495 setNeedsCommit(); 496} 497 498bool PlatformCALayer::acceleratesDrawing() const 499{ 500 return false; 501} 502 503void PlatformCALayer::setAcceleratesDrawing(bool) 504{ 505} 506 507CFTypeRef PlatformCALayer::contents() const 508{ 509 return CACFLayerGetContents(m_layer.get()); 510} 511 512void PlatformCALayer::setContents(CFTypeRef value) 513{ 514 CACFLayerSetContents(m_layer.get(), value); 515 setNeedsCommit(); 516} 517 518FloatRect PlatformCALayer::contentsRect() const 519{ 520 return CACFLayerGetContentsRect(m_layer.get()); 521} 522 523void PlatformCALayer::setContentsRect(const FloatRect& value) 524{ 525 CACFLayerSetContentsRect(m_layer.get(), value); 526 setNeedsCommit(); 527} 528 529void PlatformCALayer::setMinificationFilter(FilterType value) 530{ 531 CACFLayerSetMinificationFilter(m_layer.get(), toCACFFilterType(value)); 532} 533 534void PlatformCALayer::setMagnificationFilter(FilterType value) 535{ 536 CACFLayerSetMagnificationFilter(m_layer.get(), toCACFFilterType(value)); 537 setNeedsCommit(); 538} 539 540Color PlatformCALayer::backgroundColor() const 541{ 542 return CACFLayerGetBackgroundColor(m_layer.get()); 543} 544 545void PlatformCALayer::setBackgroundColor(const Color& value) 546{ 547 CGFloat components[4]; 548 value.getRGBA(components[0], components[1], components[2], components[3]); 549 550 RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB()); 551 RetainPtr<CGColorRef> color = adoptCF(CGColorCreate(colorSpace.get(), components)); 552 553 CACFLayerSetBackgroundColor(m_layer.get(), color.get()); 554 setNeedsCommit(); 555} 556 557float PlatformCALayer::borderWidth() const 558{ 559 return CACFLayerGetBorderWidth(m_layer.get()); 560} 561 562void PlatformCALayer::setBorderWidth(float value) 563{ 564 CACFLayerSetBorderWidth(m_layer.get(), value); 565 setNeedsCommit(); 566} 567 568Color PlatformCALayer::borderColor() const 569{ 570 return CACFLayerGetBorderColor(m_layer.get()); 571} 572 573void PlatformCALayer::setBorderColor(const Color& value) 574{ 575 CGFloat components[4]; 576 value.getRGBA(components[0], components[1], components[2], components[3]); 577 578 RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreateDeviceRGB()); 579 RetainPtr<CGColorRef> color = adoptCF(CGColorCreate(colorSpace.get(), components)); 580 581 CACFLayerSetBorderColor(m_layer.get(), color.get()); 582 setNeedsCommit(); 583} 584 585float PlatformCALayer::opacity() const 586{ 587 return CACFLayerGetOpacity(m_layer.get()); 588} 589 590void PlatformCALayer::setOpacity(float value) 591{ 592 CACFLayerSetOpacity(m_layer.get(), value); 593 setNeedsCommit(); 594} 595 596#if ENABLE(CSS_FILTERS) 597 598void PlatformCALayer::setFilters(const FilterOperations&) 599{ 600} 601 602void PlatformCALayer::copyFiltersFrom(const PlatformCALayer*) 603{ 604} 605 606bool PlatformCALayer::filtersCanBeComposited(const FilterOperations&) 607{ 608 return false; 609} 610 611#endif // ENABLE(CSS_FILTERS) 612 613String PlatformCALayer::name() const 614{ 615 return CACFLayerGetName(m_layer.get()); 616} 617 618void PlatformCALayer::setName(const String& value) 619{ 620 CACFLayerSetName(m_layer.get(), value.createCFString().get()); 621 setNeedsCommit(); 622} 623 624FloatRect PlatformCALayer::frame() const 625{ 626 return CACFLayerGetFrame(m_layer.get()); 627} 628 629void PlatformCALayer::setFrame(const FloatRect& value) 630{ 631 intern(this)->setFrame(value); 632 setNeedsLayout(); 633} 634 635float PlatformCALayer::speed() const 636{ 637 return CACFLayerGetSpeed(m_layer.get()); 638} 639 640void PlatformCALayer::setSpeed(float value) 641{ 642 CACFLayerSetSpeed(m_layer.get(), value); 643 setNeedsCommit(); 644} 645 646CFTimeInterval PlatformCALayer::timeOffset() const 647{ 648 return CACFLayerGetTimeOffset(m_layer.get()); 649} 650 651void PlatformCALayer::setTimeOffset(CFTimeInterval value) 652{ 653 CACFLayerSetTimeOffset(m_layer.get(), value); 654 setNeedsCommit(); 655} 656 657float PlatformCALayer::contentsScale() const 658{ 659 return 1; 660} 661 662void PlatformCALayer::setContentsScale(float) 663{ 664} 665 666TiledBacking* PlatformCALayer::tiledBacking() 667{ 668 return 0; 669} 670 671#ifndef NDEBUG 672static void printIndent(int indent) 673{ 674 for ( ; indent > 0; --indent) 675 fprintf(stderr, " "); 676} 677 678static void printTransform(const CATransform3D& transform) 679{ 680 fprintf(stderr, "[%g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]", 681 transform.m11, transform.m12, transform.m13, transform.m14, 682 transform.m21, transform.m22, transform.m23, transform.m24, 683 transform.m31, transform.m32, transform.m33, transform.m34, 684 transform.m41, transform.m42, transform.m43, transform.m44); 685} 686 687static void printLayer(const PlatformCALayer* layer, int indent) 688{ 689 FloatPoint3D layerPosition = layer->position(); 690 FloatPoint3D layerAnchorPoint = layer->anchorPoint(); 691 FloatRect layerBounds = layer->bounds(); 692 printIndent(indent); 693 694 char* layerTypeName = 0; 695 switch (layer->layerType()) { 696 case PlatformCALayer::LayerTypeLayer: layerTypeName = "layer"; break; 697 case PlatformCALayer::LayerTypeWebLayer: layerTypeName = "web-layer"; break; 698 case PlatformCALayer::LayerTypeTransformLayer: layerTypeName = "transform-layer"; break; 699 case PlatformCALayer::LayerTypeWebTiledLayer: layerTypeName = "web-tiled-layer"; break; 700 case PlatformCALayer::LayerTypeRootLayer: layerTypeName = "root-layer"; break; 701 case PlatformCALayer::LayerTypeCustom: layerTypeName = "custom-layer"; break; 702 } 703 704 fprintf(stderr, "(%s [%g %g %g] [%g %g %g %g] [%g %g %g] superlayer=%p\n", 705 layerTypeName, 706 layerPosition.x(), layerPosition.y(), layerPosition.z(), 707 layerBounds.x(), layerBounds.y(), layerBounds.width(), layerBounds.height(), 708 layerAnchorPoint.x(), layerAnchorPoint.y(), layerAnchorPoint.z(), layer->superlayer()); 709 710 // Print name if needed 711 String layerName = layer->name(); 712 if (!layerName.isEmpty()) { 713 printIndent(indent + 1); 714 fprintf(stderr, "(name %s)\n", layerName.utf8().data()); 715 } 716 717 // Print masksToBounds if needed 718 bool layerMasksToBounds = layer->masksToBounds(); 719 if (layerMasksToBounds) { 720 printIndent(indent + 1); 721 fprintf(stderr, "(masksToBounds true)\n"); 722 } 723 724 // Print opacity if needed 725 float layerOpacity = layer->opacity(); 726 if (layerOpacity != 1) { 727 printIndent(indent + 1); 728 fprintf(stderr, "(opacity %hf)\n", layerOpacity); 729 } 730 731 // Print sublayerTransform if needed 732 TransformationMatrix layerTransform = layer->sublayerTransform(); 733 if (!layerTransform.isIdentity()) { 734 printIndent(indent + 1); 735 fprintf(stderr, "(sublayerTransform "); 736 printTransform(layerTransform); 737 fprintf(stderr, ")\n"); 738 } 739 740 // Print transform if needed 741 layerTransform = layer->transform(); 742 if (!layerTransform.isIdentity()) { 743 printIndent(indent + 1); 744 fprintf(stderr, "(transform "); 745 printTransform(layerTransform); 746 fprintf(stderr, ")\n"); 747 } 748 749 // Print contents if needed 750 CFTypeRef layerContents = layer->contents(); 751 if (layerContents) { 752 if (CFGetTypeID(layerContents) == CGImageGetTypeID()) { 753 CGImageRef imageContents = static_cast<CGImageRef>(const_cast<void*>(layerContents)); 754 printIndent(indent + 1); 755 fprintf(stderr, "(contents (image [%d %d]))\n", 756 CGImageGetWidth(imageContents), CGImageGetHeight(imageContents)); 757 } 758 } 759 760 // Print sublayers if needed 761 int n = layer->sublayerCount(); 762 if (n > 0) { 763 printIndent(indent + 1); 764 fprintf(stderr, "(sublayers\n"); 765 766 PlatformCALayerList sublayers; 767 intern(layer)->getSublayers(sublayers); 768 ASSERT(n == sublayers.size()); 769 for (int i = 0; i < n; ++i) 770 printLayer(sublayers[i].get(), indent + 2); 771 772 printIndent(indent + 1); 773 fprintf(stderr, ")\n"); 774 } 775 776 printIndent(indent); 777 fprintf(stderr, ")\n"); 778} 779 780void PlatformCALayer::printTree() const 781{ 782 // Print heading info 783 CGRect rootBounds = bounds(); 784 fprintf(stderr, "\n\n** Render tree at time %g (bounds %g, %g %gx%g) **\n\n", 785 currentTime(), rootBounds.origin.x, rootBounds.origin.y, rootBounds.size.width, rootBounds.size.height); 786 787 // Print layer tree from the root 788 printLayer(this, 0); 789} 790#endif // #ifndef NDEBUG 791 792#endif // USE(ACCELERATED_COMPOSITING) 793