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