Remove the Timer parameters from timer callbacks
[WebKit-https.git] / Source / WebKit2 / Shared / mac / RemoteLayerBackingStoreCollection.mm
1  /*
2  * Copyright (C) 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 "RemoteLayerBackingStoreCollection.h"
28
29 #import "PlatformCALayerRemote.h"
30 #import "RemoteLayerBackingStore.h"
31 #import "RemoteLayerTreeContext.h"
32
33 const std::chrono::seconds volatileBackingStoreAgeThreshold = 1_s;
34 const std::chrono::milliseconds volatileSecondaryBackingStoreAgeThreshold = 200_ms;
35 const std::chrono::milliseconds volatilityTimerInterval = 200_ms;
36
37 namespace WebKit {
38
39 RemoteLayerBackingStoreCollection::RemoteLayerBackingStoreCollection()
40     : m_volatilityTimer(*this, &RemoteLayerBackingStoreCollection::volatilityTimerFired)
41     , m_inLayerFlush(false)
42 {
43 }
44
45 void RemoteLayerBackingStoreCollection::willFlushLayers()
46 {
47     m_inLayerFlush = true;
48     m_reachableBackingStoreInLatestFlush.clear();
49 }
50
51 void RemoteLayerBackingStoreCollection::willCommitLayerTree(RemoteLayerTreeTransaction& transaction)
52 {
53     ASSERT(m_inLayerFlush);
54     Vector<WebCore::GraphicsLayer::PlatformLayerID> newlyUnreachableLayerIDs;
55     for (auto& backingStore : m_liveBackingStore) {
56         if (!m_reachableBackingStoreInLatestFlush.contains(backingStore))
57             newlyUnreachableLayerIDs.append(backingStore->layer()->layerID());
58     }
59
60     transaction.setLayerIDsWithNewlyUnreachableBackingStore(newlyUnreachableLayerIDs);
61 }
62
63 void RemoteLayerBackingStoreCollection::didFlushLayers()
64 {
65     m_inLayerFlush = false;
66
67     Vector<RemoteLayerBackingStore*> newlyUnreachableBackingStore;
68     for (auto& backingStore : m_liveBackingStore) {
69         if (!m_reachableBackingStoreInLatestFlush.contains(backingStore))
70             newlyUnreachableBackingStore.append(backingStore);
71     }
72
73     for (auto& backingStore : newlyUnreachableBackingStore)
74         backingStoreBecameUnreachable(*backingStore);
75
76     if (!newlyUnreachableBackingStore.isEmpty())
77         scheduleVolatilityTimer();
78 }
79
80 void RemoteLayerBackingStoreCollection::backingStoreWasCreated(RemoteLayerBackingStore& backingStore)
81 {
82     m_liveBackingStore.add(&backingStore);
83 }
84
85 void RemoteLayerBackingStoreCollection::backingStoreWillBeDestroyed(RemoteLayerBackingStore& backingStore)
86 {
87     m_liveBackingStore.remove(&backingStore);
88     m_unparentedBackingStore.remove(&backingStore);
89 }
90
91 void RemoteLayerBackingStoreCollection::backingStoreWillBeDisplayed(RemoteLayerBackingStore& backingStore)
92 {
93     ASSERT(m_inLayerFlush);
94     m_reachableBackingStoreInLatestFlush.add(&backingStore);
95
96     auto backingStoreIter = m_unparentedBackingStore.find(&backingStore);
97     if (backingStoreIter == m_unparentedBackingStore.end())
98         return;
99     m_liveBackingStore.add(&backingStore);
100     m_unparentedBackingStore.remove(backingStoreIter);
101 }
102
103 bool RemoteLayerBackingStoreCollection::markBackingStoreVolatileImmediately(RemoteLayerBackingStore& backingStore, VolatilityMarkingFlags volatilityMarkingFlags)
104 {
105     ASSERT(!m_inLayerFlush);
106     bool successfullyMadeBackingStoreVolatile = true;
107
108     if (!backingStore.setBufferVolatility(RemoteLayerBackingStore::BufferType::SecondaryBack, true))
109         successfullyMadeBackingStoreVolatile = false;
110
111     if (!backingStore.setBufferVolatility(RemoteLayerBackingStore::BufferType::Back, true))
112         successfullyMadeBackingStoreVolatile = false;
113
114     if (!m_reachableBackingStoreInLatestFlush.contains(&backingStore) || (volatilityMarkingFlags & MarkBuffersIgnoringReachability)) {
115         if (!backingStore.setBufferVolatility(RemoteLayerBackingStore::BufferType::Front, true))
116             successfullyMadeBackingStoreVolatile = false;
117     }
118
119     return successfullyMadeBackingStoreVolatile;
120 }
121
122 bool RemoteLayerBackingStoreCollection::markBackingStoreVolatile(RemoteLayerBackingStore& backingStore, std::chrono::steady_clock::time_point now)
123 {
124     if (now - backingStore.lastDisplayTime() < volatileBackingStoreAgeThreshold) {
125         if (now - backingStore.lastDisplayTime() >= volatileSecondaryBackingStoreAgeThreshold)
126             backingStore.setBufferVolatility(RemoteLayerBackingStore::BufferType::SecondaryBack, true);
127
128         return false;
129     }
130     
131     return markBackingStoreVolatileImmediately(backingStore);
132 }
133
134 void RemoteLayerBackingStoreCollection::backingStoreBecameUnreachable(RemoteLayerBackingStore& backingStore)
135 {
136     ASSERT(backingStore.layer());
137
138     auto backingStoreIter = m_liveBackingStore.find(&backingStore);
139     if (backingStoreIter == m_liveBackingStore.end())
140         return;
141     m_unparentedBackingStore.add(&backingStore);
142     m_liveBackingStore.remove(backingStoreIter);
143
144     // If a layer with backing store is removed from the tree, mark it as having changed backing store, so that
145     // on the commit which returns it to the tree, we serialize the backing store (despite possibly not painting).
146     backingStore.layer()->properties().notePropertiesChanged(RemoteLayerTreeTransaction::BackingStoreChanged);
147
148     // This will not succeed in marking all buffers as volatile, because the commit unparenting the layer hasn't
149     // made it to the UI process yet. The volatility timer will finish marking the remaining buffers later.
150     markBackingStoreVolatileImmediately(backingStore);
151 }
152
153 bool RemoteLayerBackingStoreCollection::markAllBackingStoreVolatileImmediatelyIfPossible()
154 {
155     bool successfullyMadeBackingStoreVolatile = true;
156
157     for (const auto& backingStore : m_liveBackingStore)
158         successfullyMadeBackingStoreVolatile &= markBackingStoreVolatileImmediately(*backingStore, MarkBuffersIgnoringReachability);
159
160     for (const auto& backingStore : m_unparentedBackingStore)
161         successfullyMadeBackingStoreVolatile &= markBackingStoreVolatileImmediately(*backingStore, MarkBuffersIgnoringReachability);
162
163     return successfullyMadeBackingStoreVolatile;
164 }
165
166 void RemoteLayerBackingStoreCollection::volatilityTimerFired()
167 {
168     bool successfullyMadeBackingStoreVolatile = true;
169
170     auto now = std::chrono::steady_clock::now();
171     for (const auto& backingStore : m_liveBackingStore)
172         successfullyMadeBackingStoreVolatile &= markBackingStoreVolatile(*backingStore, now);
173
174     for (const auto& backingStore : m_unparentedBackingStore)
175         successfullyMadeBackingStoreVolatile &= markBackingStoreVolatileImmediately(*backingStore);
176
177     if (successfullyMadeBackingStoreVolatile)
178         m_volatilityTimer.stop();
179 }
180
181 void RemoteLayerBackingStoreCollection::scheduleVolatilityTimer()
182 {
183     if (m_volatilityTimer.isActive())
184         return;
185
186     m_volatilityTimer.startRepeating(volatilityTimerInterval);
187 }
188
189 } // namespace WebKit