1 /*
2 * Copyright (c) 2025 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 "feature/hpae/rs_hpae_buffer.h"
17
18 #include "feature/hpae/rs_hpae_render_listener.h"
19 #include "hpae_base/rs_hpae_log.h"
20
21 #include "pipeline/main_thread/rs_main_thread.h"
22 #include "pipeline/render_thread/rs_base_render_engine.h"
23 #include "pipeline/render_thread/rs_uni_render_thread.h"
24 #include "pipeline/render_thread/rs_uni_render_util.h"
25 #include "pipeline/rs_surface_handler.h"
26 #include "platform/common/rs_log.h"
27 #ifdef RS_ENABLE_VK
28 #include "platform/ohos/backend/rs_surface_ohos_vulkan.h"
29 #endif
30
31 namespace OHOS::Rosen {
32 namespace DrawableV2 {
33
RSHpaeBuffer(const std::string & name,const int layerId)34 RSHpaeBuffer::RSHpaeBuffer(const std::string& name, const int layerId)
35 {
36 layerName_ = name;
37 surfaceHandler_ = std::make_shared<RSSurfaceHandler>(layerId);
38 }
39
~RSHpaeBuffer()40 RSHpaeBuffer::~RSHpaeBuffer()
41 {
42 }
43
44 // reference to RSDisplayRenderNodeDrawable::RequestFrame
RequestFrame(const BufferRequestConfig & config,bool isHebc)45 std::unique_ptr<RSRenderFrame> RSHpaeBuffer::RequestFrame(const BufferRequestConfig& config, bool isHebc)
46 {
47 #if defined(ROSEN_OHOS) && defined(ENABLE_HPAE_BLUR)
48 HPAE_TRACE_NAME("RSHpaeBuffer:RequestFrame");
49 bufferConfig_ = config;
50 std::shared_ptr<RSBaseRenderEngine> uniRenderEngine = RSUniRenderThread::Instance().GetRenderEngine();
51 if (UNLIKELY(!uniRenderEngine)) {
52 RS_LOGE("RSHpaeBuffer::RequestFrame RenderEngine is null!");
53 return nullptr;
54 }
55
56 if (grContext_ == nullptr) {
57 if (uniRenderEngine->GetRenderContext()) {
58 grContext_ = uniRenderEngine->GetRenderContext()->GetSharedDrGPUContext();
59 } else {
60 HPAE_TRACE_NAME("Exception: context is nullptr");
61 return nullptr;
62 }
63 }
64
65 if (!surfaceCreated_) {
66 sptr<IBufferConsumerListener> listener = new RSHpaeRenderListener(surfaceHandler_);
67 HPAE_TRACE_NAME("create layer surface");
68 if (!CreateSurface(listener)) {
69 RS_LOGE("RSHpaeBuffer::RequestFrame CreateSurface failed");
70 return nullptr;
71 }
72 }
73
74 if (rsSurface_ == nullptr) {
75 RS_LOGE("RSHpaeBuffer::RequestFrame: surface is null!");
76 return nullptr;
77 }
78
79 auto renderFrame = uniRenderEngine->RequestFrame(std::static_pointer_cast<RSSurfaceOhos>(rsSurface_),
80 config, false, isHebc);
81 if (!renderFrame) {
82 RS_LOGE("RSHpaeBuffer::RequestFrame renderEngine requestFrame is null");
83 return nullptr;
84 }
85
86 return renderFrame;
87 #else
88 return nullptr;
89 #endif
90 }
91
FlushFrame()92 bool RSHpaeBuffer::FlushFrame()
93 {
94 #if defined(ROSEN_OHOS) && defined(ENABLE_HPAE_BLUR)
95 if (!producerSurface_ || !surfaceHandler_) {
96 RS_LOGE("RSHpaeBuffer::FlushFrame producerSurface_ or surfaceHandler_ is nullptr");
97 return false;
98 }
99 BufferFlushConfig flushConfig_ = {
100 .damage = {
101 .x = 0,
102 .y = 0,
103 .w = bufferConfig_.width,
104 .h = bufferConfig_.height,
105 },
106 };
107 HPAE_TRACE_NAME_FMT("RSHpaeBuffer::FlushFrame: %p", surfaceHandler_->GetBuffer().GetRefPtr());
108
109 auto fbBuffer = rsSurface_->GetCurrentBuffer();
110
111 SurfaceError err = producerSurface_->FlushBuffer(fbBuffer, -1, flushConfig_);
112 if (err != SURFACE_ERROR_OK) {
113 int errval = err;
114 RS_LOGE("RSHpaeBuffer::Flushframe Failed, error is : %{public}s, errval:%{public}d",
115 SurfaceErrorStr(err).c_str(), errval);
116 return false;
117 }
118 return true;
119 #else
120 return false;
121 #endif
122 }
123
ForceDropFrame(uint64_t presentWhen)124 GSError RSHpaeBuffer::ForceDropFrame(uint64_t presentWhen)
125 {
126 #if defined(ROSEN_OHOS) && defined(ENABLE_HPAE_BLUR)
127 if (!surfaceHandle_) {
128 RS_LOGE("RSHpaeBuffer::ForceDropFrame surfaceHandler_ is nullptr");
129 return OHOS::GSERROR_NOT_INIT;
130 }
131 const auto surfaceConsumer = surfaceHandler_->GetConsumer();
132 if (surfaceConsumer == nullptr) {
133 RS_LOGE("RsDebug RSHpaeBuffer::DropFrame (node: %{public}" PRIu64 "): surfaceConsumer is null!",
134 surfaceHandler_->GetNodeId());
135 return OHOS::GSERROR_NO_CONSUMER;
136 }
137
138 IConsumerSurface::AcquireBufferReturnValue returnValue;
139 returnValue.fence = SyncFence::InvalidFence();
140 int32_t ret = surfaceConsumer->AcquireBuffer(returnValue, static_cast<int64_t>(presentWhen), false);
141 if (ret != OHOS::SURFACE_ERROR_OK) {
142 RS_LOGE("RSHpaeBuffer::DropFrameProcess(node: %{public}" PRIu64 "): AcquireBuffer failed("
143 " ret: %{public}d), do nothing ", surfaceHandler_->GetNodeId(), ret);
144 return OHOS::GSERROR_NO_BUFFER;
145 }
146
147 HPAE_TRACE_NAME_FMT("Force drop: DropFrame: %p, %p", returnValue.buffer.GetRefPtr(),
148 surfaceHandler_->GetBuffer().GetRefPtr());
149 ret = surfaceConsumer->ReleaseBuffer(returnValue.buffer, returnValue.fence);
150 if (ret != OHOS::SURFACE_ERROR_OK) {
151 RS_LOGE("RSHpaeBuffer::DropFrameProcess(node: %{public}" PRIu64
152 "): ReleaseBuffer failed(ret: %{public}d), Acquire done ",
153 surfaceHandler_->GetNodeId(), ret);
154 }
155 surfaceHandler_->SetAvailiableBufferCount(static_cast<int32_t>(surfaceConsumer->GetAvailableBufferCount()));
156 RS_LOGD("RsDebug RSHpaeBuffer::DropFrameProcess (node: %{public}" PRIu64 "), drop one frame",
157 surfaceHandler_->GetNodeId());
158
159 return OHOS::GSERROR_OK;
160 #else
161 return GSERROR_NOT_INIT;
162 #endif
163 }
164
165 #if defined(ROSEN_OHOS)
166 // reference to RSDisplayRenderNodeDrawable::CreateSurface
CreateSurface(sptr<IBufferConsumerListener> listener)167 bool RSHpaeBuffer::CreateSurface(sptr<IBufferConsumerListener> listener)
168 {
169 auto consumer = surfaceHandler_->GetConsumer();
170 if (consumer != nullptr && rsSurface_ != nullptr) {
171 RS_LOGI("RSHpaeBuffer::CreateSurface already created, return");
172 return true;
173 }
174 consumer = IConsumerSurface::Create(layerName_);
175 if (consumer == nullptr) {
176 RS_LOGE("RSHpaeBuffer::CreateSurface get consumer surface fail");
177 return false;
178 }
179 SurfaceError ret = consumer->RegisterConsumerListener(listener);
180 if (ret != SURFACE_ERROR_OK) {
181 RS_LOGE("RSHpaeBuffer::CreateSurface RegisterConsumerListener fail");
182 return false;
183 }
184 auto producer = consumer->GetProducer();
185 producerSurface_ = Surface::CreateSurfaceAsProducer(producer);
186 if (!producerSurface_) {
187 RS_LOGE("RSHpaeBuffer::CreateSurface CreateSurfaceAsProducer fail");
188 return false;
189 }
190 producerSurface_->SetQueueSize(HPAE_BUFFER_SIZE);
191
192 auto client = std::static_pointer_cast<RSRenderServiceClient>(RSIRenderClient::CreateRenderServiceClient());
193 auto surface = client->CreateRSSurface(producerSurface_);
194 rsSurface_ = std::static_pointer_cast<RSSurfaceOhos>(surface);
195 RS_LOGI("RSHpaeBuffer::CreateSurface end");
196 surfaceCreated_ = true;
197 surfaceHandler_->SetConsumer(consumer);
198
199 return true;
200 }
201 #endif
202
GetBufferHandle()203 void* RSHpaeBuffer::GetBufferHandle()
204 {
205 #if defined(ROSEN_OHOS) && defined(ENABLE_HPAE_BLUR)
206 if (UNLIKELY(!rsSurface_)) {
207 HPAE_LOGE("surface not exist");
208 return nullptr;
209 }
210
211 auto buffer = rsSurface_->GetCurrentBuffer();
212 if (buffer) {
213 bufferHandle_ = buffer->GetBufferHandle();
214 HPAE_TRACE_NAME_FMT("getBufferHandle: %p", bufferHandle_);
215 return bufferHandle_;
216 }
217 #endif
218 return nullptr;
219 }
220
221 } // DrawableV2
222 } // OHOS::Rosen