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_rcd_render_visitor.h"
17 
18 #include "pipeline/rs_main_thread.h"
19 #include "rs_rcd_render_listener.h"
20 #include "rs_trace.h"
21 
22 namespace OHOS {
23 namespace Rosen {
RSRcdRenderVisitor()24 RSRcdRenderVisitor::RSRcdRenderVisitor()
25 {
26     renderEngine_ = RSUniRenderThread::Instance().GetRenderEngine();
27 }
28 
ConsumeAndUpdateBuffer(RSRcdSurfaceRenderNode & node)29 bool RSRcdRenderVisitor::ConsumeAndUpdateBuffer(RSRcdSurfaceRenderNode& node)
30 {
31     auto availableBufferCnt = node.GetAvailableBufferCount();
32     if (availableBufferCnt <= 0) {
33         // this node has no new buffer, try use old buffer.
34         return true;
35     }
36 
37     auto consumer = node.GetConsumer();
38     if (consumer == nullptr) {
39         return false;
40     }
41 
42     sptr<SurfaceBuffer> buffer;
43     sptr<SyncFence> acquireFence = SyncFence::InvalidFence();
44     int64_t timestamp = 0;
45     Rect damage;
46     auto ret = consumer->AcquireBuffer(buffer, acquireFence, timestamp, damage);
47     if (buffer == nullptr || ret != SURFACE_ERROR_OK) {
48         RS_LOGE("RsDebug RSRcdSurfaceRenderNode(id: %{public}" PRIu64 ") AcquireBuffer failed(ret: %{public}d)!",
49             node.GetNodeId(), ret);
50         return false;
51     }
52 
53     node.SetBuffer(buffer, acquireFence, damage, timestamp);
54 
55     if (!node.SetHardwareResourceToBuffer()) {
56         RS_LOGE("RSRcdRenderVisitor SetHardwareResourceToBuffer Failed!");
57         return false;
58     }
59 
60     node.SetCurrentFrameBufferConsumed();
61     node.ReduceAvailableBuffer();
62     return true;
63 }
64 
ProcessRcdSurfaceRenderNodeMainThread(RSRcdSurfaceRenderNode & node,bool resourceChanged)65 void RSRcdRenderVisitor::ProcessRcdSurfaceRenderNodeMainThread(RSRcdSurfaceRenderNode& node, bool resourceChanged)
66 {
67     if (uniProcessor_ == nullptr || node.IsInvalidSurface() || resourceChanged) {
68         RS_LOGE("RSRcdRenderVisitor RSProcessor is null or node invalid or resource is changed!");
69         return;
70     }
71 
72     sptr<SurfaceBuffer> buffer = node.GetBuffer();
73     if (buffer != nullptr) {
74         uniProcessor_->ProcessRcdSurface(node);
75         return;
76     }
77 }
78 
ProcessRcdSurfaceRenderNode(RSRcdSurfaceRenderNode & node,const std::shared_ptr<rs_rcd::RoundCornerLayer> & layerInfo,bool resourceChanged)79 bool RSRcdRenderVisitor::ProcessRcdSurfaceRenderNode(
80     RSRcdSurfaceRenderNode& node, const std::shared_ptr<rs_rcd::RoundCornerLayer> &layerInfo, bool resourceChanged)
81 {
82     std::lock_guard<std::mutex> lock(bufferMut_);
83     if (uniProcessor_ == nullptr || node.IsInvalidSurface() || renderEngine_ == nullptr) {
84         RS_LOGE("RSRcdRenderVisitor RSProcessor is null or node invalid!");
85         return false;
86     }
87 
88     sptr<SurfaceBuffer> buffer = node.GetBuffer();
89     if (!resourceChanged && buffer != nullptr) {
90         uniProcessor_->ProcessRcdSurface(node);
91         return true;
92     }
93 
94     auto surfaceNodePtr = node.ReinterpretCastTo<RSRcdSurfaceRenderNode>();
95     if (surfaceNodePtr == nullptr || (!node.IsSurfaceCreated())) {
96         sptr<IBufferConsumerListener> listener = new RSRcdRenderListener(surfaceNodePtr);
97         if (listener == nullptr || (!node.CreateSurface(listener))) {
98             RS_LOGE("RSRcdRenderVisitor::RenderExpandedFrame CreateSurface failed");
99             return false;
100         }
101     }
102 #ifdef NEW_RENDER_CONTEXT
103     auto rsSurface = std::static_pointer_cast<RSRenderSurfaceOhos>(node.GetRSSurface());
104 #else
105     auto rsSurface = std::static_pointer_cast<RSSurfaceOhos>(node.GetRSSurface());
106 #endif
107     if (rsSurface == nullptr || layerInfo == nullptr || (!node.PrepareHardwareResourceBuffer(layerInfo))) {
108         RS_LOGE("no RSSurface found or PrepareHardwareResourceBuffer is wrong");
109         return false;
110     }
111 
112     rsSurface->SetTimeOut(node.GetHardenBufferRequestConfig().timeout);
113     auto renderFrame = renderEngine_->RequestFrame(rsSurface,
114         node.GetHardenBufferRequestConfig(), true, false);
115     if (renderFrame == nullptr) {
116         rsSurface->GetSurface()->CleanCache(true);
117         RS_LOGE("RSRcdRenderVisitor Request Frame Failed");
118         return false;
119     }
120     renderFrame->Flush();
121     if (!ConsumeAndUpdateBuffer(node)) {
122         RS_LOGE("RSRcdRenderVisitor ConsumeAndUpdateBuffer Failed");
123         return false;
124     }
125     ScalingMode scalingMode = ScalingMode::SCALING_MODE_SCALE_TO_WINDOW;
126     if (node.GetConsumer() && node.GetBuffer()) {
127         node.GetConsumer()->SetScalingMode(node.GetBuffer()->GetSeqNum(), scalingMode);
128     }
129 
130     uniProcessor_->ProcessRcdSurface(node);
131     return true;
132 }
133 
SetUniProcessor(std::shared_ptr<RSProcessor> processor)134 void RSRcdRenderVisitor::SetUniProcessor(std::shared_ptr<RSProcessor> processor)
135 {
136     uniProcessor_ = processor;
137 }
138 } // namespace Rosen
139 } // namespace OHOS