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 <memory>
19 #include <unistd.h>
20
21 #include "frame_report.h"
22 #include "hdi_backend.h"
23 #include "hgm_core.h"
24 #include "hgm_frame_rate_manager.h"
25 #include "parameters.h"
26 #include "rs_realtime_refresh_rate_manager.h"
27 #include "rs_trace.h"
28 #include "vsync_sampler.h"
29
30 #include "common/rs_optional_trace.h"
31 #include "common/rs_singleton.h"
32 #include "pipeline/rs_base_render_util.h"
33 #include "pipeline/rs_main_thread.h"
34 #include "pipeline/rs_uni_render_engine.h"
35 #include "pipeline/rs_uni_render_thread.h"
36 #include "pipeline/rs_uni_render_util.h"
37 #include "platform/common/rs_log.h"
38 #include "platform/common/rs_system_properties.h"
39 #include "platform/ohos/backend/rs_surface_ohos_gl.h"
40 #include "platform/ohos/backend/rs_surface_ohos_raster.h"
41 #include "screen_manager/rs_screen_manager.h"
42
43 #ifdef RS_ENABLE_EGLIMAGE
44 #include "src/gpu/gl/GrGLDefines.h"
45 #endif
46
47 #ifdef RS_ENABLE_VK
48 #include "platform/ohos/backend/rs_surface_ohos_vulkan.h"
49 #include "rs_vk_image_manager.h"
50 #endif
51
52 #ifdef RS_ENABLE_EGLIMAGE
53 #include "rs_egl_image_manager.h"
54 #endif // RS_ENABLE_EGLIMAGE
55
56 #ifdef USE_VIDEO_PROCESSING_ENGINE
57 #include "metadata_helper.h"
58 #endif
59
60 #ifdef RES_SCHED_ENABLE
61 #include "system_ability_definition.h"
62 #include "if_system_ability_manager.h"
63 #include <iservice_registry.h>
64 #include "ressched_event_listener.h"
65 #endif
66
67 namespace OHOS::Rosen {
68 namespace {
69 constexpr uint32_t HARDWARE_THREAD_TASK_NUM = 2;
70 }
71
Instance()72 RSHardwareThread& RSHardwareThread::Instance()
73 {
74 static RSHardwareThread instance;
75 return instance;
76 }
77
Start()78 void RSHardwareThread::Start()
79 {
80 RS_LOGI("RSHardwareThread::Start()!");
81 hdiBackend_ = HdiBackend::GetInstance();
82 runner_ = AppExecFwk::EventRunner::Create("RSHardwareThread");
83 handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
84 redrawCb_ = [this](const sptr<Surface>& surface, const std::vector<LayerInfoPtr>& layers, uint32_t screenId) {
85 return this->Redraw(surface, layers, screenId);
86 };
87 if (handler_) {
88 ScheduleTask(
89 [this]() {
90 auto screenManager = CreateOrGetScreenManager();
91 if (screenManager == nullptr || !screenManager->Init()) {
92 RS_LOGE("RSHardwareThread CreateOrGetScreenManager or init fail.");
93 return;
94 }
95 #ifdef RES_SCHED_ENABLE
96 SubScribeSystemAbility();
97 #endif
98 uniRenderEngine_ = std::make_shared<RSUniRenderEngine>();
99 #ifdef RS_ENABLE_VK
100 if (RSSystemProperties::IsUseVulkan()) {
101 RsVulkanContext::GetSingleton().SetIsProtected(true);
102 }
103 #endif
104 uniRenderEngine_->Init(true);
105 hardwareTid_ = gettid();
106 }).wait();
107 }
108 auto onPrepareCompleteFunc = [this](auto& surface, const auto& param, void* data) {
109 OnPrepareComplete(surface, param, data);
110 };
111 if (hdiBackend_ != nullptr) {
112 hdiBackend_->RegPrepareComplete(onPrepareCompleteFunc, this);
113 }
114 }
115
GetHardwareTid() const116 int RSHardwareThread::GetHardwareTid() const
117 {
118 return hardwareTid_;
119 }
120
PostTask(const std::function<void ()> & task)121 void RSHardwareThread::PostTask(const std::function<void()>& task)
122 {
123 if (handler_) {
124 handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
125 }
126 }
127
PostDelayTask(const std::function<void ()> & task,int64_t delayTime)128 void RSHardwareThread::PostDelayTask(const std::function<void()>& task, int64_t delayTime)
129 {
130 if (handler_) {
131 handler_->PostTask(task, delayTime, AppExecFwk::EventQueue::Priority::IMMEDIATE);
132 }
133 }
134
GetunExecuteTaskNum()135 uint32_t RSHardwareThread::GetunExecuteTaskNum()
136 {
137 return unExecuteTaskNum_;
138 }
139
RefreshRateCounts(std::string & dumpString)140 void RSHardwareThread::RefreshRateCounts(std::string& dumpString)
141 {
142 if (refreshRateCounts_.empty()) {
143 return;
144 }
145 std::map<uint32_t, uint64_t>::iterator iter;
146 for (iter = refreshRateCounts_.begin(); iter != refreshRateCounts_.end(); ++iter) {
147 dumpString.append(
148 "Refresh Rate:" + std::to_string(iter->first) + ", Count:" + std::to_string(iter->second) + ";\n");
149 }
150 RS_LOGD("RSHardwareThread::RefreshRateCounts refresh rate counts info is displayed");
151 }
152
ClearRefreshRateCounts(std::string & dumpString)153 void RSHardwareThread::ClearRefreshRateCounts(std::string& dumpString)
154 {
155 if (refreshRateCounts_.empty()) {
156 return;
157 }
158 refreshRateCounts_.clear();
159 dumpString.append("The refresh rate counts info is cleared successfully!\n");
160 RS_LOGD("RSHardwareThread::RefreshRateCounts refresh rate counts info is cleared");
161 }
162
CommitAndReleaseLayers(OutputPtr output,const std::vector<LayerInfoPtr> & layers)163 void RSHardwareThread::CommitAndReleaseLayers(OutputPtr output, const std::vector<LayerInfoPtr>& layers)
164 {
165 if (!handler_) {
166 RS_LOGE("RSHardwareThread::CommitAndReleaseLayers handler is nullptr");
167 return;
168 }
169 delayTime_ = 0;
170 LayerComposeCollection::GetInstance().UpdateUniformOrOfflineComposeFrameNumberForDFX(layers.size());
171 RefreshRateParam param = GetRefreshRateParam();
172 #ifdef RES_SCHED_ENABLE
173 ResschedEventListener::GetInstance()->ReportFrameToRSS();
174 #endif
175 RSTaskMessage::RSTask task = [this, output = output, layers = layers, param = param]() {
176 if (output == nullptr || hdiBackend_ == nullptr) {
177 return;
178 }
179 int64_t startTimeNs = 0;
180 int64_t endTimeNs = 0;
181 bool hasGameScene = FrameReport::GetInstance().HasGameScene();
182 if (hasGameScene) {
183 startTimeNs = std::chrono::duration_cast<std::chrono::nanoseconds>(
184 std::chrono::steady_clock::now().time_since_epoch()).count();
185 }
186 uint32_t currentRate = HgmCore::Instance().GetScreenCurrentRefreshRate(HgmCore::Instance().GetActiveScreenId());
187 RS_TRACE_NAME_FMT("RSHardwareThread::CommitAndReleaseLayers rate: %d, now: %lu, size: %lu",
188 currentRate, param.frameTimestamp, layers.size());
189 RS_LOGI("RSHardwareThread::CommitAndReleaseLayers rate:%{public}d, now:%{public}" PRIu64 ", size:%{public}zu",
190 currentRate, param.frameTimestamp, layers.size());
191 ExecuteSwitchRefreshRate(param.rate);
192 PerformSetActiveMode(output, param.frameTimestamp, param.constraintRelativeTime);
193 AddRefreshRateCount();
194 output->SetLayerInfo(layers);
195 if (output->IsDeviceValid()) {
196 hdiBackend_->Repaint(output);
197 }
198 output->ReleaseLayers(releaseFence_);
199 RSBaseRenderUtil::DecAcquiredBufferCount();
200 RSUniRenderThread::Instance().NotifyDisplayNodeBufferReleased();
201 if (hasGameScene) {
202 endTimeNs = std::chrono::duration_cast<std::chrono::nanoseconds>(
203 std::chrono::steady_clock::now().time_since_epoch()).count();
204 FrameReport::GetInstance().SetLastSwapBufferTime(endTimeNs - startTimeNs);
205 }
206
207 unExecuteTaskNum_--;
208 if (unExecuteTaskNum_ <= HARDWARE_THREAD_TASK_NUM) {
209 RSMainThread::Instance()->NotifyHardwareThreadCanExecuteTask();
210 }
211 };
212 RSBaseRenderUtil::IncAcquiredBufferCount();
213 unExecuteTaskNum_++;
214 RSMainThread::Instance()->SetHardwareTaskNum(unExecuteTaskNum_.load());
215 auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
216 if (!hgmCore.GetLtpoEnabled()) {
217 PostTask(task);
218 } else {
219 auto period = CreateVSyncSampler()->GetHardwarePeriod();
220 int64_t pipelineOffset = hgmCore.GetPipelineOffset();
221 uint64_t expectCommitTime = static_cast<uint64_t>(param.frameTimestamp +
222 static_cast<uint64_t>(pipelineOffset) - static_cast<uint64_t>(period));
223 uint64_t currTime = static_cast<uint64_t>(
224 std::chrono::duration_cast<std::chrono::nanoseconds>(
225 std::chrono::steady_clock::now().time_since_epoch()).count());
226 delayTime_ = std::round((static_cast<int64_t>(expectCommitTime - currTime)) / 1000000);
227 RS_TRACE_NAME_FMT("RSHardwareThread::CommitAndReleaseLayers " \
228 "expectCommitTime: %lu, currTime: %lu, delayTime: %ld, pipelineOffset: %ld, period: %ld",
229 expectCommitTime, currTime, delayTime_, pipelineOffset, period);
230 if (period == 0 || delayTime_ <= 0) {
231 PostTask(task);
232 } else {
233 PostDelayTask(task, delayTime_);
234 }
235 }
236
237 for (const auto& layer : layers) {
238 if (layer == nullptr || layer->GetClearCacheSet().empty()) {
239 continue;
240 }
241
242 // Remove image caches when their SurfaceNode has gobackground/cleancache.
243 RSTaskMessage::RSTask clearTask = [this, cacheset = layer->GetClearCacheSet()]() {
244 if (uniRenderEngine_ != nullptr) {
245 uniRenderEngine_->ClearCacheSet(cacheset);
246 }
247 };
248 PostTask(clearTask);
249 }
250 }
251
GetRefreshRateParam()252 RefreshRateParam RSHardwareThread::GetRefreshRateParam()
253 {
254 // need to sync the hgm data from main thread.
255 // Temporary sync the timestamp to fix the duplicate time stamp issue.
256 auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
257 bool directComposition = hgmCore.GetDirectCompositionFlag();
258 if (directComposition) {
259 hgmCore.SetDirectCompositionFlag(false);
260 }
261 RefreshRateParam param;
262 if (directComposition) {
263 param = {
264 .rate = hgmCore.GetPendingScreenRefreshRate(),
265 .frameTimestamp = hgmCore.GetCurrentTimestamp(),
266 .constraintRelativeTime = hgmCore.GetPendingConstraintRelativeTime(),
267 };
268 } else {
269 param = {
270 .rate = RSUniRenderThread::Instance().GetPendingScreenRefreshRate(),
271 .frameTimestamp = RSUniRenderThread::Instance().GetCurrentTimestamp(),
272 .constraintRelativeTime = RSUniRenderThread::Instance().GetPendingConstraintRelativeTime(),
273 };
274 }
275 return param;
276 }
277
OnScreenVBlankIdleCallback(ScreenId screenId,uint64_t timestamp)278 void RSHardwareThread::OnScreenVBlankIdleCallback(ScreenId screenId, uint64_t timestamp)
279 {
280 RS_TRACE_NAME_FMT("RSHardwareThread::OnScreenVBlankIdleCallback screenId: %d now: %lu", screenId, timestamp);
281 vblankIdleCorrector_.SetScreenVBlankIdle(screenId);
282 }
283
ExecuteSwitchRefreshRate(uint32_t refreshRate)284 void RSHardwareThread::ExecuteSwitchRefreshRate(uint32_t refreshRate)
285 {
286 static bool refreshRateSwitch = system::GetBoolParameter("persist.hgm.refreshrate.enabled", true);
287 if (!refreshRateSwitch) {
288 RS_LOGD("RSHardwareThread: refreshRateSwitch is off, currRefreshRate is %{public}d", refreshRate);
289 return;
290 }
291
292 static ScreenId lastScreenId = 12345; // init value diff with any real screen id
293 auto screenManager = CreateOrGetScreenManager();
294 auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
295 if (hgmCore.GetFrameRateMgr() == nullptr) {
296 RS_LOGD("FrameRateMgr is null");
297 return;
298 }
299 auto screenRefreshRateImme = hgmCore.GetScreenRefreshRateImme();
300 if (screenRefreshRateImme > 0) {
301 RS_LOGD("ExecuteSwitchRefreshRate:rate change: %{public}u -> %{public}u", refreshRate, screenRefreshRateImme);
302 refreshRate = screenRefreshRateImme;
303 }
304 ScreenId id = hgmCore.GetFrameRateMgr()->GetCurScreenId();
305 if (refreshRate != hgmCore.GetScreenCurrentRefreshRate(id) || lastScreenId != id) {
306 RS_LOGI("RSHardwareThread::CommitAndReleaseLayers screenId %{public}d refreshRate %{public}d",
307 static_cast<int>(id), refreshRate);
308 lastScreenId = id;
309 int32_t status = hgmCore.SetScreenRefreshRate(id, 0, refreshRate);
310 if (status < EXEC_SUCCESS) {
311 RS_LOGD("RSHardwareThread: failed to set refreshRate %{public}d, screenId %{public}" PRIu64 "", refreshRate,
312 id);
313 }
314 }
315 }
316
PerformSetActiveMode(OutputPtr output,uint64_t timestamp,uint64_t constraintRelativeTime)317 void RSHardwareThread::PerformSetActiveMode(OutputPtr output, uint64_t timestamp, uint64_t constraintRelativeTime)
318 {
319 auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
320 auto screenManager = CreateOrGetScreenManager();
321 if (screenManager == nullptr) {
322 RS_LOGE("RSHardwareThread CreateOrGetScreenManager fail.");
323 return;
324 }
325
326 vblankIdleCorrector_.ProcessScreenConstraint(timestamp, constraintRelativeTime);
327 HgmRefreshRates newRate = RSSystemProperties::GetHgmRefreshRatesEnabled();
328 if (hgmRefreshRates_ != newRate) {
329 hgmRefreshRates_ = newRate;
330 hgmCore.SetScreenRefreshRate(screenManager->GetDefaultScreenId(), 0, static_cast<int32_t>(hgmRefreshRates_));
331 }
332
333 std::unique_ptr<std::unordered_map<ScreenId, int32_t>> modeMap(hgmCore.GetModesToApply());
334 if (modeMap == nullptr) {
335 return;
336 }
337
338 RS_TRACE_NAME_FMT("RSHardwareThread::PerformSetActiveMode setting active mode. rate: %d",
339 HgmCore::Instance().GetScreenCurrentRefreshRate(HgmCore::Instance().GetActiveScreenId()));
340 for (auto mapIter = modeMap->begin(); mapIter != modeMap->end(); ++mapIter) {
341 ScreenId id = mapIter->first;
342 int32_t modeId = mapIter->second;
343
344 auto supportedModes = screenManager->GetScreenSupportedModes(id);
345 for (auto mode : supportedModes) {
346 RS_OPTIONAL_TRACE_NAME_FMT("RSHardwareThread check modes w: %d, h: %d, rate: %d, id: %d",
347 mode.GetScreenWidth(), mode.GetScreenHeight(), mode.GetScreenRefreshRate(), mode.GetScreenModeId());
348 }
349
350 screenManager->SetScreenActiveMode(id, modeId);
351 auto pendingPeriod = hgmCore.GetIdealPeriod(hgmCore.GetScreenCurrentRefreshRate(id));
352 int64_t pendingTimestamp = static_cast<int64_t>(timestamp);
353 if (hdiBackend_) {
354 hdiBackend_->SetPendingMode(output, pendingPeriod, pendingTimestamp);
355 hdiBackend_->StartSample(output);
356 }
357 }
358 }
359
OnPrepareComplete(sptr<Surface> & surface,const PrepareCompleteParam & param,void * data)360 void RSHardwareThread::OnPrepareComplete(sptr<Surface>& surface,
361 const PrepareCompleteParam& param, void* data)
362 {
363 // unused data.
364 (void)(data);
365
366 if (!param.needFlushFramebuffer) {
367 return;
368 }
369
370 if (redrawCb_ != nullptr) {
371 redrawCb_(surface, param.layers, param.screenId);
372 }
373 }
374
ClearFrameBuffers(OutputPtr output)375 GSError RSHardwareThread::ClearFrameBuffers(OutputPtr output)
376 {
377 if (output == nullptr) {
378 RS_LOGE("Clear frame buffers failed for the output is nullptr");
379 return GSERROR_INVALID_ARGUMENTS;
380 }
381 RS_TRACE_NAME("RSHardwareThread::ClearFrameBuffers");
382 if (uniRenderEngine_ != nullptr) {
383 uniRenderEngine_->ResetCurrentContext();
384 }
385 #ifdef RS_ENABLE_VK
386 if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN) {
387 auto frameBufferSurface = std::static_pointer_cast<RSSurfaceOhosVulkan>(frameBufferSurfaceOhos_);
388 if (frameBufferSurface) {
389 frameBufferSurface->WaitSurfaceClear();
390 }
391 }
392 #endif
393 return output->ClearFrameBuffer();
394 }
395
CreateFrameBufferSurfaceOhos(const sptr<Surface> & surface)396 std::shared_ptr<RSSurfaceOhos> RSHardwareThread::CreateFrameBufferSurfaceOhos(const sptr<Surface>& surface)
397 {
398 std::shared_ptr<RSSurfaceOhos> rsSurface = nullptr;
399 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
400 if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
401 rsSurface = std::make_shared<RSSurfaceOhosGl>(surface);
402 }
403 #endif
404 #if (defined RS_ENABLE_VK)
405 if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN) {
406 rsSurface = std::make_shared<RSSurfaceOhosVulkan>(surface);
407 }
408 #endif
409 RS_LOGD("RSHardwareThread::Redraw: CreateFrameBufferSurfaceOhos.");
410 return rsSurface;
411 }
412
Redraw(const sptr<Surface> & surface,const std::vector<LayerInfoPtr> & layers,uint32_t screenId)413 void RSHardwareThread::Redraw(const sptr<Surface>& surface, const std::vector<LayerInfoPtr>& layers, uint32_t screenId)
414 {
415 RS_TRACE_NAME("RSHardwareThread::Redraw");
416 if (surface == nullptr || uniRenderEngine_ == nullptr) {
417 RS_LOGE("RSHardwareThread::Redraw: surface or uniRenderEngine is null.");
418 return;
419 }
420 bool isProtected = false;
421 #ifdef RS_ENABLE_VK
422 if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
423 RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
424 if (RSSystemProperties::GetDrmEnabled() && RSMainThread::Instance()->GetDeviceType() != DeviceType::PC) {
425 for (const auto& layer : layers) {
426 if (layer && layer->GetBuffer() && (layer->GetBuffer()->GetUsage() & BUFFER_USAGE_PROTECTED)) {
427 isProtected = true;
428 break;
429 }
430 }
431 if (RSSystemProperties::IsUseVulkan()) {
432 RsVulkanContext::GetSingleton().SetIsProtected(isProtected);
433 }
434 } else {
435 RsVulkanContext::GetSingleton().SetIsProtected(false);
436 }
437 }
438 #endif
439
440 RS_LOGD("RsDebug RSHardwareThread::Redraw flush frame buffer start");
441 bool forceCPU = RSBaseRenderEngine::NeedForceCPU(layers);
442 auto screenManager = CreateOrGetScreenManager();
443 if (screenManager == nullptr) {
444 RS_LOGE("RSHardwareThread::Redraw: screenManager is null.");
445 return;
446 }
447 auto screenInfo = screenManager->QueryScreenInfo(screenId);
448 std::shared_ptr<Drawing::ColorSpace> drawingColorSpace = nullptr;
449 #ifdef USE_VIDEO_PROCESSING_ENGINE
450 GraphicColorGamut colorGamut = ComputeTargetColorGamut(layers);
451 GraphicPixelFormat pixelFormat = ComputeTargetPixelFormat(layers);
452 auto renderFrameConfig = RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo,
453 true, isProtected, colorGamut, pixelFormat);
454 drawingColorSpace = RSBaseRenderEngine::ConvertColorGamutToDrawingColorSpace(colorGamut);
455 // set color space to surface buffer metadata
456 using namespace HDI::Display::Graphic::Common::V1_0;
457 CM_ColorSpaceType colorSpace = CM_SRGB_FULL;
458 if (ConvertColorGamutToSpaceType(colorGamut, colorSpace)) {
459 if (surface->SetUserData("ATTRKEY_COLORSPACE_INFO", std::to_string(colorSpace)) != GSERROR_OK) {
460 RS_LOGD("RSHardwareThread::Redraw set user data failed");
461 }
462 }
463 #else
464 auto renderFrameConfig = RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo, true, isProtected);
465 #endif
466 // override redraw frame buffer with physical screen resolution.
467 renderFrameConfig.width = static_cast<int32_t>(screenInfo.phyWidth);
468 renderFrameConfig.height = static_cast<int32_t>(screenInfo.phyHeight);
469 if (frameBufferSurfaceOhos_ == nullptr) {
470 frameBufferSurfaceOhos_ = CreateFrameBufferSurfaceOhos(surface);
471 }
472 FrameContextConfig frameContextConfig = {isProtected, false};
473 if (RSSystemProperties::GetVkQueueDividedEnable()) {
474 frameContextConfig.independentContext = true;
475 }
476 auto renderFrame = uniRenderEngine_->RequestFrame(frameBufferSurfaceOhos_, renderFrameConfig,
477 forceCPU, true, frameContextConfig);
478 if (renderFrame == nullptr) {
479 RS_LOGE("RsDebug RSHardwareThread::Redraw failed to request frame.");
480 return;
481 }
482 auto canvas = renderFrame->GetCanvas();
483 if (canvas == nullptr) {
484 RS_LOGE("RsDebug RSHardwareThread::Redraw canvas is nullptr.");
485 return;
486 }
487 #ifdef RS_ENABLE_VK
488 if (RSSystemProperties::IsUseVulkan()) {
489 canvas->Clear(Drawing::Color::COLOR_TRANSPARENT);
490 }
491 #endif
492
493 #ifdef USE_VIDEO_PROCESSING_ENGINE
494 uniRenderEngine_->DrawLayers(*canvas, layers, false, screenInfo, colorGamut);
495 #else
496 uniRenderEngine_->DrawLayers(*canvas, layers, false, screenInfo);
497 #endif
498
499 renderFrame->Flush();
500 RS_LOGD("RsDebug RSHardwareThread::Redraw flush frame buffer end");
501 }
502
AddRefreshRateCount()503 void RSHardwareThread::AddRefreshRateCount()
504 {
505 auto screenManager = CreateOrGetScreenManager();
506 if (screenManager == nullptr) {
507 RS_LOGE("RSHardwareThread::AddRefreshRateCount screenManager is nullptr");
508 return;
509 }
510 ScreenId id = screenManager->GetDefaultScreenId();
511 auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
512 uint32_t currentRefreshRate = hgmCore.GetScreenCurrentRefreshRate(id);
513 auto [iter, success] = refreshRateCounts_.try_emplace(currentRefreshRate, 1);
514 if (!success) {
515 iter->second++;
516 }
517 RSRealtimeRefreshRateManager::Instance().CountRealtimeFrame();
518
519 auto frameRateMgr = hgmCore.GetFrameRateMgr();
520 if (frameRateMgr == nullptr) {
521 return;
522 }
523 frameRateMgr->GetTouchManager().HandleRsFrame();
524 }
525
SubScribeSystemAbility()526 void RSHardwareThread::SubScribeSystemAbility()
527 {
528 RS_LOGI("%{public}s", __func__);
529 sptr<ISystemAbilityManager> systemAbilityManager =
530 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
531 if (!systemAbilityManager) {
532 RS_LOGE("%{public}s failed to get system ability manager client", __func__);
533 return;
534 }
535 std::string threadName = "RSHardwareThread";
536 std::string strUid = std::to_string(getuid());
537 std::string strPid = std::to_string(getpid());
538 std::string strTid = std::to_string(gettid());
539
540 saStatusChangeListener_ = new (std::nothrow)VSyncSystemAbilityListener(threadName, strUid, strPid, strTid);
541 int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, saStatusChangeListener_);
542 if (ret != ERR_OK) {
543 RS_LOGE("%{public}s subscribe system ability %{public}d failed.", __func__, RES_SCHED_SYS_ABILITY_ID);
544 saStatusChangeListener_ = nullptr;
545 }
546 }
547
548 #ifdef USE_VIDEO_PROCESSING_ENGINE
ComputeTargetColorGamut(const std::vector<LayerInfoPtr> & layers)549 GraphicColorGamut RSHardwareThread::ComputeTargetColorGamut(const std::vector<LayerInfoPtr>& layers)
550 {
551 using namespace HDI::Display::Graphic::Common::V1_0;
552 GraphicColorGamut colorGamut = GRAPHIC_COLOR_GAMUT_SRGB;
553 for (auto& layer : layers) {
554 if (layer == nullptr) {
555 RS_LOGE("RSHardwareThread::ComputeTargetColorGamut layer is nullptr");
556 continue;
557 }
558 auto buffer = layer->GetBuffer();
559 if (buffer == nullptr) {
560 RS_LOGW("RSHardwareThread::ComputeTargetColorGamut The buffer of layer is nullptr");
561 continue;
562 }
563
564 CM_ColorSpaceInfo colorSpaceInfo;
565 if (MetadataHelper::GetColorSpaceInfo(buffer, colorSpaceInfo) != GSERROR_OK) {
566 RS_LOGD("RSHardwareThread::ComputeTargetColorGamut Get color space failed");
567 continue;
568 }
569
570 if (colorSpaceInfo.primaries != COLORPRIMARIES_SRGB) {
571 colorGamut = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
572 break;
573 }
574 }
575
576 return colorGamut;
577 }
578
ComputeTargetPixelFormat(const std::vector<LayerInfoPtr> & layers)579 GraphicPixelFormat RSHardwareThread::ComputeTargetPixelFormat(const std::vector<LayerInfoPtr>& layers)
580 {
581 using namespace HDI::Display::Graphic::Common::V1_0;
582 GraphicPixelFormat pixelFormat = GRAPHIC_PIXEL_FMT_RGBA_8888;
583 for (auto& layer : layers) {
584 if (layer == nullptr) {
585 continue;
586 }
587 auto buffer = layer->GetBuffer();
588 if (buffer == nullptr) {
589 RS_LOGW("RSHardwareThread::ComputeTargetPixelFormat The buffer of layer is nullptr");
590 continue;
591 }
592
593 auto bufferPixelFormat = buffer->GetFormat();
594 if (bufferPixelFormat == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
595 bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCBCR_P010 ||
596 bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCRCB_P010) {
597 pixelFormat = GRAPHIC_PIXEL_FMT_RGBA_1010102;
598 RS_LOGD("RSHardwareThread::ComputeTargetPixelFormat pixelformat is set to 1010102 for 10bit buffer");
599 break;
600 }
601 }
602
603 return pixelFormat;
604 }
605
ConvertColorGamutToSpaceType(const GraphicColorGamut & colorGamut,HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceType & colorSpaceType)606 bool RSHardwareThread::ConvertColorGamutToSpaceType(const GraphicColorGamut& colorGamut,
607 HDI::Display::Graphic::Common::V1_0::CM_ColorSpaceType& colorSpaceType)
608 {
609 using namespace HDI::Display::Graphic::Common::V1_0;
610 static const std::map<GraphicColorGamut, CM_ColorSpaceType> RS_TO_COMMON_COLOR_SPACE_TYPE_MAP {
611 {GRAPHIC_COLOR_GAMUT_STANDARD_BT601, CM_BT601_EBU_FULL},
612 {GRAPHIC_COLOR_GAMUT_STANDARD_BT709, CM_BT709_FULL},
613 {GRAPHIC_COLOR_GAMUT_SRGB, CM_SRGB_FULL},
614 {GRAPHIC_COLOR_GAMUT_ADOBE_RGB, CM_ADOBERGB_FULL},
615 {GRAPHIC_COLOR_GAMUT_DISPLAY_P3, CM_P3_FULL},
616 {GRAPHIC_COLOR_GAMUT_BT2020, CM_DISPLAY_BT2020_SRGB},
617 {GRAPHIC_COLOR_GAMUT_BT2100_PQ, CM_BT2020_PQ_FULL},
618 {GRAPHIC_COLOR_GAMUT_BT2100_HLG, CM_BT2020_HLG_FULL},
619 {GRAPHIC_COLOR_GAMUT_DISPLAY_BT2020, CM_DISPLAY_BT2020_SRGB},
620 };
621
622 if (RS_TO_COMMON_COLOR_SPACE_TYPE_MAP.find(colorGamut) == RS_TO_COMMON_COLOR_SPACE_TYPE_MAP.end()) {
623 return false;
624 }
625
626 colorSpaceType = RS_TO_COMMON_COLOR_SPACE_TYPE_MAP.at(colorGamut);
627 return true;
628 }
629 #endif
630 }
631