1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "rs_frame_rate_linker.h"
17 
18 #include "command/rs_frame_rate_linker_command.h"
19 #include "platform/common/rs_log.h"
20 #include "sandbox_utils.h"
21 #include "transaction/rs_transaction_proxy.h"
22 #include "transaction/rs_interfaces.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 static bool g_isUniRenderEnabled = false;
GenerateId()27 FrameRateLinkerId RSFrameRateLinker::GenerateId()
28 {
29     static pid_t pid_ = GetRealPid();
30     static std::atomic<uint32_t> currentId_ = 0;
31 
32     auto currentId = currentId_.fetch_add(1, std::memory_order_relaxed);
33     if (currentId == UINT32_MAX) {
34         ROSEN_LOGE("RSFrameRateLinker Id overflow");
35     }
36 
37     // concat two 32-bit numbers to one 64-bit number
38     return ((FrameRateLinkerId)pid_ << 32) | (currentId);
39 }
40 
Create()41 std::shared_ptr<RSFrameRateLinker> RSFrameRateLinker::Create()
42 {
43     auto linker = std::make_shared<RSFrameRateLinker>();
44     ROSEN_LOGI("RSFrameRateLinker::Create id: %{public}" PRIu64, linker->GetId());
45     return linker;
46 }
47 
RSFrameRateLinker()48 RSFrameRateLinker::RSFrameRateLinker() : id_(GenerateId())
49 {
50     InitUniRenderEnabled();
51 }
52 
~RSFrameRateLinker()53 RSFrameRateLinker::~RSFrameRateLinker()
54 {
55     // tell RT/RS to destroy related frameRateLinker
56     auto transactionProxy = RSTransactionProxy::GetInstance();
57     if (transactionProxy == nullptr) {
58         return;
59     }
60     std::unique_ptr<RSCommand> command = std::make_unique<RSFrameRateLinkerDestroy>(id_);
61     transactionProxy->AddCommand(command, IsUniRenderEnabled());
62 
63     auto renderServiceClient =
64             std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
65     if (renderServiceClient == nullptr) {
66         ROSEN_LOGE("RSFrameRateLinker renderServiceClient is nullptr!");
67         return;
68     }
69     renderServiceClient->UnregisterFrameRateLinker(id_);
70     ROSEN_LOGI("RSFrameRateLinker::Destroy id: %{public}" PRIu64, id_);
71 }
72 
GetId() const73 FrameRateLinkerId RSFrameRateLinker::GetId() const
74 {
75     return id_;
76 }
77 
IsUniRenderEnabled() const78 bool RSFrameRateLinker::IsUniRenderEnabled() const
79 {
80     return g_isUniRenderEnabled;
81 }
82 
UpdateFrameRateRange(const FrameRateRange & range,int32_t animatorExpectedFrameRate)83 void RSFrameRateLinker::UpdateFrameRateRange(const FrameRateRange& range, int32_t animatorExpectedFrameRate)
84 {
85     if (currentRange_ != range || currAnimatorExpectedFrameRate_ != animatorExpectedFrameRate) {
86         currentRange_ = range;
87         currAnimatorExpectedFrameRate_ = animatorExpectedFrameRate;
88         std::unique_ptr<RSCommand> command = std::make_unique<RSFrameRateLinkerUpdateRange>(GetId(),
89             range, animatorExpectedFrameRate);
90         auto transactionProxy = RSTransactionProxy::GetInstance();
91         if (transactionProxy != nullptr) {
92             transactionProxy->AddCommand(command, IsUniRenderEnabled());
93         }
94     }
95 }
96 
UpdateFrameRateRangeImme(const FrameRateRange & range,int32_t animatorExpectedFrameRate)97 void RSFrameRateLinker::UpdateFrameRateRangeImme(const FrameRateRange& range, int32_t animatorExpectedFrameRate)
98 {
99     if (currentRange_ != range || currAnimatorExpectedFrameRate_ != animatorExpectedFrameRate) {
100         currentRange_ = range;
101         currAnimatorExpectedFrameRate_ = animatorExpectedFrameRate;
102         RSInterfaces::GetInstance().SyncFrameRateRange(GetId(), range, animatorExpectedFrameRate);
103     }
104 }
105 
SetEnable(bool enabled)106 void RSFrameRateLinker::SetEnable(bool enabled)
107 {
108     isEnabled_ = enabled;
109 }
110 
IsEnable()111 bool RSFrameRateLinker::IsEnable()
112 {
113     return isEnabled_;
114 }
115 
InitUniRenderEnabled()116 void RSFrameRateLinker::InitUniRenderEnabled()
117 {
118     static bool inited = false;
119     if (!inited) {
120         inited = true;
121         g_isUniRenderEnabled = RSSystemProperties::GetUniRenderEnabled();
122         ROSEN_LOGD("RSFrameRateLinker::InitUniRenderEnabled:%{public}d", g_isUniRenderEnabled);
123     }
124 }
125 } // namespace Rosen
126 } // namespace OHOS
127