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