1 /*
2 * Copyright (c) 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_composer_adapter.h"
17 #include <memory>
18
19 #include "common/rs_common_def.h"
20 #include "common/rs_obj_abs_geometry.h"
21 #include "common/rs_optional_trace.h"
22 #include "drawable/rs_display_render_node_drawable.h"
23 #include "drawable/rs_render_node_drawable_adapter.h"
24 #include "drawable/rs_surface_render_node_drawable.h"
25 #include "params/rs_render_params.h"
26 #include "pipeline/rs_uni_render_util.h"
27 #include "pipeline/rs_uni_render_listener.h"
28 #include "platform/common/rs_log.h"
29 #include "rs_divided_render_util.h"
30 #include "rs_trace.h"
31 #include "string_utils.h"
32 #include "metadata_helper.h"
33 #include "surface_type.h"
34 #include "third_party/libdrm/include/drm/drm.h"
35
36 #include "pipeline/round_corner_display/rs_rcd_surface_render_node.h"
37
38 namespace OHOS {
39 namespace Rosen {
40 namespace {
41 constexpr uint32_t FLAT_ANGLE = 180;
42 constexpr int32_t DEFAULT_BRIGHTNESS = 500;
43 constexpr float NO_RATIO = 1.0f;
44 static const int GLOBAL_ALPHA_MAX = 255;
45 }
46
Init(const ScreenInfo & screenInfo,int32_t offsetX,int32_t offsetY,float mirrorAdaptiveCoefficient)47 bool RSUniRenderComposerAdapter::Init(const ScreenInfo& screenInfo, int32_t offsetX, int32_t offsetY,
48 float mirrorAdaptiveCoefficient)
49 {
50 hdiBackend_ = HdiBackend::GetInstance();
51 if (hdiBackend_ == nullptr) {
52 RS_LOGE("RSUniRenderComposerAdapter::Init: hdiBackend is nullptr");
53 return false;
54 }
55 auto screenManager = CreateOrGetScreenManager();
56 if (screenManager == nullptr) {
57 RS_LOGE("RSUniRenderComposerAdapter::Init: ScreenManager is nullptr");
58 return false;
59 }
60 output_ = screenManager->GetOutput(ToScreenPhysicalId(screenInfo.id));
61 if (output_ == nullptr) {
62 RS_LOGE("RSUniRenderComposerAdapter::Init: output_ is nullptr");
63 return false;
64 }
65
66 offsetX_ = offsetX;
67 offsetY_ = offsetY;
68 mirrorAdaptiveCoefficient_ = mirrorAdaptiveCoefficient;
69 screenInfo_ = screenInfo;
70
71 GraphicIRect damageRect {0, 0, static_cast<int32_t>(screenInfo_.width), static_cast<int32_t>(screenInfo_.height)};
72 std::vector<GraphicIRect> damageRects;
73 damageRects.emplace_back(damageRect);
74 output_->SetOutputDamages(damageRects);
75 bool directClientCompEnableStatus = RSSystemProperties::GetDirectClientCompEnableStatus();
76 output_->SetDirectClientCompEnableStatus(directClientCompEnableStatus);
77
78 #if (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK))
79 // enable direct GPU composition.
80 output_->SetLayerCompCapacity(LAYER_COMPOSITION_CAPACITY);
81 #else // (defined RS_ENABLE_GL)
82 output_->SetLayerCompCapacity(LAYER_COMPOSITION_CAPACITY_INVALID);
83 #endif // (defined RS_ENABLE_GL)
84 return true;
85 }
86
CommitLayers(const std::vector<LayerInfoPtr> & layers)87 void RSUniRenderComposerAdapter::CommitLayers(const std::vector<LayerInfoPtr>& layers)
88 {
89 if (hdiBackend_ == nullptr) {
90 RS_LOGE("RSUniRenderComposerAdapter::CommitLayers: backend is nullptr");
91 return;
92 }
93
94 if (output_ == nullptr) {
95 RS_LOGE("RSUniRenderComposerAdapter::CommitLayers: output is nullptr");
96 return;
97 }
98 RSHardwareThread::Instance().CommitAndReleaseLayers(output_, layers);
99 }
100
SetPreBufferInfo(RSSurfaceHandler & surfaceHandler,ComposeInfo & info) const101 void RSUniRenderComposerAdapter::SetPreBufferInfo(RSSurfaceHandler& surfaceHandler, ComposeInfo& info) const
102 {
103 info.preBuffer = surfaceHandler.GetPreBuffer();
104 surfaceHandler.ResetPreBuffer();
105 }
106
107 // private func, for RSDisplayRenderNode
BuildComposeInfo(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,const std::vector<RectI> & dirtyRegion)108 ComposeInfo RSUniRenderComposerAdapter::BuildComposeInfo(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable,
109 const std::vector<RectI>& dirtyRegion)
110 {
111 ComposeInfo info {};
112 SetBufferColorSpace(displayDrawable);
113 auto surfaceHandler = displayDrawable.GetMutableRSSurfaceHandlerOnDraw();
114 auto& params = displayDrawable.GetRenderParams();
115 if (!surfaceHandler || !params) {
116 return info;
117 }
118 const auto& buffer = surfaceHandler->GetBuffer(); // we guarantee the buffer is valid.
119 info.srcRect = GraphicIRect {0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight()};
120 info.dstRect = GraphicIRect {0, 0, static_cast<int32_t>(screenInfo_.GetRotatedPhyWidth()),
121 static_cast<int32_t>(screenInfo_.GetRotatedPhyHeight())};
122 auto bound = params->GetBounds();
123 info.boundRect = {0, 0,
124 static_cast<int32_t>(bound.GetWidth()), static_cast<int32_t>(bound.GetHeight())};
125 info.visibleRect = GraphicIRect {info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h};
126 std::vector<GraphicIRect> dirtyRects;
127 // layer damage always relative to the top-left, no matter gl or vk
128 std::vector<RectI> flipDirtyRects =
129 RSUniRenderUtil::GetFilpDirtyRects(dirtyRegion, screenInfo_);
130 for (const auto& rect : flipDirtyRects) {
131 dirtyRects.emplace_back(GraphicIRect {rect.left_, rect.top_, rect.width_, rect.height_});
132 }
133 if (RSSystemProperties::GetUniPartialRenderEnabled() == PartialRenderType::DISABLED && dirtyRects.empty()) {
134 dirtyRects.emplace_back(info.srcRect);
135 }
136 info.dirtyRects = dirtyRects;
137 auto displayParams = static_cast<RSDisplayRenderParams*>(params.get());
138 info.zOrder = static_cast<int32_t>(displayParams->GetGlobalZOrder());
139 info.alpha.enGlobalAlpha = true;
140 info.alpha.gAlpha = GLOBAL_ALPHA_MAX;
141 SetPreBufferInfo(*surfaceHandler, info);
142 info.buffer = buffer;
143 info.fence = surfaceHandler->GetAcquireFence();
144 info.blendType = GRAPHIC_BLEND_SRCOVER;
145 info.needClient = RSSystemProperties::IsForceClient();
146 auto matrix = params->GetMatrix();
147 info.matrix = GraphicMatrix {matrix.Get(Drawing::Matrix::Index::SCALE_X),
148 matrix.Get(Drawing::Matrix::Index::SKEW_X), matrix.Get(Drawing::Matrix::Index::TRANS_X),
149 matrix.Get(Drawing::Matrix::Index::SKEW_Y), matrix.Get(Drawing::Matrix::Index::SCALE_Y),
150 matrix.Get(Drawing::Matrix::Index::TRANS_Y), matrix.Get(Drawing::Matrix::Index::PERSP_0),
151 matrix.Get(Drawing::Matrix::Index::PERSP_1), matrix.Get(Drawing::Matrix::Index::PERSP_2)};
152 info.gravity = static_cast<int32_t>(Gravity::RESIZE);
153
154 const auto curDisplayParam = static_cast<RSDisplayRenderParams*>(displayDrawable.GetRenderParams().get());
155 if (curDisplayParam) {
156 info.brightnessRatio = curDisplayParam->GetBrightnessRatio();
157 }
158 return info;
159 }
160
BuildComposeInfo(RSRcdSurfaceRenderNode & node) const161 ComposeInfo RSUniRenderComposerAdapter::BuildComposeInfo(RSRcdSurfaceRenderNode& node) const
162 {
163 const auto& buffer = node.GetBuffer(); // we guarantee the buffer is valid.
164 if (buffer == nullptr) {
165 RS_LOGW("RSUniRenderComposerAdapter::BuildComposeInfo RSRcdSurfaceRenderNode buffer is nullptr");
166 }
167 const RectI& dstRect = node.GetDstRect();
168 const auto& srcRect = node.GetSrcRect();
169 ComposeInfo info {};
170 info.srcRect = GraphicIRect {srcRect.left_, srcRect.top_, srcRect.width_, srcRect.height_};
171 info.dstRect = GraphicIRect {static_cast<int32_t>(dstRect.left_ * screenInfo_.GetRogWidthRatio()),
172 static_cast<int32_t>(dstRect.top_ * screenInfo_.GetRogHeightRatio()),
173 static_cast<int32_t>(dstRect.width_ * screenInfo_.GetRogWidthRatio()),
174 static_cast<int32_t>(dstRect.height_ * screenInfo_.GetRogHeightRatio())};
175 info.boundRect = info.dstRect;
176 info.visibleRect = info.dstRect;
177 std::vector<GraphicIRect> dirtyRects;
178 dirtyRects.emplace_back(GraphicIRect {0, 0, 0, 0});
179 info.dirtyRects = dirtyRects;
180 info.zOrder = static_cast<int32_t>(node.GetGlobalZOrder());
181 info.alpha.enGlobalAlpha = true;
182 info.alpha.gAlpha = 255; // 255 means not transparent
183 SetPreBufferInfo(node, info);
184 info.buffer = buffer;
185 info.fence = node.GetAcquireFence();
186 info.blendType = GRAPHIC_BLEND_SRCOVER;
187 info.needClient = false;
188 info.matrix = GraphicMatrix {1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f};
189 info.gravity = static_cast<int32_t>(Gravity::RESIZE);
190
191 info.displayNit = DEFAULT_BRIGHTNESS;
192 info.brightnessRatio = NO_RATIO;
193 return info;
194 }
195
SetComposeInfoToLayer(const LayerInfoPtr & layer,const ComposeInfo & info,const sptr<IConsumerSurface> & surface) const196 void RSUniRenderComposerAdapter::SetComposeInfoToLayer(
197 const LayerInfoPtr& layer,
198 const ComposeInfo& info,
199 const sptr<IConsumerSurface>& surface) const
200 {
201 if (layer == nullptr) {
202 return;
203 }
204 layer->SetSurface(surface);
205 layer->SetBuffer(info.buffer, info.fence);
206 layer->SetPreBuffer(info.preBuffer);
207 layer->SetZorder(info.zOrder);
208 layer->SetAlpha(info.alpha);
209 layer->SetLayerSize(info.dstRect);
210 layer->SetBoundSize(info.boundRect);
211 layer->SetCompositionType(info.needClient ?
212 GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT : GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE);
213 std::vector<GraphicIRect> visibleRegions;
214 visibleRegions.emplace_back(info.visibleRect);
215 layer->SetVisibleRegions(visibleRegions);
216 if (RSSystemProperties::GetHwcDirtyRegionEnabled()) {
217 layer->SetDirtyRegions(info.dirtyRects);
218 } else {
219 std::vector<GraphicIRect> dirtyRegions;
220 dirtyRegions.emplace_back(info.srcRect);
221 layer->SetDirtyRegions(dirtyRegions);
222 }
223 layer->SetBlendType(info.blendType);
224 layer->SetCropRect(info.srcRect);
225 layer->SetMatrix(info.matrix);
226 layer->SetGravity(info.gravity);
227 SetMetaDataInfoToLayer(layer, info.buffer, surface);
228 layer->SetDisplayNit(info.displayNit);
229 layer->SetBrightnessRatio(info.brightnessRatio);
230 }
231
SetBufferColorSpace(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)232 void RSUniRenderComposerAdapter::SetBufferColorSpace(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
233 {
234 sptr<SurfaceBuffer> buffer = displayDrawable.GetRSSurfaceHandlerOnDraw()->GetBuffer();
235 if (buffer == nullptr) {
236 RS_LOGE("RSUniRenderComposerAdapter::SetBufferColorSpace SurfaceBuffer is null");
237 return;
238 }
239
240 auto rsSurface = displayDrawable.GetRSSurface();
241 if (rsSurface == nullptr) {
242 RS_LOGE("RSUniRenderComposerAdapter::SetBufferColorSpace RSSurface is null");
243 return;
244 }
245
246 using namespace HDI::Display::Graphic::Common::V1_0;
247 static const std::map<GraphicColorGamut, CM_ColorSpaceType> RS_TO_COMMON_COLOR_SPACE_TYPE_MAP {
248 {GRAPHIC_COLOR_GAMUT_STANDARD_BT601, CM_BT601_EBU_FULL},
249 {GRAPHIC_COLOR_GAMUT_STANDARD_BT709, CM_BT709_FULL},
250 {GRAPHIC_COLOR_GAMUT_SRGB, CM_SRGB_FULL},
251 {GRAPHIC_COLOR_GAMUT_ADOBE_RGB, CM_ADOBERGB_FULL},
252 {GRAPHIC_COLOR_GAMUT_DISPLAY_P3, CM_P3_FULL},
253 {GRAPHIC_COLOR_GAMUT_BT2020, CM_DISPLAY_BT2020_SRGB},
254 {GRAPHIC_COLOR_GAMUT_BT2100_PQ, CM_BT2020_PQ_FULL},
255 {GRAPHIC_COLOR_GAMUT_BT2100_HLG, CM_BT2020_HLG_FULL},
256 {GRAPHIC_COLOR_GAMUT_DISPLAY_BT2020, CM_DISPLAY_BT2020_SRGB},
257 };
258
259 GraphicColorGamut rsColorSpace = rsSurface->GetColorSpace();
260 CM_ColorSpaceType colorSpace;
261 auto it = RS_TO_COMMON_COLOR_SPACE_TYPE_MAP.find(rsColorSpace);
262 if (it != RS_TO_COMMON_COLOR_SPACE_TYPE_MAP.end()) {
263 colorSpace = it->second;
264 } else {
265 RS_LOGW("RSUniRenderComposerAdapter::SetBufferColorSpace unknown color space");
266 colorSpace = CM_COLORSPACE_NONE;
267 }
268
269 if (MetadataHelper::SetColorSpaceType(buffer, colorSpace) != GSERROR_OK) {
270 RS_LOGE("RSUniRenderComposerAdapter::SetBufferColorSpace set color space fail");
271 }
272 }
273
SetMetaDataInfoToLayer(const LayerInfoPtr & layer,const sptr<SurfaceBuffer> & buffer,const sptr<IConsumerSurface> & surface) const274 void RSUniRenderComposerAdapter::SetMetaDataInfoToLayer(const LayerInfoPtr& layer, const sptr<SurfaceBuffer>& buffer,
275 const sptr<IConsumerSurface>& surface) const
276 {
277 HDRMetaDataType type;
278 if (!layer || !surface || !buffer) {
279 RS_LOGE("RSUniRenderComposerAdapter::SetMDataInfoToLayer fail, layer or surface or buffer is nullptr");
280 return;
281 }
282 if (surface->QueryMetaDataType(buffer->GetSeqNum(), type) != GSERROR_OK) {
283 RS_LOGD("RSUniRenderComposerAdapter::SetComposeInfoToLayer: QueryMetaDataType failed");
284 return;
285 }
286 switch (type) {
287 case HDRMetaDataType::HDR_META_DATA: {
288 std::vector<GraphicHDRMetaData> metaData;
289 if (surface->GetMetaData(buffer->GetSeqNum(), metaData) != GSERROR_OK) {
290 RS_LOGE("RSUniRenderComposerAdapter::SetComposeInfoToLayer: GetMetaData failed");
291 return;
292 }
293 layer->SetMetaData(metaData);
294 break;
295 }
296 case HDRMetaDataType::HDR_META_DATA_SET: {
297 GraphicHDRMetadataKey key;
298 std::vector<uint8_t> metaData;
299 if (surface->GetMetaDataSet(buffer->GetSeqNum(), key, metaData) != GSERROR_OK) {
300 RS_LOGE("RSUniRenderComposerAdapter::SetComposeInfoToLayer: GetMetaDataSet failed");
301 return;
302 }
303 GraphicHDRMetaDataSet metaDataSet;
304 metaDataSet.key = key;
305 metaDataSet.metaData = metaData;
306 layer->SetMetaDataSet(metaDataSet);
307 break;
308 }
309 case HDRMetaDataType::HDR_NOT_USED: {
310 break;
311 }
312 default: {
313 break;
314 }
315 }
316 }
317
GetComposerInfoSrcRect(ComposeInfo & info,const RSSurfaceRenderNode & node)318 void RSUniRenderComposerAdapter::GetComposerInfoSrcRect(ComposeInfo &info, const RSSurfaceRenderNode& node)
319 {
320 auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
321 if (!consumer || !info.buffer) {
322 return;
323 }
324 const auto& property = node.GetRenderProperties();
325 const auto bufferWidth = info.buffer->GetSurfaceBufferWidth();
326 const auto bufferHeight = info.buffer->GetSurfaceBufferHeight();
327 auto boundsWidth = property.GetBoundsWidth();
328 auto boundsHeight = property.GetBoundsHeight();
329 GraphicTransformType transformType = RSBaseRenderUtil::GetRotateTransform(
330 RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, node.GetRSSurfaceHandler()->GetBuffer()));
331 if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
332 transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
333 std::swap(boundsWidth, boundsHeight);
334 }
335 if ((bufferWidth != boundsWidth || bufferHeight != boundsHeight) &&
336 node.GetRenderProperties().GetFrameGravity() != Gravity::TOP_LEFT) {
337 float xScale = (ROSEN_EQ(boundsWidth, 0.0f) ? 1.0f : bufferWidth / boundsWidth);
338 float yScale = (ROSEN_EQ(boundsHeight, 0.0f) ? 1.0f : bufferHeight / boundsHeight);
339
340 const auto nodeParams = static_cast<RSSurfaceRenderParams*>(node.GetRenderParams().get());
341 if (!nodeParams) {
342 RS_LOGE("RSUniRenderComposerAdapter::GetCInfoSrcRect fail, node params is true");
343 return;
344 }
345 // If the scaling mode is SCALING_MODE_SCALE_TO_WINDOW, the scale should use smaller one.
346 ScalingMode scalingMode = nodeParams->GetScalingMode();
347 if (consumer->GetScalingMode(info.buffer->GetSeqNum(), scalingMode) == GSERROR_OK) {
348 nodeParams->SetScalingMode(scalingMode);
349 }
350 if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
351 float scale = std::min(xScale, yScale);
352 info.srcRect.x = info.srcRect.x * scale;
353 info.srcRect.y = info.srcRect.y * scale;
354 if (ROSEN_EQ(scale, 0.f)) {
355 return;
356 }
357 info.srcRect.w = (bufferWidth / scale - (boundsWidth - info.srcRect.w)) * scale;
358 info.srcRect.h = (bufferHeight / scale - (boundsHeight - info.srcRect.h)) * scale;
359 } else {
360 auto geo = property.GetBoundsGeometry();
361 if (geo && geo->GetAbsRect() == node.GetDstRect()) {
362 // If the SurfaceRenderNode is completely in the DisplayRenderNode,
363 // we do not need to crop the buffer.
364 info.srcRect.w = bufferWidth;
365 info.srcRect.h = bufferHeight;
366 } else {
367 info.srcRect.x = info.srcRect.x * xScale;
368 info.srcRect.y = info.srcRect.y * yScale;
369 info.srcRect.w = std::min(static_cast<int32_t>(std::ceil(info.srcRect.w * xScale)), bufferWidth);
370 info.srcRect.h = std::min(static_cast<int32_t>(std::ceil(info.srcRect.h * yScale)), bufferHeight);
371 }
372 }
373 }
374 Drawing::RectI srcRect(
375 info.srcRect.x, info.srcRect.y, info.srcRect.w + info.srcRect.x, info.srcRect.h + info.srcRect.y);
376 Drawing::RectI bufferRect(0, 0, bufferWidth, bufferHeight);
377 if (srcRect.Intersect(bufferRect)) {
378 info.srcRect.x = srcRect.GetLeft();
379 info.srcRect.y = srcRect.GetTop();
380 info.srcRect.w = srcRect.GetWidth();
381 info.srcRect.h = srcRect.GetHeight();
382 } else {
383 info.srcRect = { 0, 0, 0, 0 };
384 }
385
386 RS_LOGD("RsDebug RSUniRenderComposerAdapter::GetComposerInfoSrcRect surfaceNode id:%{public}" PRIu64 ","\
387 "srcRect [%{public}d %{public}d %{public}d %{public}d]",
388 node.GetId(), info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h);
389 }
390
GetComposerInfoSrcRect(ComposeInfo & info,const DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable)391 void RSUniRenderComposerAdapter::GetComposerInfoSrcRect(
392 ComposeInfo& info, const DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable)
393 {
394 auto& params = surfaceDrawable.GetRenderParams();
395 if (!params || !info.buffer || !surfaceDrawable.GetConsumerOnDraw()) {
396 return;
397 }
398 const auto bufferWidth = info.buffer->GetSurfaceBufferWidth();
399 const auto bufferHeight = info.buffer->GetSurfaceBufferHeight();
400 auto boundsWidth = params->GetBounds().GetWidth();
401 auto boundsHeight = params->GetBounds().GetHeight();
402 GraphicTransformType transformType = RSBaseRenderUtil::GetRotateTransform(
403 RSBaseRenderUtil::GetSurfaceBufferTransformType(surfaceDrawable.GetConsumerOnDraw(), info.buffer));
404 if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
405 transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
406 std::swap(boundsWidth, boundsHeight);
407 }
408 if ((bufferWidth != boundsWidth || bufferHeight != boundsHeight) &&
409 params->GetFrameGravity() != Gravity::TOP_LEFT) {
410 float xScale = (ROSEN_EQ(boundsWidth, 0.0f) ? 1.0f : bufferWidth / boundsWidth);
411 float yScale = (ROSEN_EQ(boundsHeight, 0.0f) ? 1.0f : bufferHeight / boundsHeight);
412
413 // If the scaling mode is SCALING_MODE_SCALE_TO_WINDOW, the scale should use smaller one.
414 ScalingMode scalingMode = params->GetScalingMode();
415 if (surfaceDrawable.GetConsumerOnDraw()->GetScalingMode(info.buffer->GetSeqNum(), scalingMode) == GSERROR_OK) {
416 params->SetScalingMode(scalingMode);
417 }
418 if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
419 float scale = std::min(xScale, yScale);
420 info.srcRect.x = info.srcRect.x * scale;
421 info.srcRect.y = info.srcRect.y * scale;
422 if (ROSEN_EQ(scale, 0.f)) {
423 return;
424 }
425 info.srcRect.w = (bufferWidth / scale - (boundsWidth - info.srcRect.w)) * scale;
426 info.srcRect.h = (bufferHeight / scale - (boundsHeight - info.srcRect.h)) * scale;
427 } else {
428 RectI layerInfoSrcRect = { params->GetLayerInfo().srcRect.x, params->GetLayerInfo().srcRect.y,
429 params->GetLayerInfo().srcRect.w, params->GetLayerInfo().srcRect.h };
430 if (params->GetAbsDrawRect() == layerInfoSrcRect) {
431 // If the SurfaceRenderNode is completely in the DisplayRenderNode,
432 // we do not need to crop the buffer.
433 info.srcRect.w = bufferWidth;
434 info.srcRect.h = bufferHeight;
435 } else {
436 info.srcRect.x = info.srcRect.x * xScale;
437 info.srcRect.y = info.srcRect.y * yScale;
438 info.srcRect.w = std::min(static_cast<int32_t>(std::ceil(info.srcRect.w * xScale)), bufferWidth);
439 info.srcRect.h = std::min(static_cast<int32_t>(std::ceil(info.srcRect.h * yScale)), bufferHeight);
440 }
441 }
442 }
443 Drawing::RectI srcRect(
444 info.srcRect.x, info.srcRect.y, info.srcRect.w + info.srcRect.x, info.srcRect.h + info.srcRect.y);
445 Drawing::RectI bufferRect(0, 0, bufferWidth, bufferHeight);
446 if (srcRect.Intersect(bufferRect)) {
447 info.srcRect.x = srcRect.GetLeft();
448 info.srcRect.y = srcRect.GetTop();
449 info.srcRect.w = srcRect.GetWidth();
450 info.srcRect.h = srcRect.GetHeight();
451 } else {
452 info.srcRect = { 0, 0, 0, 0 };
453 }
454
455 RS_LOGD("RsDebug RSUniRenderComposerAdapter::GetComposerInfoSrcRect surfaceNode id:%{public}" PRIu64 ","\
456 "srcRect [%{public}d %{public}d %{public}d %{public}d]",
457 surfaceDrawable.GetId(), info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h);
458 }
459
GetComposerInfoNeedClient(const ComposeInfo & info,RSRenderParams & params) const460 bool RSUniRenderComposerAdapter::GetComposerInfoNeedClient(const ComposeInfo& info, RSRenderParams& params) const
461 {
462 bool needClient = params.GetNeedClient();
463 if (info.buffer &&
464 info.buffer->GetSurfaceBufferColorGamut() != static_cast<GraphicColorGamut>(screenInfo_.colorGamut)) {
465 needClient = true;
466 }
467 return needClient;
468 }
469
DealWithNodeGravity(const RSSurfaceRenderNode & node,ComposeInfo & info) const470 void RSUniRenderComposerAdapter::DealWithNodeGravity(const RSSurfaceRenderNode& node, ComposeInfo& info) const
471 {
472 const auto& property = node.GetRenderProperties();
473 const float frameWidth = info.buffer->GetSurfaceBufferWidth();
474 const float frameHeight = info.buffer->GetSurfaceBufferHeight();
475 const float boundsWidth = property.GetBoundsWidth();
476 const float boundsHeight = property.GetBoundsHeight();
477 const Gravity frameGravity = property.GetFrameGravity();
478 info.gravity = static_cast<int32_t>(frameGravity);
479 // we do not need to do additional works for Gravity::RESIZE and if frameSize == boundsSize.
480 if (frameGravity == Gravity::RESIZE || frameGravity == Gravity::TOP_LEFT ||
481 (frameWidth == boundsWidth && frameHeight == boundsHeight)) {
482 return;
483 }
484 auto traceInfo = node.GetName() + " DealWithNodeGravity " + std::to_string(static_cast<int>(frameGravity));
485 RS_TRACE_NAME(traceInfo.c_str());
486 // get current node's translate matrix and calculate gravity matrix.
487 auto translateMatrix = Drawing::Matrix();
488 translateMatrix.Translate(node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_X),
489 std::ceil(node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_Y)));
490 Drawing::Matrix gravityMatrix;
491 (void)RSPropertiesPainter::GetGravityMatrix(frameGravity,
492 RectF {0.0f, 0.0f, boundsWidth, boundsHeight}, frameWidth, frameHeight, gravityMatrix);
493 // create a canvas to calculate new dstRect and new srcRect
494 int32_t screenWidth = screenInfo_.phyWidth;
495 int32_t screenHeight = screenInfo_.phyHeight;
496 const auto screenRotation = screenInfo_.rotation;
497 if (screenRotation == ScreenRotation::ROTATION_90 || screenRotation == ScreenRotation::ROTATION_270) {
498 std::swap(screenWidth, screenHeight);
499 }
500 auto canvas = std::make_unique<Drawing::Canvas>(screenWidth, screenHeight);
501 canvas->ConcatMatrix(translateMatrix);
502 canvas->ConcatMatrix(gravityMatrix);
503 Drawing::Rect clipRect;
504 gravityMatrix.MapRect(clipRect, Drawing::Rect(0, 0, frameWidth, frameHeight));
505 canvas->ClipRect(Drawing::Rect(0, 0, clipRect.GetWidth(), clipRect.GetHeight()), Drawing::ClipOp::INTERSECT);
506 Drawing::RectI newDstRect = canvas->GetDeviceClipBounds();
507 // we make the newDstRect as the intersection of new and old dstRect,
508 // to deal with the situation that frameSize > boundsSize.
509 newDstRect.Intersect(Drawing::RectI(
510 info.dstRect.x, info.dstRect.y, info.dstRect.w + info.dstRect.x, info.dstRect.h + info.dstRect.y));
511 auto localRect = canvas->GetLocalClipBounds();
512 int left = std::clamp<int>(localRect.GetLeft(), 0, frameWidth);
513 int top = std::clamp<int>(localRect.GetTop(), 0, frameHeight);
514 int width = std::clamp<int>(localRect.GetWidth(), 0, frameWidth - left);
515 int height = std::clamp<int>(localRect.GetHeight(), 0, frameHeight - top);
516 GraphicIRect newSrcRect = {left, top, width, height};
517
518 // log and apply new dstRect and srcRect
519 RS_LOGD("RsDebug DealWithNodeGravity: name[%{public}s], gravity[%{public}d], oldDstRect[%{public}d %{public}d"
520 " %{public}d %{public}d], newDstRect[%{public}d %{public}d %{public}d %{public}d], oldSrcRect[%{public}d"
521 " %{public}d %{public}d %{public}d], newSrcRect[%{public}d %{public}d %{public}d %{public}d].",
522 node.GetName().c_str(), static_cast<int>(frameGravity),
523 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
524 newDstRect.GetLeft(), newDstRect.GetTop(), newDstRect.GetWidth(), newDstRect.GetHeight(),
525 info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
526 newSrcRect.x, newSrcRect.y, newSrcRect.w, newSrcRect.h);
527 info.dstRect = {newDstRect.GetLeft(), newDstRect.GetTop(), newDstRect.GetWidth(), newDstRect.GetHeight()};
528 info.srcRect = newSrcRect;
529 }
530
DealWithNodeGravity(const DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable,ComposeInfo & info) const531 void RSUniRenderComposerAdapter::DealWithNodeGravity(
532 const DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, ComposeInfo& info) const
533 {
534 auto& params = surfaceDrawable.GetRenderParams();
535 if (!params) {
536 return;
537 }
538 const float frameWidth = info.buffer->GetSurfaceBufferWidth();
539 const float frameHeight = info.buffer->GetSurfaceBufferHeight();
540 const float boundsWidth = params->GetBounds().GetWidth();
541 const float boundsHeight = params->GetBounds().GetHeight();
542 const Gravity frameGravity = params->GetFrameGravity();
543 info.gravity = static_cast<int32_t>(frameGravity);
544 // we do not need to do additional works for Gravity::RESIZE and if frameSize == boundsSize.
545 if (frameGravity == Gravity::RESIZE || frameGravity == Gravity::TOP_LEFT ||
546 (frameWidth == boundsWidth && frameHeight == boundsHeight)) {
547 return;
548 }
549
550 auto traceInfo =
551 surfaceDrawable.GetName() + " DealWithNodeGravity " + std::to_string(static_cast<int>(frameGravity));
552 RS_TRACE_NAME(traceInfo.c_str());
553
554 // get current node's translate matrix and calculate gravity matrix.
555 auto translateMatrix = Drawing::Matrix();
556 translateMatrix.Translate(params->GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_X),
557 std::ceil(params->GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_Y)));
558 Drawing::Matrix gravityMatrix;
559 (void)RSPropertiesPainter::GetGravityMatrix(frameGravity,
560 RectF {0.0f, 0.0f, boundsWidth, boundsHeight}, frameWidth, frameHeight, gravityMatrix);
561 // create a canvas to calculate new dstRect and new srcRect
562 int32_t screenWidth = screenInfo_.phyWidth;
563 int32_t screenHeight = screenInfo_.phyHeight;
564 const auto screenRotation = screenInfo_.rotation;
565 if (screenRotation == ScreenRotation::ROTATION_90 || screenRotation == ScreenRotation::ROTATION_270) {
566 std::swap(screenWidth, screenHeight);
567 }
568 auto canvas = std::make_unique<Drawing::Canvas>(screenWidth, screenHeight);
569 canvas->ConcatMatrix(translateMatrix);
570 canvas->ConcatMatrix(gravityMatrix);
571 Drawing::Rect clipRect;
572 gravityMatrix.MapRect(clipRect, Drawing::Rect(0, 0, frameWidth, frameHeight));
573 canvas->ClipRect(Drawing::Rect(0, 0, clipRect.GetWidth(), clipRect.GetHeight()), Drawing::ClipOp::INTERSECT);
574 Drawing::RectI newDstRect = canvas->GetDeviceClipBounds();
575 // we make the newDstRect as the intersection of new and old dstRect,
576 // to deal with the situation that frameSize > boundsSize.
577 newDstRect.Intersect(Drawing::RectI(
578 info.dstRect.x, info.dstRect.y, info.dstRect.w + info.dstRect.x, info.dstRect.h + info.dstRect.y));
579 auto localRect = canvas->GetLocalClipBounds();
580 int left = std::clamp<int>(localRect.GetLeft(), 0, frameWidth);
581 int top = std::clamp<int>(localRect.GetTop(), 0, frameHeight);
582 int width = std::clamp<int>(localRect.GetWidth(), 0, frameWidth - left);
583 int height = std::clamp<int>(localRect.GetHeight(), 0, frameHeight - top);
584 GraphicIRect newSrcRect = {left, top, width, height};
585
586 // log and apply new dstRect and srcRect
587 RS_LOGD("RsDebug DealWithNodeGravity: name[%{public}s], gravity[%{public}d], oldDstRect[%{public}d %{public}d"
588 " %{public}d %{public}d], newDstRect[%{public}d %{public}d %{public}d %{public}d], oldSrcRect[%{public}d"
589 " %{public}d %{public}d %{public}d], newSrcRect[%{public}d %{public}d %{public}d %{public}d].",
590 surfaceDrawable.GetName().c_str(), static_cast<int>(frameGravity),
591 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
592 newDstRect.GetLeft(), newDstRect.GetTop(), newDstRect.GetWidth(), newDstRect.GetHeight(),
593 info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
594 newSrcRect.x, newSrcRect.y, newSrcRect.w, newSrcRect.h);
595 info.dstRect = {newDstRect.GetLeft(), newDstRect.GetTop(), newDstRect.GetWidth(), newDstRect.GetHeight()};
596 info.srcRect = newSrcRect;
597 }
598
SrcRectRotateTransform(RSSurfaceRenderNode & node)599 RectI RSUniRenderComposerAdapter::SrcRectRotateTransform(RSSurfaceRenderNode& node)
600 {
601 auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
602 if (!consumer) {
603 return node.GetSrcRect();
604 }
605 RectI srcRect = node.GetSrcRect();
606 int left = srcRect.GetLeft();
607 int top = srcRect.GetTop();
608 int width = srcRect.GetWidth();
609 int height = srcRect.GetHeight();
610 GraphicTransformType transformType = RSBaseRenderUtil::GetRotateTransform(
611 RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, node.GetRSSurfaceHandler()->GetBuffer()));
612 int boundsWidth = static_cast<int>(node.GetRenderProperties().GetBoundsWidth());
613 int boundsHeight = static_cast<int>(node.GetRenderProperties().GetBoundsHeight());
614 // Left > 0 means move xComponent to the left outside of the screen
615 // Top > 0 means move xComponent to the top outside of the screen
616 // The left and top should recalculate when transformType is not GRAPHIC_ROTATE_NONE
617 // The width and height should exchange when transformType is GRAPHIC_ROTATE_270 and GRAPHIC_ROTATE_90
618 switch (transformType) {
619 case GraphicTransformType::GRAPHIC_ROTATE_270: {
620 left = std::max(top, 0);
621 top = std::max(boundsWidth - width - srcRect.GetLeft(), 0);
622 srcRect = RectI {left, top, height, width};
623 break;
624 }
625 case GraphicTransformType::GRAPHIC_ROTATE_180: {
626 left = std::max(boundsWidth - width - left, 0);
627 top = std::max(boundsHeight - height - top, 0);
628 srcRect = RectI {left, top, width, height};
629 break;
630 }
631 case GraphicTransformType::GRAPHIC_ROTATE_90: {
632 left = std::max(boundsHeight - height - top, 0);
633 top = std::max(srcRect.GetLeft(), 0);
634 srcRect = RectI {left, top, height, width};
635 break;
636 }
637 default: {
638 break;
639 }
640 }
641 RS_LOGD("BuildComposeInfo: srcRect transformed info NodeId:%{public}" PRIu64 ", XYWH:%{public}u,"
642 "%{public}u,%{public}u,%{public}u", node.GetId(),
643 srcRect.GetLeft(), srcRect.GetTop(), srcRect.GetWidth(), srcRect.GetHeight());
644 return srcRect;
645 }
646
SrcRectRotateTransform(DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable)647 RectI RSUniRenderComposerAdapter::SrcRectRotateTransform(DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable)
648 {
649 auto& params = surfaceDrawable.GetRenderParams();
650 auto consumer = surfaceDrawable.GetConsumerOnDraw();
651 if (!params || !consumer) {
652 return {};
653 }
654 const auto& srcGraphicRect = params->GetLayerInfo().srcRect;
655 RectI srcRect = {srcGraphicRect.x, srcGraphicRect.y, srcGraphicRect.w, srcGraphicRect.h};
656 int left = srcRect.GetLeft();
657 int top = srcRect.GetTop();
658 int width = srcRect.GetWidth();
659 int height = srcRect.GetHeight();
660 GraphicTransformType transformType = RSBaseRenderUtil::GetRotateTransform(
661 RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, params->GetBuffer()));
662 const auto& bounds = params->GetBounds();
663 int boundsWidth = static_cast<int>(bounds.GetWidth());
664 int boundsHeight = static_cast<int>(bounds.GetHeight());
665 // Left > 0 means move xComponent to the left outside of the screen
666 // Top > 0 means move xComponent to the top outside of the screen
667 // The left and top should recalculate when transformType is not GRAPHIC_ROTATE_NONE
668 // The width and height should exchange when transformType is GRAPHIC_ROTATE_270 and GRAPHIC_ROTATE_90
669 switch (transformType) {
670 case GraphicTransformType::GRAPHIC_ROTATE_270: {
671 left = std::max(top, 0);
672 top = std::max(boundsWidth - width - srcRect.GetLeft(), 0);
673 srcRect = RectI {left, top, height, width};
674 break;
675 }
676 case GraphicTransformType::GRAPHIC_ROTATE_180: {
677 left = std::max(boundsWidth - width - left, 0);
678 top = std::max(boundsHeight - height - top, 0);
679 srcRect = RectI {left, top, width, height};
680 break;
681 }
682 case GraphicTransformType::GRAPHIC_ROTATE_90: {
683 left = std::max(boundsHeight - height - top, 0);
684 top = std::max(srcRect.GetLeft(), 0);
685 srcRect = RectI {left, top, height, width};
686 break;
687 }
688 default: {
689 break;
690 }
691 }
692 RS_LOGD("BuildComposeInfo: srcRect transformed info NodeId:%{public}" PRIu64 ", XYWH:%{public}u,"
693 "%{public}u,%{public}u,%{public}u", surfaceDrawable.GetId(),
694 srcRect.GetLeft(), srcRect.GetTop(), srcRect.GetWidth(), srcRect.GetHeight());
695 return srcRect;
696 }
697
698 // private func, for RSSurfaceRenderNode.
BuildComposeInfo(RSSurfaceRenderNode & node) const699 ComposeInfo RSUniRenderComposerAdapter::BuildComposeInfo(RSSurfaceRenderNode& node) const
700 {
701 ComposeInfo info {};
702 auto& params = node.GetStagingRenderParams();
703 if (!params) {
704 RS_LOGE("RSUniRenderComposerAdapter::BuildComposeInfo fail, node params is nullptr");
705 return info;
706 }
707
708 auto surfaceHandler = node.GetRSSurfaceHandler();
709 const auto& dstRect = node.GetDstRect();
710 const auto srcRect = SrcRectRotateTransform(node);
711 info.srcRect = GraphicIRect {srcRect.left_, srcRect.top_, srcRect.width_, srcRect.height_};
712 info.dstRect = GraphicIRect {
713 static_cast<int32_t>(static_cast<float>(dstRect.left_) * screenInfo_.GetRogWidthRatio()),
714 static_cast<int32_t>(static_cast<float>(dstRect.top_) * screenInfo_.GetRogHeightRatio()),
715 static_cast<int32_t>(static_cast<float>(dstRect.width_) * screenInfo_.GetRogWidthRatio()),
716 static_cast<int32_t>(static_cast<float>(dstRect.height_) * screenInfo_.GetRogHeightRatio())
717 };
718 info.zOrder = surfaceHandler->GetGlobalZOrder();
719 info.alpha.enGlobalAlpha = true;
720 info.alpha.gAlpha = node.GetGlobalAlpha() * 255; // map gAlpha from float(0, 1) to uint8_t(0, 255).
721 info.fence = surfaceHandler->GetAcquireFence();
722 info.blendType = node.GetBlendType();
723 const auto& buffer = surfaceHandler->GetBuffer();
724 info.buffer = buffer;
725 SetPreBufferInfo(*surfaceHandler, info);
726 GetComposerInfoSrcRect(info, node);
727 info.needClient = GetComposerInfoNeedClient(info, *params);
728 DealWithNodeGravity(node, info);
729
730 info.dstRect.x -= offsetX_;
731 info.dstRect.y -= offsetY_;
732 info.visibleRect = info.dstRect;
733 std::vector<GraphicIRect> dirtyRects;
734 const Rect& dirtyRect = surfaceHandler->GetDamageRegion();
735 dirtyRects.emplace_back(GraphicIRect {dirtyRect.x, dirtyRect.y, dirtyRect.w, dirtyRect.h});
736 info.dirtyRects = dirtyRects;
737 auto totalMatrix = node.GetTotalMatrix();
738 info.matrix = GraphicMatrix {totalMatrix.Get(Drawing::Matrix::Index::SCALE_X),
739 totalMatrix.Get(Drawing::Matrix::Index::SKEW_X), totalMatrix.Get(Drawing::Matrix::Index::TRANS_X),
740 totalMatrix.Get(Drawing::Matrix::Index::SKEW_Y), totalMatrix.Get(Drawing::Matrix::Index::SCALE_Y),
741 totalMatrix.Get(Drawing::Matrix::Index::TRANS_Y), totalMatrix.Get(Drawing::Matrix::Index::PERSP_0),
742 totalMatrix.Get(Drawing::Matrix::Index::PERSP_1), totalMatrix.Get(Drawing::Matrix::Index::PERSP_2)};
743
744 const auto& property = node.GetRenderProperties();
745 info.boundRect = { 0, 0,
746 static_cast<int32_t>(property.GetBoundsWidth()), static_cast<int32_t>(property.GetBoundsHeight())};
747
748 const auto& renderParam = static_cast<RSSurfaceRenderParams*>(params.get());
749 if (renderParam == nullptr) {
750 RS_LOGE("RSUniRenderComposerAdapter::BuildComposeInfo fail, node params is nullptr");
751 return info;
752 }
753 info.displayNit = renderParam->GetDisplayNit();
754 info.brightnessRatio = renderParam->GetBrightnessRatio();
755 return info;
756 }
757
BuildComposeInfo(DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable) const758 ComposeInfo RSUniRenderComposerAdapter::BuildComposeInfo(DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable) const
759 {
760 ComposeInfo info {};
761 auto& params = surfaceDrawable.GetRenderParams();
762 if (!params) {
763 return info;
764 }
765 const auto& dstRect = params->GetLayerInfo().dstRect;
766 const auto srcRect = SrcRectRotateTransform(surfaceDrawable);
767 info.srcRect = GraphicIRect {srcRect.left_, srcRect.top_, srcRect.width_, srcRect.height_};
768 info.dstRect = GraphicIRect { static_cast<int32_t>(static_cast<float>(dstRect.x) * screenInfo_.GetRogWidthRatio()),
769 static_cast<int32_t>(static_cast<float>(dstRect.y) * screenInfo_.GetRogHeightRatio()),
770 static_cast<int32_t>(static_cast<float>(dstRect.w) * screenInfo_.GetRogWidthRatio()),
771 static_cast<int32_t>(static_cast<float>(dstRect.h) * screenInfo_.GetRogHeightRatio()) };
772 info.zOrder = params->GetLayerInfo().zOrder;
773 info.alpha.enGlobalAlpha = true;
774 info.alpha.gAlpha = params->GetGlobalAlpha() * 255; // map gAlpha from float(0, 1) to uint8_t(0, 255).
775 info.fence = params->GetAcquireFence();
776 info.blendType = params->GetLayerInfo().blendType;
777 const auto& buffer = params->GetBuffer();
778 info.buffer = buffer;
779 info.preBuffer = params->GetPreBuffer();
780 GetComposerInfoSrcRect(info, surfaceDrawable);
781 info.needClient = GetComposerInfoNeedClient(info, *params);
782 DealWithNodeGravity(surfaceDrawable, info);
783
784 info.dstRect.x -= offsetX_;
785 info.dstRect.y -= offsetY_;
786 info.visibleRect = info.dstRect;
787 std::vector<GraphicIRect> dirtyRects;
788 const Rect& dirtyRect = params->GetBufferDamage();
789 dirtyRects.emplace_back(GraphicIRect {dirtyRect.x, dirtyRect.y, dirtyRect.w, dirtyRect.h});
790 info.dirtyRects = dirtyRects;
791 auto totalMatrix = params->GetTotalMatrix();
792 info.matrix = GraphicMatrix {totalMatrix.Get(Drawing::Matrix::Index::SCALE_X),
793 totalMatrix.Get(Drawing::Matrix::Index::SKEW_X), totalMatrix.Get(Drawing::Matrix::Index::TRANS_X),
794 totalMatrix.Get(Drawing::Matrix::Index::SKEW_Y), totalMatrix.Get(Drawing::Matrix::Index::SCALE_Y),
795 totalMatrix.Get(Drawing::Matrix::Index::TRANS_Y), totalMatrix.Get(Drawing::Matrix::Index::PERSP_0),
796 totalMatrix.Get(Drawing::Matrix::Index::PERSP_1), totalMatrix.Get(Drawing::Matrix::Index::PERSP_2)};
797
798 info.boundRect = { 0, 0,
799 static_cast<int32_t>(params->GetBounds().GetWidth()), static_cast<int32_t>(params->GetBounds().GetHeight())};
800
801 const auto& curRenderParam = static_cast<RSSurfaceRenderParams*>(params.get());
802 if (curRenderParam == nullptr) {
803 RS_LOGE("RSUniRenderComposerAdapter::curRenderParam is nullptr");
804 return info;
805 }
806 info.displayNit = curRenderParam->GetDisplayNit();
807 info.brightnessRatio = curRenderParam->GetBrightnessRatio();
808 return info;
809 }
810
CheckStatusBeforeCreateLayer(RSSurfaceRenderNode & node) const811 bool RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer(RSSurfaceRenderNode& node) const
812 {
813 if (output_ == nullptr) {
814 RS_LOGE("RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer: output is nullptr");
815 return false;
816 }
817 auto surfaceHandler = node.GetRSSurfaceHandler();
818 if (!surfaceHandler) {
819 return false;
820 }
821 const auto& buffer = surfaceHandler->GetBuffer();
822 if (buffer == nullptr) {
823 RS_LOGD("RsDebug RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer:"\
824 " node(%{public}" PRIu64 ") has no available buffer.", node.GetId());
825 return false;
826 }
827 const auto& dstRect = node.GetDstRect();
828 const auto& srcRect = node.GetSrcRect();
829
830 // check if the node's srcRect and dstRect are valid.
831 if (srcRect.width_ <= 0 || srcRect.height_ <= 0 || dstRect.width_ <= 0 || dstRect.height_ <= 0) {
832 return false;
833 }
834
835 auto& geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
836 if (geoPtr == nullptr) {
837 RS_LOGW("RsDebug RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer:"\
838 " node(%{public}" PRIu64 ")'s geoPtr is nullptr!", node.GetId());
839 return false;
840 }
841 return true;
842 }
843
CheckStatusBeforeCreateLayer(DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable) const844 bool RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer(
845 DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable) const
846 {
847 if (output_ == nullptr) {
848 RS_LOGE("RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer: output is nullptr");
849 return false;
850 }
851
852 auto& params = surfaceDrawable.GetRenderParams();
853 if (!params) {
854 return false;
855 }
856 const auto& buffer = params->GetBuffer();
857 if (buffer == nullptr) {
858 RS_LOGD("RsDebug RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer:"\
859 " node(%{public}" PRIu64 ") has no available buffer.", surfaceDrawable.GetId());
860 return false;
861 }
862 const auto& dstRect = params->GetLayerInfo().dstRect;
863 const auto& srcRect = params->GetLayerInfo().srcRect;
864 // check if the node's srcRect and dstRect are valid.
865 if (srcRect.w <= 0 || srcRect.h <= 0 || dstRect.w <= 0 || dstRect.h <= 0) {
866 return false;
867 }
868
869 return true;
870 }
871
872 // private func, guarantee the layer is valid
LayerCrop(const LayerInfoPtr & layer) const873 void RSUniRenderComposerAdapter::LayerCrop(const LayerInfoPtr& layer) const
874 {
875 GraphicIRect dstRect = layer->GetLayerSize();
876 GraphicIRect srcRect = layer->GetCropRect();
877 GraphicIRect originSrcRect = srcRect;
878
879 RectI dstRectI(dstRect.x, dstRect.y, dstRect.w, dstRect.h);
880 RectI screenRectI(0, 0, static_cast<int32_t>(screenInfo_.phyWidth),
881 static_cast<int32_t>(screenInfo_.phyHeight));
882 RectI resDstRect = dstRectI.IntersectRect(screenRectI);
883 if (resDstRect == dstRectI) {
884 return;
885 }
886 dstRect = {resDstRect.left_, resDstRect.top_, resDstRect.width_, resDstRect.height_};
887 srcRect.x = (resDstRect.IsEmpty() || dstRectI.IsEmpty()) ? 0 : std::ceil((resDstRect.left_ - dstRectI.left_) *
888 originSrcRect.w / dstRectI.width_);
889 srcRect.y = (resDstRect.IsEmpty() || dstRectI.IsEmpty()) ? 0 : std::ceil((resDstRect.top_ - dstRectI.top_) *
890 originSrcRect.h / dstRectI.height_);
891 srcRect.w = dstRectI.IsEmpty() ? 0 : originSrcRect.w * resDstRect.width_ / dstRectI.width_;
892 srcRect.h = dstRectI.IsEmpty() ? 0 : originSrcRect.h * resDstRect.height_ / dstRectI.height_;
893 layer->SetLayerSize(dstRect);
894 std::vector<GraphicIRect> dirtyRegions;
895 dirtyRegions.emplace_back(srcRect);
896 layer->SetDirtyRegions(dirtyRegions);
897 layer->SetCropRect(srcRect);
898 RS_LOGD("RsDebug RSUniRenderComposerAdapter::LayerCrop layer has been cropped dst[%{public}d %{public}d %{public}d"
899 " %{public}d] src[%{public}d %{public}d %{public}d %{public}d]",
900 dstRect.x, dstRect.y, dstRect.w, dstRect.h, srcRect.x, srcRect.y, srcRect.w, srcRect.h);
901 }
902
903 // private func, guarantee the layer is valid
LayerScaleDown(const LayerInfoPtr & layer,RSSurfaceRenderNode & node)904 void RSUniRenderComposerAdapter::LayerScaleDown(const LayerInfoPtr& layer, RSSurfaceRenderNode& node)
905 {
906 const auto& buffer = layer->GetBuffer();
907 const auto& surface = layer->GetSurface();
908 if (buffer == nullptr || surface == nullptr) {
909 return;
910 }
911
912 GraphicIRect dstRect = layer->GetLayerSize();
913 GraphicIRect srcRect = layer->GetCropRect();
914
915 uint32_t newWidth = static_cast<uint32_t>(srcRect.w);
916 uint32_t newHeight = static_cast<uint32_t>(srcRect.h);
917 uint32_t dstWidth = static_cast<uint32_t>(dstRect.w);
918 uint32_t dstHeight = static_cast<uint32_t>(dstRect.h);
919
920 // If surfaceRotation is not a multiple of 180, need to change the correspondence between width & height.
921 // ScreenRotation has been processed in SetLayerSize, and do not change the width & height correspondence.
922 int surfaceRotation = RSUniRenderUtil::GetRotationFromMatrix(node.GetTotalMatrix()) +
923 RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(
924 RSBaseRenderUtil::GetSurfaceBufferTransformType(surface, buffer)));
925 if (surfaceRotation % FLAT_ANGLE != 0) {
926 std::swap(dstWidth, dstHeight);
927 }
928
929 uint32_t newWidthDstHeight = newWidth * dstHeight;
930 uint32_t newHeightDstWidth = newHeight * dstWidth;
931 if (newWidthDstHeight > newHeightDstWidth) {
932 // too wide
933 newWidth = dstWidth * newHeight / dstHeight;
934 } else if (newWidthDstHeight < newHeightDstWidth) {
935 // too tall
936 newHeight = dstHeight * newWidth / dstWidth;
937 } else {
938 return;
939 }
940
941 uint32_t currentWidth = static_cast<uint32_t>(srcRect.w);
942 uint32_t currentHeight = static_cast<uint32_t>(srcRect.h);
943 if (newWidth < currentWidth) {
944 // the crop is too wide
945 uint32_t dw = currentWidth - newWidth;
946 auto halfdw = dw / 2;
947 srcRect.x += static_cast<int32_t>(halfdw);
948 srcRect.w = static_cast<int32_t>(newWidth);
949 } else {
950 // thr crop is too tall
951 uint32_t dh = currentHeight - newHeight;
952 auto halfdh = dh / 2;
953 srcRect.y += static_cast<int32_t>(halfdh);
954 srcRect.h = static_cast<int32_t>(newHeight);
955 }
956 std::vector<GraphicIRect> dirtyRegions;
957 dirtyRegions.emplace_back(srcRect);
958 layer->SetDirtyRegions(dirtyRegions);
959 layer->SetCropRect(srcRect);
960 RS_LOGD("RsDebug RSUniRenderComposerAdapter::LayerScaleDown layer has been scaledown dst[%{public}d %{public}d"
961 " %{public}d %{public}d] src[%{public}d %{public}d %{public}d %{public}d]",
962 dstRect.x, dstRect.y, dstRect.w, dstRect.h, srcRect.x, srcRect.y, srcRect.w, srcRect.h);
963 }
964
LayerScaleDown(const LayerInfoPtr & layer,DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable)965 void RSUniRenderComposerAdapter::LayerScaleDown(
966 const LayerInfoPtr& layer, DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable)
967 {
968 auto& params = surfaceDrawable.GetRenderParams();
969 const auto& buffer = layer->GetBuffer();
970 const auto& surface = layer->GetSurface();
971 if (!params || !buffer || !surface) {
972 return;
973 }
974
975 GraphicIRect dstRect = layer->GetLayerSize();
976 GraphicIRect srcRect = layer->GetCropRect();
977
978 uint32_t newWidth = static_cast<uint32_t>(srcRect.w);
979 uint32_t newHeight = static_cast<uint32_t>(srcRect.h);
980 uint32_t dstWidth = static_cast<uint32_t>(dstRect.w);
981 uint32_t dstHeight = static_cast<uint32_t>(dstRect.h);
982
983 // If surfaceRotation is not a multiple of 180, need to change the correspondence between width & height.
984 // ScreenRotation has been processed in SetLayerSize, and do not change the width & height correspondence.
985 int surfaceRotation = RSUniRenderUtil::GetRotationFromMatrix(params->GetTotalMatrix()) +
986 RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(
987 RSBaseRenderUtil::GetSurfaceBufferTransformType(surface, buffer)));
988 if (surfaceRotation % FLAT_ANGLE != 0) {
989 std::swap(dstWidth, dstHeight);
990 }
991
992 uint32_t newWidthDstHeight = newWidth * dstHeight;
993 uint32_t newHeightDstWidth = newHeight * dstWidth;
994
995 if (newWidthDstHeight > newHeightDstWidth) {
996 // too wide
997 newWidth = dstWidth * newHeight / dstHeight;
998 } else if (newWidthDstHeight < newHeightDstWidth) {
999 // too tall
1000 newHeight = dstHeight * newWidth / dstWidth;
1001 } else {
1002 return;
1003 }
1004
1005 uint32_t currentWidth = static_cast<uint32_t>(srcRect.w);
1006 uint32_t currentHeight = static_cast<uint32_t>(srcRect.h);
1007
1008 if (newWidth < currentWidth) {
1009 // the crop is too wide
1010 uint32_t dw = currentWidth - newWidth;
1011 auto halfdw = dw / 2;
1012 srcRect.x += static_cast<int32_t>(halfdw);
1013 srcRect.w = static_cast<int32_t>(newWidth);
1014 } else {
1015 // thr crop is too tall
1016 uint32_t dh = currentHeight - newHeight;
1017 auto halfdh = dh / 2;
1018 srcRect.y += static_cast<int32_t>(halfdh);
1019 srcRect.h = static_cast<int32_t>(newHeight);
1020 }
1021 std::vector<GraphicIRect> dirtyRegions;
1022 dirtyRegions.emplace_back(srcRect);
1023 layer->SetDirtyRegions(dirtyRegions);
1024 layer->SetCropRect(srcRect);
1025 RS_LOGD("RsDebug RSUniRenderComposerAdapter::LayerScaleDown layer has been scaledown dst[%{public}d %{public}d"
1026 " %{public}d %{public}d] src[%{public}d %{public}d %{public}d %{public}d]",
1027 dstRect.x, dstRect.y, dstRect.w, dstRect.h, srcRect.x, srcRect.y, srcRect.w, srcRect.h);
1028 }
1029
1030 // private func, guarantee the layer is valid
LayerScaleFit(const LayerInfoPtr & layer) const1031 void RSUniRenderComposerAdapter::LayerScaleFit(const LayerInfoPtr& layer) const
1032 {
1033 const auto& buffer = layer->GetBuffer();
1034 const auto& surface = layer->GetSurface();
1035 if (buffer == nullptr || surface == nullptr) {
1036 RS_LOGE("buffer or surface is nullptr");
1037 return;
1038 }
1039
1040 GraphicIRect srcRect = layer->GetCropRect();
1041 GraphicIRect dstRect = layer->GetLayerSize();
1042
1043 ScreenRotation rotation = screenInfo_.rotation;
1044 if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
1045 std::swap(srcRect.w, srcRect.h);
1046 }
1047
1048 uint32_t newWidth = static_cast<uint32_t>(srcRect.w);
1049 uint32_t newHeight = static_cast<uint32_t>(srcRect.h);
1050 uint32_t dstWidth = static_cast<uint32_t>(dstRect.w);
1051 uint32_t dstHeight = static_cast<uint32_t>(dstRect.h);
1052
1053 uint32_t newWidthDstHeight = newWidth * dstHeight;
1054 uint32_t newHeightDstWidth = newHeight * dstWidth;
1055
1056 if (newWidthDstHeight > newHeightDstWidth) {
1057 newHeight = newHeight * dstWidth / newWidth;
1058 newWidth = dstWidth;
1059 } else if (newWidthDstHeight < newHeightDstWidth) {
1060 newWidth = newWidth * dstHeight / newHeight;
1061 newHeight = dstHeight;
1062 } else {
1063 newHeight = dstHeight;
1064 newWidth = dstWidth;
1065 }
1066
1067 if (newWidth < dstWidth) {
1068 uint32_t dw = dstWidth - newWidth;
1069 auto halfdw = dw / 2;
1070 dstRect.x += static_cast<int32_t>(halfdw);
1071 } else if (newHeight < dstHeight) {
1072 uint32_t dh = dstHeight - newHeight;
1073 auto halfdh = dh / 2;
1074 dstRect.y += static_cast<int32_t>(halfdh);
1075 }
1076 dstRect.h = static_cast<int32_t>(newHeight);
1077 dstRect.w = static_cast<int32_t>(newWidth);
1078 layer->SetLayerSize(dstRect);
1079 RS_LOGD("RsDebug RSUniRenderComposerAdapter::LayerScaleFit layer has been scalefit dst[%{public}d %{public}d"
1080 " %{public}d %{public}d] src[%{public}d %{public}d %{public}d %{public}d]",
1081 dstRect.x, dstRect.y, dstRect.w, dstRect.h, srcRect.x, srcRect.y, srcRect.w, srcRect.h);
1082 }
1083
1084 // private func
IsOutOfScreenRegion(const ComposeInfo & info) const1085 bool RSUniRenderComposerAdapter::IsOutOfScreenRegion(const ComposeInfo& info) const
1086 {
1087 int32_t boundWidth = static_cast<int32_t>(screenInfo_.phyWidth);
1088 int32_t boundHeight = static_cast<int32_t>(screenInfo_.phyHeight);
1089 ScreenRotation rotation = screenInfo_.rotation;
1090 if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
1091 std::swap(boundWidth, boundHeight);
1092 }
1093
1094 const auto& dstRect = info.dstRect;
1095 if (dstRect.x + dstRect.w <= 0 ||
1096 dstRect.x >= boundWidth ||
1097 dstRect.y + dstRect.h <= 0 ||
1098 dstRect.y >= boundHeight) {
1099 return true;
1100 }
1101
1102 return false;
1103 }
1104
CreateBufferLayer(DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable) const1105 LayerInfoPtr RSUniRenderComposerAdapter::CreateBufferLayer(
1106 DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable) const
1107 {
1108 auto& params = surfaceDrawable.GetRenderParams();
1109 if (!params) {
1110 return nullptr;
1111 }
1112
1113 if (!CheckStatusBeforeCreateLayer(surfaceDrawable)) {
1114 return nullptr;
1115 }
1116 ComposeInfo info = BuildComposeInfo(surfaceDrawable);
1117 if (IsOutOfScreenRegion(info)) {
1118 RS_LOGD("RsDebug RSUniRenderComposerAdapter::CreateBufferLayer: node(%{public}" PRIu64
1119 ") out of screen region, no need to composite.",
1120 surfaceDrawable.GetId());
1121 return nullptr;
1122 }
1123 RS_TRACE_NAME_FMT("CreateLayer:%s XYWH[%d %d %d %d]", surfaceDrawable.GetName().c_str(),
1124 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h);
1125 if (info.buffer) {
1126 RS_LOGD("RsDebug RSUniRenderComposerAdapter::CreateBufferLayer surfaceNode id:%{public}" PRIu64 " name:"
1127 "[%{public}s] dst [%{public}d %{public}d %{public}d %{public}d] SrcRect [%{public}d %{public}d]"
1128 " rawbuffer [%{public}d %{public}d] surfaceBuffer [%{public}d %{public}d], z:%{public}d,"
1129 " globalZOrder:%{public}d, blendType = %{public}d",
1130 surfaceDrawable.GetId(), surfaceDrawable.GetName().c_str(), info.dstRect.x, info.dstRect.y, info.dstRect.w,
1131 info.dstRect.h, info.srcRect.w, info.srcRect.h, info.buffer->GetWidth(), info.buffer->GetHeight(),
1132 info.buffer->GetSurfaceBufferWidth(), info.buffer->GetSurfaceBufferHeight(), params->GetLayerInfo().zOrder,
1133 info.zOrder, info.blendType);
1134 }
1135 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
1136 // planning surfaceNode prebuffer is set to hdilayerInfo, enable release prebuffer when HWC composition is ready
1137 SetComposeInfoToLayer(layer, info, surfaceDrawable.GetConsumerOnDraw());
1138 LayerRotate(layer, surfaceDrawable);
1139 LayerCrop(layer);
1140 ScalingMode scalingMode = params->GetScalingMode();
1141 const auto& buffer = layer->GetBuffer();
1142 const auto& surface = layer->GetSurface();
1143 if (buffer == nullptr || surface == nullptr) {
1144 RS_LOGE("buffer or surface is nullptr");
1145 return layer;
1146 }
1147
1148 if (surface->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK) {
1149 params->SetScalingMode(scalingMode);
1150 }
1151 if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
1152 LayerScaleDown(layer, surfaceDrawable);
1153 } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
1154 LayerScaleFit(layer);
1155 }
1156 return layer;
1157 }
1158
CreateBufferLayer(RSSurfaceRenderNode & node) const1159 LayerInfoPtr RSUniRenderComposerAdapter::CreateBufferLayer(RSSurfaceRenderNode& node) const
1160 {
1161 if (!CheckStatusBeforeCreateLayer(node)) {
1162 return nullptr;
1163 }
1164 auto surfaceHandler = node.GetRSSurfaceHandler();
1165 if (!surfaceHandler) {
1166 return nullptr;
1167 }
1168 ComposeInfo info = BuildComposeInfo(node);
1169 if (IsOutOfScreenRegion(info)) {
1170 RS_LOGD("RsDebug RSUniRenderComposerAdapter::CreateBufferLayer: node(%{public}" PRIu64
1171 ") out of screen region, no need to composite.",
1172 node.GetId());
1173 return nullptr;
1174 }
1175 RS_TRACE_NAME_FMT("CreateLayer:%s XYWH[%d %d %d %d]", node.GetName().c_str(),
1176 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h);
1177 if (info.buffer) {
1178 RS_LOGD(
1179 "RsDebug RSUniRenderComposerAdapter::CreateBufferLayer surfaceNode id:%{public}" PRIu64 " name:"
1180 "[%{public}s] dst [%{public}d %{public}d %{public}d %{public}d] SrcRect [%{public}d %{public}d]"
1181 " rawbuffer [%{public}d %{public}d] surfaceBuffer [%{public}d %{public}d], z:%{public}f,"
1182 " globalZOrder:%{public}d, blendType = %{public}d",
1183 node.GetId(), node.GetName().c_str(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
1184 info.srcRect.w, info.srcRect.h, info.buffer->GetWidth(), info.buffer->GetHeight(),
1185 info.buffer->GetSurfaceBufferWidth(), info.buffer->GetSurfaceBufferHeight(),
1186 surfaceHandler->GetGlobalZOrder(), info.zOrder, info.blendType);
1187 }
1188 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
1189 // planning surfaceNode prebuffer is set to hdilayerInfo, enable release prebuffer when HWC composition is ready
1190 SetComposeInfoToLayer(layer, info, surfaceHandler->GetConsumer());
1191 LayerRotate(layer, node);
1192 LayerCrop(layer);
1193 layer->SetNodeId(node.GetId());
1194 const auto nodeParams = static_cast<RSSurfaceRenderParams*>(node.GetRenderParams().get());
1195 if (!nodeParams) {
1196 RS_LOGE("node params is nullptr");
1197 return layer;
1198 }
1199 ScalingMode scalingMode = nodeParams->GetScalingMode();
1200 const auto& buffer = layer->GetBuffer();
1201 const auto& surface = layer->GetSurface();
1202 if (buffer == nullptr || surface == nullptr) {
1203 RS_LOGE("buffer or surface is nullptr");
1204 return layer;
1205 }
1206 if (surface->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK) {
1207 nodeParams->SetScalingMode(scalingMode);
1208 }
1209 if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
1210 LayerScaleDown(layer, node);
1211 } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
1212 LayerScaleFit(layer);
1213 }
1214 return layer;
1215 }
1216
CreateLayer(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable)1217 LayerInfoPtr RSUniRenderComposerAdapter::CreateLayer(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable)
1218 {
1219 if (output_ == nullptr) {
1220 RS_LOGE("RSUniRenderComposerAdapter::CreateLayer: output is nullptr");
1221 return nullptr;
1222 }
1223 auto surfaceHandler = displayDrawable.GetMutableRSSurfaceHandlerOnDraw();
1224 if (!surfaceHandler) {
1225 return nullptr;
1226 }
1227 RS_LOGD("RSUniRenderComposerAdapter::CreateLayer displayNode id:%{public}" PRIu64 " available buffer:%{public}d",
1228 displayDrawable.GetId(), surfaceHandler->GetAvailableBufferCount());
1229 if (!displayDrawable.IsSurfaceCreated()) {
1230 sptr<IBufferConsumerListener> listener = new RSUniRenderListener(surfaceHandler);
1231 if (!displayDrawable.CreateSurface(listener)) {
1232 RS_LOGE("RSUniRenderComposerAdapter::CreateLayer CreateSurface failed");
1233 return nullptr;
1234 }
1235 }
1236 if (!RSBaseRenderUtil::ConsumeAndUpdateBuffer(*surfaceHandler) ||
1237 !surfaceHandler->GetBuffer()) {
1238 RS_LOGE("RSUniRenderComposerAdapter::CreateLayer RSDisplayRenderNodeDrawable consume buffer failed. %{public}d",
1239 !surfaceHandler->GetBuffer());
1240 return nullptr;
1241 }
1242 ComposeInfo info = BuildComposeInfo(displayDrawable, displayDrawable.GetDirtyRects());
1243 RS_OPTIONAL_TRACE_NAME_FMT("CreateLayer displayDrawable zorder:%d bufferFormat:%d", info.zOrder,
1244 surfaceHandler->GetBuffer()->GetFormat());
1245 if (info.buffer) {
1246 RS_LOGD("RSUniRenderComposerAdapter::CreateLayer displayDrawable id:%{public}" PRIu64 " dst [%{public}d"
1247 " %{public}d %{public}d %{public}d] SrcRect [%{public}d %{public}d] rawbuffer [%{public}d %{public}d]"
1248 " surfaceBuffer [%{public}d %{public}d], globalZOrder:%{public}d, blendType = %{public}d, bufferFormat:%d",
1249 displayDrawable.GetId(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
1250 info.srcRect.w, info.srcRect.h, info.buffer->GetWidth(), info.buffer->GetHeight(),
1251 info.buffer->GetSurfaceBufferWidth(), info.buffer->GetSurfaceBufferHeight(), info.zOrder, info.blendType,
1252 surfaceHandler->GetBuffer()->GetFormat());
1253 }
1254 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
1255 layer->SetUniRenderFlag(true);
1256 SetComposeInfoToLayer(layer, info, surfaceHandler->GetConsumer());
1257 LayerRotate(layer, displayDrawable);
1258 // do not crop or scale down for displayNode's layer.
1259 return layer;
1260 }
1261
CreateLayer(RSDisplayRenderNode & node)1262 LayerInfoPtr RSUniRenderComposerAdapter::CreateLayer(RSDisplayRenderNode& node)
1263 {
1264 if (output_ == nullptr) {
1265 RS_LOGE("RSUniRenderComposerAdapter::CreateLayer: output is nullptr");
1266 return nullptr;
1267 }
1268 auto drawable = node.GetRenderDrawable();
1269 if (!drawable) {
1270 return nullptr;
1271 }
1272 auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
1273 auto surfaceHandler = displayDrawable->GetMutableRSSurfaceHandlerOnDraw();
1274 RS_OPTIONAL_TRACE_NAME("RSUniRenderComposerAdapter::CreateLayer DisplayNode");
1275 if (!displayDrawable->IsSurfaceCreated()) {
1276 return nullptr;
1277 }
1278 RS_LOGD("RSUniRenderComposerAdapter::CreateLayer displayNode id:%{public}" PRIu64 " available buffer:%{public}d",
1279 node.GetId(), surfaceHandler->GetAvailableBufferCount());
1280 if (!RSBaseRenderUtil::ConsumeAndUpdateBuffer(*surfaceHandler) ||
1281 !surfaceHandler->GetBuffer()) {
1282 RS_LOGE("RSUniRenderComposerAdapter::CreateLayer consume buffer failed.");
1283 return nullptr;
1284 }
1285 std::vector<RectI> dirtyRegions;
1286 if (auto dirtyManager = node.GetDirtyManager()) {
1287 dirtyRegions.emplace_back(dirtyManager->GetCurrentFrameDirtyRegion());
1288 }
1289 ComposeInfo info = BuildComposeInfo(*displayDrawable, dirtyRegions);
1290 RS_OPTIONAL_TRACE_NAME_FMT("CreateLayer displayNode zorder:%d bufferFormat:%d", info.zOrder,
1291 surfaceHandler->GetBuffer()->GetFormat());
1292 if (info.buffer) {
1293 RS_LOGD("RSUniRenderComposerAdapter::CreateLayer displayNode id:%{public}" PRIu64 " dst [%{public}d %{public}d"
1294 " %{public}d %{public}d] SrcRect [%{public}d %{public}d] rawbuffer [%{public}d %{public}d] surfaceBuffer"
1295 " [%{public}d %{public}d], globalZOrder:%{public}d, blendType = %{public}d, bufferFormat:%d",
1296 node.GetId(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h, info.srcRect.w,
1297 info.srcRect.h, info.buffer->GetWidth(), info.buffer->GetHeight(), info.buffer->GetSurfaceBufferWidth(),
1298 info.buffer->GetSurfaceBufferHeight(), info.zOrder, info.blendType,
1299 surfaceHandler->GetBuffer()->GetFormat());
1300 }
1301 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
1302 layer->SetNodeId(node.GetId());
1303 layer->SetUniRenderFlag(true);
1304 SetComposeInfoToLayer(layer, info, surfaceHandler->GetConsumer());
1305 LayerRotate(layer, *displayDrawable);
1306 // do not crop or scale down for displayNode's layer.
1307 return layer;
1308 }
1309
CreateLayer(RSSurfaceRenderNode & node) const1310 LayerInfoPtr RSUniRenderComposerAdapter::CreateLayer(RSSurfaceRenderNode& node) const
1311 {
1312 const auto& consumer = node.GetRSSurfaceHandler()->GetConsumer();
1313 if (consumer == nullptr) {
1314 RS_LOGE("RSUniRenderComposerAdapter::CreateLayer get consumer fail");
1315 return nullptr;
1316 }
1317 return CreateBufferLayer(node);
1318 }
1319
CreateLayer(DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable) const1320 LayerInfoPtr RSUniRenderComposerAdapter::CreateLayer(DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable) const
1321 {
1322 const auto consumer = surfaceDrawable.GetConsumerOnDraw();
1323 if (consumer == nullptr) {
1324 RS_LOGE("RSUniRenderComposerAdapter::CreateLayer get consumer fail");
1325 return nullptr;
1326 }
1327 return CreateBufferLayer(surfaceDrawable);
1328 }
1329
CreateLayer(RSRcdSurfaceRenderNode & node)1330 LayerInfoPtr RSUniRenderComposerAdapter::CreateLayer(RSRcdSurfaceRenderNode& node)
1331 {
1332 if (output_ == nullptr) {
1333 RS_LOGE("RSUniRenderComposerAdapter::CreateLayer: output is nullptr");
1334 return nullptr;
1335 }
1336
1337 if (node.GetBuffer() == nullptr) {
1338 RS_LOGE("RSUniRenderComposerAdapter::CreateLayer buffer is nullptr!");
1339 return nullptr;
1340 }
1341
1342 ComposeInfo info = BuildComposeInfo(node);
1343 if (info.buffer) {
1344 RS_LOGD("RSUniRenderComposerAdapter::ProcessRcdSurface rcdSurfaceNode id:%{public}" PRIu64 " DstRect"
1345 " [%{public}d %{public}d %{public}d %{public}d] SrcRect [%{public}d %{public}d %{public}d %{public}d]"
1346 " rawbuffer [%{public}d %{public}d] surfaceBuffer [%{public}d %{public}d], z-Order:%{public}d,"
1347 " blendType = %{public}d",
1348 node.GetId(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
1349 info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
1350 info.buffer->GetWidth(), info.buffer->GetHeight(), info.buffer->GetSurfaceBufferWidth(),
1351 info.buffer->GetSurfaceBufferHeight(), info.zOrder, info.blendType);
1352 }
1353 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
1354 SetComposeInfoToLayer(layer, info, node.GetConsumer());
1355 auto drawable = node.GetRenderDrawable();
1356 if (drawable) {
1357 LayerRotate(layer, *drawable);
1358 }
1359 layer->SetNodeId(node.GetId());
1360 return layer;
1361 }
1362
GetSurfaceNodeRotation(RSBaseRenderNode & node)1363 static int GetSurfaceNodeRotation(RSBaseRenderNode& node)
1364 {
1365 // only surface render node has the ability to rotate
1366 // the rotation of display render node is calculated as screen rotation
1367 if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
1368 return 0;
1369 }
1370 auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1371 return RSUniRenderUtil::GetRotationFromMatrix(surfaceNode.GetTotalMatrix());
1372 }
1373
GetSurfaceNodeRotation(DrawableV2::RSRenderNodeDrawableAdapter & drawable)1374 static int GetSurfaceNodeRotation(DrawableV2::RSRenderNodeDrawableAdapter& drawable)
1375 {
1376 // only surface render node has the ability to rotate
1377 // the rotation of display render node is calculated as screen rotation
1378 if (drawable.GetNodeType() != RSRenderNodeType::SURFACE_NODE) {
1379 return 0;
1380 }
1381
1382 auto& params = drawable.GetRenderParams();
1383 return params ? RSUniRenderUtil::GetRotationFromMatrix(params->GetTotalMatrix()) : 0;
1384 }
1385
SetLayerTransform(const LayerInfoPtr & layer,RSSurfaceRenderNode & node,const sptr<IConsumerSurface> & surface,ScreenRotation screenRotation)1386 static void SetLayerTransform(const LayerInfoPtr& layer, RSSurfaceRenderNode& node,
1387 const sptr<IConsumerSurface>& surface, ScreenRotation screenRotation)
1388 {
1389 // screenRotation: anti-clockwise, surfaceNodeRotation: anti-clockwise, surfaceTransform: anti-clockwise
1390 // layerTransform: clockwise
1391 int surfaceNodeRotation = GetSurfaceNodeRotation(node);
1392 auto transform = RSBaseRenderUtil::GetSurfaceBufferTransformType(layer->GetSurface(), layer->GetBuffer());
1393 int totalRotation = (RSBaseRenderUtil::RotateEnumToInt(screenRotation) + surfaceNodeRotation +
1394 RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(transform))) % 360;
1395 GraphicTransformType rotateEnum =
1396 RSBaseRenderUtil::RotateEnumToInt(totalRotation, RSBaseRenderUtil::GetFlipTransform(transform));
1397 layer->SetTransform(rotateEnum);
1398 }
1399
SetLayerTransform(const LayerInfoPtr & layer,DrawableV2::RSRenderNodeDrawableAdapter & drawable,const sptr<IConsumerSurface> & surface,ScreenRotation screenRotation)1400 static void SetLayerTransform(const LayerInfoPtr& layer, DrawableV2::RSRenderNodeDrawableAdapter& drawable,
1401 const sptr<IConsumerSurface>& surface, ScreenRotation screenRotation)
1402 {
1403 // screenRotation: anti-clockwise, surfaceNodeRotation: anti-clockwise, surfaceTransform: anti-clockwise
1404 // layerTransform: clockwise
1405 int surfaceNodeRotation = GetSurfaceNodeRotation(drawable);
1406 auto transform = RSBaseRenderUtil::GetSurfaceBufferTransformType(layer->GetSurface(), layer->GetBuffer());
1407 int totalRotation = (RSBaseRenderUtil::RotateEnumToInt(screenRotation) + surfaceNodeRotation +
1408 RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(transform))) % 360;
1409 GraphicTransformType rotateEnum =
1410 RSBaseRenderUtil::RotateEnumToInt(totalRotation, RSBaseRenderUtil::GetFlipTransform(transform));
1411 layer->SetTransform(rotateEnum);
1412 }
1413
SetLayerSize(const LayerInfoPtr & layer,const ScreenInfo & screenInfo)1414 static void SetLayerSize(const LayerInfoPtr& layer, const ScreenInfo& screenInfo)
1415 {
1416 const auto screenWidth = static_cast<int32_t>(screenInfo.width);
1417 const auto screenHeight = static_cast<int32_t>(screenInfo.height);
1418 const auto screenRotation = screenInfo.rotation;
1419 const auto rect = layer->GetLayerSize();
1420 // screenRotation: anti-clockwise, surfaceTransform: anti-clockwise, layerTransform: clockwise
1421 switch (screenRotation) {
1422 case ScreenRotation::ROTATION_90: {
1423 RS_LOGD("RsDebug ScreenRotation 90,Before Rotate layer size [%{public}d %{public}d %{public}d %{public}d]",
1424 rect.x, rect.y, rect.w, rect.h);
1425 layer->SetLayerSize(GraphicIRect {rect.y, screenHeight - rect.x - rect.w, rect.h, rect.w});
1426 RS_LOGD("RsDebug ScreenRotation 90, After Rotate layer size [%{public}d %{public}d %{public}d %{public}d]",
1427 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
1428 break;
1429 }
1430 case ScreenRotation::ROTATION_180: {
1431 RS_LOGD("RsDebug ScreenRotation 180, Before Rotate layer size [%{public}d %{public}d %{public}d"
1432 " %{public}d]", rect.x, rect.y, rect.w, rect.h);
1433 layer->SetLayerSize(
1434 GraphicIRect {screenWidth - rect.x - rect.w, screenHeight - rect.y - rect.h, rect.w, rect.h});
1435 RS_LOGD("RsDebug ScreenRotation 180,After Rotate layer size [%{public}d %{public}d %{public}d %{public}d]",
1436 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
1437 break;
1438 }
1439 case ScreenRotation::ROTATION_270: {
1440 RS_LOGD("RsDebug ScreenRotation 270, Before Rotate layer size [%{public}d %{public}d %{public}d"
1441 " %{public}d]", rect.x, rect.y, rect.w, rect.h);
1442 layer->SetLayerSize(GraphicIRect {screenWidth - rect.y - rect.h, rect.x, rect.h, rect.w});
1443 RS_LOGD("RsDebug ScreenRotation 270,After Rotate layer size [%{public}d %{public}d %{public}d %{public}d]",
1444 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
1445 break;
1446 }
1447 default: {
1448 break;
1449 }
1450 }
1451 }
1452
1453 // private func, guarantee the layer is valid
LayerRotate(const LayerInfoPtr & layer,RSSurfaceRenderNode & node) const1454 void RSUniRenderComposerAdapter::LayerRotate(
1455 const LayerInfoPtr& layer, RSSurfaceRenderNode& node) const
1456 {
1457 auto surface = layer->GetSurface();
1458 if (surface == nullptr) {
1459 return;
1460 }
1461 SetLayerSize(layer, screenInfo_);
1462 SetLayerTransform(layer, node, surface, screenInfo_.rotation);
1463 }
1464
1465
LayerRotate(const LayerInfoPtr & layer,DrawableV2::RSRenderNodeDrawableAdapter & drawable) const1466 void RSUniRenderComposerAdapter::LayerRotate(
1467 const LayerInfoPtr& layer, DrawableV2::RSRenderNodeDrawableAdapter& drawable) const
1468 {
1469 auto surface = layer->GetSurface();
1470 if (surface == nullptr) {
1471 return;
1472 }
1473 SetLayerSize(layer, screenInfo_);
1474 SetLayerTransform(layer, drawable, surface, screenInfo_.rotation);
1475 }
1476
1477 } // namespace Rosen
1478 } // namespace OHOS
1479