• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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