• 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 #include <memory>
18 #include <unistd.h>
19 
20 #ifdef RS_ENABLE_EGLIMAGE
21 #include "src/gpu/gl/GrGLDefines.h"
22 #endif
23 
24 #include "hgm_core.h"
25 #include "pipeline/rs_base_render_util.h"
26 #include "pipeline/rs_uni_render_util.h"
27 #include "pipeline/rs_main_thread.h"
28 #include "pipeline/rs_uni_render_engine.h"
29 #include "pipeline/round_corner_display/rs_round_corner_display.h"
30 #include "hgm_frame_rate_manager.h"
31 #include "platform/common/rs_log.h"
32 #include "platform/common/rs_system_properties.h"
33 #include "screen_manager/rs_screen_manager.h"
34 #include "common/rs_singleton.h"
35 #include "rs_realtime_refresh_rate_manager.h"
36 #include "rs_trace.h"
37 #include "common/rs_optional_trace.h"
38 #include "frame_report.h"
39 #include "hdi_backend.h"
40 #include "vsync_sampler.h"
41 #include "parameters.h"
42 #ifdef RS_ENABLE_VK
43 #include "rs_vk_image_manager.h"
44 #endif
45 
46 #ifdef RS_ENABLE_EGLIMAGE
47 #include "rs_egl_image_manager.h"
48 #endif // RS_ENABLE_EGLIMAGE
49 
50 #ifdef USE_VIDEO_PROCESSING_ENGINE
51 #include "metadata_helper.h"
52 #endif
53 
54 namespace OHOS::Rosen {
55 namespace {
56 constexpr uint32_t HARDWARE_THREAD_TASK_NUM = 2;
57 
58 #if defined(USE_ROSEN_DRAWING) && defined(RS_ENABLE_VK)
GetColorTypeFromBufferFormat(int32_t pixelFmt)59 Drawing::ColorType GetColorTypeFromBufferFormat(int32_t pixelFmt)
60 {
61     switch (pixelFmt) {
62         case GRAPHIC_PIXEL_FMT_RGBA_8888:
63             return Drawing::ColorType::COLORTYPE_RGBA_8888;
64         case GRAPHIC_PIXEL_FMT_BGRA_8888 :
65             return Drawing::ColorType::COLORTYPE_BGRA_8888;
66         case GRAPHIC_PIXEL_FMT_RGB_565:
67             return Drawing::ColorType::COLORTYPE_RGB_565;
68         default:
69             return Drawing::ColorType::COLORTYPE_RGBA_8888;
70     }
71 }
72 #endif
73 }
74 
Instance()75 RSHardwareThread& RSHardwareThread::Instance()
76 {
77     static RSHardwareThread instance;
78     return instance;
79 }
80 
Start()81 void RSHardwareThread::Start()
82 {
83     RS_LOGI("RSHardwareThread::Start()!");
84     hdiBackend_ = HdiBackend::GetInstance();
85     runner_ = AppExecFwk::EventRunner::Create("RSHardwareThread");
86     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
87     redrawCb_ = std::bind(&RSHardwareThread::Redraw, this, std::placeholders::_1, std::placeholders::_2,
88         std::placeholders::_3);
89     if (handler_) {
90         ScheduleTask(
91             [this]() {
92                 auto screenManager = CreateOrGetScreenManager();
93                 if (screenManager == nullptr || !screenManager->Init()) {
94                     RS_LOGE("RSHardwareThread CreateOrGetScreenManager or init fail.");
95                     return;
96                 }
97                 uniRenderEngine_ = std::make_shared<RSUniRenderEngine>();
98                 uniRenderEngine_->Init(true);
99                 hardwareTid_ = gettid();
100             }).wait();
101     }
102     auto onPrepareCompleteFunc = [this](auto& surface, const auto& param, void* data) {
103         OnPrepareComplete(surface, param, data);
104     };
105     if (hdiBackend_ != nullptr) {
106         hdiBackend_->RegPrepareComplete(onPrepareCompleteFunc, this);
107     }
108 }
109 
GetHardwareTid() const110 int RSHardwareThread::GetHardwareTid() const
111 {
112     return hardwareTid_;
113 }
114 
PostTask(const std::function<void ()> & task)115 void RSHardwareThread::PostTask(const std::function<void()>& task)
116 {
117     if (handler_) {
118         handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
119     }
120 }
121 
PostDelayTask(const std::function<void ()> & task,int64_t delayTime)122 void RSHardwareThread::PostDelayTask(const std::function<void()>& task, int64_t delayTime)
123 {
124     if (handler_) {
125         handler_->PostTask(task, delayTime, AppExecFwk::EventQueue::Priority::IMMEDIATE);
126     }
127 }
128 
GetunExcuteTaskNum()129 uint32_t RSHardwareThread::GetunExcuteTaskNum()
130 {
131     return unExcuteTaskNum_;
132 }
133 
ReleaseBuffer(sptr<SurfaceBuffer> buffer,sptr<SyncFence> releaseFence,sptr<IConsumerSurface> cSurface)134 void RSHardwareThread::ReleaseBuffer(sptr<SurfaceBuffer> buffer, sptr<SyncFence> releaseFence,
135     sptr<IConsumerSurface> cSurface)
136 {
137     if (cSurface == nullptr) {
138         RS_LOGE("RsDebug RSHardwareThread:: ReleaseBuffer failed, no consumer!");
139         return;
140     }
141 
142     if (buffer != nullptr) {
143         RS_TRACE_NAME("RSHardwareThread::ReleaseBuffer");
144         auto ret = cSurface->ReleaseBuffer(buffer, releaseFence);
145         if (ret != OHOS::SURFACE_ERROR_OK) {
146             return;
147         }
148         // reset prevBuffer if we release it successfully,
149         // to avoid releasing the same buffer next frame in some situations.
150         buffer = nullptr;
151         releaseFence = SyncFence::INVALID_FENCE;
152     }
153 }
154 
RefreshRateCounts(std::string & dumpString)155 void RSHardwareThread::RefreshRateCounts(std::string& dumpString)
156 {
157     if (refreshRateCounts_.empty()) {
158         return;
159     }
160     std::map<uint32_t, uint64_t>::iterator iter;
161     for (iter = refreshRateCounts_.begin(); iter != refreshRateCounts_.end(); iter++) {
162         dumpString.append(
163             "Refresh Rate:" + std::to_string(iter->first) + ", Count:" + std::to_string(iter->second) + ";\n");
164     }
165     RS_LOGD("RSHardwareThread::RefreshRateCounts refresh rate counts info is displayed");
166 }
167 
ClearRefreshRateCounts(std::string & dumpString)168 void RSHardwareThread::ClearRefreshRateCounts(std::string& dumpString)
169 {
170     if (refreshRateCounts_.empty()) {
171         return;
172     }
173     refreshRateCounts_.clear();
174     dumpString.append("The refresh rate counts info is cleared successfully!\n");
175     RS_LOGD("RSHardwareThread::RefreshRateCounts refresh rate counts info is cleared");
176 }
177 
ReleaseLayers(OutputPtr output,const std::unordered_map<uint32_t,LayerPtr> & layerMap)178 void RSHardwareThread::ReleaseLayers(OutputPtr output, const std::unordered_map<uint32_t, LayerPtr>& layerMap)
179 {
180     // get present timestamp from and set present timestamp to surface
181     for (const auto& [id, layer] : layerMap) {
182         if (layer == nullptr || layer->GetLayerInfo()->GetSurface() == nullptr) {
183             RS_LOGW("RSHardwareThread::ReleaseLayers: layer or layer's cSurface is nullptr");
184             continue;
185         }
186         LayerPresentTimestamp(layer->GetLayerInfo(), layer->GetLayerInfo()->GetSurface());
187     }
188 
189     // set all layers' releaseFence.
190     if (output == nullptr) {
191         RS_LOGE("RSHardwareThread::ReleaseLayers: output is nullptr");
192         return;
193     }
194     const auto layersReleaseFence = output->GetLayersReleaseFence();
195     if (layersReleaseFence.size() == 0) {
196         // When release fence's size is 0, the output may invalid, release all buffer
197         // This situation may happen when killing composer_host
198         for (const auto& [id, layer] : layerMap) {
199             if (layer == nullptr || layer->GetLayerInfo()->GetSurface() == nullptr) {
200                 RS_LOGW("RSHardwareThread::ReleaseLayers: layer or layer's cSurface is nullptr");
201                 continue;
202             }
203             auto preBuffer = layer->GetLayerInfo()->GetPreBuffer();
204             auto consumer = layer->GetLayerInfo()->GetSurface();
205             ReleaseBuffer(preBuffer, SyncFence::INVALID_FENCE, consumer);
206         }
207         RS_LOGE("RSHardwareThread::ReleaseLayers: no layer needs to release");
208     }
209     for (const auto& [layer, fence] : layersReleaseFence) {
210         if (layer == nullptr) {
211             continue;
212         }
213         auto preBuffer = layer->GetPreBuffer();
214         auto consumer = layer->GetSurface();
215         ReleaseBuffer(preBuffer, fence, consumer);
216     }
217     RSMainThread::Instance()->NotifyDisplayNodeBufferReleased();
218 }
219 
CommitAndReleaseLayers(OutputPtr output,const std::vector<LayerInfoPtr> & layers)220 void RSHardwareThread::CommitAndReleaseLayers(OutputPtr output, const std::vector<LayerInfoPtr>& layers)
221 {
222     if (!handler_) {
223         RS_LOGE("RSHardwareThread::CommitAndReleaseLayers handler is nullptr");
224         return;
225     }
226     auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
227     uint32_t rate = hgmCore.GetPendingScreenRefreshRate();
228     uint32_t currentRate = hgmCore.GetScreenCurrentRefreshRate(hgmCore.GetActiveScreenId());
229     uint64_t currTimestamp = hgmCore.GetCurrentTimestamp();
230     RSTaskMessage::RSTask task = [this, output = output, layers = layers, rate = rate,
231         currentRate = currentRate, timestamp = currTimestamp]() {
232         int64_t startTimeNs = 0;
233         int64_t endTimeNs = 0;
234 
235         if (FrameReport::GetInstance().IsGameScene()) {
236             startTimeNs = std::chrono::duration_cast<std::chrono::nanoseconds>(
237                 std::chrono::steady_clock::now().time_since_epoch()).count();
238         }
239 
240         RS_TRACE_NAME_FMT("RSHardwareThread::CommitAndReleaseLayers rate: %d, now: %lu", currentRate, timestamp);
241         ExecuteSwitchRefreshRate(rate);
242         PerformSetActiveMode(output, timestamp);
243         AddRefreshRateCount();
244         output->SetLayerInfo(layers);
245         if (output->IsDeviceValid()) {
246             hdiBackend_->Repaint(output);
247         }
248         auto layerMap = output->GetLayers();
249         ReleaseLayers(output, layerMap);
250 
251         if (FrameReport::GetInstance().IsGameScene()) {
252             endTimeNs = std::chrono::duration_cast<std::chrono::nanoseconds>(
253                 std::chrono::steady_clock::now().time_since_epoch()).count();
254             FrameReport::GetInstance().SetLastSwapBufferTime(endTimeNs - startTimeNs);
255         }
256 
257         unExcuteTaskNum_--;
258         if (unExcuteTaskNum_ <= HARDWARE_THREAD_TASK_NUM) {
259             RSMainThread::Instance()->NotifyHardwareThreadCanExcuteTask();
260         }
261     };
262     unExcuteTaskNum_++;
263 
264     if (!hgmCore.GetLtpoEnabled()) {
265         PostTask(task);
266     } else {
267         auto period  = CreateVSyncSampler()->GetHardwarePeriod();
268         int64_t pipelineOffset = hgmCore.GetPipelineOffset();
269         uint64_t expectCommitTime = static_cast<uint64_t>(currTimestamp + static_cast<uint64_t>(pipelineOffset) -
270             static_cast<uint64_t>(period));
271         uint64_t currTime = static_cast<uint64_t>(
272             std::chrono::duration_cast<std::chrono::nanoseconds>(
273                 std::chrono::steady_clock::now().time_since_epoch()).count());
274         int64_t delayTime = std::round((static_cast<int64_t>(expectCommitTime - currTime)) / 1000000);
275         RS_TRACE_NAME_FMT("RSHardwareThread::CommitAndReleaseLayers " \
276             "expectCommitTime: %lu, currTime: %lu, delayTime: %ld, pipelineOffset: %ld, period: %ld",
277             expectCommitTime, currTime, delayTime, pipelineOffset, period);
278         if (period == 0 || delayTime <= 0) {
279             PostTask(task);
280         } else {
281             PostDelayTask(task, delayTime);
282         }
283     }
284 }
285 
ExecuteSwitchRefreshRate(uint32_t refreshRate)286 void RSHardwareThread::ExecuteSwitchRefreshRate(uint32_t refreshRate)
287 {
288     static bool refreshRateSwitch = system::GetBoolParameter("persist.hgm.refreshrate.enabled", true);
289     if (!refreshRateSwitch) {
290         RS_LOGD("RSHardwareThread: refreshRateSwitch is off, currRefreshRate is %{public}d", refreshRate);
291         return;
292     }
293 
294     auto screenManager = CreateOrGetScreenManager();
295     auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
296     ScreenId id = hgmCore.GetFrameRateMgr()->GetCurScreenId();
297     if (refreshRate != hgmCore.GetScreenCurrentRefreshRate(id)) {
298         RS_LOGI("RSHardwareThread::CommitAndReleaseLayers screenId %{public}d refreshRate %{public}d",
299             static_cast<int>(id), refreshRate);
300         int32_t status = hgmCore.SetScreenRefreshRate(id, 0, refreshRate);
301         if (status < EXEC_SUCCESS) {
302             RS_LOGD("RSHardwareThread: failed to set refreshRate %{public}d, screenId %{public}llu", refreshRate, id);
303         }
304     }
305 }
306 
PerformSetActiveMode(OutputPtr output,uint64_t timestamp)307 void RSHardwareThread::PerformSetActiveMode(OutputPtr output, uint64_t timestamp)
308 {
309     auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
310     auto screenManager = CreateOrGetScreenManager();
311     if (screenManager == nullptr) {
312         RS_LOGE("RSHardwareThread CreateOrGetScreenManager fail.");
313         return;
314     }
315 
316     HgmRefreshRates newRate = RSSystemProperties::GetHgmRefreshRatesEnabled();
317     if (hgmRefreshRates_ != newRate) {
318         hgmRefreshRates_ = newRate;
319         hgmCore.SetScreenRefreshRate(screenManager->GetDefaultScreenId(), 0, static_cast<int32_t>(hgmRefreshRates_));
320     }
321 
322     std::unique_ptr<std::unordered_map<ScreenId, int32_t>> modeMap(hgmCore.GetModesToApply());
323     if (modeMap == nullptr) {
324         return;
325     }
326 
327     RS_TRACE_NAME_FMT("RSHardwareThread::PerformSetActiveMode setting active mode. rate: %d",
328         hgmCore.GetScreenCurrentRefreshRate(screenManager->GetDefaultScreenId()));
329     for (auto mapIter = modeMap->begin(); mapIter != modeMap->end(); ++mapIter) {
330         ScreenId id = mapIter->first;
331         int32_t modeId = mapIter->second;
332 
333         auto supportedModes = screenManager->GetScreenSupportedModes(id);
334         for (auto mode : supportedModes) {
335             RS_OPTIONAL_TRACE_NAME_FMT("RSHardwareThread check modes w: %d, h: %d, rate: %d, id: %d",
336                 mode.GetScreenWidth(), mode.GetScreenHeight(), mode.GetScreenRefreshRate(), mode.GetScreenModeId());
337         }
338 
339         screenManager->SetScreenActiveMode(id, modeId);
340         if (!hgmCore.GetLtpoEnabled()) {
341             hdiBackend_->StartSample(output);
342         } else {
343             auto pendingPeriod = hgmCore.GetIdealPeriod(hgmCore.GetScreenCurrentRefreshRate(id));
344             int64_t pendingTimestamp = static_cast<int64_t>(timestamp);
345             hdiBackend_->SetPendingMode(output, pendingPeriod, pendingTimestamp);
346             hdiBackend_->StartSample(output);
347         }
348     }
349 }
350 
OnPrepareComplete(sptr<Surface> & surface,const PrepareCompleteParam & param,void * data)351 void RSHardwareThread::OnPrepareComplete(sptr<Surface>& surface,
352     const PrepareCompleteParam& param, void* data)
353 {
354     // unused data.
355     (void)(data);
356 
357     if (!param.needFlushFramebuffer) {
358         return;
359     }
360 
361     if (redrawCb_ != nullptr) {
362         redrawCb_(surface, param.layers, param.screenId);
363     }
364 }
365 
ClearFrameBuffers(OutputPtr output)366 GSError RSHardwareThread::ClearFrameBuffers(OutputPtr output)
367 {
368     if (output == nullptr) {
369         RS_LOGE("Clear frame buffers failed for the output is nullptr");
370         return GSERROR_INVALID_ARGUMENTS;
371     }
372     if (uniRenderEngine_ != nullptr) {
373         uniRenderEngine_->ResetCurrentContext();
374     }
375     return output->ClearFrameBuffer();
376 }
377 
Redraw(const sptr<Surface> & surface,const std::vector<LayerInfoPtr> & layers,uint32_t screenId)378 void RSHardwareThread::Redraw(const sptr<Surface>& surface, const std::vector<LayerInfoPtr>& layers, uint32_t screenId)
379 {
380     RS_TRACE_NAME("RSHardwareThread::Redraw");
381     if (surface == nullptr) {
382         RS_LOGE("RSHardwareThread::Redraw: surface is null.");
383         return;
384     }
385 
386     RS_LOGD("RsDebug RSHardwareThread::Redraw flush frame buffer start");
387     bool forceCPU = RSBaseRenderEngine::NeedForceCPU(layers);
388     auto screenManager = CreateOrGetScreenManager();
389     auto screenInfo = screenManager->QueryScreenInfo(screenId);
390 #ifndef USE_ROSEN_DRAWING
391     sk_sp<SkColorSpace> skColorSpace = nullptr;
392 #else
393     std::shared_ptr<Drawing::ColorSpace> drawingColorSpace = nullptr;
394 #endif
395 #ifdef USE_VIDEO_PROCESSING_ENGINE
396     GraphicColorGamut colorGamut = ComputeTargetColorGamut(layers);
397     GraphicPixelFormat pixelFormat = ComputeTargetPixelFormat(layers);
398     auto renderFrameConfig = RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo, true, colorGamut, pixelFormat);
399 #ifndef USE_ROSEN_DRAWING
400     skColorSpace = RSBaseRenderEngine::ConvertColorGamutToSkColorSpace(colorGamut);
401 #else
402     drawingColorSpace = RSBaseRenderEngine::ConvertColorGamutToDrawingColorSpace(colorGamut);
403 #endif
404 #else
405     auto renderFrameConfig = RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo, true);
406 #endif
407     auto renderFrame = uniRenderEngine_->RequestFrame(surface, renderFrameConfig, forceCPU);
408     if (renderFrame == nullptr) {
409         RS_LOGE("RsDebug RSHardwareThread::Redraw failed to request frame.");
410         return;
411     }
412     auto canvas = renderFrame->GetCanvas();
413     if (canvas == nullptr) {
414         RS_LOGE("RsDebug RSHardwareThread::Redraw canvas is nullptr.");
415         return;
416     }
417 #ifdef RS_ENABLE_EGLIMAGE
418 #ifdef RS_ENABLE_VK
419     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
420         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
421 #ifndef USE_ROSEN_DRAWING
422         canvas->clear(SK_ColorTRANSPARENT);
423 #else
424         canvas->Clear(Drawing::Color::COLOR_TRANSPARENT);
425 #endif
426     }
427     std::unordered_map<int32_t, std::shared_ptr<NativeVkImageRes>> imageCacheSeqsVK;
428 #endif
429 #ifdef RS_ENABLE_GL
430     std::unordered_map<int32_t, std::unique_ptr<ImageCacheSeq>> imageCacheSeqs;
431 #endif
432 #endif // RS_ENABLE_EGLIMAGE
433     bool isTopGpuDraw = false;
434     bool isBottomGpuDraw = false;
435     for (const auto& layer : layers) {
436         if (layer == nullptr) {
437             continue;
438         }
439 
440         if (layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE ||
441             layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE_CLEAR) {
442             continue;
443         }
444 
445         if (layer->GetSurface()->GetName() == "RCDTopSurfaceNode") {
446             isTopGpuDraw = true;
447             continue;
448         }
449         if (layer->GetSurface()->GetName() == "RCDBottomSurfaceNode") {
450             isBottomGpuDraw = true;
451             continue;
452         }
453 
454 #ifndef USE_ROSEN_DRAWING
455         RSAutoCanvasRestore acr(canvas_);
456         auto dstRect = layer->GetLayerSize();
457         SkRect clipRect = SkRect::MakeXYWH(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y),
458             static_cast<float>(dstRect.w), static_cast<float>(dstRect.h));
459         canvas->clipRect(clipRect);
460 
461         // prepare BufferDrawParam
462         auto params = RSUniRenderUtil::CreateLayerBufferDrawParam(layer, forceCPU);
463         canvas->concat(params.matrix);
464 #else
465         Drawing::AutoCanvasRestore acr(*canvas, true);
466         auto dstRect = layer->GetLayerSize();
467         Drawing::Rect clipRect = Drawing::Rect(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y),
468             static_cast<float>(dstRect.w) + static_cast<float>(dstRect.x),
469             static_cast<float>(dstRect.h) + static_cast<float>(dstRect.y));
470         canvas->ClipRect(clipRect, Drawing::ClipOp::INTERSECT, false);
471 
472         // prepare BufferDrawParam
473         auto params = RSUniRenderUtil::CreateLayerBufferDrawParam(layer, forceCPU);
474         canvas->ConcatMatrix(params.matrix);
475 #endif
476 #ifndef RS_ENABLE_EGLIMAGE
477         uniRenderEngine_->DrawBuffer(*canvas, params);
478 #else
479         if (!params.useCPU) {
480             if (!RSBaseRenderUtil::IsBufferValid(params.buffer)) {
481                 RS_LOGE("RSHardwareThread::Redraw CreateEglImageFromBuffer invalid param!");
482                 continue;
483             }
484 #ifndef USE_ROSEN_DRAWING
485 #ifdef NEW_SKIA
486             if (canvas->recordingContext() == nullptr) {
487 #else
488             if (canvas->getGrContext() == nullptr) {
489 #endif
490 #else
491             if (canvas->GetGPUContext() == nullptr) {
492 #endif
493                 RS_LOGE("RSHardwareThread::Redraw CreateEglImageFromBuffer GrContext is null!");
494                 continue;
495             }
496             uint32_t eglTextureId = 0;
497             uint32_t bufferId = 0;
498             (void)eglTextureId;
499             (void)bufferId;
500 #if defined(RS_ENABLE_GL) && defined(RS_ENABLE_EGLIMAGE)
501             if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
502                 auto eglImageCache = uniRenderEngine_->GetEglImageManager()->CreateImageCacheFromBuffer(params.buffer,
503                     params.acquireFence);
504                 if (eglImageCache == nullptr) {
505                     continue;
506                 }
507                 eglTextureId = eglImageCache->TextureId();
508                 if (eglTextureId == 0) {
509                     RS_LOGE("RSHardwareThread::Redraw CreateImageCacheFromBuffer return invalid texture ID");
510                     continue;
511                 }
512                 bufferId = params.buffer->GetSeqNum();
513                 imageCacheSeqs[bufferId] = std::move(eglImageCache);
514             }
515 #endif
516 #ifndef USE_ROSEN_DRAWING
517             SkColorType colorType = kRGBA_8888_SkColorType;
518             std::shared_ptr<GrBackendTexture> backendTexturePtr = nullptr;
519             auto pixelFmt = params.buffer->GetFormat();
520             if (pixelFmt == GRAPHIC_PIXEL_FMT_BGRA_8888) {
521                 colorType = kBGRA_8888_SkColorType;
522             } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_P010 || pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_P010) {
523                 colorType = kRGBA_1010102_SkColorType;
524             }
525             (void)backendTexturePtr;
526 #if defined(RS_ENABLE_GL) && defined(RS_ENABLE_EGLIMAGE)
527             if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
528                 auto glType = GL_RGBA8;
529                 if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_P010 || pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_P010) {
530                     glType = GL_RGB10_A2;
531                 }
532 
533                 GrGLTextureInfo grExternalTextureInfo = { GL_TEXTURE_EXTERNAL_OES, eglTextureId,
534                     static_cast<GrGLenum>(glType) };
535                 backendTexturePtr = std::make_shared<GrBackendTexture>(params.buffer->GetSurfaceBufferWidth(),
536                     params.buffer->GetSurfaceBufferHeight(), GrMipMapped::kNo, grExternalTextureInfo);
537             }
538 #endif
539             sk_sp<SkImage> image = nullptr;
540             (void)image;
541 #if defined(RS_ENABLE_GL) && defined(RS_ENABLE_EGLIMAGE)
542             if (RSSystemProperties::GetGpuApiType() != GpuApiType::VULKAN &&
543                 RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR && backendTexturePtr != nullptr) {
544                 image = SkImage::MakeFromTexture(canvas->recordingContext(), *backendTexturePtr,
545                     kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, skColorSpace);
546             }
547 #endif
548 #if defined(RS_ENABLE_VK)
549             if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
550                 RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
551                 auto imageCache = uniRenderEngine_->GetVkImageManager()->CreateImageCacheFromBuffer(
552                     params.buffer, params.acquireFence);
553                 if (!imageCache) {
554                     continue;
555                 }
556                 auto bufferId = params.buffer->GetSeqNum();
557                 imageCacheSeqsVK[bufferId] = imageCache;
558                 auto& backendTexture = imageCache->GetBackendTexture();
559                 if (!backendTexture.isValid()) {
560                     ROSEN_LOGE("RSHardwareThread: backendTexture is not valid!!!");
561                     return;
562                 }
563 
564                 image = SkImage::MakeFromTexture(
565                     canvas->recordingContext(),
566                     backendTexture,
567                     kTopLeft_GrSurfaceOrigin,
568                     colorType,
569                     kPremul_SkAlphaType,
570                     skColorSpace,
571                     NativeBufferUtils::DeleteVkImage,
572                     imageCache->RefCleanupHelper());
573             } else {
574                 image = SkImage::MakeFromTexture(canvas->getGrContext(), backendTexture,
575                     kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, skColorSpace);
576             }
577 #endif
578             if (image == nullptr) {
579                 RS_LOGE("RSHardwareThread::DrawImage: image is nullptr!");
580                 return;
581             }
582 #ifdef USE_VIDEO_PROCESSING_ENGINE
583             SkMatrix matrix;
584             auto sx = params.dstRect.width() / params.srcRect.width();
585             auto sy = params.dstRect.height() / params.srcRect.height();
586             matrix.setScaleTranslate(sx, sy, params.dstRect.x(), params.dstRect.y());
587             sk_sp<SkShader> imageShader = image->makeShader(SkSamplingOptions(), matrix);
588             if (imageShader == nullptr) {
589                 RS_LOGE("RSHardwareThread::DrawImage imageShader is nullptr.");
590             } else {
591                 params.paint.setShader(imageShader);
592                 params.targetColorGamut = colorGamut;
593                 params.screenBrightnessNits = screenManager->GetScreenBrightnessNits(screenId);
594 
595                 uniRenderEngine_->ColorSpaceConvertor(imageShader, params);
596             }
597 #endif
598 
599             RS_TRACE_NAME_FMT("DrawImage(GPU) seqNum: %d", bufferId);
600 #ifndef USE_VIDEO_PROCESSING_ENGINE
601             canvas->drawImageRect(image, params.srcRect, params.dstRect, SkSamplingOptions(),
602                 &(params.paint), SkCanvas::kStrict_SrcRectConstraint);
603 #else
604             canvas->drawRect(params.dstRect, (params.paint));
605 #endif // USE_VIDEO_PROCESSING_ENGINE
606 #else // USE_ROSEN_DRAWING
607             std::shared_ptr<Drawing::Image> image = nullptr;
608 #if defined(RS_ENABLE_GL) && defined(RS_ENABLE_EGLIMAGE)
609             if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
610                 Drawing::ColorType colorType = Drawing::ColorType::COLORTYPE_RGBA_8888;
611                 auto pixelFmt = params.buffer->GetFormat();
612                 if (pixelFmt == GRAPHIC_PIXEL_FMT_BGRA_8888) {
613                     colorType = Drawing::ColorType::COLORTYPE_BGRA_8888;
614                 } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_P010 || pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_P010) {
615                     colorType = Drawing::ColorType::COLORTYPE_RGBA_1010102;
616                 }
617 
618                 Drawing::BitmapFormat bitmapFormat = { colorType, Drawing::AlphaType::ALPHATYPE_PREMUL };
619 
620                 Drawing::TextureInfo externalTextureInfo;
621                 externalTextureInfo.SetWidth(params.buffer->GetSurfaceBufferWidth());
622                 externalTextureInfo.SetHeight(params.buffer->GetSurfaceBufferHeight());
623                 externalTextureInfo.SetIsMipMapped(false);
624                 externalTextureInfo.SetTarget(GL_TEXTURE_EXTERNAL_OES);
625                 externalTextureInfo.SetID(eglTextureId);
626                 auto glType = GR_GL_RGBA8;
627                 if (pixelFmt == GRAPHIC_PIXEL_FMT_BGRA_8888) {
628                     glType = GR_GL_BGRA8;
629                 } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_P010 || pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_P010) {
630                     glType = GL_RGB10_A2;
631                 }
632                 externalTextureInfo.SetFormat(glType);
633 
634                 image = std::make_shared<Drawing::Image>();
635                 if (!image->BuildFromTexture(*canvas->GetGPUContext(), externalTextureInfo,
636                     Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, drawingColorSpace)) {
637                     RS_LOGE("RSHardwareThread::Redraw: image BuildFromTexture failed");
638                     return;
639                 }
640             }
641 #endif
642 #ifdef RS_ENABLE_VK
643             if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
644                 RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
645                 Drawing::ColorType colorType = GetColorTypeFromBufferFormat(params.buffer->GetFormat());
646                 auto imageCache = uniRenderEngine_->GetVkImageManager()->CreateImageCacheFromBuffer(
647                     params.buffer, params.acquireFence);
648                 if (!imageCache) {
649                     continue;
650                 }
651                 auto bufferId = params.buffer->GetSeqNum();
652                 imageCacheSeqsVK[bufferId] = imageCache;
653                 auto& backendTexture = imageCache->GetBackendTexture();
654 
655                 Drawing::BitmapFormat bitmapFormat = { colorType, Drawing::AlphaType::ALPHATYPE_PREMUL };
656 
657                 image = std::make_shared<Drawing::Image>();
658                 if (!image->BuildFromTexture(*canvas->GetGPUContext(), backendTexture.GetTextureInfo(),
659                     Drawing::TextureOrigin::TOP_LEFT, bitmapFormat, drawingColorSpace,
660                     NativeBufferUtils::DeleteVkImage,
661                     imageCache->RefCleanupHelper())) {
662                     RS_LOGE("RSHardwareThread::Redraw: image BuildFromTexture failed");
663                     return;
664                 }
665             }
666 #endif
667             if (image == nullptr) {
668                 RS_LOGE("RSHardwareThread::DrawImage: image is nullptr!");
669                 return;
670             }
671 #ifdef USE_VIDEO_PROCESSING_ENGINE
672             Drawing::Matrix matrix;
673             auto sx = params.dstRect.GetWidth() / params.srcRect.GetWidth();
674             auto sy = params.dstRect.GetHeight() / params.srcRect.GetHeight();
675             matrix.SetScaleTranslate(sx, sy, params.dstRect.GetLeft(), params.dstRect.GetTop());
676             auto imageShader = Drawing::ShaderEffect::CreateImageShader(
677                 *image, Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP, Drawing::SamplingOptions(), matrix);
678             if (imageShader == nullptr) {
679                 RS_LOGE("RSHardwareThread::DrawImage imageShader is nullptr.");
680             } else {
681                 params.paint.SetShaderEffect(imageShader);
682                 params.targetColorGamut = colorGamut;
683                 params.screenBrightnessNits = screenManager->GetScreenBrightnessNits(screenId);
684 
685                 uniRenderEngine_->ColorSpaceConvertor(imageShader, params);
686             }
687 #endif
688 
689             canvas->AttachBrush(params.paint);
690             RS_TRACE_NAME_FMT("DrawImage(GPU) seqNum: %d", bufferId);
691 #ifndef USE_VIDEO_PROCESSING_ENGINE
692             canvas->DrawImageRect(*image, params.srcRect, params.dstRect,
693                 Drawing::SamplingOptions(), Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
694 #else
695             canvas->DrawRect(params.dstRect);
696 #endif
697             canvas->DetachBrush();
698 #endif // USE_ROSEN_DRAWING
699         } else {
700             uniRenderEngine_->DrawBuffer(*canvas, params);
701         }
702 #endif
703     }
704 
705     if (isTopGpuDraw && RSSingleton<RoundCornerDisplay>::GetInstance().GetRcdEnable()) {
706         RSSingleton<RoundCornerDisplay>::GetInstance().DrawTopRoundCorner(canvas.get());
707     }
708 
709     if (isBottomGpuDraw && RSSingleton<RoundCornerDisplay>::GetInstance().GetRcdEnable()) {
710         RSSingleton<RoundCornerDisplay>::GetInstance().DrawBottomRoundCorner(canvas.get());
711     }
712     renderFrame->Flush();
713 #ifdef RS_ENABLE_EGLIMAGE
714 #ifdef RS_ENABLE_VK
715     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
716         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
717         imageCacheSeqsVK.clear();
718     }
719 #endif
720 #ifdef RS_ENABLE_GL
721     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
722         imageCacheSeqs.clear();
723     }
724 #endif
725 #endif
726     RS_LOGD("RsDebug RSHardwareThread::Redraw flush frame buffer end");
727 }
728 
729 // private func, guarantee the layer and surface are valid
730 void RSHardwareThread::LayerPresentTimestamp(const LayerInfoPtr& layer, const sptr<IConsumerSurface>& surface) const
731 {
732     if (!layer->IsSupportedPresentTimestamp()) {
733         return;
734     }
735     const auto& buffer = layer->GetBuffer();
736     if (buffer == nullptr) {
737         return;
738     }
739     if (surface->SetPresentTimestamp(buffer->GetSeqNum(), layer->GetPresentTimestamp()) != GSERROR_OK) {
740         RS_LOGD("RsDebug RSUniRenderComposerAdapter::LayerPresentTimestamp: SetPresentTimestamp failed");
741     }
742 }
743 
744 void RSHardwareThread::AddRefreshRateCount()
745 {
746     auto screenManager = CreateOrGetScreenManager();
747     ScreenId id = screenManager->GetDefaultScreenId();
748     auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
749     uint32_t currentRefreshRate = hgmCore.GetScreenCurrentRefreshRate(id);
750     auto [iter, success] = refreshRateCounts_.try_emplace(currentRefreshRate, 1);
751     if (!success) {
752         iter->second++;
753     }
754     RSRealtimeRefreshRateManager::Instance().CountRealtimeFrame();
755 }
756 
757 #ifdef USE_VIDEO_PROCESSING_ENGINE
758 GraphicColorGamut RSHardwareThread::ComputeTargetColorGamut(const std::vector<LayerInfoPtr>& layers)
759 {
760     using namespace HDI::Display::Graphic::Common::V1_0;
761     GraphicColorGamut colorGamut = GRAPHIC_COLOR_GAMUT_SRGB;
762     for (auto& layer : layers) {
763         auto buffer = layer->GetBuffer();
764         if (buffer == nullptr) {
765             RS_LOGW("RSHardwareThread::ComputeTargetColorGamut The buffer of layer is nullptr");
766             continue;
767         }
768 
769         CM_ColorSpaceInfo colorSpaceInfo;
770         if (MetadataHelper::GetColorSpaceInfo(buffer, colorSpaceInfo) != GSERROR_OK) {
771             RS_LOGD("RSHardwareThread::ComputeTargetColorGamut Get color space failed");
772             continue;
773         }
774 
775         if (colorSpaceInfo.primaries != COLORPRIMARIES_SRGB) {
776             colorGamut = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
777             break;
778         }
779     }
780 
781     return colorGamut;
782 }
783 
784 GraphicPixelFormat RSHardwareThread::ComputeTargetPixelFormat(const std::vector<LayerInfoPtr>& layers)
785 {
786     using namespace HDI::Display::Graphic::Common::V1_0;
787     GraphicPixelFormat pixelFormat = GRAPHIC_PIXEL_FMT_RGBA_8888;
788     for (auto& layer : layers) {
789         auto buffer = layer->GetBuffer();
790         if (buffer == nullptr) {
791             RS_LOGW("RSHardwareThread::ComputeTargetPixelFormat The buffer of layer is nullptr");
792             continue;
793         }
794 
795         auto bufferPixelFormat = buffer->GetFormat();
796         if (bufferPixelFormat == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
797             bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCBCR_P010 ||
798             bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCRCB_P010) {
799             pixelFormat = GRAPHIC_PIXEL_FMT_RGBA_1010102;
800             RS_LOGD("RSHardwareThread::ComputeTargetPixelFormat pixelformat is set to 1010102 for 10bit buffer");
801             break;
802         }
803     }
804 
805     return pixelFormat;
806 }
807 #endif
808 }
809