[WTF] Move currentCPUTime and sleep(Seconds) to CPUTime.h and Seconds.h respectively
[WebKit-https.git] / Source / WebCore / platform / graphics / DisplayRefreshMonitorManager.cpp
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 #include "config.h"
27 #include "DisplayRefreshMonitorManager.h"
28
29 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
30
31 #include "DisplayRefreshMonitor.h"
32 #include "DisplayRefreshMonitorClient.h"
33 #include "Logging.h"
34
35 namespace WebCore {
36
37 DisplayRefreshMonitorManager::~DisplayRefreshMonitorManager() = default;
38
39 DisplayRefreshMonitorManager& DisplayRefreshMonitorManager::sharedManager()
40 {
41     static NeverDestroyed<DisplayRefreshMonitorManager> manager;
42     return manager.get();
43 }
44
45 DisplayRefreshMonitor* DisplayRefreshMonitorManager::createMonitorForClient(DisplayRefreshMonitorClient& client)
46 {
47     PlatformDisplayID clientDisplayID = client.displayID();
48     for (const RefPtr<DisplayRefreshMonitor>& monitor : m_monitors) {
49         if (monitor->displayID() != clientDisplayID)
50             continue;
51         monitor->addClient(client);
52         return monitor.get();
53     }
54
55     auto monitor = DisplayRefreshMonitor::create(client);
56     if (!monitor)
57         return nullptr;
58
59     LOG(RequestAnimationFrame, "DisplayRefreshMonitorManager::createMonitorForClient() - created monitor %p", monitor.get());
60     monitor->addClient(client);
61     DisplayRefreshMonitor* result = monitor.get();
62     m_monitors.append(WTFMove(monitor));
63     return result;
64 }
65
66 void DisplayRefreshMonitorManager::registerClient(DisplayRefreshMonitorClient& client)
67 {
68     if (!client.hasDisplayID())
69         return;
70
71     createMonitorForClient(client);
72 }
73
74 void DisplayRefreshMonitorManager::unregisterClient(DisplayRefreshMonitorClient& client)
75 {
76     if (!client.hasDisplayID())
77         return;
78
79     PlatformDisplayID clientDisplayID = client.displayID();
80     for (size_t i = 0; i < m_monitors.size(); ++i) {
81         RefPtr<DisplayRefreshMonitor> monitor = m_monitors[i];
82         if (monitor->displayID() != clientDisplayID)
83             continue;
84         if (monitor->removeClient(client)) {
85             if (!monitor->hasClients())
86                 m_monitors.remove(i);
87         }
88         return;
89     }
90 }
91
92 bool DisplayRefreshMonitorManager::scheduleAnimation(DisplayRefreshMonitorClient& client)
93 {
94     if (!client.hasDisplayID())
95         return false;
96
97     DisplayRefreshMonitor* monitor = createMonitorForClient(client);
98     if (!monitor)
99         return false;
100
101     client.setIsScheduled(true);
102     return monitor->requestRefreshCallback();
103 }
104
105 void DisplayRefreshMonitorManager::displayDidRefresh(DisplayRefreshMonitor& monitor)
106 {
107     if (!monitor.shouldBeTerminated())
108         return;
109     LOG(RequestAnimationFrame, "DisplayRefreshMonitorManager::displayDidRefresh() - destroying monitor %p", &monitor);
110
111     size_t monitorIndex = m_monitors.find(&monitor);
112     if (monitorIndex != notFound)
113         m_monitors.remove(monitorIndex);
114 }
115
116 void DisplayRefreshMonitorManager::windowScreenDidChange(PlatformDisplayID displayID, DisplayRefreshMonitorClient& client)
117 {
118     if (client.hasDisplayID() && client.displayID() == displayID)
119         return;
120     
121     unregisterClient(client);
122     client.setDisplayID(displayID);
123     registerClient(client);
124     if (client.isScheduled())
125         scheduleAnimation(client);
126 }
127
128 }
129
130 #endif // USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)