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