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