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