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()88 void RSRenderServiceListener::OnCleanCache()
89 {
90 auto node = surfaceRenderNode_.lock();
91 if (node == nullptr) {
92 RS_LOGD("RSRenderServiceListener::OnBufferAvailable node is nullptr");
93 return;
94 }
95 RS_LOGD("RsDebug RSRenderServiceListener::OnCleanCache node id:%{public}" PRIu64, node->GetId());
96 node->GetRSSurfaceHandler()->ResetBufferAvailableCount();
97 RSMainThread::Instance()->PostTask([nodePtr = node]() {
98 nodePtr->NeedClearBufferCache();
99 });
100 }
101
OnGoBackground()102 void RSRenderServiceListener::OnGoBackground()
103 {
104 std::weak_ptr<RSSurfaceRenderNode> surfaceNode = surfaceRenderNode_;
105 RSMainThread::Instance()->PostTask([surfaceNode]() {
106 auto node = surfaceNode.lock();
107 if (node == nullptr) {
108 RS_LOGD("RSRenderServiceListener::OnBufferAvailable node is nullptr");
109 return;
110 }
111 auto surfaceHandler = node->GetMutableRSSurfaceHandler();
112 RS_LOGD("RsDebug RSRenderServiceListener::OnGoBackground node id:%{public}" PRIu64, node->GetId());
113 node->NeedClearBufferCache();
114 surfaceHandler->ResetBufferAvailableCount();
115 surfaceHandler->CleanCache();
116 node->UpdateBufferInfo(nullptr, {}, nullptr, nullptr);
117 node->SetNotifyRTBufferAvailable(false);
118 node->SetContentDirty();
119 node->ResetHardwareEnabledStates();
120 });
121 }
122
OnTransformChange()123 void RSRenderServiceListener::OnTransformChange()
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::OnTransformChange node is nullptr");
130 return;
131 }
132 RS_LOGD("RsDebug RSRenderServiceListener::OnTransformChange node id:%{public}" PRIu64, node->GetId());
133 node->SetContentDirty();
134 node->SetDoDirectComposition(false);
135 if (node->GetRSSurfaceHandler() != nullptr) {
136 node->GetRSSurfaceHandler()->SetBufferTransformTypeChanged(true);
137 }
138 });
139 }
140 } // namespace Rosen
141 } // namespace OHOS
142