1/* 2 * Copyright (C) 2010, 2014 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 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#import "config.h" 27#import "DisplayRefreshMonitorIOS.h" 28 29#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 30 31#import "WebCoreThread.h" 32#import <QuartzCore/QuartzCore.h> 33#import <wtf/CurrentTime.h> 34#import <wtf/MainThread.h> 35 36using namespace WebCore; 37 38@interface WebDisplayLinkHandler : NSObject 39{ 40 DisplayRefreshMonitorIOS* m_monitor; 41 CADisplayLink *m_displayLink; 42} 43 44- (id)initWithMonitor:(DisplayRefreshMonitorIOS*)monitor; 45- (void)handleDisplayLink:(CADisplayLink *)sender; 46- (void)invalidate; 47 48@end 49 50@implementation WebDisplayLinkHandler 51 52- (id)initWithMonitor:(DisplayRefreshMonitorIOS*)monitor 53{ 54 if (self = [super init]) { 55 m_monitor = monitor; 56 // Note that CADisplayLink retains its target (self), so a call to -invalidate is needed on teardown. 57 m_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)]; 58 [m_displayLink addToRunLoop:WebThreadNSRunLoop() forMode:NSDefaultRunLoopMode]; 59 } 60 return self; 61} 62 63- (void)dealloc 64{ 65 ASSERT(!m_displayLink); // -invalidate should have been called already. 66 [super dealloc]; 67} 68 69- (void)handleDisplayLink:(CADisplayLink *)sender 70{ 71 ASSERT(isMainThread()); 72 m_monitor->displayLinkFired(sender.timestamp); 73} 74 75- (void)invalidate 76{ 77 [m_displayLink invalidate]; 78 m_displayLink = nullptr; 79} 80 81@end 82 83namespace WebCore { 84 85DisplayRefreshMonitorIOS::DisplayRefreshMonitorIOS(PlatformDisplayID displayID) 86 : DisplayRefreshMonitor(displayID) 87{ 88} 89 90DisplayRefreshMonitorIOS::~DisplayRefreshMonitorIOS() 91{ 92 [m_handler invalidate]; 93} 94 95bool DisplayRefreshMonitorIOS::requestRefreshCallback() 96{ 97 if (!isActive()) 98 return false; 99 100 if (!m_handler) { 101 m_handler = adoptNS([[WebDisplayLinkHandler alloc] initWithMonitor:this]); 102 setIsActive(true); 103 } 104 105 setIsScheduled(true); 106 return true; 107} 108 109static double mediaTimeToCurrentTime(CFTimeInterval t) 110{ 111 // FIXME: This may be a no-op if CACurrentMediaTime is *guaranteed* to be mach_absolute_time. 112 return monotonicallyIncreasingTime() + t - CACurrentMediaTime(); 113} 114 115void DisplayRefreshMonitorIOS::displayLinkFired(double nowSeconds) 116{ 117 if (!isPreviousFrameDone()) 118 return; 119 120 setIsPreviousFrameDone(false); 121 setMonotonicAnimationStartTime(mediaTimeToCurrentTime(nowSeconds)); 122 123 handleDisplayRefreshedNotificationOnMainThread(this); 124} 125 126} 127 128#endif // USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 129