DisplayRefreshMonitor.h [plain text]
#ifndef DisplayRefreshMonitor_h
#define DisplayRefreshMonitor_h
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
#include "PlatformScreen.h"
#include <wtf/Threading.h>
#include <wtf/Vector.h>
#if PLATFORM(BLACKBERRY)
#include <BlackBerryPlatformAnimation.h>
#endif
#if PLATFORM(MAC)
typedef struct __CVDisplayLink *CVDisplayLinkRef;
#endif
namespace WebCore {
class DisplayRefreshMonitor;
class DisplayRefreshMonitorManager;
class DisplayRefreshMonitorClient {
friend class DisplayRefreshMonitor;
friend class DisplayRefreshMonitorManager;
public:
DisplayRefreshMonitorClient();
virtual ~DisplayRefreshMonitorClient();
virtual void displayRefreshFired(double timestamp) = 0;
private:
void fireDisplayRefreshIfNeeded(double timestamp);
void setDisplayID(PlatformDisplayID displayID)
{
m_displayID = displayID;
m_displayIDIsSet = true;
}
bool m_scheduled;
bool m_displayIDIsSet;
PlatformDisplayID m_displayID;
};
#if PLATFORM(BLACKBERRY)
class DisplayAnimationClient : public BlackBerry::Platform::AnimationFrameRateClient {
public:
DisplayAnimationClient(DisplayRefreshMonitor *);
~DisplayAnimationClient() { }
private:
virtual void animationFrameChanged();
DisplayRefreshMonitor *m_monitor;
};
#endif
class DisplayRefreshMonitor {
public:
DisplayRefreshMonitor(PlatformDisplayID);
~DisplayRefreshMonitor();
bool requestRefreshCallback();
void windowScreenDidChange(PlatformDisplayID);
bool hasClients() const { return m_clients.size(); }
void addClient(DisplayRefreshMonitorClient* client) { m_clients.append(client); }
bool removeClient(DisplayRefreshMonitorClient* client)
{
size_t i = m_clients.find(client);
if (i == notFound)
return false;
m_clients.remove(i);
return true;
}
PlatformDisplayID displayID() const { return m_displayID; }
private:
void notifyClients();
static void refreshDisplayOnMainThread(void* data);
double m_timestamp;
bool m_active;
bool m_scheduled;
bool m_previousFrameDone;
PlatformDisplayID m_displayID;
DisplayRefreshMonitorManager* m_manager;
Mutex m_mutex;
Vector<DisplayRefreshMonitorClient*> m_clients;
#if PLATFORM(BLACKBERRY)
public:
void displayLinkFired();
private:
DisplayAnimationClient *m_animationClient;
void startAnimationClient();
void stopAnimationClient();
#endif
#if PLATFORM(MAC)
public:
void displayLinkFired(double nowSeconds, double outputTimeSeconds);
private:
CVDisplayLinkRef m_displayLink;
#endif
};
class DisplayRefreshMonitorManager {
public:
static DisplayRefreshMonitorManager* sharedManager();
void registerClient(DisplayRefreshMonitorClient*);
void unregisterClient(DisplayRefreshMonitorClient*);
bool scheduleAnimation(DisplayRefreshMonitorClient*);
void windowScreenDidChange(PlatformDisplayID, DisplayRefreshMonitorClient*);
private:
DisplayRefreshMonitorManager() { }
size_t findMonitor(PlatformDisplayID) const;
Vector<DisplayRefreshMonitor*> m_monitors;
};
}
#endif // USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
#endif