xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/Utils/FenceUtils.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /**
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2024 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <ui/Fence.h>
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker namespace android {
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker // TODO: measure if Fence::merge is cheaper
mergeFence(const char * debugName,sp<Fence> && incomingFence,sp<Fence> & prevFence)24*38e8c45fSAndroid Build Coastguard Worker inline void mergeFence(const char* debugName, sp<Fence>&& incomingFence, sp<Fence>& prevFence) {
25*38e8c45fSAndroid Build Coastguard Worker     if (prevFence == nullptr && incomingFence->getStatus() != Fence::Status::Invalid) {
26*38e8c45fSAndroid Build Coastguard Worker         prevFence = std::move(incomingFence);
27*38e8c45fSAndroid Build Coastguard Worker     } else if (prevFence != nullptr) {
28*38e8c45fSAndroid Build Coastguard Worker         // If both fences are signaled or both are unsignaled, we need to merge
29*38e8c45fSAndroid Build Coastguard Worker         // them to get an accurate timestamp.
30*38e8c45fSAndroid Build Coastguard Worker         if (prevFence->getStatus() != Fence::Status::Invalid &&
31*38e8c45fSAndroid Build Coastguard Worker             prevFence->getStatus() == incomingFence->getStatus()) {
32*38e8c45fSAndroid Build Coastguard Worker             char fenceName[32] = {};
33*38e8c45fSAndroid Build Coastguard Worker             snprintf(fenceName, 32, "%.28s", debugName);
34*38e8c45fSAndroid Build Coastguard Worker             sp<Fence> mergedFence = Fence::merge(fenceName, prevFence, incomingFence);
35*38e8c45fSAndroid Build Coastguard Worker             if (mergedFence->isValid()) {
36*38e8c45fSAndroid Build Coastguard Worker                 prevFence = std::move(mergedFence);
37*38e8c45fSAndroid Build Coastguard Worker             }
38*38e8c45fSAndroid Build Coastguard Worker         } else if (incomingFence->getStatus() == Fence::Status::Unsignaled) {
39*38e8c45fSAndroid Build Coastguard Worker             // If one fence has signaled and the other hasn't, the unsignaled
40*38e8c45fSAndroid Build Coastguard Worker             // fence will approximately correspond with the correct timestamp.
41*38e8c45fSAndroid Build Coastguard Worker             // There's a small race if both fences signal at about the same time
42*38e8c45fSAndroid Build Coastguard Worker             // and their statuses are retrieved with unfortunate timing. However,
43*38e8c45fSAndroid Build Coastguard Worker             // by this point, they will have both signaled and only the timestamp
44*38e8c45fSAndroid Build Coastguard Worker             // will be slightly off; any dependencies after this point will
45*38e8c45fSAndroid Build Coastguard Worker             // already have been met.
46*38e8c45fSAndroid Build Coastguard Worker             prevFence = std::move(incomingFence);
47*38e8c45fSAndroid Build Coastguard Worker         }
48*38e8c45fSAndroid Build Coastguard Worker     }
49*38e8c45fSAndroid Build Coastguard Worker }
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker } // namespace android
52