• 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 "platform/common/rs_log.h"
26 #ifndef NEW_RENDER_CONTEXT
27 #include "platform/ohos/backend/rs_surface_frame_ohos_raster.h"
28 #endif
29 #include "pipeline/rs_uni_render_util.h"
30 #include "pipeline/rs_main_thread.h"
31 #include "string_utils.h"
32 
33 namespace OHOS {
34 namespace Rosen {
InitForRenderThread(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,ScreenId mirroredId,std::shared_ptr<RSBaseRenderEngine> renderEngine)35 bool RSUniRenderVirtualProcessor::InitForRenderThread(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable,
36     ScreenId mirroredId, std::shared_ptr<RSBaseRenderEngine> renderEngine)
37 {
38     if (!RSProcessor::InitForRenderThread(displayDrawable, mirroredId, renderEngine)) {
39         return false;
40     }
41 
42     // Do expand screen if the mirror id is invalid.
43     isExpand_ = (mirroredId == INVALID_SCREEN_ID);
44     auto screenManager = CreateOrGetScreenManager();
45     if (screenManager == nullptr) {
46         return false;
47     }
48     auto& params = displayDrawable.GetRenderParams();
49     if (!params) {
50         return false;
51     }
52     virtualScreenId_ = params->GetScreenId();
53     auto virtualScreenInfo = screenManager->QueryScreenInfo(virtualScreenId_);
54     canvasRotation_ = screenManager->GetCanvasRotation(virtualScreenId_);
55     scaleMode_ = screenManager->GetScaleMode(virtualScreenId_);
56     virtualScreenWidth_ = static_cast<float>(virtualScreenInfo.width);
57     virtualScreenHeight_ = static_cast<float>(virtualScreenInfo.height);
58     originalVirtualScreenWidth_ = virtualScreenWidth_;
59     originalVirtualScreenHeight_ = virtualScreenHeight_;
60     auto mirroredDisplayDrawable =
61         std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(params->GetMirrorSourceDrawable().lock());
62     if (mirroredDisplayDrawable) {
63         auto& mirroredParams = mirroredDisplayDrawable->GetRenderParams();
64         if (mirroredParams) {
65             screenRotation_ = mirroredParams->GetScreenRotation();
66             screenCorrection_ = screenManager->GetScreenCorrection(mirroredParams->GetScreenId());
67             auto mainScreenInfo = screenManager->QueryScreenInfo(mirroredParams->GetScreenId());
68             mirroredScreenWidth_ = static_cast<float>(mainScreenInfo.width);
69             mirroredScreenHeight_ = static_cast<float>(mainScreenInfo.height);
70         }
71     }
72 
73     renderFrameConfig_.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_MEM_DMA;
74     FrameContextConfig frameContextConfig = {false, false};
75     frameContextConfig.isVirtual = true;
76     frameContextConfig.timeOut = 0;
77 
78     producerSurface_ = screenManager->GetProducerSurface(virtualScreenId_);
79     if (producerSurface_ == nullptr) {
80         RS_LOGE("RSUniRenderVirtualProcessor::Init for Screen(id %{public}" PRIu64 "): ProducerSurface is null!",
81             virtualScreenId_);
82         return false;
83     }
84 #ifdef RS_ENABLE_GL
85     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
86         renderFrame_ = renderEngine_->RequestFrame(producerSurface_, renderFrameConfig_, forceCPU_, false,
87             frameContextConfig);
88     }
89 #endif
90     if (renderFrame_ == nullptr) {
91         uint64_t pSurfaceUniqueId = producerSurface_->GetUniqueId();
92         auto rsSurface = displayDrawable.GetVirtualSurface(pSurfaceUniqueId);
93         if (rsSurface == nullptr || screenManager->GetAndResetVirtualSurfaceUpdateFlag(virtualScreenId_)) {
94             RS_LOGD("RSUniRenderVirtualProcessor::Init Make rssurface from producer Screen(id %{public}" PRIu64 ")",
95                 virtualScreenId_);
96             RS_TRACE_NAME_FMT("RSUniRenderVirtualProcessor::Init Make rssurface from producer Screen(id %" PRIu64 ")",
97                 virtualScreenId_);
98             rsSurface = renderEngine_->MakeRSSurface(producerSurface_, forceCPU_);
99             displayDrawable.SetVirtualSurface(rsSurface, pSurfaceUniqueId);
100         }
101 #ifdef NEW_RENDER_CONTEXT
102         renderFrame_ = renderEngine_->RequestFrame(
103             std::static_pointer_cast<RSRenderSurfaceOhos>(rsSurface), renderFrameConfig_, forceCPU_, false,
104             frameContextConfig);
105 #else
106         renderFrame_ = renderEngine_->RequestFrame(
107             std::static_pointer_cast<RSSurfaceOhos>(rsSurface), renderFrameConfig_, forceCPU_, false,
108             frameContextConfig);
109 #endif
110     }
111     if (renderFrame_ == nullptr) {
112         RS_LOGE("RSUniRenderVirtualProcessor::Init for Screen(id %{public}" PRIu64 "): RenderFrame is null!",
113             virtualScreenId_);
114         return false;
115     }
116 
117     RS_LOGD("RSUniRenderVirtualProcessor::Init, RequestFrame succeed.");
118     RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVirtualProcessor::Init, RequestFrame succeed.");
119 
120     canvas_ = renderFrame_->GetCanvas();
121     if (canvas_ == nullptr) {
122         RS_LOGE("RSUniRenderVirtualProcessor::Init for Screen(id %{public}" PRIu64 "): Canvas is null!",
123             virtualScreenId_);
124         return false;
125     }
126 
127     CanvasInit(displayDrawable);
128 
129     return true;
130 }
131 
RequestVirtualFrame(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)132 bool RSUniRenderVirtualProcessor::RequestVirtualFrame(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
133 {
134     auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
135     if (renderEngine == nullptr) {
136         RS_LOGE("RSUniRenderVirtualProcessor::RequestVirtualFrame RenderEngine is null!");
137         return false;
138     }
139     if (producerSurface_ == nullptr) {
140         RS_LOGE("RSUniRenderVirtualProcessor::RequestVirtualFrame for virtualScreen(id %{public}" PRIu64 "):"
141             "ProducerSurface is null!", virtualScreenId_);
142         return false;
143     }
144 #ifdef RS_ENABLE_GL
145     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
146         renderFrame_ = renderEngine->RequestFrame(producerSurface_, renderFrameConfig_, forceCPU_, false);
147     }
148 #endif
149     if (renderFrame_ == nullptr) {
150         uint64_t pSurfaceUniqueId = producerSurface_->GetUniqueId();
151         auto rsSurface = displayDrawable.GetVirtualSurface(pSurfaceUniqueId);
152         if (rsSurface == nullptr || updateFlag_) {
153             RS_LOGD("RSUniRenderVirtualProcessor::RequestVirtualFrame,"
154                 "Make rssurface from producer virtualScreen(id %{public}" PRIu64 ")", virtualScreenId_);
155             RS_TRACE_NAME_FMT("RSUniRenderVirtualProcessor::RequestVirtualFrame,"
156                 "Make rssurface from producer virtualScreen(id %" PRIu64 ")", virtualScreenId_);
157             rsSurface = renderEngine->MakeRSSurface(producerSurface_, forceCPU_);
158             displayDrawable.SetVirtualSurface(rsSurface, pSurfaceUniqueId);
159         }
160 #ifdef NEW_RENDER_CONTEXT
161         renderFrame_ = renderEngine->RequestFrame(
162             std::static_pointer_cast<RSRenderSurfaceOhos>(rsSurface), renderFrameConfig_, forceCPU_, false);
163 #else
164         renderFrame_ = renderEngine->RequestFrame(
165             std::static_pointer_cast<RSSurfaceOhos>(rsSurface), renderFrameConfig_, forceCPU_, false);
166 #endif
167     }
168     if (renderFrame_ == nullptr) {
169         RS_LOGE("RSUniRenderVirtualProcessor::RequestVirtualFrame RenderFrame is null!");
170         return false;
171     }
172     return true;
173 }
174 
CanvasInit(RSDisplayRenderNode & node)175 void RSUniRenderVirtualProcessor::CanvasInit(RSDisplayRenderNode& node)
176 {
177     if (node.IsFirstTimeToProcessor() || canvasRotation_) {
178         if (node.IsFirstTimeToProcessor()) {
179             RS_LOGI("RSUniRenderVirtualProcessor::FirstInit, id: %{public}" PRIu64 ", " \
180                 "screen(%{public}f, %{public}f, %{public}f, %{public}f), " \
181                 "rotation: %{public}d, correction: %{public}d, needRotation: %{public}d, scaleMode: %{public}d",
182                 node.GetScreenId(), mainWidth_, mainHeight_, mirrorWidth_, mirrorHeight_,
183                 screenRotation_, screenCorrection_, canvasRotation_, scaleMode_);
184         }
185         node.SetOriginScreenRotation(screenRotation_);
186     }
187     auto rotationDiff = static_cast<int>(node.GetOriginScreenRotation()) - static_cast<int>(screenCorrection_);
188     auto rotationAngle = static_cast<ScreenRotation>((rotationDiff + SCREEN_ROTATION_NUM) % SCREEN_ROTATION_NUM);
189     OriginScreenRotation(rotationAngle, renderFrameConfig_.width, renderFrameConfig_.height);
190 
191     RS_LOGD("RSUniRenderVirtualProcessor::CanvasInit, id: %{public}" PRIu64 ", " \
192         "screen(%{public}f, %{public}f, %{public}f, %{public}f), " \
193         "rotation: %{public}d, correction: %{public}d, needRotation: %{public}d, rotationAngle: %{public}d",
194         node.GetScreenId(), mainWidth_, mainHeight_, mirrorWidth_, mirrorHeight_,
195         screenRotation_, screenCorrection_, canvasRotation_, rotationAngle);
196 }
197 
CanvasInit(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)198 void RSUniRenderVirtualProcessor::CanvasInit(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
199 {
200     // Save the initial canvas state
201     canvas_->Save();
202     if (displayDrawable.IsFirstTimeToProcessor() || canvasRotation_) {
203         if (displayDrawable.IsFirstTimeToProcessor()) {
204             RS_LOGI("RSUniRenderVirtualProcessor::CanvasInit, id: %{public}" PRIu64 ", " \
205                 "screen(%{public}f, %{public}f, %{public}f, %{public}f), " \
206                 "rotation: %{public}d, correction: %{public}d, needRotation: %{public}d, scaleMode: %{public}d",
207                 virtualScreenId_, mirroredScreenWidth_, mirroredScreenHeight_, virtualScreenWidth_,
208                 virtualScreenHeight_, screenRotation_, screenCorrection_, canvasRotation_, scaleMode_);
209         }
210         displayDrawable.SetOriginScreenRotation(screenRotation_);
211     }
212     auto rotationDiff = static_cast<int>(displayDrawable.GetOriginScreenRotation()) -
213         static_cast<int>(screenCorrection_);
214     auto rotationAngle = static_cast<ScreenRotation>((rotationDiff + SCREEN_ROTATION_NUM) % SCREEN_ROTATION_NUM);
215     OriginScreenRotation(rotationAngle, renderFrameConfig_.width, renderFrameConfig_.height);
216 
217     RS_LOGD("RSUniRenderVirtualProcessor::CanvasInit, id: %{public}" PRIu64 ", " \
218         "screen(%{public}f, %{public}f, %{public}f, %{public}f), " \
219         "rotation: %{public}d, correction: %{public}d, needRotation: %{public}d, scaleMode: %{public}d",
220         virtualScreenId_, mirroredScreenWidth_, mirroredScreenHeight_, virtualScreenWidth_, virtualScreenHeight_,
221         screenRotation_, screenCorrection_, canvasRotation_, scaleMode_);
222 }
223 
GetBufferAge() const224 int32_t RSUniRenderVirtualProcessor::GetBufferAge() const
225 {
226     if (renderFrame_ == nullptr) {
227         RS_LOGE("RSUniRenderVirtualProcessor::GetBufferAge renderFrame_ is null.");
228         return 0;
229     }
230     return renderFrame_->GetBufferAge();
231 }
232 
SetDirtyInfo(std::vector<RectI> & damageRegion)233 void RSUniRenderVirtualProcessor::SetDirtyInfo(std::vector<RectI>& damageRegion)
234 {
235     if (renderFrame_ == nullptr) {
236         RS_LOGW("RSUniRenderVirtualProcessor::SetDirtyInfo renderFrame_ is null.");
237         return;
238     }
239     renderFrame_->SetDamageRegion(damageRegion);
240     if (SetRoiRegionToCodec(damageRegion) != GSERROR_OK) {
241         RS_LOGD("RSUniRenderVirtualProcessor::SetDirtyInfo SetRoiRegionToCodec failed.");
242     }
243 }
244 
SetRoiRegionToCodec(std::vector<RectI> & damageRegion)245 GSError RSUniRenderVirtualProcessor::SetRoiRegionToCodec(std::vector<RectI>& damageRegion)
246 {
247     auto& rsSurface = renderFrame_->GetSurface();
248     if (rsSurface == nullptr) {
249         RS_LOGD("RSUniRenderVirtualProcessor::SetRoiRegionToCodec surface is null.");
250         return GSERROR_INVALID_ARGUMENTS;
251     }
252 
253     auto buffer = rsSurface->GetCurrentBuffer();
254     if (buffer == nullptr) {
255         RS_LOGD("RSUniRenderVirtualProcessor::SetRoiRegionToCodec buffer is null, not support get surfacebuffer.");
256         return GSERROR_NO_BUFFER;
257     }
258 
259     RoiRegions roiRegions;
260     const RectI screenRect{0, 0, originalVirtualScreenWidth_, originalVirtualScreenHeight_};
261     if (damageRegion.size() <= ROI_REGIONS_MAX_CNT) {
262         for (auto rect : damageRegion) {
263             rect = rect.IntersectRect(screenRect);
264             if (!rect.IsEmpty()) {
265                 RoiRegionInfo region = RoiRegionInfo{rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight()};
266                 roiRegions.regions[roiRegions.regionCnt++] = region;
267             }
268         }
269     } else {
270         RectI mergedRect;
271         for (auto& rect : damageRegion) {
272             mergedRect = mergedRect.JoinRect(rect);
273         }
274         mergedRect = mergedRect.IntersectRect(screenRect);
275         if (!mergedRect.IsEmpty()) {
276             RoiRegionInfo region = RoiRegionInfo{mergedRect.GetLeft(), mergedRect.GetTop(),
277                 mergedRect.GetWidth(), mergedRect.GetHeight()};
278             roiRegions.regions[roiRegions.regionCnt++] = region;
279         }
280     }
281 
282     std::vector<uint8_t> roiRegionsVec;
283     auto ret = MetadataHelper::ConvertMetadataToVec(roiRegions, roiRegionsVec);
284     if (ret != GSERROR_OK) {
285         RS_LOGD("RSUniRenderVirtualProcessor::SetRoiRegionToCodec ConvertMetadataToVec failed.");
286         return ret;
287     }
288     return buffer->SetMetadata(GrallocBufferAttr::GRALLOC_BUFFER_ATTR_BUFFER_ROI_INFO, roiRegionsVec);
289 }
290 
OriginScreenRotation(ScreenRotation screenRotation,float width,float height)291 void RSUniRenderVirtualProcessor::OriginScreenRotation(ScreenRotation screenRotation, float width, float height)
292 {
293     if (screenRotation == ScreenRotation::ROTATION_0) {
294         return;
295     } else if (screenRotation == ScreenRotation::ROTATION_90) {
296         canvas_->Translate(width / 2.0f, height / 2.0f);
297         canvas_->Rotate(90, 0, 0); // 90 degrees
298         canvas_->Translate(-(height / 2.0f), -(width / 2.0f));
299     } else if (screenRotation == ScreenRotation::ROTATION_180) {
300         canvas_->Rotate(180, width / 2.0f, height / 2.0f); // 180 degrees
301     } else if (screenRotation == ScreenRotation::ROTATION_270) {
302         canvas_->Translate(width / 2.0f, height / 2.0f);
303         canvas_->Rotate(270, 0, 0); // 270 degrees
304         canvas_->Translate(-(height / 2.0f), -(width / 2.0f));
305     }
306 }
307 
ScaleMirrorIfNeed(RSDisplayRenderNode & node,RSPaintFilterCanvas & canvas)308 void RSUniRenderVirtualProcessor::ScaleMirrorIfNeed(RSDisplayRenderNode& node, RSPaintFilterCanvas& canvas)
309 {
310     if (screenCorrection_ == ScreenRotation::ROTATION_90 ||
311         screenCorrection_ == ScreenRotation::ROTATION_270) {
312         std::swap(mirrorWidth_, mirrorHeight_);
313     }
314 
315     auto angle = node.GetOriginScreenRotation();
316     if (angle == ScreenRotation::ROTATION_90 ||
317         angle == ScreenRotation::ROTATION_270) {
318         std::swap(mirrorWidth_, mirrorHeight_);
319     }
320 
321     RS_LOGD("RSUniRenderVirtualProcessor::ScaleMirrorIfNeed:(%{public}f, %{public}f, %{public}f, %{public}f), " \
322         "screenCorrection:%{public}d, oriRotation:%{public}d, scaleMode:%{public}d",
323         mainWidth_, mainHeight_, mirrorWidth_, mirrorHeight_,
324         static_cast<int>(screenCorrection_), static_cast<int>(angle), static_cast<int>(scaleMode_));
325 
326     if (mainWidth_ == mirrorWidth_ && mainHeight_ == mirrorHeight_) {
327         return;
328     }
329 
330     canvas.Clear(SK_ColorBLACK);
331     if (scaleMode_ == ScreenScaleMode::FILL_MODE) {
332         Fill(canvas, mainWidth_, mainHeight_, mirrorWidth_, mirrorHeight_);
333     } else if (scaleMode_ == ScreenScaleMode::UNISCALE_MODE) {
334         UniScale(canvas, mainWidth_, mainHeight_, mirrorWidth_, mirrorHeight_);
335     }
336 }
337 
ScaleMirrorIfNeed(const ScreenRotation angle,RSPaintFilterCanvas & canvas)338 void RSUniRenderVirtualProcessor::ScaleMirrorIfNeed(const ScreenRotation angle, RSPaintFilterCanvas& canvas)
339 {
340     if (screenCorrection_ == ScreenRotation::ROTATION_90 ||
341         screenCorrection_ == ScreenRotation::ROTATION_270) {
342         std::swap(virtualScreenWidth_, virtualScreenHeight_);
343     }
344 
345     if (angle == ScreenRotation::ROTATION_90 ||
346         angle == ScreenRotation::ROTATION_270) {
347         std::swap(virtualScreenWidth_, virtualScreenHeight_);
348     }
349 
350     RS_TRACE_NAME_FMT("RSUniRenderVirtualProcessor::ScaleMirrorIfNeed:(%f, %f, %f, %f), " \
351         "screenCorrection:%d, oriRotation:%d",
352         mirroredScreenWidth_, mirroredScreenHeight_, virtualScreenWidth_, virtualScreenHeight_,
353         static_cast<int>(screenCorrection_), static_cast<int>(angle));
354 
355     if (mirroredScreenWidth_ == virtualScreenWidth_ && mirroredScreenHeight_ == virtualScreenHeight_) {
356         return;
357     }
358 
359     if (scaleMode_ == ScreenScaleMode::FILL_MODE) {
360         Fill(canvas, mirroredScreenWidth_, mirroredScreenHeight_, virtualScreenWidth_, virtualScreenHeight_);
361     } else if (scaleMode_ == ScreenScaleMode::UNISCALE_MODE) {
362         UniScale(canvas, mirroredScreenWidth_, mirroredScreenHeight_, virtualScreenWidth_, virtualScreenHeight_);
363     }
364 }
365 
PostProcess()366 void RSUniRenderVirtualProcessor::PostProcess()
367 {
368     if (renderFrame_ == nullptr || renderEngine_ == nullptr) {
369         RS_LOGE("RSUniRenderVirtualProcessor::PostProcess renderFrame or renderEngine is nullptr");
370         return;
371     }
372     auto surfaceOhos = renderFrame_->GetSurface();
373     renderEngine_->SetUiTimeStamp(renderFrame_, surfaceOhos);
374     renderFrame_->Flush();
375     RS_LOGD("RSUniRenderVirtualProcessor::PostProcess, FlushFrame succeed.");
376     RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVirtualProcessor::PostProcess, FlushFrame succeed.");
377 }
378 
ProcessSurface(RSSurfaceRenderNode & node)379 void RSUniRenderVirtualProcessor::ProcessSurface(RSSurfaceRenderNode& node)
380 {
381     (void)node;
382     RS_LOGI("RSUniRenderVirtualProcessor::ProcessSurface() is not supported.");
383 }
384 
CalculateTransform(RSDisplayRenderNode & node)385 void RSUniRenderVirtualProcessor::CalculateTransform(RSDisplayRenderNode& node)
386 {
387     if (isExpand_) {
388         return;
389     }
390     auto drawable = node.GetRenderDrawable();
391     if (!drawable) {
392         return;
393     }
394     auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
395     if (canvas_ == nullptr || displayDrawable->GetRSSurfaceHandlerOnDraw()->GetBuffer() == nullptr) {
396         RS_LOGE("RSUniRenderVirtualProcessor::ProcessDisplaySurface: Canvas or buffer is null!");
397         return;
398     }
399 
400     canvas_->Save();
401     ScaleMirrorIfNeed(node, *canvas_);
402     canvasMatrix_ = canvas_->GetTotalMatrix();
403 }
404 
CalculateTransform(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)405 void RSUniRenderVirtualProcessor::CalculateTransform(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
406 {
407     if (canvas_ == nullptr || displayDrawable.GetRSSurfaceHandlerOnDraw()->GetBuffer() == nullptr) {
408         RS_LOGE("RSUniRenderVirtualProcessor::CalculateTransform: Canvas or buffer is null!");
409         return;
410     }
411 
412     canvas_->Save();
413     ScreenRotation angle = displayDrawable.GetOriginScreenRotation();
414     ScaleMirrorIfNeed(angle, *canvas_);
415     canvasMatrix_ = canvas_->GetTotalMatrix();
416 }
417 
ProcessDisplaySurfaceForRenderThread(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)418 void RSUniRenderVirtualProcessor::ProcessDisplaySurfaceForRenderThread(
419     DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
420 {
421     if (isExpand_) {
422         return;
423     }
424     auto surfaceHandler = displayDrawable.GetRSSurfaceHandlerOnDraw();
425     if (canvas_ == nullptr || surfaceHandler->GetBuffer() == nullptr) {
426         RS_LOGE("RSUniRenderVirtualProcessor::ProcessDisplaySurface: Canvas or buffer is null!");
427         return;
428     }
429     auto params = RSUniRenderUtil::CreateBufferDrawParam(*surfaceHandler, forceCPU_);
430     params.isMirror = true;
431     renderEngine_->DrawDisplayNodeWithParams(*canvas_, *surfaceHandler, params);
432     canvas_->Restore();
433 }
434 
ProcessVirtualDisplaySurface(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)435 void RSUniRenderVirtualProcessor::ProcessVirtualDisplaySurface(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
436 {
437     auto surfaceHandler = displayDrawable.GetRSSurfaceHandlerOnDraw();
438     if (canvas_ == nullptr || surfaceHandler->GetBuffer() == nullptr) {
439         RS_LOGE("RSUniRenderVirtualProcessor::ProcessVirtualDisplaySurface: Canvas or buffer is null!");
440         return;
441     }
442     auto bufferDrawParam = RSUniRenderUtil::CreateBufferDrawParam(*surfaceHandler, forceCPU_);
443     bufferDrawParam.isMirror = true;
444     renderEngine_->DrawDisplayNodeWithParams(*canvas_, *surfaceHandler, bufferDrawParam);
445     canvas_->Restore();
446 }
447 
Fill(RSPaintFilterCanvas & canvas,float mainWidth,float mainHeight,float mirrorWidth,float mirrorHeight)448 void RSUniRenderVirtualProcessor::Fill(RSPaintFilterCanvas& canvas,
449     float mainWidth, float mainHeight, float mirrorWidth, float mirrorHeight)
450 {
451     if (mainWidth > 0 && mainHeight > 0) {
452         mirrorScaleX_ = mirrorWidth / mainWidth;
453         mirrorScaleY_ = mirrorHeight / mainHeight;
454         canvas.Scale(mirrorScaleX_, mirrorScaleY_);
455     }
456 }
457 
UniScale(RSPaintFilterCanvas & canvas,float mainWidth,float mainHeight,float mirrorWidth,float mirrorHeight)458 void RSUniRenderVirtualProcessor::UniScale(RSPaintFilterCanvas& canvas,
459     float mainWidth, float mainHeight, float mirrorWidth, float mirrorHeight)
460 {
461     if (mainWidth > 0 && mainHeight > 0) {
462         float startX = 0.0f;
463         float startY = 0.0f;
464         mirrorScaleX_ = mirrorWidth / mainWidth;
465         mirrorScaleY_ = mirrorHeight / mainHeight;
466         if (mirrorScaleY_ < mirrorScaleX_) {
467             mirrorScaleX_ = mirrorScaleY_;
468             startX = (mirrorWidth - (mirrorScaleX_ * mainWidth)) / 2; // 2 for calc X
469         } else {
470             mirrorScaleY_ = mirrorScaleX_;
471             startY = (mirrorHeight - (mirrorScaleY_ * mainHeight)) / 2; // 2 for calc Y
472         }
473         canvas.Translate(startX, startY);
474         canvas.Scale(mirrorScaleX_, mirrorScaleY_);
475     }
476 }
477 
CanvasClipRegionForUniscaleMode()478 void RSUniRenderVirtualProcessor::CanvasClipRegionForUniscaleMode()
479 {
480     if (canvas_ == nullptr) {
481         RS_LOGE("RSUniRenderVirtualProcessor::CanvasClipRegion: Canvas is null!");
482         return;
483     }
484     if (scaleMode_ == ScreenScaleMode::UNISCALE_MODE) {
485         Drawing::Rect rect(0, 0, mirroredScreenWidth_, mirroredScreenHeight_);
486         canvas_->GetTotalMatrix().MapRect(rect, rect);
487         Drawing::RectI rectI = {rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom()};
488         Drawing::Region clipRegion;
489         clipRegion.SetRect(rectI);
490         canvas_->ClipRegion(clipRegion);
491     }
492 }
493 
ProcessRcdSurface(RSRcdSurfaceRenderNode & node)494 void RSUniRenderVirtualProcessor::ProcessRcdSurface(RSRcdSurfaceRenderNode& node)
495 {
496     RS_LOGI("RSUniRenderVirtualProcessor::ProcessRcdSurface() is not supported.");
497 }
498 } // namespace Rosen
499 } // namespace OHOS
500