WeakPtrFactory should populate m_ref lazily.
[WebKit-https.git] / Source / WebCore / platform / graphics / mac / DisplayRefreshMonitorMac.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 "DisplayRefreshMonitorMac.h"
28
29 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
30
31 #include <QuartzCore/QuartzCore.h>
32 #include <wtf/CurrentTime.h>
33 #include <wtf/RunLoop.h>
34
35 namespace WebCore {
36
37 DisplayRefreshMonitorMac::DisplayRefreshMonitorMac(PlatformDisplayID displayID)
38     : DisplayRefreshMonitor(displayID)
39     , m_displayLink(nullptr)
40 {
41 }
42
43 DisplayRefreshMonitorMac::~DisplayRefreshMonitorMac()
44 {
45     if (m_displayLink) {
46         CVDisplayLinkStop(m_displayLink);
47         CVDisplayLinkRelease(m_displayLink);
48         m_displayLink = nullptr;
49     }
50 }
51
52 static CVReturn displayLinkCallback(CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* data)
53 {
54     DisplayRefreshMonitorMac* monitor = static_cast<DisplayRefreshMonitorMac*>(data);
55     monitor->displayLinkFired();
56     return kCVReturnSuccess;
57 }
58
59 bool DisplayRefreshMonitorMac::requestRefreshCallback()
60 {
61     if (!isActive())
62         return false;
63
64     if (!m_displayLink) {
65         setIsActive(false);
66         CVReturn error = CVDisplayLinkCreateWithCGDisplay(displayID(), &m_displayLink);
67         if (error)
68             return false;
69
70         error = CVDisplayLinkSetOutputCallback(m_displayLink, displayLinkCallback, this);
71         if (error)
72             return false;
73
74         error = CVDisplayLinkStart(m_displayLink);
75         if (error)
76             return false;
77
78         setIsActive(true);
79     }
80
81     LockHolder lock(mutex());
82     setIsScheduled(true);
83     return true;
84 }
85
86 void DisplayRefreshMonitorMac::displayLinkFired()
87 {
88     LockHolder lock(mutex());
89     if (!isPreviousFrameDone())
90         return;
91
92     setIsPreviousFrameDone(false);
93
94     RunLoop::main().dispatch([weakPtr = m_weakFactory.createWeakPtr(*this)] {
95         if (auto* monitor = weakPtr.get())
96             handleDisplayRefreshedNotificationOnMainThread(monitor);
97     });
98 }
99
100 }
101
102 #endif // USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)