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