1 /**
2  * Copyright (C) 2024 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 #pragma once
18 
19 #include <ui/Fence.h>
20 
21 namespace android {
22 
23 // TODO: measure if Fence::merge is cheaper
mergeFence(const char * debugName,sp<Fence> && incomingFence,sp<Fence> & prevFence)24 inline void mergeFence(const char* debugName, sp<Fence>&& incomingFence, sp<Fence>& prevFence) {
25     if (prevFence == nullptr && incomingFence->getStatus() != Fence::Status::Invalid) {
26         prevFence = std::move(incomingFence);
27     } else if (prevFence != nullptr) {
28         // If both fences are signaled or both are unsignaled, we need to merge
29         // them to get an accurate timestamp.
30         if (prevFence->getStatus() != Fence::Status::Invalid &&
31             prevFence->getStatus() == incomingFence->getStatus()) {
32             char fenceName[32] = {};
33             snprintf(fenceName, 32, "%.28s", debugName);
34             sp<Fence> mergedFence = Fence::merge(fenceName, prevFence, incomingFence);
35             if (mergedFence->isValid()) {
36                 prevFence = std::move(mergedFence);
37             }
38         } else if (incomingFence->getStatus() == Fence::Status::Unsignaled) {
39             // If one fence has signaled and the other hasn't, the unsignaled
40             // fence will approximately correspond with the correct timestamp.
41             // There's a small race if both fences signal at about the same time
42             // and their statuses are retrieved with unfortunate timing. However,
43             // by this point, they will have both signaled and only the timestamp
44             // will be slightly off; any dependencies after this point will
45             // already have been met.
46             prevFence = std::move(incomingFence);
47         }
48     }
49 }
50 
51 } // namespace android
52