1 /*
2 * Copyright (c) 2021-2022 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 "pipeline/rs_render_service_listener.h"
17
18 #include "platform/common/rs_log.h"
19 #include "pipeline/rs_main_thread.h"
20 #include "frame_report.h"
21 #include "sync_fence.h"
22 #include "pipeline/rs_uni_render_thread.h"
23 #include "rs_trace.h"
24 namespace OHOS {
25 namespace Rosen {
26
~RSRenderServiceListener()27 RSRenderServiceListener::~RSRenderServiceListener() {}
28
RSRenderServiceListener(std::weak_ptr<RSSurfaceRenderNode> surfaceRenderNode)29 RSRenderServiceListener::RSRenderServiceListener(std::weak_ptr<RSSurfaceRenderNode> surfaceRenderNode)
30 : surfaceRenderNode_(surfaceRenderNode)
31 {}
32
OnBufferAvailable()33 void RSRenderServiceListener::OnBufferAvailable()
34 {
35 auto node = surfaceRenderNode_.lock();
36 if (node == nullptr) {
37 RS_LOGD("RSRenderServiceListener::OnBufferAvailable node is nullptr");
38 return;
39 }
40 RS_LOGD("RsDebug RSRenderServiceListener::OnBufferAvailable node id:%{public}" PRIu64, node->GetId());
41 auto surfaceHandler = node->GetMutableRSSurfaceHandler();
42 surfaceHandler->IncreaseAvailableBuffer();
43 if (auto consumer = surfaceHandler->GetConsumer()) {
44 uint64_t uniqueId = consumer->GetUniqueId();
45 bool isActiveGame = FrameReport::GetInstance().IsActiveGameWithUniqueId(uniqueId);
46 if (isActiveGame) {
47 std::string name = node->GetName();
48 FrameReport::GetInstance().SetPendingBufferNum(name, surfaceHandler->GetAvailableBufferCount());
49 }
50 }
51
52 if (!node->IsNotifyUIBufferAvailable()) {
53 // Only ipc for one time.
54 RS_LOGD("RsDebug RSRenderServiceListener::OnBufferAvailable id = %{public}" PRIu64 " Notify"
55 " UI buffer available", node->GetId());
56 node->NotifyUIBufferAvailable();
57 }
58 if (node->GetIsTextureExportNode()) {
59 RS_LOGD("RsDebug RSRenderServiceListener::OnBufferAvailable id = %{public}" PRIu64 " Notify"
60 " RT buffer available", node->GetId());
61 node->NotifyRTBufferAvailable(node->GetIsTextureExportNode());
62 }
63 if (node->IsLayerTop()) {
64 // Ensure that the compose task is completed within single frame
65 RSMainThread::Instance()->ForceRefreshForUni();
66 return;
67 }
68 RSMainThread::Instance()->RequestNextVSync();
69 }
70
OnTunnelHandleChange()71 void RSRenderServiceListener::OnTunnelHandleChange()
72 {
73 auto node = surfaceRenderNode_.lock();
74 if (node == nullptr) {
75 RS_LOGE("RSRenderServiceListener::OnTunnelHandleChange node is nullptr");
76 return;
77 }
78 node->SetTunnelHandleChange(true);
79 if (!node->IsNotifyUIBufferAvailable()) {
80 // Only ipc for one time.
81 RS_LOGD("RsDebug RSRenderServiceListener::OnTunnelHandleChange id = %{public}" PRIu64 " Notify"
82 " UI buffer available", node->GetId());
83 node->NotifyUIBufferAvailable();
84 }
85 RSMainThread::Instance()->RequestNextVSync();
86 }
87
OnCleanCache(uint32_t * bufSeqNum)88 void RSRenderServiceListener::OnCleanCache(uint32_t *bufSeqNum)
89 {
90 auto node = surfaceRenderNode_.lock();
91 if (node == nullptr) {
92 RS_LOGD("RSRenderServiceListener::OnCleanCache node is nullptr");
93 return;
94 }
95 RS_LOGD("RsDebug RSRenderServiceListener::OnCleanCache node id:%{public}" PRIu64, node->GetId());
96
97 auto surfaceHandler = node->GetRSSurfaceHandler();
98 if (surfaceHandler) {
99 auto curBuffer = surfaceHandler->GetBuffer();
100 if (curBuffer && bufSeqNum) {
101 *bufSeqNum = curBuffer->GetSeqNum();
102 }
103 surfaceHandler->ResetBufferAvailableCount();
104 }
105 std::weak_ptr<RSSurfaceRenderNode> surfaceNode = surfaceRenderNode_;
106 RSMainThread::Instance()->PostTask([surfaceNode]() {
107 auto node = surfaceNode.lock();
108 if (node == nullptr) {
109 RS_LOGD("RSRenderServiceListener::OnCleanCache node is nullptr");
110 return;
111 }
112 auto surfaceHandler = node->GetRSSurfaceHandler();
113 if (surfaceHandler == nullptr) {
114 RS_LOGD("RSRenderServiceListener::OnCleanCache surfaceHandler is nullptr");
115 return;
116 }
117 RS_LOGD("RsDebug RSRenderServiceListener::OnCleanCache in mainthread node id:%{public}" PRIu64, node->GetId());
118 surfaceHandler->ResetPreBuffer();
119 node->NeedClearPreBuffer();
120 });
121 }
122
OnGoBackground()123 void RSRenderServiceListener::OnGoBackground()
124 {
125 std::weak_ptr<RSSurfaceRenderNode> surfaceNode = surfaceRenderNode_;
126 RSMainThread::Instance()->PostTask([surfaceNode]() {
127 auto node = surfaceNode.lock();
128 if (node == nullptr) {
129 RS_LOGD("RSRenderServiceListener::OnBufferAvailable node is nullptr");
130 return;
131 }
132 auto surfaceHandler = node->GetMutableRSSurfaceHandler();
133 RS_LOGD("RsDebug RSRenderServiceListener::OnGoBackground node id:%{public}" PRIu64, node->GetId());
134 node->NeedClearBufferCache();
135 surfaceHandler->ResetBufferAvailableCount();
136 surfaceHandler->CleanCache();
137 node->UpdateBufferInfo(nullptr, {}, nullptr, nullptr);
138 node->SetNotifyRTBufferAvailable(false);
139 node->SetContentDirty();
140 node->ResetHardwareEnabledStates();
141 });
142 }
143
OnTransformChange()144 void RSRenderServiceListener::OnTransformChange()
145 {
146 std::weak_ptr<RSSurfaceRenderNode> surfaceNode = surfaceRenderNode_;
147 RSMainThread::Instance()->PostTask([surfaceNode]() {
148 auto node = surfaceNode.lock();
149 if (node == nullptr) {
150 RS_LOGD("RSRenderServiceListener::OnTransformChange node is nullptr");
151 return;
152 }
153 RS_LOGD("RsDebug RSRenderServiceListener::OnTransformChange node id:%{public}" PRIu64, node->GetId());
154 node->SetContentDirty();
155 node->SetDoDirectComposition(false);
156 if (node->GetRSSurfaceHandler() != nullptr) {
157 node->GetRSSurfaceHandler()->SetBufferTransformTypeChanged(true);
158 }
159 });
160 }
161 } // namespace Rosen
162 } // namespace OHOS
163