1 /*
2 * Copyright (c) 2022-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 "pipeline/rs_hardware_thread.h"
17
18 #include "hgm_core.h"
19 #include "pipeline/rs_base_render_util.h"
20 #include "pipeline/rs_uni_render_util.h"
21 #include "pipeline/rs_main_thread.h"
22 #include "pipeline/rs_uni_render_engine.h"
23 #include "platform/common/rs_log.h"
24 #include "platform/common/rs_system_properties.h"
25 #include "screen_manager/rs_screen_manager.h"
26 #include "rs_trace.h"
27 #include "hdi_backend.h"
28
29 #ifdef RS_ENABLE_EGLIMAGE
30 #include "rs_egl_image_manager.h"
31 #endif // RS_ENABLE_EGLIMAGE
32
33 namespace OHOS::Rosen {
Instance()34 RSHardwareThread& RSHardwareThread::Instance()
35 {
36 static RSHardwareThread instance;
37 return instance;
38 }
39
Start()40 void RSHardwareThread::Start()
41 {
42 RS_LOGI("RSHardwareThread::Start()!");
43 hdiBackend_ = HdiBackend::GetInstance();
44 runner_ = AppExecFwk::EventRunner::Create("RSHardwareThread");
45 handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
46 redrawCb_ = std::bind(&RSHardwareThread::Redraw, this,std::placeholders::_1, std::placeholders::_2,
47 std::placeholders::_3);
48 if (handler_) {
49 ScheduleTask(
50 [this]() {
51 auto screenManager = CreateOrGetScreenManager();
52 if (screenManager == nullptr || !screenManager->Init()) {
53 RS_LOGE("RSHardwareThread CreateOrGetScreenManager or init fail.");
54 return;
55 }
56 uniRenderEngine_ = std::make_shared<RSUniRenderEngine>();
57 uniRenderEngine_->Init();
58 }).wait();
59 }
60 auto onPrepareCompleteFunc = [this](auto& surface, const auto& param, void* data) {
61 OnPrepareComplete(surface, param, data);
62 };
63 if (hdiBackend_ != nullptr) {
64 hdiBackend_->RegPrepareComplete(onPrepareCompleteFunc, this);
65 }
66 }
67
PostTask(const std::function<void ()> & task)68 void RSHardwareThread::PostTask(const std::function<void()>& task)
69 {
70 if (handler_) {
71 handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
72 }
73 }
74
ReleaseBuffer(sptr<SurfaceBuffer> buffer,sptr<SyncFence> releaseFence,sptr<IConsumerSurface> cSurface)75 void RSHardwareThread::ReleaseBuffer(sptr<SurfaceBuffer> buffer, sptr<SyncFence> releaseFence,
76 sptr<IConsumerSurface> cSurface)
77 {
78 if (cSurface == nullptr) {
79 RS_LOGE("RsDebug RSHardwareThread:: ReleaseBuffer failed, no consumer!");
80 return;
81 }
82
83 if (buffer != nullptr) {
84 RS_TRACE_NAME("RSHardwareThread::ReleaseBuffer");
85 auto ret = cSurface->ReleaseBuffer(buffer, releaseFence);
86 if (ret != OHOS::SURFACE_ERROR_OK) {
87 return;
88 }
89 // reset prevBuffer if we release it successfully,
90 // to avoid releasing the same buffer next frame in some situations.
91 buffer = nullptr;
92 releaseFence = SyncFence::INVALID_FENCE;
93 }
94 }
95
ReleaseLayers(OutputPtr output,const std::unordered_map<uint32_t,LayerPtr> & layerMap)96 void RSHardwareThread::ReleaseLayers(OutputPtr output, const std::unordered_map<uint32_t, LayerPtr>& layerMap)
97 {
98 // get present timestamp from and set present timestamp to surface
99 for (const auto& [id, layer] : layerMap) {
100 if (layer == nullptr || layer->GetLayerInfo()->GetSurface() == nullptr) {
101 RS_LOGW("RSHardwareThread::ReleaseLayers: layer or layer's cSurface is nullptr");
102 continue;
103 }
104 LayerPresentTimestamp(layer->GetLayerInfo(), layer->GetLayerInfo()->GetSurface());
105 }
106
107 // set all layers' releaseFence.
108 if (output == nullptr) {
109 RS_LOGE("RSHardwareThread::ReleaseLayers: output is nullptr");
110 return;
111 }
112 const auto layersReleaseFence = output->GetLayersReleaseFence();
113 if (layersReleaseFence.size() == 0) {
114 RS_LOGE("RSHardwareThread::ReleaseLayers: no layer needs to release");
115 }
116 for (const auto& [layer, fence] : layersReleaseFence) {
117 if (layer == nullptr) {
118 continue;
119 }
120 auto preBuffer = layer->GetPreBuffer();
121 auto consumer = layer->GetSurface();
122 ReleaseBuffer(preBuffer, fence, consumer);
123 }
124 RSMainThread::Instance()->NotifyDisplayNodeBufferReleased();
125 }
126
CommitAndReleaseLayers(OutputPtr output,const std::vector<LayerInfoPtr> & layers)127 void RSHardwareThread::CommitAndReleaseLayers(OutputPtr output, const std::vector<LayerInfoPtr>& layers)
128 {
129 if (!handler_) {
130 RS_LOGE("RSHardwareThread::CommitAndReleaseLayers handler is nullptr");
131 return;
132 }
133 RSTaskMessage::RSTask task = [this, output = output, layers = layers]() {
134 RS_TRACE_NAME("RSHardwareThread::CommitAndReleaseLayers");
135 PerformSetActiveMode();
136 output->SetLayerInfo(layers);
137 hdiBackend_->Repaint(output);
138 auto layerMap = output->GetLayers();
139 ReleaseLayers(output, layerMap);
140 };
141 PostTask(task);
142 }
143
PerformSetActiveMode()144 void RSHardwareThread::PerformSetActiveMode()
145 {
146 auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
147 auto screenManager = CreateOrGetScreenManager();
148 if (screenManager == nullptr) {
149 RS_LOGE("RSHardwareThread CreateOrGetScreenManager fail.");
150 return;
151 }
152
153 HgmRefreshRates newRate = RSSystemProperties::GetHgmRefreshRatesEnabled();
154 HgmRefreshRateModes newRateMode = RSSystemProperties::GetHgmRefreshRateModesEnabled();
155 if (hgmRefreshRates_ != newRate) {
156 hgmRefreshRates_ = newRate;
157 hgmCore.SetScreenRefreshRate(screenManager->GetDefaultScreenId(), 0, static_cast<int32_t>(hgmRefreshRates_));
158 }
159 if (hgmRefreshRateModes_ != newRateMode) {
160 hgmRefreshRateModes_ = newRateMode;
161 hgmCore.SetRefreshRateMode(static_cast<RefreshRateMode>(hgmRefreshRateModes_));
162 }
163
164 if (lockRefreshRateOnce_ == false) {
165 hgmCore.SetDefaultRefreshRateMode();
166 lockRefreshRateOnce_ = true;
167 }
168
169 std::unique_ptr<std::unordered_map<ScreenId, int32_t>> modeMap(hgmCore.GetModesToApply());
170 if (modeMap == nullptr) {
171 return;
172 }
173
174 RS_TRACE_NAME("RSHardwareThread::PerformSetActiveMode setting active mode");
175 for (auto mapIter = modeMap->begin(); mapIter != modeMap->end(); ++mapIter) {
176 ScreenId id = mapIter->first;
177 int32_t modeId = mapIter->second;
178
179 auto supportedModes = screenManager->GetScreenSupportedModes(id);
180 for (auto mode : supportedModes) {
181 std::string temp = "RSHardwareThread check modes w: " + std::to_string(mode.GetScreenWidth()) +
182 ", h: " + std::to_string(mode.GetScreenHeight()) +
183 ", rate: " + std::to_string(mode.GetScreenRefreshRate()) +
184 ", id: " + std::to_string(mode.GetScreenModeId());
185 RS_LOGD(temp.c_str());
186 }
187
188 screenManager->SetScreenActiveMode(id, modeId);
189 }
190 }
191
OnPrepareComplete(sptr<Surface> & surface,const PrepareCompleteParam & param,void * data)192 void RSHardwareThread::OnPrepareComplete(sptr<Surface>& surface,
193 const PrepareCompleteParam& param, void* data)
194 {
195 // unused data.
196 (void)(data);
197
198 if (!param.needFlushFramebuffer) {
199 return;
200 }
201
202 if (redrawCb_ != nullptr) {
203 redrawCb_(surface, param.layers, param.screenId);
204 }
205 }
206
Redraw(const sptr<Surface> & surface,const std::vector<LayerInfoPtr> & layers,uint32_t screenId)207 void RSHardwareThread::Redraw(const sptr<Surface>& surface, const std::vector<LayerInfoPtr>& layers, uint32_t screenId)
208 {
209 RS_TRACE_NAME("RSHardwareThread::Redraw");
210 if (surface == nullptr) {
211 RS_LOGE("RSHardwareThread::Redraw: surface is null.");
212 return;
213 }
214
215 RS_LOGD("RsDebug RSHardwareThread::Redraw flush frame buffer start");
216 bool forceCPU = RSBaseRenderEngine::NeedForceCPU(layers);
217 auto screenManager = CreateOrGetScreenManager();
218 auto screenInfo = screenManager->QueryScreenInfo(screenId);
219 auto renderFrameConfig = RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo, true);
220 auto renderFrame = uniRenderEngine_->RequestFrame(surface, renderFrameConfig, forceCPU);
221 if (renderFrame == nullptr) {
222 RS_LOGE("RsDebug RSHardwareThread::Redraw:failed to request frame.");
223 return;
224 }
225 auto canvas = renderFrame->GetCanvas();
226 if (canvas == nullptr) {
227 RS_LOGE("RsDebug RSHardwareThread::Redraw:canvas is nullptr.");
228 return;
229 }
230 #ifdef RS_ENABLE_EGLIMAGE
231 std::unordered_map<int32_t, std::unique_ptr<ImageCacheSeq>> imageCacheSeqs;
232 #endif
233 for (const auto& layer : layers) {
234 if (layer == nullptr) {
235 continue;
236 }
237 if (layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE ||
238 layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE_CLEAR) {
239 continue;
240 }
241 #ifndef USE_ROSEN_DRAWING
242 auto saveCount = canvas->getSaveCount();
243
244 canvas->save();
245 auto dstRect = layer->GetLayerSize();
246 SkRect clipRect = SkRect::MakeXYWH(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y),
247 static_cast<float>(dstRect.w), static_cast<float>(dstRect.h));
248 canvas->clipRect(clipRect);
249
250 // prepare BufferDrawParam
251 auto params = RSUniRenderUtil::CreateLayerBufferDrawParam(layer, forceCPU);
252 canvas->concat(params.matrix);
253 #else
254 auto saveCount = canvas->GetSaveCount();
255
256 canvas->Save();
257 auto dstRect = layer->GetLayerSize();
258 Drawing::Rect clipRect = Drawing::Rect(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y),
259 static_cast<float>(dstRect.w) + static_cast<float>(dstRect.x),
260 static_cast<float>(dstRect.h) + static_cast<float>(dstRect.y));
261 canvas->ClipRect(clipRect, Drawing::ClipOp::INTERSECT, false);
262
263 // prepare BufferDrawParam
264 auto params = RSUniRenderUtil::CreateLayerBufferDrawParam(layer, forceCPU);
265 canvas->ConcatMatrix(params.matrix);
266 #endif
267 #ifndef RS_ENABLE_EGLIMAGE
268 uniRenderEngine_->DrawBuffer(*canvas, params);
269 #else
270 if (!params.useCPU) {
271 if (!RSBaseRenderUtil::IsBufferValid(params.buffer)) {
272 RS_LOGE("RSHardwareThread::Redraw CreateEglImageFromBuffer invalid param!");
273 continue;
274 }
275 #ifndef USE_ROSEN_DRAWING
276 #ifdef NEW_SKIA
277 if (canvas->recordingContext() == nullptr) {
278 #else
279 if (canvas->getGrContext() == nullptr) {
280 #endif
281 #else
282 if (canvas->GetGPUContext() == nullptr) {
283 #endif
284 RS_LOGE("RSBaseRenderEngine::CreateEglImageFromBuffer GrContext is null!");
285 continue;
286 }
287 auto eglImageCache = uniRenderEngine_->GetEglImageManager()->CreateImageCacheFromBuffer(params.buffer,
288 params.acquireFence);
289 if (eglImageCache == nullptr) {
290 continue;
291 }
292 auto eglTextureId = eglImageCache->TextureId();
293 if (eglTextureId == 0) {
294 RS_LOGE("RSHardwareThread::Redraw CreateImageCacheFromBuffer return invalid texture ID");
295 continue;
296 }
297 auto bufferId = params.buffer->GetSeqNum();
298 imageCacheSeqs[bufferId] = std::move(eglImageCache);
299 #ifndef USE_ROSEN_DRAWING
300 SkColorType colorType = (params.buffer->GetFormat() == GRAPHIC_PIXEL_FMT_BGRA_8888) ?
301 kBGRA_8888_SkColorType : kRGBA_8888_SkColorType;
302 GrGLTextureInfo grExternalTextureInfo = { GL_TEXTURE_EXTERNAL_OES, eglTextureId, GL_RGBA8 };
303 GrBackendTexture backendTexture(params.buffer->GetSurfaceBufferWidth(),
304 params.buffer->GetSurfaceBufferHeight(), GrMipMapped::kNo, grExternalTextureInfo);
305 #ifdef NEW_SKIA
306 auto image = SkImage::MakeFromTexture(canvas->recordingContext(), backendTexture,
307 kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, nullptr);
308 #else
309 auto image = SkImage::MakeFromTexture(canvas->getGrContext(), backendTexture,
310 kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, nullptr);
311 #endif
312 if (image == nullptr) {
313 RS_LOGE("RSDividedRenderUtil::DrawImage: image is nullptr!");
314 return;
315 }
316 #ifdef NEW_SKIA
317 RS_TRACE_NAME_FMT("DrawImage(GPU) seqNum: %d", bufferId);
318 canvas->drawImageRect(image, params.srcRect, params.dstRect, SkSamplingOptions(),
319 &(params.paint), SkCanvas::kStrict_SrcRectConstraint);
320 #else
321 RS_TRACE_NAME_FMT("DrawImage(GPU) seqNum: %d", bufferId);
322 canvas->drawImageRect(image, params.srcRect, params.dstRect, &(params.paint));
323 #endif
324 #else // USE_ROSEN_DRAWING
325 Drawing::ColorType colorType = (params.buffer->GetFormat() == GRAPHIC_PIXEL_FMT_BGRA_8888) ?
326 Drawing::ColorType::COLORTYPE_BGRA_8888 : Drawing::ColorType::COLORTYPE_RGBA_8888;
327 Drawing::BitmapFormat bitmapFormat = { colorType, Drawing::AlphaType::ALPHATYPE_PREMUL };
328
329 Drawing::TextureInfo externalTextureInfo;
330 externalTextureInfo.SetWidth(params.buffer->GetSurfaceBufferWidth());
331 externalTextureInfo.SetHeight(params.buffer->GetSurfaceBufferHeight());
332 externalTextureInfo.SetIsMipMapped(false);
333 externalTextureInfo.SetTarget(GL_TEXTURE_EXTERNAL_OES);
334 externalTextureInfo.SetID(eglTextureId);
335 externalTextureInfo.SetFormat(GL_RGBA8);
336
337 auto image = std::make_shared<Drawing::Image>();
338 if (!image->BuildFromTexture(*canvas->GetGPUContext(), externalTextureInfo,
339 Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, nullptr)) {
340 RS_LOGE("RSDividedRenderUtil::DrawImage: image BuildFromTexture failed");
341 return;
342 }
343 canvas->AttachBrush(params.paint);
344 RS_TRACE_NAME_FMT("DrawImage(GPU) seqNum: %d", bufferId);
345 canvas->DrawImageRect(*image, params.srcRect, params.dstRect,
346 Drawing::SamplingOptions(), Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
347 canvas->DetachBrush();
348 #endif // USE_ROSEN_DRAWING
349 } else {
350 uniRenderEngine_->DrawBuffer(*canvas, params);
351 }
352 #endif
353 #ifndef USE_ROSEN_DRAWING
354 canvas->restore();
355 canvas->restoreToCount(saveCount);
356 #else
357 canvas->Restore();
358 canvas->RestoreToCount(saveCount);
359 #endif
360 }
361 renderFrame->Flush();
362 #ifdef RS_ENABLE_EGLIMAGE
363 imageCacheSeqs.clear();
364 #endif
365 RS_LOGD("RsDebug RSHardwareThread::Redraw flush frame buffer end");
366 }
367
368 // private func, guarantee the layer and surface are valid
369 void RSHardwareThread::LayerPresentTimestamp(const LayerInfoPtr& layer, const sptr<IConsumerSurface>& surface) const
370 {
371 if (!layer->IsSupportedPresentTimestamp()) {
372 return;
373 }
374 const auto& buffer = layer->GetBuffer();
375 if (buffer == nullptr) {
376 return;
377 }
378 if (surface->SetPresentTimestamp(buffer->GetSeqNum(), layer->GetPresentTimestamp()) != GSERROR_OK) {
379 RS_LOGD("RsDebug RSUniRenderComposerAdapter::LayerPresentTimestamp: SetPresentTimestamp failed");
380 }
381 }
382 }
383