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 <wtf/CurrentTime.h> 34 35namespace WebCore { 36 37DisplayRefreshMonitorManager::~DisplayRefreshMonitorManager() 38{ 39} 40 41DisplayRefreshMonitorManager& DisplayRefreshMonitorManager::sharedManager() 42{ 43 static NeverDestroyed<DisplayRefreshMonitorManager> manager; 44 return manager.get(); 45} 46 47DisplayRefreshMonitor* DisplayRefreshMonitorManager::ensureMonitorForClient(DisplayRefreshMonitorClient* client) 48{ 49 DisplayRefreshMonitorMap::iterator it = m_monitors.find(client->displayID()); 50 if (it == m_monitors.end()) { 51 RefPtr<DisplayRefreshMonitor> monitor = DisplayRefreshMonitor::create(client); 52 monitor->addClient(client); 53 DisplayRefreshMonitor* result = monitor.get(); 54 m_monitors.add(client->displayID(), monitor.release()); 55 return result; 56 } 57 it->value->addClient(client); 58 return it->value.get(); 59} 60 61void DisplayRefreshMonitorManager::registerClient(DisplayRefreshMonitorClient* client) 62{ 63 if (!client->hasDisplayID()) 64 return; 65 66 ensureMonitorForClient(client); 67} 68 69void DisplayRefreshMonitorManager::unregisterClient(DisplayRefreshMonitorClient* client) 70{ 71 if (!client->hasDisplayID()) 72 return; 73 74 DisplayRefreshMonitorMap::iterator it = m_monitors.find(client->displayID()); 75 if (it == m_monitors.end()) 76 return; 77 78 DisplayRefreshMonitor* monitor = it->value.get(); 79 if (monitor->removeClient(client)) { 80 if (!monitor->hasClients()) 81 m_monitors.remove(it); 82 } 83} 84 85bool DisplayRefreshMonitorManager::scheduleAnimation(DisplayRefreshMonitorClient* client) 86{ 87 if (!client->hasDisplayID()) 88 return false; 89 90 DisplayRefreshMonitor* monitor = ensureMonitorForClient(client); 91 92 client->setIsScheduled(true); 93 return monitor->requestRefreshCallback(); 94} 95 96void DisplayRefreshMonitorManager::displayDidRefresh(DisplayRefreshMonitor* monitor) 97{ 98 if (monitor->shouldBeTerminated()) { 99 ASSERT(m_monitors.contains(monitor->displayID())); 100 m_monitors.remove(monitor->displayID()); 101 } 102} 103 104void DisplayRefreshMonitorManager::windowScreenDidChange(PlatformDisplayID displayID, DisplayRefreshMonitorClient* client) 105{ 106 if (client->hasDisplayID() && client->displayID() == displayID) 107 return; 108 109 unregisterClient(client); 110 client->setDisplayID(displayID); 111 registerClient(client); 112 if (client->isScheduled()) 113 scheduleAnimation(client); 114} 115 116} 117 118#endif // USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) 119