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