blob: 5514c06c84ed751c4238d890f1650a6e7b79fabb [file] [log] [blame]
Vishnu Nairdc4d31b2022-11-17 03:20:58 +00001/*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
19#undef LOG_TAG
20#define LOG_TAG "LayerLifecycleManager"
21
22#include "LayerLifecycleManager.h"
23#include "Layer.h" // temporarily needed for LayerHandle
24#include "LayerHandle.h"
25#include "SwapErase.h"
26
27namespace android::surfaceflinger::frontend {
28
29using namespace ftl::flag_operators;
30
31void LayerLifecycleManager::addLayers(std::vector<std::unique_ptr<RequestedLayerState>> newLayers) {
32 if (newLayers.empty()) {
33 return;
34 }
35
36 mGlobalChanges |= RequestedLayerState::Changes::Hierarchy;
37 for (auto& newLayer : newLayers) {
38 RequestedLayerState& layer = *newLayer.get();
39 auto [it, inserted] = mIdToLayer.try_emplace(layer.id, References{.owner = layer});
40 if (!inserted) {
41 LOG_ALWAYS_FATAL("Duplicate layer id %d found. Existing layer: %s", layer.id,
42 it->second.owner.getDebugString().c_str());
43 }
44
Vishnu Nair04f89692022-11-16 23:21:05 +000045 layer.parentId = linkLayer(layer.parentId, layer.id);
46 layer.relativeParentId = linkLayer(layer.relativeParentId, layer.id);
47 layer.mirrorId = linkLayer(layer.mirrorId, layer.id);
48 layer.touchCropId = linkLayer(layer.touchCropId, layer.id);
Vishnu Nairdc4d31b2022-11-17 03:20:58 +000049
50 mLayers.emplace_back(std::move(newLayer));
51 }
52}
53
54void LayerLifecycleManager::onHandlesDestroyed(const std::vector<uint32_t>& destroyedHandles) {
55 std::vector<uint32_t> layersToBeDestroyed;
56 for (const auto& layerId : destroyedHandles) {
57 auto it = mIdToLayer.find(layerId);
58 if (it == mIdToLayer.end()) {
59 LOG_ALWAYS_FATAL("%s Layerid not found %d", __func__, layerId);
60 continue;
61 }
62 RequestedLayerState& layer = it->second.owner;
63 layer.handleAlive = false;
64 if (!layer.canBeDestroyed()) {
65 continue;
66 }
67 layer.changes |= RequestedLayerState::Changes::Destroyed;
68 layersToBeDestroyed.emplace_back(layerId);
69 }
70
71 if (layersToBeDestroyed.empty()) {
72 return;
73 }
74
75 mGlobalChanges |= RequestedLayerState::Changes::Hierarchy;
76 for (size_t i = 0; i < layersToBeDestroyed.size(); i++) {
77 uint32_t layerId = layersToBeDestroyed[i];
78 auto it = mIdToLayer.find(layerId);
79 if (it == mIdToLayer.end()) {
80 LOG_ALWAYS_FATAL("%s Layer with id %d not found", __func__, layerId);
81 continue;
82 }
83
84 RequestedLayerState& layer = it->second.owner;
85
Vishnu Nair04f89692022-11-16 23:21:05 +000086 layer.parentId = unlinkLayer(layer.parentId, layer.id);
87 layer.relativeParentId = unlinkLayer(layer.relativeParentId, layer.id);
88 layer.mirrorId = unlinkLayer(layer.mirrorId, layer.id);
89 layer.touchCropId = unlinkLayer(layer.touchCropId, layer.id);
Vishnu Nairdc4d31b2022-11-17 03:20:58 +000090
91 auto& references = it->second.references;
92 for (uint32_t linkedLayerId : references) {
93 RequestedLayerState* linkedLayer = getLayerFromId(linkedLayerId);
94 if (!linkedLayer) {
95 LOG_ALWAYS_FATAL("%s Layerid reference %d not found for %d", __func__,
96 linkedLayerId, layer.id);
97 continue;
98 };
99 if (linkedLayer->parentId == layer.id) {
100 linkedLayer->parentId = UNASSIGNED_LAYER_ID;
101 if (linkedLayer->canBeDestroyed()) {
102 linkedLayer->changes |= RequestedLayerState::Changes::Destroyed;
103 layersToBeDestroyed.emplace_back(linkedLayer->id);
104 }
105 }
106 if (linkedLayer->relativeParentId == layer.id) {
107 linkedLayer->relativeParentId = UNASSIGNED_LAYER_ID;
108 }
109 if (linkedLayer->mirrorId == layer.id) {
110 linkedLayer->mirrorId = UNASSIGNED_LAYER_ID;
111 }
112 if (linkedLayer->touchCropId == layer.id) {
113 linkedLayer->touchCropId = UNASSIGNED_LAYER_ID;
114 }
115 }
116 mIdToLayer.erase(it);
117 }
118
119 auto it = mLayers.begin();
120 while (it != mLayers.end()) {
121 RequestedLayerState* layer = it->get();
122 if (layer->changes.test(RequestedLayerState::Changes::Destroyed)) {
123 ALOGV("%s destroyed layer %s", __func__, layer->getDebugStringShort().c_str());
124 std::iter_swap(it, mLayers.end() - 1);
125 mDestroyedLayers.emplace_back(std::move(mLayers.back()));
Vishnu Nairaa548fd2022-11-23 18:50:09 +0000126 if (it == mLayers.end() - 1) {
127 it = mLayers.erase(mLayers.end() - 1);
128 } else {
129 mLayers.erase(mLayers.end() - 1);
130 }
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000131 } else {
132 it++;
133 }
134 }
135}
136
137void LayerLifecycleManager::applyTransactions(const std::vector<TransactionState>& transactions) {
138 for (const auto& transaction : transactions) {
139 for (const auto& resolvedComposerState : transaction.states) {
140 const auto& clientState = resolvedComposerState.state;
141 uint32_t layerId = LayerHandle::getLayerId(clientState.surface);
142 if (layerId == UNASSIGNED_LAYER_ID) {
143 ALOGW("%s Handle %p is not valid", __func__, clientState.surface.get());
144 continue;
145 }
146
147 RequestedLayerState* layer = getLayerFromId(layerId);
148 if (layer == nullptr) {
149 LOG_ALWAYS_FATAL("%s Layer with handle %p (layerid=%d) not found", __func__,
150 clientState.surface.get(), layerId);
151 continue;
152 }
153
154 if (!layer->handleAlive) {
155 LOG_ALWAYS_FATAL("%s Layer's handle %p (layerid=%d) is not alive. Possible out of "
156 "order LayerLifecycleManager updates",
157 __func__, clientState.surface.get(), layerId);
158 continue;
159 }
160
161 uint32_t oldParentId = layer->parentId;
162 uint32_t oldRelativeParentId = layer->relativeParentId;
163 uint32_t oldTouchCropId = layer->touchCropId;
164 layer->merge(resolvedComposerState);
165
166 if (layer->what & layer_state_t::eBackgroundColorChanged) {
167 if (layer->bgColorLayerId == UNASSIGNED_LAYER_ID && layer->bgColorAlpha != 0) {
168 LayerCreationArgs backgroundLayerArgs{nullptr,
169 nullptr,
170 layer->name + "BackgroundColorLayer",
171 ISurfaceComposerClient::eFXSurfaceEffect,
172 {}};
173 std::vector<std::unique_ptr<RequestedLayerState>> newLayers;
174 newLayers.emplace_back(
175 std::make_unique<RequestedLayerState>(backgroundLayerArgs));
176 RequestedLayerState* backgroundLayer = newLayers.back().get();
177 backgroundLayer->handleAlive = false;
178 backgroundLayer->parentId = layer->id;
179 backgroundLayer->z = std::numeric_limits<int32_t>::min();
180 backgroundLayer->color.rgb = layer->color.rgb;
181 backgroundLayer->color.a = layer->bgColorAlpha;
182 backgroundLayer->dataspace = layer->bgColorDataspace;
183
184 layer->bgColorLayerId = backgroundLayer->id;
185 addLayers({std::move(newLayers)});
186 } else if (layer->bgColorLayerId != UNASSIGNED_LAYER_ID &&
187 layer->bgColorAlpha == 0) {
188 RequestedLayerState* bgColorLayer = getLayerFromId(layer->bgColorLayerId);
189 bgColorLayer->parentId = UNASSIGNED_LAYER_ID;
190 onHandlesDestroyed({layer->bgColorLayerId});
191 } else if (layer->bgColorLayerId != UNASSIGNED_LAYER_ID) {
192 RequestedLayerState* bgColorLayer = getLayerFromId(layer->bgColorLayerId);
193 bgColorLayer->color.rgb = layer->color.rgb;
194 bgColorLayer->color.a = layer->bgColorAlpha;
195 bgColorLayer->dataspace = layer->bgColorDataspace;
196 mGlobalChanges |= RequestedLayerState::Changes::Content;
197 }
198 }
199
200 if (oldParentId != layer->parentId) {
201 unlinkLayer(oldParentId, layer->id);
Vishnu Nair04f89692022-11-16 23:21:05 +0000202 layer->parentId = linkLayer(layer->parentId, layer->id);
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000203 }
204 if (oldRelativeParentId != layer->relativeParentId) {
205 unlinkLayer(oldRelativeParentId, layer->id);
Vishnu Nair04f89692022-11-16 23:21:05 +0000206 layer->relativeParentId = linkLayer(layer->relativeParentId, layer->id);
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000207 }
208 if (oldTouchCropId != layer->touchCropId) {
209 unlinkLayer(oldTouchCropId, layer->id);
Vishnu Nair04f89692022-11-16 23:21:05 +0000210 layer->touchCropId = linkLayer(layer->touchCropId, layer->id);
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000211 }
212
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000213 mGlobalChanges |= layer->changes;
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000214 }
215 }
216}
217
218void LayerLifecycleManager::commitChanges() {
219 for (auto& layer : mLayers) {
220 if (layer->changes.test(RequestedLayerState::Changes::Created)) {
221 for (auto listener : mListeners) {
222 listener->onLayerAdded(*layer);
223 }
224 }
225 layer->what = 0;
226 layer->changes.clear();
227 }
228
229 for (auto& destroyedLayer : mDestroyedLayers) {
230 if (destroyedLayer->changes.test(RequestedLayerState::Changes::Created)) {
231 for (auto listener : mListeners) {
232 listener->onLayerAdded(*destroyedLayer);
233 }
234 }
235
236 for (auto listener : mListeners) {
237 listener->onLayerDestroyed(*destroyedLayer);
238 }
239 }
240 mDestroyedLayers.clear();
241 mGlobalChanges.clear();
242}
243
244void LayerLifecycleManager::addLifecycleListener(std::shared_ptr<ILifecycleListener> listener) {
245 mListeners.emplace_back(std::move(listener));
246}
247
248void LayerLifecycleManager::removeLifecycleListener(std::shared_ptr<ILifecycleListener> listener) {
249 swapErase(mListeners, listener);
250}
251
252const std::vector<std::unique_ptr<RequestedLayerState>>& LayerLifecycleManager::getLayers() const {
253 return mLayers;
254}
255
256const std::vector<std::unique_ptr<RequestedLayerState>>& LayerLifecycleManager::getDestroyedLayers()
257 const {
258 return mDestroyedLayers;
259}
260
261const ftl::Flags<RequestedLayerState::Changes> LayerLifecycleManager::getGlobalChanges() const {
262 return mGlobalChanges;
263}
264
265RequestedLayerState* LayerLifecycleManager::getLayerFromId(uint32_t id) {
266 if (id == UNASSIGNED_LAYER_ID) {
267 return nullptr;
268 }
269 auto it = mIdToLayer.find(id);
270 if (it == mIdToLayer.end()) {
271 return nullptr;
272 }
273 return &it->second.owner;
274}
275
276std::vector<uint32_t>* LayerLifecycleManager::getLinkedLayersFromId(uint32_t id) {
277 if (id == UNASSIGNED_LAYER_ID) {
278 return nullptr;
279 }
280 auto it = mIdToLayer.find(id);
281 if (it == mIdToLayer.end()) {
282 return nullptr;
283 }
284 return &it->second.references;
285}
286
Vishnu Nair04f89692022-11-16 23:21:05 +0000287uint32_t LayerLifecycleManager::linkLayer(uint32_t layerId, uint32_t layerToLink) {
288 if (layerId == UNASSIGNED_LAYER_ID) {
289 return UNASSIGNED_LAYER_ID;
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000290 }
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000291
292 std::vector<uint32_t>* linkedLayers = getLinkedLayersFromId(layerId);
293 if (!linkedLayers) {
Vishnu Nair04f89692022-11-16 23:21:05 +0000294 ALOGV("Could not find layer id %d to link %d. Parent is probably destroyed", layerId,
295 layerToLink);
296 return UNASSIGNED_LAYER_ID;
297 }
298 linkedLayers->emplace_back(layerToLink);
299 return layerId;
300}
301
302uint32_t LayerLifecycleManager::unlinkLayer(uint32_t layerId, uint32_t linkedLayer) {
303 std::vector<uint32_t>* linkedLayers = getLinkedLayersFromId(layerId);
304 if (!linkedLayers) {
305 return UNASSIGNED_LAYER_ID;
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000306 }
307 swapErase(*linkedLayers, linkedLayer);
Vishnu Nair04f89692022-11-16 23:21:05 +0000308 return UNASSIGNED_LAYER_ID;
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000309}
310
311std::string LayerLifecycleManager::References::getDebugString() const {
312 std::string debugInfo = owner.name + "[" + std::to_string(owner.id) + "] refs:";
313 std::for_each(references.begin(), references.end(),
314 [&debugInfo = debugInfo](const uint32_t& reference) mutable {
315 debugInfo += std::to_string(reference) + ",";
316 });
317 return debugInfo;
318}
319
Vishnu Nair04f89692022-11-16 23:21:05 +0000320void LayerLifecycleManager::fixRelativeZLoop(uint32_t relativeRootId) {
321 auto it = mIdToLayer.find(relativeRootId);
322 if (it == mIdToLayer.end()) {
323 return;
324 }
325 RequestedLayerState& layer = it->second.owner;
326 layer.relativeParentId = unlinkLayer(layer.relativeParentId, layer.id);
327 layer.changes |=
328 RequestedLayerState::Changes::Hierarchy | RequestedLayerState::Changes::RelativeParent;
329 mGlobalChanges |= RequestedLayerState::Changes::Hierarchy;
330}
331
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000332} // namespace android::surfaceflinger::frontend