requestFrameAnimation() callback timestamp should be very close to Performance.now()
[WebKit-https.git] / Source / WebCore / platform / graphics / ios / DisplayRefreshMonitorIOS.mm
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 #import <wtf/SystemTracing.h>
36
37 using namespace WebCore;
38
39 @interface WebDisplayLinkHandler : NSObject
40 {
41     DisplayRefreshMonitorIOS* m_monitor;
42     CADisplayLink *m_displayLink;
43 }
44
45 - (id)initWithMonitor:(DisplayRefreshMonitorIOS*)monitor;
46 - (void)handleDisplayLink:(CADisplayLink *)sender;
47 - (void)invalidate;
48
49 @end
50
51 @implementation WebDisplayLinkHandler
52
53 - (id)initWithMonitor:(DisplayRefreshMonitorIOS*)monitor
54 {
55     if (self = [super init]) {
56         m_monitor = monitor;
57         // Note that CADisplayLink retains its target (self), so a call to -invalidate is needed on teardown.
58         m_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
59         [m_displayLink addToRunLoop:WebThreadNSRunLoop() forMode:NSDefaultRunLoopMode];
60     }
61     return self;
62 }
63
64 - (void)dealloc
65 {
66     ASSERT(!m_displayLink); // -invalidate should have been called already.
67     [super dealloc];
68 }
69
70 - (void)handleDisplayLink:(CADisplayLink *)sender
71 {
72     UNUSED_PARAM(sender);
73     ASSERT(isMainThread());
74     m_monitor->displayLinkFired();
75 }
76
77 - (void)invalidate
78 {
79     [m_displayLink invalidate];
80     m_displayLink = nullptr;
81 }
82
83 @end
84
85 namespace WebCore {
86
87 DisplayRefreshMonitorIOS::DisplayRefreshMonitorIOS(PlatformDisplayID displayID)
88     : DisplayRefreshMonitor(displayID)
89 {
90 }
91
92 DisplayRefreshMonitorIOS::~DisplayRefreshMonitorIOS()
93 {
94     [m_handler invalidate];
95 }
96
97 bool DisplayRefreshMonitorIOS::requestRefreshCallback()
98 {
99     if (!isActive())
100         return false;
101
102     TracePoint(RAFDisplayLinkScheduled);
103     
104     if (!m_handler) {
105         m_handler = adoptNS([[WebDisplayLinkHandler alloc] initWithMonitor:this]);
106         setIsActive(true);
107     }
108
109     setIsScheduled(true);
110     return true;
111 }
112
113 void DisplayRefreshMonitorIOS::displayLinkFired()
114 {
115     if (!isPreviousFrameDone())
116         return;
117
118     setIsPreviousFrameDone(false);
119     handleDisplayRefreshedNotificationOnMainThread(this);
120     
121     TracePoint(RAFDisplayLinkFired);
122 }
123
124 }
125
126 #endif // USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)