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. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#import "config.h" 27#import "TiledCoreAnimationDrawingArea.h" 28 29#if ENABLE(THREADED_SCROLLING) 30 31#import "ColorSpaceData.h" 32#import "DrawingAreaProxyMessages.h" 33#import "EventDispatcher.h" 34#import "LayerHostingContext.h" 35#import "LayerTreeContext.h" 36#import "WebFrame.h" 37#import "WebPage.h" 38#import "WebPageCreationParameters.h" 39#import "WebPageProxyMessages.h" 40#import "WebProcess.h" 41#import <QuartzCore/QuartzCore.h> 42#import <WebCore/Frame.h> 43#import <WebCore/FrameView.h> 44#import <WebCore/GraphicsContext.h> 45#import <WebCore/GraphicsLayerCA.h> 46#import <WebCore/Page.h> 47#import <WebCore/RenderView.h> 48#import <WebCore/ScrollingCoordinator.h> 49#import <WebCore/ScrollingThread.h> 50#import <WebCore/ScrollingTree.h> 51#import <WebCore/Settings.h> 52#import <WebCore/TiledBacking.h> 53#import <wtf/MainThread.h> 54 55@interface CATransaction (Details) 56+ (void)synchronize; 57@end 58 59using namespace WebCore; 60 61namespace WebKit { 62 63PassOwnPtr<TiledCoreAnimationDrawingArea> TiledCoreAnimationDrawingArea::create(WebPage* webPage, const WebPageCreationParameters& parameters) 64{ 65 return adoptPtr(new TiledCoreAnimationDrawingArea(webPage, parameters)); 66} 67 68TiledCoreAnimationDrawingArea::TiledCoreAnimationDrawingArea(WebPage* webPage, const WebPageCreationParameters& parameters) 69 : DrawingArea(DrawingAreaTypeTiledCoreAnimation, webPage) 70 , m_layerTreeStateIsFrozen(false) 71 , m_layerFlushScheduler(this) 72 , m_isPaintingSuspended(!parameters.isVisible) 73 , m_clipsToExposedRect(false) 74 , m_updateIntrinsicContentSizeTimer(this, &TiledCoreAnimationDrawingArea::updateIntrinsicContentSizeTimerFired) 75{ 76 Page* page = m_webPage->corePage(); 77 78 page->settings()->setScrollingCoordinatorEnabled(true); 79 page->settings()->setForceCompositingMode(true); 80 81 WebProcess::shared().eventDispatcher().addScrollingTreeForPage(webPage); 82 83 m_rootLayer = [CALayer layer]; 84 85 CGRect rootLayerFrame = m_webPage->bounds(); 86 m_rootLayer.get().frame = rootLayerFrame; 87 m_rootLayer.get().opaque = YES; 88 m_rootLayer.get().geometryFlipped = YES; 89 90 updateLayerHostingContext(); 91 setColorSpace(parameters.colorSpace); 92 93 LayerTreeContext layerTreeContext; 94 layerTreeContext.contextID = m_layerHostingContext->contextID(); 95 m_webPage->send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(0, layerTreeContext)); 96} 97 98TiledCoreAnimationDrawingArea::~TiledCoreAnimationDrawingArea() 99{ 100 WebProcess::shared().eventDispatcher().removeScrollingTreeForPage(m_webPage); 101 102 m_layerFlushScheduler.invalidate(); 103} 104 105void TiledCoreAnimationDrawingArea::setNeedsDisplay() 106{ 107} 108 109void TiledCoreAnimationDrawingArea::setNeedsDisplayInRect(const IntRect& rect) 110{ 111} 112 113void TiledCoreAnimationDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) 114{ 115 updateScrolledExposedRect(); 116} 117 118void TiledCoreAnimationDrawingArea::invalidateAllPageOverlays() 119{ 120 for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it) 121 it->value->setNeedsDisplay(); 122} 123 124void TiledCoreAnimationDrawingArea::didChangeScrollOffsetForAnyFrame() 125{ 126 invalidateAllPageOverlays(); 127} 128 129void TiledCoreAnimationDrawingArea::setRootCompositingLayer(GraphicsLayer* graphicsLayer) 130{ 131 CALayer *rootCompositingLayer = graphicsLayer ? graphicsLayer->platformLayer() : nil; 132 133 if (m_layerTreeStateIsFrozen) { 134 m_pendingRootCompositingLayer = rootCompositingLayer; 135 return; 136 } 137 138 setRootCompositingLayer(rootCompositingLayer); 139} 140 141void TiledCoreAnimationDrawingArea::forceRepaint() 142{ 143 if (m_layerTreeStateIsFrozen) 144 return; 145 146 for (Frame* frame = m_webPage->corePage()->mainFrame(); frame; frame = frame->tree()->traverseNext()) { 147 FrameView* frameView = frame->view(); 148 if (!frameView || !frameView->tiledBacking()) 149 continue; 150 151 frameView->tiledBacking()->forceRepaint(); 152 } 153 154 flushLayers(); 155 [CATransaction flush]; 156 [CATransaction synchronize]; 157} 158 159bool TiledCoreAnimationDrawingArea::forceRepaintAsync(uint64_t callbackID) 160{ 161 if (m_layerTreeStateIsFrozen) 162 return false; 163 164 dispatchAfterEnsuringUpdatedScrollPosition(bind(^{ 165 m_webPage->drawingArea()->forceRepaint(); 166 m_webPage->send(Messages::WebPageProxy::VoidCallback(callbackID)); 167 })); 168 return true; 169} 170 171void TiledCoreAnimationDrawingArea::setLayerTreeStateIsFrozen(bool layerTreeStateIsFrozen) 172{ 173 if (m_layerTreeStateIsFrozen == layerTreeStateIsFrozen) 174 return; 175 176 m_layerTreeStateIsFrozen = layerTreeStateIsFrozen; 177 if (m_layerTreeStateIsFrozen) 178 m_layerFlushScheduler.suspend(); 179 else 180 m_layerFlushScheduler.resume(); 181} 182 183bool TiledCoreAnimationDrawingArea::layerTreeStateIsFrozen() const 184{ 185 return m_layerTreeStateIsFrozen; 186} 187 188void TiledCoreAnimationDrawingArea::scheduleCompositingLayerFlush() 189{ 190 m_layerFlushScheduler.schedule(); 191} 192 193void TiledCoreAnimationDrawingArea::didInstallPageOverlay(PageOverlay* pageOverlay) 194{ 195 m_webPage->corePage()->scrollingCoordinator()->setForceMainThreadScrollLayerPositionUpdates(true); 196 197 createPageOverlayLayer(pageOverlay); 198} 199 200void TiledCoreAnimationDrawingArea::didUninstallPageOverlay(PageOverlay* pageOverlay) 201{ 202 destroyPageOverlayLayer(pageOverlay); 203 scheduleCompositingLayerFlush(); 204 205 if (m_pageOverlayLayers.size()) 206 return; 207 208 if (Page* page = m_webPage->corePage()) 209 page->scrollingCoordinator()->setForceMainThreadScrollLayerPositionUpdates(false); 210} 211 212void TiledCoreAnimationDrawingArea::setPageOverlayNeedsDisplay(PageOverlay* pageOverlay, const IntRect& rect) 213{ 214 GraphicsLayer* layer = m_pageOverlayLayers.get(pageOverlay); 215 216 if (!layer) 217 return; 218 219 if (!layer->drawsContent()) { 220 layer->setDrawsContent(true); 221 layer->setSize(expandedIntSize(FloatSize(m_rootLayer.get().frame.size))); 222 } 223 224 layer->setNeedsDisplayInRect(rect); 225 scheduleCompositingLayerFlush(); 226} 227 228void TiledCoreAnimationDrawingArea::updatePreferences(const WebPreferencesStore&) 229{ 230 Settings* settings = m_webPage->corePage()->settings(); 231 bool scrollingPerformanceLoggingEnabled = m_webPage->scrollingPerformanceLoggingEnabled(); 232 ScrollingThread::dispatch(bind(&ScrollingTree::setScrollingPerformanceLoggingEnabled, m_webPage->corePage()->scrollingCoordinator()->scrollingTree(), scrollingPerformanceLoggingEnabled)); 233 234 if (TiledBacking* tiledBacking = mainFrameTiledBacking()) 235 tiledBacking->setAggressivelyRetainsTiles(settings->aggressiveTileRetentionEnabled()); 236 237 for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it) { 238 it->value->setAcceleratesDrawing(settings->acceleratedDrawingEnabled()); 239 it->value->setShowDebugBorder(settings->showDebugBorders()); 240 it->value->setShowRepaintCounter(settings->showRepaintCounter()); 241 } 242 243 // Soon we want pages with fixed positioned elements to be able to be scrolled by the ScrollingCoordinator. 244 // As a part of that work, we have to composite fixed position elements, and we have to allow those 245 // elements to create a stacking context. 246 settings->setAcceleratedCompositingForFixedPositionEnabled(true); 247 settings->setFixedPositionCreatesStackingContext(true); 248 249 bool showTiledScrollingIndicator = settings->showTiledScrollingIndicator(); 250 if (showTiledScrollingIndicator == !!m_debugInfoLayer) 251 return; 252 253 updateDebugInfoLayer(showTiledScrollingIndicator); 254} 255 256void TiledCoreAnimationDrawingArea::mainFrameContentSizeChanged(const IntSize&) 257{ 258 if (!m_webPage->minimumLayoutSize().width()) 259 return; 260 261 if (m_inUpdateGeometry) 262 return; 263 264 if (!m_updateIntrinsicContentSizeTimer.isActive()) 265 m_updateIntrinsicContentSizeTimer.startOneShot(0); 266} 267 268void TiledCoreAnimationDrawingArea::updateIntrinsicContentSizeTimerFired(Timer<TiledCoreAnimationDrawingArea>*) 269{ 270 Frame* frame = m_webPage->corePage()->mainFrame(); 271 if (!frame) 272 return; 273 274 FrameView* frameView = frame->view(); 275 if (!frameView) 276 return; 277 278 IntSize contentSize = frameView->autoSizingIntrinsicContentSize(); 279 280 if (m_lastSentIntrinsicContentSize == contentSize) 281 return; 282 283 m_lastSentIntrinsicContentSize = contentSize; 284 m_webPage->send(Messages::DrawingAreaProxy::IntrinsicContentSizeDidChange(contentSize)); 285} 286 287void TiledCoreAnimationDrawingArea::dispatchAfterEnsuringUpdatedScrollPosition(const Function<void ()>& functionRef) 288{ 289 m_webPage->ref(); 290 m_webPage->corePage()->scrollingCoordinator()->commitTreeStateIfNeeded(); 291 292 if (!m_layerTreeStateIsFrozen) 293 m_layerFlushScheduler.suspend(); 294 295 Function<void ()> function = functionRef; 296 297 // It is possible for the drawing area to be destroyed before the bound block 298 // is invoked, so grab a reference to the web page here so we can access the drawing area through it. 299 // (The web page is already kept alive by dispatchAfterEnsuringUpdatedScrollPosition). 300 WebPage* webPage = m_webPage; 301 302 ScrollingThread::dispatchBarrier(bind(^{ 303 DrawingArea* drawingArea = webPage->drawingArea(); 304 if (!drawingArea) 305 return; 306 307 function(); 308 309 if (!m_layerTreeStateIsFrozen) 310 m_layerFlushScheduler.resume(); 311 312 webPage->deref(); 313 })); 314} 315 316void TiledCoreAnimationDrawingArea::notifyAnimationStarted(const GraphicsLayer*, double) 317{ 318} 319 320void TiledCoreAnimationDrawingArea::notifyFlushRequired(const GraphicsLayer*) 321{ 322} 323 324void TiledCoreAnimationDrawingArea::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& clipRect) 325{ 326 for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it) { 327 if (it->value == graphicsLayer) { 328 m_webPage->drawPageOverlay(it->key, graphicsContext, clipRect); 329 break; 330 } 331 } 332} 333 334float TiledCoreAnimationDrawingArea::deviceScaleFactor() const 335{ 336 return m_webPage->corePage()->deviceScaleFactor(); 337} 338 339bool TiledCoreAnimationDrawingArea::flushLayers() 340{ 341 ASSERT(!m_layerTreeStateIsFrozen); 342 343 // This gets called outside of the normal event loop so wrap in an autorelease pool 344 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 345 346 m_webPage->layoutIfNeeded(); 347 348 if (m_pendingRootCompositingLayer) { 349 setRootCompositingLayer(m_pendingRootCompositingLayer.get()); 350 m_pendingRootCompositingLayer = nullptr; 351 } 352 353 IntRect visibleRect = enclosingIntRect(m_rootLayer.get().frame); 354 if (m_clipsToExposedRect) 355 visibleRect.intersect(enclosingIntRect(m_scrolledExposedRect)); 356 357 for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it) { 358 GraphicsLayer* layer = it->value.get(); 359 layer->flushCompositingState(visibleRect); 360 } 361 362 bool returnValue = m_webPage->corePage()->mainFrame()->view()->flushCompositingStateIncludingSubframes(); 363 364 [pool drain]; 365 return returnValue; 366} 367 368void TiledCoreAnimationDrawingArea::suspendPainting() 369{ 370 ASSERT(!m_isPaintingSuspended); 371 m_isPaintingSuspended = true; 372 373 [m_rootLayer.get() setValue:(id)kCFBooleanTrue forKey:@"NSCAViewRenderPaused"]; 374 [[NSNotificationCenter defaultCenter] postNotificationName:@"NSCAViewRenderDidPauseNotification" object:nil userInfo:[NSDictionary dictionaryWithObject:m_rootLayer.get() forKey:@"layer"]]; 375 376 m_webPage->corePage()->suspendScriptedAnimations(); 377} 378 379void TiledCoreAnimationDrawingArea::resumePainting() 380{ 381 if (!m_isPaintingSuspended) { 382 // FIXME: We can get a call to resumePainting when painting is not suspended. 383 // This happens when sending a synchronous message to create a new page. See <rdar://problem/8976531>. 384 return; 385 } 386 m_isPaintingSuspended = false; 387 388 [m_rootLayer.get() setValue:(id)kCFBooleanFalse forKey:@"NSCAViewRenderPaused"]; 389 [[NSNotificationCenter defaultCenter] postNotificationName:@"NSCAViewRenderDidResumeNotification" object:nil userInfo:[NSDictionary dictionaryWithObject:m_rootLayer.get() forKey:@"layer"]]; 390 391 if (m_webPage->windowIsVisible()) { 392 m_webPage->corePage()->resumeScriptedAnimations(); 393 394 m_webPage->corePage()->resumeAnimatingImages(); 395 } 396} 397 398void TiledCoreAnimationDrawingArea::setExposedRect(const FloatRect& exposedRect) 399{ 400 m_exposedRect = exposedRect; 401 updateScrolledExposedRect(); 402} 403 404void TiledCoreAnimationDrawingArea::setClipsToExposedRect(bool clipsToExposedRect) 405{ 406 m_clipsToExposedRect = clipsToExposedRect; 407 updateScrolledExposedRect(); 408 updateMainFrameClipsToExposedRect(); 409} 410 411void TiledCoreAnimationDrawingArea::updateScrolledExposedRect() 412{ 413 if (!m_clipsToExposedRect) 414 return; 415 416 Frame* frame = m_webPage->corePage()->mainFrame(); 417 if (!frame) 418 return; 419 420 FrameView* frameView = frame->view(); 421 if (!frameView) 422 return; 423 424 IntPoint scrollPositionWithOrigin = frameView->scrollPosition() + toIntSize(frameView->scrollOrigin()); 425 426 m_scrolledExposedRect = m_exposedRect; 427 m_scrolledExposedRect.moveBy(scrollPositionWithOrigin); 428 429 mainFrameTiledBacking()->setExposedRect(m_scrolledExposedRect); 430 431 for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it) { 432 if (TiledBacking* tiledBacking = it->value->tiledBacking()) 433 tiledBacking->setExposedRect(m_scrolledExposedRect); 434 } 435} 436 437void TiledCoreAnimationDrawingArea::updateGeometry(const IntSize& viewSize, const IntSize& layerPosition) 438{ 439 m_inUpdateGeometry = true; 440 441 IntSize size = viewSize; 442 IntSize contentSize = IntSize(-1, -1); 443 444 if (!m_webPage->minimumLayoutSize().width() || m_webPage->autoSizingShouldExpandToViewHeight()) 445 m_webPage->setSize(size); 446 447 FrameView* frameView = m_webPage->mainFrameView(); 448 449 if (m_webPage->autoSizingShouldExpandToViewHeight() && frameView) 450 frameView->setAutoSizeFixedMinimumHeight(viewSize.height()); 451 452 m_webPage->layoutIfNeeded(); 453 454 if (m_webPage->minimumLayoutSize().width() && frameView) { 455 contentSize = frameView->autoSizingIntrinsicContentSize(); 456 size = contentSize; 457 } 458 459 for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it) { 460 GraphicsLayer* layer = it->value.get(); 461 if (layer->drawsContent()) 462 layer->setSize(viewSize); 463 } 464 465 if (!m_layerTreeStateIsFrozen) 466 flushLayers(); 467 468 invalidateAllPageOverlays(); 469 470 [CATransaction begin]; 471 [CATransaction setDisableActions:YES]; 472 473 m_rootLayer.get().frame = CGRectMake(layerPosition.width(), layerPosition.height(), viewSize.width(), viewSize.height()); 474 475 [CATransaction commit]; 476 477 [CATransaction flush]; 478 [CATransaction synchronize]; 479 480 m_webPage->send(Messages::DrawingAreaProxy::DidUpdateGeometry()); 481 482 if (m_webPage->minimumLayoutSize().width() && !m_updateIntrinsicContentSizeTimer.isActive()) 483 m_updateIntrinsicContentSizeTimer.startOneShot(0); 484 485 m_inUpdateGeometry = false; 486} 487 488void TiledCoreAnimationDrawingArea::setDeviceScaleFactor(float deviceScaleFactor) 489{ 490 m_webPage->setDeviceScaleFactor(deviceScaleFactor); 491 492 for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it) 493 it->value->noteDeviceOrPageScaleFactorChangedIncludingDescendants(); 494} 495 496void TiledCoreAnimationDrawingArea::setLayerHostingMode(uint32_t opaqueLayerHostingMode) 497{ 498 LayerHostingMode layerHostingMode = static_cast<LayerHostingMode>(opaqueLayerHostingMode); 499 if (layerHostingMode == m_webPage->layerHostingMode()) 500 return; 501 502 m_webPage->setLayerHostingMode(layerHostingMode); 503 504 updateLayerHostingContext(); 505 506 // Finally, inform the UIProcess that the context has changed. 507 LayerTreeContext layerTreeContext; 508 layerTreeContext.contextID = m_layerHostingContext->contextID(); 509 m_webPage->send(Messages::DrawingAreaProxy::UpdateAcceleratedCompositingMode(0, layerTreeContext)); 510} 511 512void TiledCoreAnimationDrawingArea::setColorSpace(const ColorSpaceData& colorSpace) 513{ 514 m_layerHostingContext->setColorSpace(colorSpace.cgColorSpace.get()); 515} 516 517void TiledCoreAnimationDrawingArea::updateLayerHostingContext() 518{ 519 RetainPtr<CGColorSpaceRef> colorSpace; 520 521 // Invalidate the old context. 522 if (m_layerHostingContext) { 523 colorSpace = m_layerHostingContext->colorSpace(); 524 m_layerHostingContext->invalidate(); 525 m_layerHostingContext = nullptr; 526 } 527 528 // Create a new context and set it up. 529 switch (m_webPage->layerHostingMode()) { 530 case LayerHostingModeDefault: 531 m_layerHostingContext = LayerHostingContext::createForPort(WebProcess::shared().compositingRenderServerPort()); 532 break; 533#if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER) 534 case LayerHostingModeInWindowServer: 535 m_layerHostingContext = LayerHostingContext::createForWindowServer(); 536 break; 537#endif 538 } 539 540 if (m_hasRootCompositingLayer) 541 m_layerHostingContext->setRootLayer(m_rootLayer.get()); 542 543 if (colorSpace) 544 m_layerHostingContext->setColorSpace(colorSpace.get()); 545} 546 547void TiledCoreAnimationDrawingArea::updateMainFrameClipsToExposedRect() 548{ 549 if (TiledBacking* tiledBacking = mainFrameTiledBacking()) 550 tiledBacking->setClipsToExposedRect(m_clipsToExposedRect); 551 552 for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it) 553 if (TiledBacking* tiledBacking = it->value->tiledBacking()) 554 tiledBacking->setClipsToExposedRect(m_clipsToExposedRect); 555 556 Frame* frame = m_webPage->corePage()->mainFrame(); 557 if (!frame) 558 return; 559 560 FrameView* frameView = frame->view(); 561 if (!frameView) 562 return; 563 564 frameView->adjustTiledBackingCoverage(); 565} 566 567void TiledCoreAnimationDrawingArea::setRootCompositingLayer(CALayer *layer) 568{ 569 ASSERT(!m_layerTreeStateIsFrozen); 570 571 bool hadRootCompositingLayer = m_hasRootCompositingLayer; 572 m_hasRootCompositingLayer = !!layer; 573 574 [CATransaction begin]; 575 [CATransaction setDisableActions:YES]; 576 577 m_rootLayer.get().sublayers = m_hasRootCompositingLayer ? [NSArray arrayWithObject:layer] : [NSArray array]; 578 579 if (hadRootCompositingLayer != m_hasRootCompositingLayer) 580 m_layerHostingContext->setRootLayer(m_hasRootCompositingLayer ? m_rootLayer.get() : 0); 581 582 for (PageOverlayLayerMap::iterator it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it) 583 [m_rootLayer.get() addSublayer:it->value->platformLayer()]; 584 585 if (TiledBacking* tiledBacking = mainFrameTiledBacking()) { 586 tiledBacking->setAggressivelyRetainsTiles(m_webPage->corePage()->settings()->aggressiveTileRetentionEnabled()); 587 tiledBacking->setExposedRect(m_scrolledExposedRect); 588 } 589 590 updateMainFrameClipsToExposedRect(); 591 592 updateDebugInfoLayer(m_webPage->corePage()->settings()->showTiledScrollingIndicator()); 593 594 [CATransaction commit]; 595} 596 597void TiledCoreAnimationDrawingArea::createPageOverlayLayer(PageOverlay* pageOverlay) 598{ 599 OwnPtr<GraphicsLayer> layer = GraphicsLayer::create(graphicsLayerFactory(), this); 600#ifndef NDEBUG 601 layer->setName("page overlay content"); 602#endif 603 604 layer->setAcceleratesDrawing(m_webPage->corePage()->settings()->acceleratedDrawingEnabled()); 605 layer->setShowDebugBorder(m_webPage->corePage()->settings()->showDebugBorders()); 606 layer->setShowRepaintCounter(m_webPage->corePage()->settings()->showRepaintCounter()); 607 608 m_pageOverlayPlatformLayers.set(layer.get(), layer->platformLayer()); 609 610 if (TiledBacking* tiledBacking = layer->tiledBacking()) { 611 tiledBacking->setExposedRect(m_scrolledExposedRect); 612 tiledBacking->setClipsToExposedRect(m_clipsToExposedRect); 613 } 614 615 [CATransaction begin]; 616 [CATransaction setDisableActions:YES]; 617 618 [m_rootLayer.get() addSublayer:layer->platformLayer()]; 619 620 [CATransaction commit]; 621 622 m_pageOverlayLayers.add(pageOverlay, layer.release()); 623} 624 625void TiledCoreAnimationDrawingArea::destroyPageOverlayLayer(PageOverlay* pageOverlay) 626{ 627 OwnPtr<GraphicsLayer> layer = m_pageOverlayLayers.take(pageOverlay); 628 ASSERT(layer); 629 630 [CATransaction begin]; 631 [CATransaction setDisableActions:YES]; 632 633 [layer->platformLayer() removeFromSuperlayer]; 634 635 [CATransaction commit]; 636 637 m_pageOverlayPlatformLayers.remove(layer.get()); 638} 639 640void TiledCoreAnimationDrawingArea::didCommitChangesForLayer(const GraphicsLayer* layer) const 641{ 642 RetainPtr<CALayer> oldPlatformLayer = m_pageOverlayPlatformLayers.get(layer); 643 644 if (!oldPlatformLayer) 645 return; 646 647 if (oldPlatformLayer.get() == layer->platformLayer()) 648 return; 649 650 [CATransaction begin]; 651 [CATransaction setDisableActions:YES]; 652 653 [m_rootLayer.get() insertSublayer:layer->platformLayer() above:oldPlatformLayer.get()]; 654 [oldPlatformLayer.get() removeFromSuperlayer]; 655 656 [CATransaction commit]; 657 658 if (TiledBacking* tiledBacking = layer->tiledBacking()) { 659 tiledBacking->setExposedRect(m_scrolledExposedRect); 660 tiledBacking->setClipsToExposedRect(m_clipsToExposedRect); 661 } 662 663 m_pageOverlayPlatformLayers.set(layer, layer->platformLayer()); 664} 665 666TiledBacking* TiledCoreAnimationDrawingArea::mainFrameTiledBacking() const 667{ 668 Frame* frame = m_webPage->corePage()->mainFrame(); 669 if (!frame) 670 return 0; 671 672 FrameView* frameView = frame->view(); 673 return frameView ? frameView->tiledBacking() : 0; 674} 675 676void TiledCoreAnimationDrawingArea::updateDebugInfoLayer(bool showLayer) 677{ 678 if (showLayer) { 679 if (TiledBacking* tiledBacking = mainFrameTiledBacking()) 680 m_debugInfoLayer = tiledBacking->tiledScrollingIndicatorLayer(); 681 682 if (m_debugInfoLayer) { 683#ifndef NDEBUG 684 [m_debugInfoLayer.get() setName:@"Debug Info"]; 685#endif 686 [m_rootLayer.get() addSublayer:m_debugInfoLayer.get()]; 687 } 688 } else if (m_debugInfoLayer) { 689 [m_debugInfoLayer.get() removeFromSuperlayer]; 690 m_debugInfoLayer = nullptr; 691 } 692} 693 694} // namespace WebKit 695 696#endif // ENABLE(THREADED_SCROLLING) 697