• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 #include "common/rs_common_def.h"
19 #include "common/rs_obj_abs_geometry.h"
20 #include "common/rs_optional_trace.h"
21 #include "pipeline/rs_uni_render_util.h"
22 #include "platform/common/rs_log.h"
23 #include "rs_divided_render_util.h"
24 #include "rs_trace.h"
25 #include "string_utils.h"
26 
27 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
28 #include "pipeline/driven_render/rs_driven_surface_render_node.h"
29 #endif
30 
31 namespace OHOS {
32 namespace Rosen {
33 using namespace std;
34 constexpr uint32_t FLAT_ANGLE = 180;
Init(const ScreenInfo & screenInfo,int32_t offsetX,int32_t offsetY,float mirrorAdaptiveCoefficient)35 bool RSUniRenderComposerAdapter::Init(const ScreenInfo& screenInfo, int32_t offsetX, int32_t offsetY,
36     float mirrorAdaptiveCoefficient)
37 {
38     hdiBackend_ = HdiBackend::GetInstance();
39     if (hdiBackend_ == nullptr) {
40         RS_LOGE("RSUniRenderComposerAdapter::Init: hdiBackend is nullptr");
41         return false;
42     }
43     auto screenManager = CreateOrGetScreenManager();
44     if (screenManager == nullptr) {
45         RS_LOGE("RSUniRenderComposerAdapter::Init: ScreenManager is nullptr");
46         return false;
47     }
48     output_ = screenManager->GetOutput(ToScreenPhysicalId(screenInfo.id));
49     if (output_ == nullptr) {
50         RS_LOGE("RSUniRenderComposerAdapter::Init: output_ is nullptr");
51         return false;
52     }
53 
54     offsetX_ = offsetX;
55     offsetY_ = offsetY;
56     mirrorAdaptiveCoefficient_ = mirrorAdaptiveCoefficient;
57     screenInfo_ = screenInfo;
58 
59     GraphicIRect damageRect {0, 0, static_cast<int32_t>(screenInfo_.width), static_cast<int32_t>(screenInfo_.height)};
60     std::vector<GraphicIRect> damageRects;
61     damageRects.emplace_back(damageRect);
62     output_->SetOutputDamages(damageRects);
63     bool directClientCompEnableStatus = RSSystemProperties::GetDirectClientCompEnableStatus();
64     output_->SetDirectClientCompEnableStatus(directClientCompEnableStatus);
65 
66 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
67     // enable direct GPU composition.
68     output_->SetLayerCompCapacity(LAYER_COMPOSITION_CAPACITY);
69 #else // (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
70     output_->SetLayerCompCapacity(LAYER_COMPOSITION_CAPACITY_INVALID);
71 #endif // (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
72     return true;
73 }
74 
CommitLayers(const std::vector<LayerInfoPtr> & layers)75 void RSUniRenderComposerAdapter::CommitLayers(const std::vector<LayerInfoPtr>& layers)
76 {
77     if (hdiBackend_ == nullptr) {
78         RS_LOGE("RSUniRenderComposerAdapter::CommitLayers: backend is nullptr");
79         return;
80     }
81 
82     if (output_ == nullptr) {
83         RS_LOGE("RSUniRenderComposerAdapter::CommitLayers: output is nullptr");
84         return;
85     }
86     RSHardwareThread::Instance().CommitAndReleaseLayers(output_, layers);
87 }
88 
SetPreBufferInfo(RSSurfaceHandler & surfaceHandler,ComposeInfo & info) const89 void RSUniRenderComposerAdapter::SetPreBufferInfo(RSSurfaceHandler& surfaceHandler, ComposeInfo& info) const
90 {
91     auto preBuffer = surfaceHandler.GetPreBuffer();
92     info.preBuffer = preBuffer.buffer;
93     preBuffer.Reset();
94 }
95 
96 // private func, for RSDisplayRenderNode
BuildComposeInfo(RSDisplayRenderNode & node) const97 ComposeInfo RSUniRenderComposerAdapter::BuildComposeInfo(RSDisplayRenderNode& node) const
98 {
99     const auto& buffer = node.GetBuffer(); // we guarantee the buffer is valid.
100     ComposeInfo info {};
101     info.srcRect = GraphicIRect {0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight()};
102     info.dstRect = GraphicIRect {
103         0,
104         0,
105         static_cast<int32_t>(static_cast<float>(screenInfo_.GetRotatedWidth()) * mirrorAdaptiveCoefficient_),
106         static_cast<int32_t>(static_cast<float>(screenInfo_.GetRotatedHeight()) * mirrorAdaptiveCoefficient_)
107     };
108     info.boundRect = info.dstRect;
109     info.visibleRect = GraphicIRect {info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h};
110     info.zOrder = static_cast<int32_t>(node.GetGlobalZOrder());
111     info.alpha.enGlobalAlpha = true;
112     info.alpha.gAlpha = 255;
113     SetPreBufferInfo(node, info);
114     info.buffer = buffer;
115     info.fence = node.GetAcquireFence();
116     info.blendType = GRAPHIC_BLEND_SRCOVER;
117     info.needClient = GetComposerInfoNeedClient(info, node);
118     info.matrix = GraphicMatrix {1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f};
119     info.gravity = static_cast<int32_t>(Gravity::RESIZE);
120     return info;
121 }
122 
BuildComposeInfo(RSDrivenSurfaceRenderNode & node) const123 ComposeInfo RSUniRenderComposerAdapter::BuildComposeInfo(RSDrivenSurfaceRenderNode& node) const
124 {
125 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
126     const auto& buffer = node.GetBuffer(); // we guarantee the buffer is valid.
127     const RectI dstRect = node.GetDstRect();
128     const auto& srcRect = node.GetSrcRect();
129     ComposeInfo info {};
130     info.srcRect = GraphicIRect {srcRect.left_, srcRect.top_, srcRect.width_, srcRect.height_};
131     info.dstRect = GraphicIRect {dstRect.left_, dstRect.top_, dstRect.width_, dstRect.height_};
132     info.boundRect = info.dstRect;
133     info.visibleRect = info.dstRect;
134     info.zOrder = static_cast<int32_t>(node.GetGlobalZOrder());
135     info.alpha.enGlobalAlpha = true;
136     info.alpha.gAlpha = 255;
137     SetPreBufferInfo(node, info);
138     info.buffer = buffer;
139     info.fence = node.GetAcquireFence();
140     info.blendType = GRAPHIC_BLEND_SRCOVER;
141     info.needClient = false;
142     info.matrix = GraphicMatrix {1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f};
143     info.gravity = static_cast<int32_t>(Gravity::RESIZE);
144     return info;
145 #else
146     return {};
147 #endif
148 }
149 
SetComposeInfoToLayer(const LayerInfoPtr & layer,const ComposeInfo & info,const sptr<IConsumerSurface> & surface,RSBaseRenderNode * node) const150 void RSUniRenderComposerAdapter::SetComposeInfoToLayer(
151     const LayerInfoPtr& layer,
152     const ComposeInfo& info,
153     const sptr<IConsumerSurface>& surface,
154     RSBaseRenderNode* node) const
155 {
156     if (layer == nullptr) {
157         return;
158     }
159     layer->SetSurface(surface);
160     layer->SetBuffer(info.buffer, info.fence);
161     layer->SetPreBuffer(info.preBuffer);
162     layer->SetZorder(info.zOrder);
163     layer->SetAlpha(info.alpha);
164     layer->SetLayerSize(info.dstRect);
165     layer->SetBoundSize(info.boundRect);
166     layer->SetCompositionType(info.needClient ?
167         GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT : GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE);
168     std::vector<GraphicIRect> visibleRegions;
169     visibleRegions.emplace_back(info.visibleRect);
170     layer->SetVisibleRegions(visibleRegions);
171     std::vector<GraphicIRect> dirtyRegions;
172     dirtyRegions.emplace_back(info.srcRect);
173     layer->SetDirtyRegions(dirtyRegions);
174     layer->SetBlendType(info.blendType);
175     layer->SetCropRect(info.srcRect);
176     layer->SetMatrix(info.matrix);
177     layer->SetGravity(info.gravity);
178     SetMetaDataInfoToLayer(layer, info, surface);
179 }
180 
SetMetaDataInfoToLayer(const LayerInfoPtr & layer,const ComposeInfo & info,const sptr<IConsumerSurface> & surface) const181 void RSUniRenderComposerAdapter::SetMetaDataInfoToLayer(const LayerInfoPtr& layer, const ComposeInfo& info,
182                                                         const sptr<IConsumerSurface>& surface) const
183 {
184     HDRMetaDataType type;
185     if (surface->QueryMetaDataType(info.buffer->GetSeqNum(), type) != GSERROR_OK) {
186         RS_LOGE("RSUniRenderComposerAdapter::SetComposeInfoToLayer: QueryMetaDataType failed");
187         return;
188     }
189     switch (type) {
190         case HDRMetaDataType::HDR_META_DATA: {
191             std::vector<GraphicHDRMetaData> metaData;
192             if (surface->GetMetaData(info.buffer->GetSeqNum(), metaData) != GSERROR_OK) {
193                 RS_LOGE("RSUniRenderComposerAdapter::SetComposeInfoToLayer: GetMetaData failed");
194                 return;
195             }
196             layer->SetMetaData(metaData);
197             break;
198         }
199         case HDRMetaDataType::HDR_META_DATA_SET: {
200             GraphicHDRMetadataKey key;
201             std::vector<uint8_t> metaData;
202             if (surface->GetMetaDataSet(info.buffer->GetSeqNum(), key, metaData) != GSERROR_OK) {
203                 RS_LOGE("RSUniRenderComposerAdapter::SetComposeInfoToLayer: GetMetaDataSet failed");
204                 return;
205             }
206             GraphicHDRMetaDataSet metaDataSet;
207             metaDataSet.key = key;
208             metaDataSet.metaData = metaData;
209             layer->SetMetaDataSet(metaDataSet);
210             break;
211         }
212         case HDRMetaDataType::HDR_NOT_USED: {
213             break;
214         }
215         default:  {
216             break;
217         }
218     }
219 }
220 
GetComposerInfoSrcRect(ComposeInfo & info,const RSSurfaceRenderNode & node)221 void RSUniRenderComposerAdapter::GetComposerInfoSrcRect(ComposeInfo &info, const RSSurfaceRenderNode& node)
222 {
223     const auto& property = node.GetRenderProperties();
224     const auto bufferWidth = info.buffer->GetSurfaceBufferWidth();
225     const auto bufferHeight = info.buffer->GetSurfaceBufferHeight();
226     auto boundsWidth = property.GetBoundsWidth();
227     auto boundsHeight = property.GetBoundsHeight();
228     GraphicTransformType transformType = RSBaseRenderUtil::GetRotateTransform(node.GetConsumer()->GetTransform());
229     if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
230         transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
231         std::swap(boundsWidth, boundsHeight);
232     }
233     if (bufferWidth != boundsWidth || bufferHeight != boundsHeight) {
234         float xScale = (ROSEN_EQ(boundsWidth, 0.0f) ? 1.0f : bufferWidth / boundsWidth);
235         float yScale = (ROSEN_EQ(boundsHeight, 0.0f) ? 1.0f : bufferHeight / boundsHeight);
236 
237         // If the scaling mode is SCALING_MODE_SCALE_TO_WINDOW, the scale should use smaller one.
238         ScalingMode scalingMode = ScalingMode::SCALING_MODE_SCALE_TO_WINDOW;
239         if (node.GetConsumer()->GetScalingMode(info.buffer->GetSeqNum(), scalingMode) == GSERROR_OK &&
240             scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
241             float scale = std::min(xScale, yScale);
242             info.srcRect.x = info.srcRect.x * scale;
243             info.srcRect.y = info.srcRect.y * scale;
244             info.srcRect.w = (bufferWidth / scale - (boundsWidth - info.srcRect.w)) * scale;
245             info.srcRect.h = (bufferHeight / scale - (boundsHeight - info.srcRect.h)) * scale;
246         } else {
247             info.srcRect.x = info.srcRect.x * xScale;
248             info.srcRect.y = info.srcRect.y * yScale;
249             info.srcRect.w = info.srcRect.w * xScale;
250             info.srcRect.h = info.srcRect.h * yScale;
251         }
252     }
253     RS_LOGD("RsDebug RSUniRenderComposerAdapter::GetComposerInfoSrcRect surfaceNode id:%" PRIu64 ","\
254             "srcRect [%d %d %d %d]", node.GetId(), info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h);
255 }
256 
GetComposerInfoNeedClient(const ComposeInfo & info,RSRenderNode & node) const257 bool RSUniRenderComposerAdapter::GetComposerInfoNeedClient(const ComposeInfo &info, RSRenderNode& node) const
258 {
259     bool needClient = RSBaseRenderUtil::IsNeedClient(node, info);
260     if (info.buffer->GetSurfaceBufferColorGamut() != static_cast<GraphicColorGamut>(screenInfo_.colorGamut)) {
261         needClient = true;
262     }
263     return needClient;
264 }
265 
DealWithNodeGravity(const RSSurfaceRenderNode & node,ComposeInfo & info) const266 void RSUniRenderComposerAdapter::DealWithNodeGravity(const RSSurfaceRenderNode& node, ComposeInfo& info) const
267 {
268     const auto& property = node.GetRenderProperties();
269     const float frameWidth = info.buffer->GetSurfaceBufferWidth();
270     const float frameHeight = info.buffer->GetSurfaceBufferHeight();
271     const float boundsWidth = property.GetBoundsWidth();
272     const float boundsHeight = property.GetBoundsHeight();
273     const Gravity frameGravity = property.GetFrameGravity();
274     info.gravity = static_cast<int32_t>(frameGravity);
275     // we do not need to do additional works for Gravity::RESIZE and if frameSize == boundsSize.
276     if (frameGravity == Gravity::RESIZE || (frameWidth == boundsWidth && frameHeight == boundsHeight)) {
277         return;
278     }
279 
280     auto traceInfo = node.GetName() + " DealWithNodeGravity " + std::to_string(static_cast<int>(frameGravity));
281     RS_TRACE_NAME(traceInfo.c_str());
282 
283     // get current node's translate matrix and calculate gravity matrix.
284 #ifndef USE_ROSEN_DRAWING
285 #ifdef NEW_SKIA
286     auto translateMatrix = SkMatrix::Translate(
287         std::ceil(node.GetTotalMatrix().getTranslateX()), std::ceil(node.GetTotalMatrix().getTranslateY()));
288 #else
289     auto translateMatrix = SkMatrix::MakeTrans(
290         std::ceil(node.GetTotalMatrix().getTranslateX()), std::ceil(node.GetTotalMatrix().getTranslateY()));
291 #endif
292     SkMatrix gravityMatrix;
293 #else
294     auto translateMatrix = Drawing::Matrix();
295     translateMatrix.Translate(node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_X),
296         std::ceil(node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_Y)));
297     Drawing::Matrix gravityMatrix;
298 #endif
299     (void)RSPropertiesPainter::GetGravityMatrix(frameGravity,
300         RectF {0.0f, 0.0f, boundsWidth, boundsHeight}, frameWidth, frameHeight, gravityMatrix);
301     // create a canvas to calculate new dstRect and new srcRect
302     int32_t screenWidth = screenInfo_.width;
303     int32_t screenHeight = screenInfo_.height;
304     const auto screenRotation = screenInfo_.rotation;
305     if (screenRotation == ScreenRotation::ROTATION_90 || screenRotation == ScreenRotation::ROTATION_270) {
306         std::swap(screenWidth, screenHeight);
307     }
308 #ifndef USE_ROSEN_DRAWING
309     auto canvas = std::make_unique<SkCanvas>(screenWidth, screenHeight);
310     canvas->concat(translateMatrix);
311     canvas->concat(gravityMatrix);
312     SkRect clipRect;
313     gravityMatrix.mapRect(&clipRect, SkRect::MakeWH(frameWidth, frameHeight));
314     canvas->clipRect(SkRect::MakeWH(clipRect.width(), clipRect.height()));
315     SkIRect newDstRect = canvas->getDeviceClipBounds();
316     // we make the newDstRect as the intersection of new and old dstRect,
317     // to deal with the situation that frameSize > boundsSize.
318     newDstRect.intersect(SkIRect::MakeXYWH(info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h));
319     auto localRect = canvas->getLocalClipBounds();
320     int left = std::clamp<int>(localRect.left(), 0, frameWidth);
321     int top = std::clamp<int>(localRect.top(), 0, frameHeight);
322     int width = std::clamp<int>(localRect.width(), 0, frameWidth - left);
323     int height = std::clamp<int>(localRect.height(), 0, frameHeight - top);
324     GraphicIRect newSrcRect = {left, top, width, height};
325 
326     // log and apply new dstRect and srcRect
327     RS_LOGD("RsDebug DealWithNodeGravity: name[%s], gravity[%d], oldDstRect[%d %d %d %d], newDstRect[%d %d %d %d],"\
328         " oldSrcRect[%d %d %d %d], newSrcRect[%d %d %d %d].",
329         node.GetName().c_str(), static_cast<int>(frameGravity),
330         info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
331         newDstRect.left(), newDstRect.top(), newDstRect.width(), newDstRect.height(),
332         info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
333         newSrcRect.x, newSrcRect.y, newSrcRect.w, newSrcRect.h);
334     info.dstRect = {newDstRect.left(), newDstRect.top(), newDstRect.width(), newDstRect.height()};
335     info.srcRect = newSrcRect;
336 #else
337     auto canvas = std::make_unique<Drawing::Canvas>(screenWidth, screenHeight);
338     canvas->ConcatMatrix(translateMatrix);
339     canvas->ConcatMatrix(gravityMatrix);
340     Drawing::Rect clipRect;
341     gravityMatrix.MapRect(clipRect, Drawing::Rect(0, 0, frameWidth, frameHeight));
342     canvas->ClipRect(Drawing::Rect(0, 0, clipRect.GetWidth(), clipRect.GetHeight()), Drawing::ClipOp::INTERSECT);
343     Drawing::RectI newDstRect = canvas->GetDeviceClipBounds();
344     // we make the newDstRect as the intersection of new and old dstRect,
345     // to deal with the situation that frameSize > boundsSize.
346     newDstRect.Intersect(Drawing::RectI(
347         info.dstRect.x, info.dstRect.y, info.dstRect.w + info.dstRect.x, info.dstRect.h + info.dstRect.y));
348     auto localRect = canvas->GetLocalClipBounds();
349     int left = std::clamp<int>(localRect.GetLeft(), 0, frameWidth);
350     int top = std::clamp<int>(localRect.GetTop(), 0, frameHeight);
351     int width = std::clamp<int>(localRect.GetWidth(), 0, frameWidth - left);
352     int height = std::clamp<int>(localRect.GetHeight(), 0, frameHeight - top);
353     GraphicIRect newSrcRect = {left, top, width, height};
354 
355     // log and apply new dstRect and srcRect
356     RS_LOGD("RsDebug DealWithNodeGravity: name[%s], gravity[%d], oldDstRect[%d %d %d %d], newDstRect[%d %d %d %d],"\
357         " oldSrcRect[%d %d %d %d], newSrcRect[%d %d %d %d].",
358         node.GetName().c_str(), static_cast<int>(frameGravity),
359         info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
360         newDstRect.GetLeft(), newDstRect.GetTop(), newDstRect.GetWidth(), newDstRect.GetHeight(),
361         info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
362         newSrcRect.x, newSrcRect.y, newSrcRect.w, newSrcRect.h);
363     info.dstRect = {newDstRect.GetLeft(), newDstRect.GetTop(), newDstRect.GetWidth(), newDstRect.GetHeight()};
364     info.srcRect = newSrcRect;
365 #endif
366 }
367 
SrcRectRotateTransform(RSSurfaceRenderNode & node)368 RectI RSUniRenderComposerAdapter::SrcRectRotateTransform(RSSurfaceRenderNode& node)
369 {
370     if (node.GetConsumer() == nullptr) {
371         return node.GetSrcRect();
372     }
373     RectI srcRect = node.GetSrcRect();
374     int left = srcRect.GetLeft();
375     int top = srcRect.GetTop();
376     int width = srcRect.GetWidth();
377     int height = srcRect.GetHeight();
378     GraphicTransformType transformType = RSBaseRenderUtil::GetRotateTransform(node.GetConsumer()->GetTransform());
379     int boundsWidth = static_cast<int>(node.GetRenderProperties().GetBoundsWidth());
380     int boundsHeight = static_cast<int>(node.GetRenderProperties().GetBoundsHeight());
381     // Left > 0 means move xComponent to the left outside of the screen
382     switch (transformType) {
383         case GraphicTransformType::GRAPHIC_ROTATE_270: {
384             top = boundsWidth - width - left > 0 ? boundsWidth - width - left : 0;
385             left = 0;
386             srcRect = RectI {left, top, height, width};
387             break;
388         }
389         case GraphicTransformType::GRAPHIC_ROTATE_180: {
390             left = left > 0 ? 0 :
391                 boundsWidth - width > 0 ? boundsWidth - width : 0;
392             top = boundsHeight - height > 0 ? boundsHeight - height : 0;
393             srcRect = RectI {left, top, width, height};
394             break;
395         }
396         case GraphicTransformType::GRAPHIC_ROTATE_90: {
397             if (left > 0) {
398                 top = boundsWidth - width > 0 ? boundsWidth - width : 0;
399             }
400             left = boundsHeight - height > 0 ? boundsHeight - height : 0;
401             srcRect = RectI {left, top, height, width};
402             break;
403         }
404         default: {
405             break;
406         }
407     }
408     RS_LOGD("BuildComposeInfo: srcRect transformed info NodeId:%" PRIu64 ", XYWH:%u,%u,%u,%u", node.GetId(),
409                 srcRect.GetLeft(), srcRect.GetTop(), srcRect.GetWidth(), srcRect.GetHeight());
410     return srcRect;
411 }
412 
413 // private func, for RSSurfaceRenderNode.
BuildComposeInfo(RSSurfaceRenderNode & node) const414 ComposeInfo RSUniRenderComposerAdapter::BuildComposeInfo(RSSurfaceRenderNode& node) const
415 {
416     const auto& dstRect = node.GetDstRect();
417     const auto srcRect = SrcRectRotateTransform(node);
418     ComposeInfo info {};
419     info.srcRect = GraphicIRect {srcRect.left_, srcRect.top_, srcRect.width_, srcRect.height_};
420     info.dstRect = GraphicIRect {
421         static_cast<int32_t>(static_cast<float>(dstRect.left_) * mirrorAdaptiveCoefficient_),
422         static_cast<int32_t>(static_cast<float>(dstRect.top_) * mirrorAdaptiveCoefficient_),
423         static_cast<int32_t>(static_cast<float>(dstRect.width_) * mirrorAdaptiveCoefficient_),
424         static_cast<int32_t>(static_cast<float>(dstRect.height_) * mirrorAdaptiveCoefficient_)
425     };
426     info.zOrder = static_cast<int32_t>(node.GetGlobalZOrder());
427     info.alpha.enGlobalAlpha = true;
428     info.alpha.gAlpha = node.GetGlobalAlpha() * 255; // map gAlpha from float(0, 1) to uint8_t(0, 255).
429     info.fence = node.GetAcquireFence();
430     info.blendType = node.GetBlendType();
431     const auto& buffer = node.GetBuffer();
432     info.buffer = buffer;
433     SetPreBufferInfo(node, info);
434     GetComposerInfoSrcRect(info, node);
435     info.needClient = GetComposerInfoNeedClient(info, node);
436     DealWithNodeGravity(node, info);
437 
438     info.dstRect.x -= static_cast<int32_t>(static_cast<float>(offsetX_) * mirrorAdaptiveCoefficient_);
439     info.dstRect.y -= static_cast<int32_t>(static_cast<float>(offsetY_) * mirrorAdaptiveCoefficient_);
440     info.visibleRect = info.dstRect;
441     auto totalMatrix = node.GetTotalMatrix();
442 #ifndef USE_ROSEN_DRAWING
443     info.matrix = GraphicMatrix {totalMatrix[0], totalMatrix[1], totalMatrix[2],
444                                  totalMatrix[3], totalMatrix[4], totalMatrix[5],
445                                  totalMatrix[6], totalMatrix[7], totalMatrix[8]};
446 #else
447     info.matrix = GraphicMatrix {totalMatrix.Get(Drawing::Matrix::Index::SCALE_X),
448         totalMatrix.Get(Drawing::Matrix::Index::SKEW_X), totalMatrix.Get(Drawing::Matrix::Index::TRANS_X),
449         totalMatrix.Get(Drawing::Matrix::Index::SKEW_Y), totalMatrix.Get(Drawing::Matrix::Index::SCALE_Y),
450         totalMatrix.Get(Drawing::Matrix::Index::TRANS_Y), totalMatrix.Get(Drawing::Matrix::Index::PERSP_0),
451         totalMatrix.Get(Drawing::Matrix::Index::PERSP_1), totalMatrix.Get(Drawing::Matrix::Index::PERSP_2)};
452 #endif
453 
454     const auto& property = node.GetRenderProperties();
455     info.boundRect = { 0, 0,
456         static_cast<int32_t>(property.GetBoundsWidth()), static_cast<int32_t>(property.GetBoundsHeight())};
457     return info;
458 }
459 
CheckStatusBeforeCreateLayer(RSSurfaceRenderNode & node) const460 bool RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer(RSSurfaceRenderNode& node) const
461 {
462     if (output_ == nullptr) {
463         RS_LOGE("RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer: output is nullptr");
464         return false;
465     }
466 
467     const auto& buffer = node.GetBuffer();
468     if (buffer == nullptr) {
469         RS_LOGD("RsDebug RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer:"\
470             " node(%" PRIu64 ") has no available buffer.", node.GetId());
471         return false;
472     }
473     const auto& dstRect = node.GetDstRect();
474     const auto& srcRect = node.GetSrcRect();
475     // check if the node's srcRect and dstRect are valid.
476     if (srcRect.width_ <= 0 || srcRect.height_ <= 0 || dstRect.width_ <= 0 || dstRect.height_ <= 0) {
477         return false;
478     }
479 
480     auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
481     if (geoPtr == nullptr) {
482         RS_LOGW("RsDebug RSUniRenderComposerAdapter::CheckStatusBeforeCreateLayer:"\
483             " node(%" PRIu64 ")'s geoPtr is nullptr!", node.GetId());
484         return false;
485     }
486     return true;
487 }
488 
489 // private func, guarantee the layer is valid
LayerCrop(const LayerInfoPtr & layer) const490 void RSUniRenderComposerAdapter::LayerCrop(const LayerInfoPtr& layer) const
491 {
492     GraphicIRect dstRect = layer->GetLayerSize();
493     GraphicIRect srcRect = layer->GetCropRect();
494     GraphicIRect originSrcRect = srcRect;
495 
496     RectI dstRectI(dstRect.x, dstRect.y, dstRect.w, dstRect.h);
497     int32_t screenWidth = static_cast<int32_t>(screenInfo_.width);
498     int32_t screenHeight = static_cast<int32_t>(screenInfo_.height);
499     RectI screenRectI(0, 0, screenWidth, screenHeight);
500     RectI resDstRect = dstRectI.IntersectRect(screenRectI);
501     if (resDstRect == dstRectI) {
502         return;
503     }
504     dstRect = {resDstRect.left_, resDstRect.top_, resDstRect.width_, resDstRect.height_};
505     srcRect.x = resDstRect.IsEmpty() ? 0 : std::ceil((resDstRect.left_ - dstRectI.left_) *
506         originSrcRect.w / dstRectI.width_);
507     srcRect.y = resDstRect.IsEmpty() ? 0 : std::ceil((resDstRect.top_ - dstRectI.top_) *
508         originSrcRect.h / dstRectI.height_);
509     srcRect.w = dstRectI.IsEmpty() ? 0 : originSrcRect.w * resDstRect.width_ / dstRectI.width_;
510     srcRect.h = dstRectI.IsEmpty() ? 0 : originSrcRect.h * resDstRect.height_ / dstRectI.height_;
511     layer->SetLayerSize(dstRect);
512     std::vector<GraphicIRect> dirtyRegions;
513     dirtyRegions.emplace_back(srcRect);
514     layer->SetDirtyRegions(dirtyRegions);
515     layer->SetCropRect(srcRect);
516     RS_LOGD("RsDebug RSUniRenderComposerAdapter::LayerCrop layer has been cropped dst[%d %d %d %d] src[%d %d %d %d]",
517         dstRect.x, dstRect.y, dstRect.w, dstRect.h, srcRect.x, srcRect.y, srcRect.w, srcRect.h);
518 }
519 
520 // private func, guarantee the layer is valid
LayerScaleDown(const LayerInfoPtr & layer,RSSurfaceRenderNode & node)521 void RSUniRenderComposerAdapter::LayerScaleDown(const LayerInfoPtr& layer, RSSurfaceRenderNode& node)
522 {
523     ScalingMode scalingMode = ScalingMode::SCALING_MODE_SCALE_TO_WINDOW;
524     const auto& buffer = layer->GetBuffer();
525     const auto& surface = layer->GetSurface();
526     if (buffer == nullptr || surface == nullptr) {
527         return;
528     }
529 
530     if (surface->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK &&
531         scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
532         GraphicIRect dstRect = layer->GetLayerSize();
533         GraphicIRect srcRect = layer->GetCropRect();
534 
535         uint32_t newWidth = static_cast<uint32_t>(srcRect.w);
536         uint32_t newHeight = static_cast<uint32_t>(srcRect.h);
537         uint32_t dstWidth = static_cast<uint32_t>(dstRect.w);
538         uint32_t dstHeight = static_cast<uint32_t>(dstRect.h);
539 
540         // If surfaceRotation is not a multiple of 180, need to change the correspondence between width & height.
541         // ScreenRotation has been processed in SetLayerSize, and do not change the width & height correspondence.
542         int surfaceRotation = RSUniRenderUtil::GetRotationFromMatrix(node.GetTotalMatrix()) +
543             RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(surface->GetTransform()));
544         if (surfaceRotation % FLAT_ANGLE != 0) {
545             std::swap(dstWidth, dstHeight);
546         }
547 
548         if (newWidth * dstHeight > newHeight * dstWidth) {
549             // too wide
550             newWidth = dstWidth * newHeight / dstHeight;
551         } else if (newWidth * dstHeight < newHeight * dstWidth) {
552             // too tall
553             newHeight = dstHeight * newWidth / dstWidth;
554         } else {
555             return;
556         }
557 
558         uint32_t currentWidth = static_cast<uint32_t>(srcRect.w);
559         uint32_t currentHeight = static_cast<uint32_t>(srcRect.h);
560 
561         if (newWidth < currentWidth) {
562             // the crop is too wide
563             uint32_t dw = currentWidth - newWidth;
564             auto halfdw = dw / 2;
565             srcRect.x += static_cast<int32_t>(halfdw);
566             srcRect.w = static_cast<int32_t>(newWidth);
567         } else {
568             // thr crop is too tall
569             uint32_t dh = currentHeight - newHeight;
570             auto halfdh = dh / 2;
571             srcRect.y += static_cast<int32_t>(halfdh);
572             srcRect.h = static_cast<int32_t>(newHeight);
573         }
574         std::vector<GraphicIRect> dirtyRegions;
575         dirtyRegions.emplace_back(srcRect);
576         layer->SetDirtyRegions(dirtyRegions);
577         layer->SetCropRect(srcRect);
578         RS_LOGD("RsDebug RSUniRenderComposerAdapter::LayerScaleDown layer has been scaledown dst[%d %d %d %d]"\
579             "src[%d %d %d %d]", dstRect.x, dstRect.y, dstRect.w, dstRect.h,
580             srcRect.x, srcRect.y, srcRect.w, srcRect.h);
581     }
582 }
583 
584 // private func
IsOutOfScreenRegion(const ComposeInfo & info) const585 bool RSUniRenderComposerAdapter::IsOutOfScreenRegion(const ComposeInfo& info) const
586 {
587     int32_t boundWidth = static_cast<int32_t>(screenInfo_.width);
588     int32_t boundHeight = static_cast<int32_t>(screenInfo_.height);
589     ScreenRotation rotation = screenInfo_.rotation;
590     if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
591         std::swap(boundWidth, boundHeight);
592     }
593 
594     const auto& dstRect = info.dstRect;
595     if (dstRect.x + dstRect.w <= 0 ||
596         dstRect.x >= boundWidth ||
597         dstRect.y + dstRect.h <= 0 ||
598         dstRect.y >= boundHeight) {
599         return true;
600     }
601 
602     return false;
603 }
604 
CreateBufferLayer(RSSurfaceRenderNode & node) const605 LayerInfoPtr RSUniRenderComposerAdapter::CreateBufferLayer(RSSurfaceRenderNode& node) const
606 {
607     if (!CheckStatusBeforeCreateLayer(node)) {
608         return nullptr;
609     }
610     ComposeInfo info = BuildComposeInfo(node);
611     if (IsOutOfScreenRegion(info)) {
612         RS_LOGD("RsDebug RSUniRenderComposerAdapter::CreateBufferLayer: node(%" PRIu64
613                 ") out of screen region, no need to composite.",
614             node.GetId());
615         return nullptr;
616     }
617     std::string traceInfo;
618     AppendFormat(traceInfo, "CreateLayer:%s XYWH[%d %d %d %d]", node.GetName().c_str(),
619         info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h);
620     RS_OPTIONAL_TRACE_BEGIN(traceInfo.c_str());
621     RS_LOGD(
622         "RsDebug RSUniRenderComposerAdapter::CreateBufferLayer surfaceNode id:%" PRIu64 " name:[%s] dst [%d %d %d %d]"
623         "SrcRect [%d %d] rawbuffer [%d %d] surfaceBuffer [%d %d], z:%f, globalZOrder:%d, blendType = %d",
624         node.GetId(), node.GetName().c_str(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
625         info.srcRect.w, info.srcRect.h, info.buffer->GetWidth(), info.buffer->GetHeight(),
626         info.buffer->GetSurfaceBufferWidth(), info.buffer->GetSurfaceBufferHeight(),
627         node.GetGlobalZOrder(), info.zOrder, info.blendType);
628     LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
629     // planning surfaceNode prebuffer is set to hdilayerInfo, enable release prebuffer when HWC composition is ready
630     SetComposeInfoToLayer(layer, info, node.GetConsumer(), &node);
631     LayerRotate(layer, node);
632     LayerCrop(layer);
633     LayerScaleDown(layer, node);
634     RS_OPTIONAL_TRACE_END();
635     return layer;
636 }
637 
CreateLayer(RSSurfaceRenderNode & node) const638 LayerInfoPtr RSUniRenderComposerAdapter::CreateLayer(RSSurfaceRenderNode& node) const
639 {
640     const auto& consumer = node.GetConsumer();
641     if (consumer == nullptr) {
642         RS_LOGE("RSUniRenderComposerAdapter::CreateLayer get consumer fail");
643         return nullptr;
644     }
645     return CreateBufferLayer(node);
646 }
647 
CreateLayer(RSDisplayRenderNode & node)648 LayerInfoPtr RSUniRenderComposerAdapter::CreateLayer(RSDisplayRenderNode& node)
649 {
650     if (output_ == nullptr) {
651         RS_LOGE("RSUniRenderComposerAdapter::CreateLayer: output is nullptr");
652         return nullptr;
653     }
654     RS_OPTIONAL_TRACE_BEGIN("RSUniRenderComposerAdapter::CreateLayer");
655     RS_LOGD("RSUniRenderComposerAdapter::CreateLayer displayNode id:%" PRIu64 " available buffer:%d", node.GetId(),
656         node.GetAvailableBufferCount());
657     if (!RSBaseRenderUtil::ConsumeAndUpdateBuffer(node) || !node.GetBuffer()) {
658         RS_LOGE("RSUniRenderComposerAdapter::CreateLayer consume buffer failed.");
659         RS_OPTIONAL_TRACE_END();
660         return nullptr;
661     }
662 
663     ComposeInfo info = BuildComposeInfo(node);
664     RS_LOGD("RSUniRenderComposerAdapter::ProcessSurface displayNode id:%" PRIu64 " dst [%d %d %d %d]"
665             "SrcRect [%d %d] rawbuffer [%d %d] surfaceBuffer [%d %d], globalZOrder:%d, blendType = %d",
666         node.GetId(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h, info.srcRect.w, info.srcRect.h,
667         info.buffer->GetWidth(), info.buffer->GetHeight(), info.buffer->GetSurfaceBufferWidth(),
668         info.buffer->GetSurfaceBufferHeight(), info.zOrder, info.blendType);
669     LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
670     SetComposeInfoToLayer(layer, info, node.GetConsumer(), &node);
671     LayerRotate(layer, node);
672     RS_OPTIONAL_TRACE_END();
673     // do not crop or scale down for displayNode's layer.
674     return layer;
675 }
676 
CreateLayer(RSDrivenSurfaceRenderNode & node)677 LayerInfoPtr RSUniRenderComposerAdapter::CreateLayer(RSDrivenSurfaceRenderNode& node)
678 {
679 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
680     if (output_ == nullptr) {
681         RS_LOGE("RSUniRenderComposerAdapter::CreateLayer: output is nullptr");
682         return nullptr;
683     }
684 
685     RS_LOGD("RSUniRenderComposerAdapter::CreateLayer RSDrivenSurfaceRenderNode id:%" PRIu64 " available buffer:%d",
686         node.GetId(), node.GetAvailableBufferCount());
687     if (!RSBaseRenderUtil::ConsumeAndUpdateBuffer(node)) {
688         RS_LOGE("RSUniRenderComposerAdapter::CreateLayer consume buffer failed.");
689         return nullptr;
690     }
691 
692     if (node.GetBuffer() == nullptr) {
693         RS_LOGE("RSUniRenderComposerAdapter::CreateLayer buffer is nullptr!");
694         return nullptr;
695     }
696 
697     ComposeInfo info = BuildComposeInfo(node);
698     RS_LOGD("RSUniRenderComposerAdapter::ProcessDrivenSurface drivenSurfaceNode id:%" PRIu64 " DstRect [%d %d %d %d]"
699             "SrcRect [%d %d %d %d] rawbuffer [%d %d] surfaceBuffer [%d %d], z-Order:%d, blendType = %d",
700         node.GetId(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
701         info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
702         info.buffer->GetWidth(), info.buffer->GetHeight(), info.buffer->GetSurfaceBufferWidth(),
703         info.buffer->GetSurfaceBufferHeight(), info.zOrder, info.blendType);
704     LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
705     SetComposeInfoToLayer(layer, info, node.GetConsumer(), &node);
706     LayerRotate(layer, node);
707     return layer;
708 #else
709     return nullptr;
710 #endif
711 }
712 
GetSurfaceNodeRotation(RSBaseRenderNode & node)713 static int GetSurfaceNodeRotation(RSBaseRenderNode& node)
714 {
715     // only surface render node has the ability to rotate
716     // the rotation of display render node is calculated as screen rotation
717     if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
718         return 0;
719     }
720 
721     auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
722     return RSUniRenderUtil::GetRotationFromMatrix(surfaceNode.GetTotalMatrix());
723 }
724 
SetLayerTransform(const LayerInfoPtr & layer,RSBaseRenderNode & node,const sptr<IConsumerSurface> & surface,ScreenRotation screenRotation)725 static void SetLayerTransform(const LayerInfoPtr& layer, RSBaseRenderNode& node,
726     const sptr<IConsumerSurface>& surface, ScreenRotation screenRotation)
727 {
728     // screenRotation: anti-clockwise, surfaceNodeRotation: anti-clockwise, surfaceTransform: anti-clockwise
729     // layerTransform: clockwise
730     int surfaceNodeRotation = GetSurfaceNodeRotation(node);
731     int totalRotation = (RotateEnumToInt(screenRotation) + surfaceNodeRotation +
732         RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(surface->GetTransform()))) % 360;
733     GraphicTransformType rotateEnum = RSBaseRenderUtil::RotateEnumToInt(totalRotation,
734         RSBaseRenderUtil::GetFlipTransform(surface->GetTransform()));
735     layer->SetTransform(rotateEnum);
736 }
737 
SetLayerSize(const LayerInfoPtr & layer,const ScreenInfo & screenInfo)738 static void SetLayerSize(const LayerInfoPtr& layer, const ScreenInfo& screenInfo)
739 {
740     const auto screenWidth = static_cast<int32_t>(screenInfo.width);
741     const auto screenHeight = static_cast<int32_t>(screenInfo.height);
742     const auto screenRotation = screenInfo.rotation;
743     const auto rect = layer->GetLayerSize();
744     // screenRotation: anti-clockwise, surfaceTransform: anti-clockwise, layerTransform: clockwise
745     switch (screenRotation) {
746         case ScreenRotation::ROTATION_90: {
747             RS_LOGD("RsDebug ScreenRotation 90, Before Rotate layer size [%d %d %d %d]",
748                 rect.x, rect.y, rect.w, rect.h);
749             layer->SetLayerSize(GraphicIRect {rect.y, screenHeight - rect.x - rect.w, rect.h, rect.w});
750             RS_LOGD("RsDebug ScreenRotation 90, After Rotate layer size [%d %d %d %d]",
751                 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
752             break;
753         }
754         case ScreenRotation::ROTATION_180: {
755             RS_LOGD("RsDebug ScreenRotation 180, Before Rotate layer size [%d %d %d %d]",
756                 rect.x, rect.y, rect.w, rect.h);
757             layer->SetLayerSize(
758                 GraphicIRect {screenWidth - rect.x - rect.w, screenHeight - rect.y - rect.h, rect.w, rect.h});
759             RS_LOGD("RsDebug ScreenRotation 180, After Rotate layer size [%d %d %d %d]",
760                 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
761             break;
762         }
763         case ScreenRotation::ROTATION_270: {
764             RS_LOGD("RsDebug ScreenRotation 270, Before Rotate layer size [%d %d %d %d]",
765                 rect.x, rect.y, rect.w, rect.h);
766             layer->SetLayerSize(GraphicIRect {screenWidth - rect.y - rect.h, rect.x, rect.h, rect.w});
767             RS_LOGD("RsDebug ScreenRotation 270, After Rotate layer size [%d %d %d %d]",
768                 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
769             break;
770         }
771         default:  {
772             break;
773         }
774     }
775 }
776 
777 // private func, guarantee the layer is valid
LayerRotate(const LayerInfoPtr & layer,RSBaseRenderNode & node) const778 void RSUniRenderComposerAdapter::LayerRotate(const LayerInfoPtr& layer, RSBaseRenderNode& node) const
779 {
780     auto surface = layer->GetSurface();
781     if (surface == nullptr) {
782         return;
783     }
784     SetLayerSize(layer, screenInfo_);
785     SetLayerTransform(layer, node, surface, screenInfo_.rotation);
786 }
787 
788 } // namespace Rosen
789 } // namespace OHOS
790