1 /*
2 * Copyright (c) 2021-2022 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 "rs_uni_render_virtual_processor.h"
17
18 #include <ctime>
19 #include <parameters.h>
20
21 #include "metadata_helper.h"
22
23 #include "common/rs_optional_trace.h"
24 #include "drawable/rs_display_render_node_drawable.h"
25 #include "graphic_feature_param_manager.h"
26 #include "platform/common/rs_log.h"
27 #include "platform/ohos/backend/rs_surface_frame_ohos_raster.h"
28 #include "rs_uni_render_util.h"
29 #include "pipeline/main_thread/rs_main_thread.h"
30 #include "string_utils.h"
31
32 namespace OHOS {
33 namespace Rosen {
InitForRenderThread(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,ScreenId mirroredId,std::shared_ptr<RSBaseRenderEngine> renderEngine)34 bool RSUniRenderVirtualProcessor::InitForRenderThread(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable,
35 ScreenId mirroredId, std::shared_ptr<RSBaseRenderEngine> renderEngine)
36 {
37 if (!RSProcessor::InitForRenderThread(displayDrawable, mirroredId, renderEngine)) {
38 return false;
39 }
40
41 // Do expand screen if the mirror id is invalid.
42 isExpand_ = (mirroredId == INVALID_SCREEN_ID);
43 auto screenManager = CreateOrGetScreenManager();
44 if (screenManager == nullptr) {
45 return false;
46 }
47 auto& params = displayDrawable.GetRenderParams();
48 if (!params) {
49 return false;
50 }
51 virtualScreenId_ = params->GetScreenId();
52 VirtualScreenStatus screenStatus = screenManager->GetVirtualScreenStatus(virtualScreenId_);
53 if (screenStatus == VIRTUAL_SCREEN_PAUSE) {
54 RS_LOGD("RSUniRenderVirtualProcessor::Init screenStatus is pause");
55 return false;
56 }
57 auto virtualScreenInfo = screenManager->QueryScreenInfo(virtualScreenId_);
58 canvasRotation_ = screenManager->GetCanvasRotation(virtualScreenId_);
59 scaleMode_ = screenManager->GetScaleMode(virtualScreenId_);
60 virtualScreenWidth_ = static_cast<float>(virtualScreenInfo.width);
61 virtualScreenHeight_ = static_cast<float>(virtualScreenInfo.height);
62 originalVirtualScreenWidth_ = virtualScreenWidth_;
63 originalVirtualScreenHeight_ = virtualScreenHeight_;
64 if (EnableVisibleRect()) {
65 const auto& rect = screenManager->GetMirrorScreenVisibleRect(virtualScreenId_);
66 visibleRect_ = Drawing::RectI(rect.x, rect.y, rect.x + rect.w, rect.y + rect.h);
67 // not support rotation for MirrorScreen visibleRect
68 canvasRotation_ = screenManager->IsVisibleRectSupportRotation(virtualScreenId_);
69 }
70
71 renderFrameConfig_.colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
72 auto mirroredDisplayDrawable =
73 std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(params->GetMirrorSourceDrawable().lock());
74 if (mirroredDisplayDrawable) {
75 auto& mirroredParams = mirroredDisplayDrawable->GetRenderParams();
76 if (mirroredParams) {
77 screenRotation_ = mirroredParams->GetScreenRotation();
78 screenCorrection_ = screenManager->GetScreenCorrection(mirroredParams->GetScreenId());
79 auto mainScreenInfo = screenManager->QueryScreenInfo(mirroredParams->GetScreenId());
80 mirroredScreenWidth_ = mainScreenInfo.isSamplingOn ? static_cast<float>(mainScreenInfo.phyWidth) :
81 static_cast<float>(mainScreenInfo.width);
82 mirroredScreenHeight_ = mainScreenInfo.isSamplingOn ? static_cast<float>(mainScreenInfo.phyHeight) :
83 static_cast<float>(mainScreenInfo.height);
84 auto displayParams = static_cast<RSDisplayRenderParams*>(params.get());
85 auto mirroredDisplayParams = static_cast<RSDisplayRenderParams*>(mirroredParams.get());
86 if (displayParams && mirroredDisplayParams &&
87 displayParams->GetNewColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB &&
88 mirroredDisplayParams->GetNewColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
89 renderFrameConfig_.colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
90 RS_LOGD("RSUniRenderVirtualProcessor::Init Set virtual screen buffer colorGamut to P3.");
91 }
92 }
93 } else if (isExpand_) {
94 auto displayParams = static_cast<RSDisplayRenderParams*>(params.get());
95 if (displayParams && displayParams->GetNewColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
96 renderFrameConfig_.colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
97 }
98 }
99
100 renderFrameConfig_.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_MEM_DMA;
101 FrameContextConfig frameContextConfig = {false, false};
102 frameContextConfig.isVirtual = true;
103 frameContextConfig.timeOut = 0;
104
105 producerSurface_ = screenManager->GetProducerSurface(virtualScreenId_);
106 if (producerSurface_ == nullptr) {
107 RS_LOGE("RSUniRenderVirtualProcessor::Init for Screen(id %{public}" PRIu64 "): ProducerSurface is null!",
108 virtualScreenId_);
109 return false;
110 }
111 #ifdef RS_ENABLE_GL
112 if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
113 renderFrame_ = renderEngine_->RequestFrame(producerSurface_, renderFrameConfig_, forceCPU_, false,
114 frameContextConfig);
115 }
116 #endif
117 if (renderFrame_ == nullptr) {
118 uint64_t pSurfaceUniqueId = producerSurface_->GetUniqueId();
119 auto rsSurface = displayDrawable.GetVirtualSurface(pSurfaceUniqueId);
120 if (rsSurface == nullptr || screenManager->GetAndResetVirtualSurfaceUpdateFlag(virtualScreenId_)) {
121 RS_LOGD("RSUniRenderVirtualProcessor::Init Make rssurface from producer Screen(id %{public}" PRIu64 ")",
122 virtualScreenId_);
123 RS_TRACE_NAME_FMT("RSUniRenderVirtualProcessor::Init Make rssurface from producer Screen(id %" PRIu64 ")",
124 virtualScreenId_);
125 rsSurface = renderEngine_->MakeRSSurface(producerSurface_, forceCPU_);
126 displayDrawable.SetVirtualSurface(rsSurface, pSurfaceUniqueId);
127 }
128 renderFrame_ = renderEngine_->RequestFrame(
129 std::static_pointer_cast<RSSurfaceOhos>(rsSurface), renderFrameConfig_, forceCPU_, false,
130 frameContextConfig);
131 }
132 if (renderFrame_ == nullptr) {
133 RS_LOGE("RSUniRenderVirtualProcessor::Init for Screen(id %{public}" PRIu64 "): RenderFrame is null!",
134 virtualScreenId_);
135 return false;
136 }
137
138 RS_LOGD("RSUniRenderVirtualProcessor::Init, RequestFrame succeed.");
139 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVirtualProcessor::Init, RequestFrame succeed.");
140 uint64_t pSurfaceUniqueId = producerSurface_->GetUniqueId();
141 auto rsSurface = displayDrawable.GetVirtualSurface(pSurfaceUniqueId);
142 if (rsSurface != nullptr && SetColorSpaceForMetadata(rsSurface->GetColorSpace()) != GSERROR_OK) {
143 RS_LOGD("RSUniRenderVirtualProcessor::SetColorSpaceForMetadata failed.");
144 }
145 canvas_ = renderFrame_->GetCanvas();
146 if (canvas_ == nullptr) {
147 RS_LOGE("RSUniRenderVirtualProcessor::Init for Screen(id %{public}" PRIu64 "): Canvas is null!",
148 virtualScreenId_);
149 return false;
150 }
151
152 CanvasInit(displayDrawable);
153
154 return true;
155 }
156
RequestVirtualFrame(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)157 bool RSUniRenderVirtualProcessor::RequestVirtualFrame(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
158 {
159 auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
160 if (renderEngine == nullptr) {
161 RS_LOGE("RSUniRenderVirtualProcessor::RequestVirtualFrame RenderEngine is null!");
162 return false;
163 }
164 if (producerSurface_ == nullptr) {
165 RS_LOGE("RSUniRenderVirtualProcessor::RequestVirtualFrame for virtualScreen(id %{public}" PRIu64 "):"
166 "ProducerSurface is null!", virtualScreenId_);
167 return false;
168 }
169 #ifdef RS_ENABLE_GL
170 if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
171 renderFrame_ = renderEngine->RequestFrame(producerSurface_, renderFrameConfig_, forceCPU_, false);
172 }
173 #endif
174 if (renderFrame_ == nullptr) {
175 uint64_t pSurfaceUniqueId = producerSurface_->GetUniqueId();
176 auto rsSurface = displayDrawable.GetVirtualSurface(pSurfaceUniqueId);
177 if (rsSurface == nullptr || updateFlag_) {
178 RS_LOGD("RSUniRenderVirtualProcessor::RequestVirtualFrame,"
179 "Make rssurface from producer virtualScreen(id %{public}" PRIu64 ")", virtualScreenId_);
180 RS_TRACE_NAME_FMT("RSUniRenderVirtualProcessor::RequestVirtualFrame,"
181 "Make rssurface from producer virtualScreen(id %" PRIu64 ")", virtualScreenId_);
182 rsSurface = renderEngine->MakeRSSurface(producerSurface_, forceCPU_);
183 displayDrawable.SetVirtualSurface(rsSurface, pSurfaceUniqueId);
184 }
185 renderFrame_ = renderEngine->RequestFrame(
186 std::static_pointer_cast<RSSurfaceOhos>(rsSurface), renderFrameConfig_, forceCPU_, false);
187 }
188 if (renderFrame_ == nullptr) {
189 RS_LOGE("RSUniRenderVirtualProcessor::RequestVirtualFrame RenderFrame is null!");
190 return false;
191 }
192 return true;
193 }
194
CanvasInit(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)195 void RSUniRenderVirtualProcessor::CanvasInit(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
196 {
197 // Save the initial canvas state
198 canvas_->Save();
199 if (displayDrawable.IsFirstTimeToProcessor() || canvasRotation_) {
200 if (displayDrawable.IsFirstTimeToProcessor()) {
201 RS_LOGI("RSUniRenderVirtualProcessor::CanvasInit, id: %{public}" PRIu64 ", " \
202 "screen(%{public}f, %{public}f, %{public}f, %{public}f), " \
203 "rotation: %{public}d, correction: %{public}d, needRotation: %{public}d, scaleMode: %{public}d",
204 virtualScreenId_, mirroredScreenWidth_, mirroredScreenHeight_, virtualScreenWidth_,
205 virtualScreenHeight_, screenRotation_, screenCorrection_, canvasRotation_, scaleMode_);
206 }
207 displayDrawable.SetOriginScreenRotation(screenRotation_);
208 }
209 auto rotationDiff = static_cast<int>(displayDrawable.GetOriginScreenRotation()) -
210 static_cast<int>(screenCorrection_);
211 auto rotationAngle = static_cast<ScreenRotation>((rotationDiff + SCREEN_ROTATION_NUM) % SCREEN_ROTATION_NUM);
212 OriginScreenRotation(rotationAngle, renderFrameConfig_.width, renderFrameConfig_.height);
213
214 RS_LOGD("RSUniRenderVirtualProcessor::CanvasInit, id: %{public}" PRIu64 ", " \
215 "screen(%{public}f, %{public}f, %{public}f, %{public}f), " \
216 "rotation: %{public}d, correction: %{public}d, needRotation: %{public}d, scaleMode: %{public}d",
217 virtualScreenId_, mirroredScreenWidth_, mirroredScreenHeight_, virtualScreenWidth_, virtualScreenHeight_,
218 screenRotation_, screenCorrection_, canvasRotation_, scaleMode_);
219 }
220
GetBufferAge() const221 int32_t RSUniRenderVirtualProcessor::GetBufferAge() const
222 {
223 if (renderFrame_ == nullptr) {
224 RS_LOGE("RSUniRenderVirtualProcessor::GetBufferAge renderFrame_ is null.");
225 return 0;
226 }
227 return renderFrame_->GetBufferAge();
228 }
229
SetColorSpaceForMetadata(GraphicColorGamut colorSpace)230 GSError RSUniRenderVirtualProcessor::SetColorSpaceForMetadata(GraphicColorGamut colorSpace)
231 {
232 if (renderFrame_ == nullptr) {
233 RS_LOGD("RSUniRenderVirtualProcessor::SetColorSpaceForMetadata renderFrame is null.");
234 return GSERROR_INVALID_ARGUMENTS;
235 }
236 auto rsSurface = renderFrame_->GetSurface();
237 if (rsSurface == nullptr) {
238 RS_LOGD("RSUniRenderVirtualProcessor::SetColorSpaceForMetadata surface is null.");
239 return GSERROR_INVALID_ARGUMENTS;
240 }
241 auto buffer = rsSurface->GetCurrentBuffer();
242 if (buffer == nullptr) {
243 RS_LOGD("RSUniRenderVirtualProcessor::SetColorSpaceForMetadata buffer is null.");
244 return GSERROR_NO_BUFFER;
245 }
246 using namespace HDI::Display::Graphic::Common::V1_0;
247 auto iter = COLORSPACE_TYPE.find(colorSpace);
248 if (iter == COLORSPACE_TYPE.end()) {
249 return GSERROR_OK;
250 }
251 CM_ColorSpaceInfo colorSpaceInfo;
252 GSError ret = MetadataHelper::ConvertColorSpaceTypeToInfo(iter->second, colorSpaceInfo);
253 if (ret != GSERROR_OK) {
254 RS_LOGD("RSUniRenderVirtualProcessor::SetColorSpaceForMetadata ConvertColorSpaceTypeToInfo failed.");
255 return ret;
256 }
257 std::vector<uint8_t> colorSpaceVec;
258 if (MetadataHelper::ConvertMetadataToVec(colorSpaceInfo, colorSpaceVec) != GSERROR_OK) {
259 RS_LOGD("RSUniRenderVirtualProcessor::SetColorSpaceForMetadata ConvertMetadataToVec failed.");
260 return GSERROR_API_FAILED;
261 }
262 return buffer->SetMetadata(ATTRKEY_COLORSPACE_INFO, colorSpaceVec);
263 }
264
SetDirtyInfo(std::vector<RectI> & damageRegion)265 void RSUniRenderVirtualProcessor::SetDirtyInfo(std::vector<RectI>& damageRegion)
266 {
267 if (renderFrame_ == nullptr) {
268 RS_LOGW("RSUniRenderVirtualProcessor::SetDirtyInfo renderFrame_ is null.");
269 return;
270 }
271 renderFrame_->SetDamageRegion(damageRegion);
272 if (SetRoiRegionToCodec(damageRegion) != GSERROR_OK) {
273 RS_LOGD("RSUniRenderVirtualProcessor::SetDirtyInfo SetRoiRegionToCodec failed.");
274 }
275 }
276
SetRoiRegionToCodec(std::vector<RectI> & damageRegion)277 GSError RSUniRenderVirtualProcessor::SetRoiRegionToCodec(std::vector<RectI>& damageRegion)
278 {
279 if (renderFrame_ == nullptr) {
280 RS_LOGD("RSUniRenderVirtualProcessor::SetRoiRegionToCodec renderFrame is null.");
281 return GSERROR_INVALID_ARGUMENTS;
282 }
283
284 auto& rsSurface = renderFrame_->GetSurface();
285 if (rsSurface == nullptr) {
286 RS_LOGD("RSUniRenderVirtualProcessor::SetRoiRegionToCodec surface is null.");
287 return GSERROR_INVALID_ARGUMENTS;
288 }
289
290 auto buffer = rsSurface->GetCurrentBuffer();
291 if (buffer == nullptr) {
292 RS_LOGD("RSUniRenderVirtualProcessor::SetRoiRegionToCodec buffer is null, not support get surfacebuffer.");
293 return GSERROR_NO_BUFFER;
294 }
295
296 RoiRegions roiRegions;
297 const RectI screenRect{0, 0, originalVirtualScreenWidth_, originalVirtualScreenHeight_};
298 if (damageRegion.size() <= ROI_REGIONS_MAX_CNT) {
299 for (auto rect : damageRegion) {
300 rect = rect.IntersectRect(screenRect);
301 if (!rect.IsEmpty()) {
302 RoiRegionInfo region = RoiRegionInfo{rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight()};
303 roiRegions.regions[roiRegions.regionCnt++] = region;
304 }
305 }
306 } else {
307 RectI mergedRect;
308 for (auto& rect : damageRegion) {
309 mergedRect = mergedRect.JoinRect(rect);
310 }
311 mergedRect = mergedRect.IntersectRect(screenRect);
312 if (!mergedRect.IsEmpty()) {
313 RoiRegionInfo region = RoiRegionInfo{mergedRect.GetLeft(), mergedRect.GetTop(),
314 mergedRect.GetWidth(), mergedRect.GetHeight()};
315 roiRegions.regions[roiRegions.regionCnt++] = region;
316 }
317 }
318
319 std::vector<uint8_t> roiRegionsVec;
320 auto ret = MetadataHelper::ConvertMetadataToVec(roiRegions, roiRegionsVec);
321 if (ret != GSERROR_OK) {
322 RS_LOGD("RSUniRenderVirtualProcessor::SetRoiRegionToCodec ConvertMetadataToVec failed.");
323 return ret;
324 }
325 return buffer->SetMetadata(GrallocBufferAttr::GRALLOC_BUFFER_ATTR_BUFFER_ROI_INFO, roiRegionsVec);
326 }
327
OriginScreenRotation(ScreenRotation screenRotation,float width,float height)328 void RSUniRenderVirtualProcessor::OriginScreenRotation(ScreenRotation screenRotation, float width, float height)
329 {
330 if (screenRotation == ScreenRotation::ROTATION_0) {
331 return;
332 } else if (screenRotation == ScreenRotation::ROTATION_90) {
333 canvas_->Translate(width / 2.0f, height / 2.0f);
334 canvas_->Rotate(90, 0, 0); // 90 degrees
335 canvas_->Translate(-(height / 2.0f), -(width / 2.0f));
336 } else if (screenRotation == ScreenRotation::ROTATION_180) {
337 canvas_->Rotate(180, width / 2.0f, height / 2.0f); // 180 degrees
338 } else if (screenRotation == ScreenRotation::ROTATION_270) {
339 canvas_->Translate(width / 2.0f, height / 2.0f);
340 canvas_->Rotate(270, 0, 0); // 270 degrees
341 canvas_->Translate(-(height / 2.0f), -(width / 2.0f));
342 }
343 }
344
ScaleMirrorIfNeed(const ScreenRotation angle,RSPaintFilterCanvas & canvas)345 void RSUniRenderVirtualProcessor::ScaleMirrorIfNeed(const ScreenRotation angle, RSPaintFilterCanvas& canvas)
346 {
347 if (screenCorrection_ == ScreenRotation::ROTATION_90 ||
348 screenCorrection_ == ScreenRotation::ROTATION_270) {
349 std::swap(virtualScreenWidth_, virtualScreenHeight_);
350 }
351
352 if (angle == ScreenRotation::ROTATION_90 ||
353 angle == ScreenRotation::ROTATION_270) {
354 std::swap(virtualScreenWidth_, virtualScreenHeight_);
355 }
356
357 RS_TRACE_NAME_FMT("RSUniRenderVirtualProcessor::ScaleMirrorIfNeed:(%f, %f, %f, %f), " \
358 "screenCorrection:%d, oriRotation:%d",
359 mirroredScreenWidth_, mirroredScreenHeight_, virtualScreenWidth_, virtualScreenHeight_,
360 static_cast<int>(screenCorrection_), static_cast<int>(angle));
361
362 float mirroredScreenWidth = mirroredScreenWidth_;
363 float mirroredScreenHeight = mirroredScreenHeight_;
364 if (EnableVisibleRect()) {
365 mirroredScreenWidth = visibleRect_.GetWidth();
366 mirroredScreenHeight = visibleRect_.GetHeight();
367 if (mirroredScreenWidth < EPSILON || mirroredScreenHeight < EPSILON) {
368 RS_LOGE("RSUniRenderVirtualProcessor::ScaleMirrorIfNeed, input is illegal.");
369 return;
370 }
371 if (!drawMirrorCopy_) {
372 float top = visibleRect_.GetTop();
373 float left = visibleRect_.GetLeft();
374 float startRectX = virtualScreenWidth_ * (left / mirroredScreenWidth);
375 float startRectY = virtualScreenHeight_ * (top / mirroredScreenHeight);
376 canvas.Translate(-startRectX, -startRectY);
377 RS_LOGD("RSUniRenderVirtualProcessor::ScaleMirrorIfNeed, top:%{public}f, left:%{public}f, width:%{public}f,"
378 "height:%{public}f, X:%{public}f, Y:%{public}f", top, left, mirroredScreenWidth,
379 mirroredScreenHeight, startRectX, startRectY);
380 }
381 }
382
383 if (mirroredScreenWidth == virtualScreenWidth_ && mirroredScreenHeight == virtualScreenHeight_) {
384 return;
385 }
386
387 if (scaleMode_ == ScreenScaleMode::FILL_MODE) {
388 Fill(canvas, mirroredScreenWidth, mirroredScreenHeight, virtualScreenWidth_, virtualScreenHeight_);
389 } else if (scaleMode_ == ScreenScaleMode::UNISCALE_MODE) {
390 UniScale(canvas, mirroredScreenWidth, mirroredScreenHeight, virtualScreenWidth_, virtualScreenHeight_);
391 }
392 }
393
PostProcess()394 void RSUniRenderVirtualProcessor::PostProcess()
395 {
396 if (renderFrame_ == nullptr || renderEngine_ == nullptr) {
397 RS_LOGE("RSUniRenderVirtualProcessor::PostProcess renderFrame or renderEngine is nullptr");
398 return;
399 }
400 auto surfaceOhos = renderFrame_->GetSurface();
401 RSBaseRenderEngine::SetUiTimeStamp(renderFrame_, surfaceOhos);
402 renderFrame_->Flush();
403 RS_LOGD("RSUniRenderVirtualProcessor::PostProcess, FlushFrame succeed.");
404 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVirtualProcessor::PostProcess, FlushFrame succeed.");
405 }
406
ProcessSurface(RSSurfaceRenderNode & node)407 void RSUniRenderVirtualProcessor::ProcessSurface(RSSurfaceRenderNode& node)
408 {
409 (void)node;
410 RS_LOGI("RSUniRenderVirtualProcessor::ProcessSurface() is not supported.");
411 }
412
CalculateTransform(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)413 void RSUniRenderVirtualProcessor::CalculateTransform(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
414 {
415 if (canvas_ == nullptr || displayDrawable.GetRSSurfaceHandlerOnDraw()->GetBuffer() == nullptr) {
416 RS_LOGE("RSUniRenderVirtualProcessor::CalculateTransform: Canvas or buffer is null!");
417 return;
418 }
419
420 canvas_->Save();
421 ScreenRotation angle = displayDrawable.GetOriginScreenRotation();
422 ScaleMirrorIfNeed(angle, *canvas_);
423 canvasMatrix_ = canvas_->GetTotalMatrix();
424 }
425
ProcessDisplaySurfaceForRenderThread(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)426 void RSUniRenderVirtualProcessor::ProcessDisplaySurfaceForRenderThread(
427 DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
428 {
429 if (isExpand_) {
430 return;
431 }
432 auto surfaceHandler = displayDrawable.GetRSSurfaceHandlerOnDraw();
433 if (canvas_ == nullptr || surfaceHandler->GetBuffer() == nullptr) {
434 RS_LOGE("RSUniRenderVirtualProcessor::ProcessDisplaySurface: Canvas or buffer is null!");
435 return;
436 }
437 auto params = RSUniRenderUtil::CreateBufferDrawParam(*surfaceHandler, forceCPU_);
438 params.isMirror = true;
439 if (EnableVisibleRect()) {
440 params.srcRect = visibleRect_;
441 params.dstRect = Drawing::Rect(0, 0, visibleRect_.GetWidth(), visibleRect_.GetHeight());
442 }
443 renderEngine_->DrawDisplayNodeWithParams(*canvas_, *surfaceHandler, params);
444 canvas_->Restore();
445 }
446
ProcessVirtualDisplaySurface(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)447 void RSUniRenderVirtualProcessor::ProcessVirtualDisplaySurface(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
448 {
449 auto surfaceHandler = displayDrawable.GetRSSurfaceHandlerOnDraw();
450 if (canvas_ == nullptr || surfaceHandler->GetBuffer() == nullptr) {
451 RS_LOGE("RSUniRenderVirtualProcessor::ProcessVirtualDisplaySurface: Canvas or buffer is null!");
452 return;
453 }
454 auto bufferDrawParam = RSUniRenderUtil::CreateBufferDrawParam(*surfaceHandler, forceCPU_);
455 bufferDrawParam.isMirror = true;
456 renderEngine_->DrawDisplayNodeWithParams(*canvas_, *surfaceHandler, bufferDrawParam);
457 canvas_->Restore();
458 }
459
Fill(RSPaintFilterCanvas & canvas,float mainWidth,float mainHeight,float mirrorWidth,float mirrorHeight)460 void RSUniRenderVirtualProcessor::Fill(RSPaintFilterCanvas& canvas,
461 float mainWidth, float mainHeight, float mirrorWidth, float mirrorHeight)
462 {
463 if (mainWidth > 0 && mainHeight > 0) {
464 mirrorScaleX_ = mirrorWidth / mainWidth;
465 mirrorScaleY_ = mirrorHeight / mainHeight;
466 canvas.Scale(mirrorScaleX_, mirrorScaleY_);
467 }
468 }
469
UniScale(RSPaintFilterCanvas & canvas,float mainWidth,float mainHeight,float mirrorWidth,float mirrorHeight)470 void RSUniRenderVirtualProcessor::UniScale(RSPaintFilterCanvas& canvas,
471 float mainWidth, float mainHeight, float mirrorWidth, float mirrorHeight)
472 {
473 if (mainWidth > 0 && mainHeight > 0) {
474 float startX = 0.0f;
475 float startY = 0.0f;
476 mirrorScaleX_ = mirrorWidth / mainWidth;
477 mirrorScaleY_ = mirrorHeight / mainHeight;
478 if (mirrorScaleY_ < mirrorScaleX_) {
479 mirrorScaleX_ = mirrorScaleY_;
480 startX = (mirrorWidth - (mirrorScaleX_ * mainWidth)) / 2; // 2 for calc X
481 } else {
482 mirrorScaleY_ = mirrorScaleX_;
483 startY = (mirrorHeight - (mirrorScaleY_ * mainHeight)) / 2; // 2 for calc Y
484 }
485
486 if (EnableSlrScale()) {
487 if (slrManager_ == nullptr) {
488 slrManager_ = std::make_shared<RSSLRScaleFunction>(virtualScreenWidth_, virtualScreenHeight_,
489 mirroredScreenWidth_, mirroredScreenHeight_);
490 } else {
491 slrManager_->CheckOrRefreshScreen(virtualScreenWidth_, virtualScreenHeight_,
492 mirroredScreenWidth_, mirroredScreenHeight_);
493 }
494 slrManager_->CanvasScale(canvas);
495 RS_LOGD("RSUniRenderVirtualProcessor::UniScale: Scale With SLR.");
496 return;
497 }
498
499 canvas.Translate(startX, startY);
500 canvas.Scale(mirrorScaleX_, mirrorScaleY_);
501 }
502 }
503
EnableSlrScale()504 bool RSUniRenderVirtualProcessor::EnableSlrScale()
505 {
506 float slrScale = std::min(mirrorScaleX_, mirrorScaleY_);
507 auto multiScreenFeatureParam = std::static_pointer_cast<MultiScreenParam>(
508 GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[MULTISCREEN]));
509 if (!multiScreenFeatureParam) {
510 RS_LOGE("RSUniRenderVirtualProcessor::EnableSlrScale multiScreenFeatureParam is null");
511 return false;
512 }
513 if (multiScreenFeatureParam->IsSlrScaleEnabled() && RSSystemProperties::GetSLRScaleEnabled() &&
514 (slrScale < SLR_SCALE_THR_HIGH) && !EnableVisibleRect() && drawMirrorCopy_) {
515 return true;
516 }
517 return false;
518 }
519
ProcessCacheImage(Drawing::Image & cacheImage)520 void RSUniRenderVirtualProcessor::ProcessCacheImage(Drawing::Image& cacheImage)
521 {
522 if (canvas_ == nullptr) {
523 RS_LOGE("RSUniRenderVirtualProcessor::ProcessCacheImage: Canvas is null!");
524 return;
525 }
526 if (EnableSlrScale()) {
527 if (slrManager_ == nullptr) {
528 RS_LOGW("RSUniRenderVirtualProcessor::ProcessCacheImage: SlrManager is null!");
529 RSUniRenderUtil::ProcessCacheImage(*canvas_, cacheImage);
530 return;
531 }
532 slrManager_->ProcessCacheImage(*canvas_, cacheImage);
533 RS_LOGD("RSUniRenderVirtualProcessor::ProcessCacheImage: Darw With SLR.");
534 return;
535 }
536 RSUniRenderUtil::ProcessCacheImage(*canvas_, cacheImage);
537 }
538
CanvasClipRegionForUniscaleMode()539 void RSUniRenderVirtualProcessor::CanvasClipRegionForUniscaleMode()
540 {
541 if (canvas_ == nullptr) {
542 RS_LOGE("RSUniRenderVirtualProcessor::CanvasClipRegion: Canvas is null!");
543 return;
544 }
545 if (scaleMode_ == ScreenScaleMode::UNISCALE_MODE) {
546 Drawing::Rect rect(0, 0, mirroredScreenWidth_, mirroredScreenHeight_);
547 canvas_->GetTotalMatrix().MapRect(rect, rect);
548 Drawing::RectI rectI = {rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom()};
549 Drawing::Region clipRegion;
550 clipRegion.SetRect(rectI);
551 canvas_->ClipRegion(clipRegion);
552 }
553 }
554
ProcessRcdSurface(RSRcdSurfaceRenderNode & node)555 void RSUniRenderVirtualProcessor::ProcessRcdSurface(RSRcdSurfaceRenderNode& node)
556 {
557 RS_LOGI("RSUniRenderVirtualProcessor::ProcessRcdSurface() is not supported.");
558 }
559
EnableVisibleRect()560 bool RSUniRenderVirtualProcessor::EnableVisibleRect()
561 {
562 auto screenManager = CreateOrGetScreenManager();
563 if (screenManager == nullptr) {
564 return false;
565 }
566 return screenManager->QueryScreenInfo(virtualScreenId_).enableVisibleRect;
567 }
568 } // namespace Rosen
569 } // namespace OHOS
570