f49b4ce4e065d6933ab8878b3cfab504f23edf2f
[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) && PLATFORM(IOS)
30
31 #import "WebCoreThread.h"
32 #import <QuartzCore/QuartzCore.h>
33 #import <wtf/CurrentTime.h>
34 #import <wtf/MainThread.h>
35
36 using WebCore::DisplayRefreshMonitorIOS;
37 @interface WebDisplayLinkHandler : NSObject
38 {
39     DisplayRefreshMonitorIOS* m_monitor;
40     CADisplayLink *m_displayLink;
41 }
42
43 - (id)initWithMonitor:(DisplayRefreshMonitorIOS*)monitor;
44 - (void)handleDisplayLink:(CADisplayLink *)sender;
45 - (void)invalidate;
46
47 @end
48
49 @implementation WebDisplayLinkHandler
50
51 - (id)initWithMonitor:(DisplayRefreshMonitorIOS*)monitor
52 {
53     if (self = [super init]) {
54         m_monitor = monitor;
55         // Note that CADisplayLink retains its target (self), so a call to -invalidate is needed on teardown.
56         m_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
57         [m_displayLink addToRunLoop:WebThreadNSRunLoop() forMode:NSDefaultRunLoopMode];
58         m_displayLink.preferredFramesPerSecond = 60;
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     UNUSED_PARAM(sender);
72     ASSERT(isMainThread());
73     m_monitor->displayLinkFired();
74 }
75
76 - (void)invalidate
77 {
78     [m_displayLink invalidate];
79     m_displayLink = nullptr;
80 }
81
82 @end
83
84 namespace WebCore {
85
86 DisplayRefreshMonitorIOS::DisplayRefreshMonitorIOS(PlatformDisplayID displayID)
87     : DisplayRefreshMonitor(displayID)
88 {
89 }
90
91 DisplayRefreshMonitorIOS::~DisplayRefreshMonitorIOS()
92 {
93     [m_handler invalidate];
94 }
95
96 bool DisplayRefreshMonitorIOS::requestRefreshCallback()
97 {
98     if (!isActive())
99         return false;
100
101     if (!m_handler) {
102         m_handler = adoptNS([[WebDisplayLinkHandler alloc] initWithMonitor:this]);
103         setIsActive(true);
104     }
105
106     setIsScheduled(true);
107     return true;
108 }
109
110 void DisplayRefreshMonitorIOS::displayLinkFired()
111 {
112     if (!isPreviousFrameDone())
113         return;
114
115     setIsPreviousFrameDone(false);
116     handleDisplayRefreshedNotificationOnMainThread(this);
117 }
118
119 }
120
121 #endif // USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) && PLATFORM(IOS)