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