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