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_composer_adapter.h"
17
18 #include <fstream>
19 #include <memory>
20 #include <sstream>
21 #include <sys/time.h>
22
23 #include "common/rs_common_def.h"
24 #include "common/rs_obj_abs_geometry.h"
25 #include "drawable/rs_render_node_drawable_adapter.h"
26 #include "drawable/rs_surface_render_node_drawable.h"
27 #include "pipeline/rs_main_thread.h"
28 #include "pipeline/rs_surface_handler.h"
29 #include "pipeline/rs_surface_render_node.h"
30 #include "platform/common/rs_log.h"
31 #include "rs_divided_render_util.h"
32 #include "rs_trace.h"
33 #include "string_utils.h"
34
35 #include "draw/canvas.h"
36 #include "drawable/rs_display_render_node_drawable.h"
37
38 namespace OHOS {
39 namespace Rosen {
Init(const ScreenInfo & screenInfo,int32_t offsetX,int32_t offsetY,float mirrorAdaptiveCoefficient,const FallbackCallback & cb)40 bool RSComposerAdapter::Init(const ScreenInfo& screenInfo, int32_t offsetX, int32_t offsetY,
41 float mirrorAdaptiveCoefficient, const FallbackCallback& cb)
42 {
43 hdiBackend_ = HdiBackend::GetInstance();
44 if (hdiBackend_ == nullptr) {
45 RS_LOGE("RSComposerAdapter::Init: hdiBackend is nullptr");
46 return false;
47 }
48 auto screenManager = CreateOrGetScreenManager();
49 if (screenManager == nullptr) {
50 RS_LOGE("RSComposerAdapter::Init: ScreenManager is nullptr");
51 return false;
52 }
53 output_ = screenManager->GetOutput(ToScreenPhysicalId(screenInfo.id));
54 if (output_ == nullptr) {
55 RS_LOGE("RSComposerAdapter::Init: output_ is nullptr");
56 return false;
57 }
58
59 fallbackCb_ = cb;
60 auto onPrepareCompleteFunc = [this](auto& surface, const auto& param, void* data) {
61 OnPrepareComplete(surface, param, data);
62 };
63 hdiBackend_->RegPrepareComplete(onPrepareCompleteFunc, this);
64
65 offsetX_ = offsetX;
66 offsetY_ = offsetY;
67 mirrorAdaptiveCoefficient_ = mirrorAdaptiveCoefficient;
68 screenInfo_ = screenInfo;
69
70 GraphicIRect damageRect {0, 0, static_cast<int32_t>(screenInfo_.width), static_cast<int32_t>(screenInfo_.height)};
71 std::vector<GraphicIRect> damageRects;
72 damageRects.emplace_back(damageRect);
73 output_->SetOutputDamages(damageRects);
74 bool directClientCompEnableStatus = RSSystemProperties::GetDirectClientCompEnableStatus();
75 output_->SetDirectClientCompEnableStatus(directClientCompEnableStatus);
76
77 #if (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)) && (defined RS_ENABLE_EGLIMAGE)
78 // enable direct GPU composition.
79 output_->SetLayerCompCapacity(LAYER_COMPOSITION_CAPACITY);
80 #else
81 output_->SetLayerCompCapacity(LAYER_COMPOSITION_CAPACITY_INVALID);
82 #endif
83
84 return true;
85 }
86
Init(const RSDisplayRenderNode & node,const ScreenInfo & screenInfo,const ScreenInfo & mirroredScreenInfo,float mirrorAdaptiveCoefficient,const FallbackCallback & cb)87 bool RSComposerAdapter::Init(const RSDisplayRenderNode& node, const ScreenInfo& screenInfo,
88 const ScreenInfo& mirroredScreenInfo, float mirrorAdaptiveCoefficient, const FallbackCallback& cb)
89 {
90 hdiBackend_ = HdiBackend::GetInstance();
91 if (hdiBackend_ == nullptr) {
92 RS_LOGE("RSComposerAdapter::Init: hdiBackend is nullptr");
93 return false;
94 }
95 auto screenManager = CreateOrGetScreenManager();
96 if (screenManager == nullptr) {
97 RS_LOGE("RSComposerAdapter::Init: ScreenManager is nullptr");
98 return false;
99 }
100 output_ = screenManager->GetOutput(ToScreenPhysicalId(screenInfo.id));
101 if (output_ == nullptr) {
102 RS_LOGE("RSComposerAdapter::Init: output_ is nullptr");
103 return false;
104 }
105
106 fallbackCb_ = cb;
107 auto onPrepareCompleteFunc = [this](auto& surface, const auto& param, void* data) {
108 OnPrepareComplete(surface, param, data);
109 };
110 hdiBackend_->RegPrepareComplete(onPrepareCompleteFunc, this);
111
112 offsetX_ = node.GetDisplayOffsetX();
113 offsetY_ = node.GetDisplayOffsetY();
114 screenInfo_ = screenInfo;
115 mirroredScreenInfo_ = mirroredScreenInfo;
116 mirrorAdaptiveCoefficient_ = mirrorAdaptiveCoefficient;
117
118 GraphicIRect damageRect { 0, 0, static_cast<int32_t>(screenInfo_.width), static_cast<int32_t>(screenInfo_.height) };
119 std::vector<GraphicIRect> damageRects;
120 damageRects.emplace_back(damageRect);
121 output_->SetOutputDamages(damageRects);
122 bool directClientCompEnableStatus = RSSystemProperties::GetDirectClientCompEnableStatus();
123 output_->SetDirectClientCompEnableStatus(directClientCompEnableStatus);
124
125 #if (defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)) && (defined RS_ENABLE_EGLIMAGE)
126 // enable direct GPU composition.
127 output_->SetLayerCompCapacity(LAYER_COMPOSITION_CAPACITY);
128 #else
129 output_->SetLayerCompCapacity(LAYER_COMPOSITION_CAPACITY_INVALID);
130 #endif
131
132 return true;
133 }
134
CommitLayers(const std::vector<LayerInfoPtr> & layers)135 void RSComposerAdapter::CommitLayers(const std::vector<LayerInfoPtr>& layers)
136 {
137 if (hdiBackend_ == nullptr) {
138 RS_LOGE("RSComposerAdapter::CommitLayers: backend is nullptr");
139 return;
140 }
141
142 if (output_ == nullptr) {
143 RS_LOGE("RSComposerAdapter::CommitLayers: output is nullptr");
144 return;
145 }
146
147 DumpLayersToFile(layers);
148
149 // do composition.
150 output_->SetLayerInfo(layers);
151 hdiBackend_->Repaint(output_);
152
153 // get present timestamp from and set present timestamp to surface
154 for (const auto& layer : layers) {
155 if (layer == nullptr || layer->GetSurface() == nullptr) {
156 RS_LOGW("RSComposerAdapter::CommitLayers: layer or layer's cSurface is nullptr");
157 continue;
158 }
159 LayerPresentTimestamp(layer, layer->GetSurface());
160 }
161
162 // set all layers' releaseFence.
163 const auto layersReleaseFence = output_->GetLayersReleaseFence();
164 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
165 for (const auto& [layer, fence] : layersReleaseFence) {
166 if (layer == nullptr) {
167 continue;
168 }
169
170 auto nodePtr = nodeMap.GetRenderNode<RSRenderNode>(layer->GetNodeId());
171 if (nodePtr == nullptr) {
172 RS_LOGW("RSComposerAdapter::PostProcess: layer's node is nullptr.");
173 continue;
174 }
175 std::shared_ptr<RSSurfaceHandler> surfaceHandler = nullptr;
176 if (nodePtr->IsInstanceOf<RSSurfaceRenderNode>()) {
177 auto surfaceNode = nodePtr->ReinterpretCastTo<RSSurfaceRenderNode>();
178 surfaceHandler = surfaceNode ? surfaceNode->GetRSSurfaceHandler() : nullptr;
179 } else if (nodePtr->IsInstanceOf<RSDisplayRenderNode>()) {
180 auto drawable = nodePtr->GetRenderDrawable();
181 if (!drawable) {
182 continue;
183 }
184 auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
185 surfaceHandler = displayDrawable->GetMutableRSSurfaceHandlerOnDraw();
186 }
187 if (!surfaceHandler) {
188 continue;
189 }
190 surfaceHandler->SetReleaseFence(fence);
191 }
192 }
193
DumpLayersToFile(const std::vector<LayerInfoPtr> & layers)194 void RSComposerAdapter::DumpLayersToFile(const std::vector<LayerInfoPtr>& layers)
195 {
196 if (!RSSystemProperties::GetDumpLayersEnabled()) {
197 return;
198 }
199
200 for (auto &layerInfo : layers) {
201 if (layerInfo == nullptr || layerInfo->GetSurface() == nullptr) {
202 continue;
203 }
204 auto buffer = layerInfo->GetBuffer();
205 if (buffer == nullptr) {
206 RS_LOGW("RSComposerAdapter::DumpLayersToFile: Buffer is null");
207 continue;
208 }
209 struct timeval now;
210 gettimeofday(&now, nullptr);
211 constexpr int secToUsec = 1000 * 1000;
212 int64_t nowVal = static_cast<int64_t>(now.tv_sec) * secToUsec + static_cast<int64_t>(now.tv_usec);
213
214 std::stringstream ss;
215 ss << "/data/layer_" << layerInfo->GetSurface()->GetName() << "_" << nowVal << "_" << buffer->GetWidth()
216 << "x" << buffer->GetHeight() << ".raw";
217
218 std::ofstream rawDataFile(ss.str(), std::ofstream::binary);
219 if (!rawDataFile.good()) {
220 RS_LOGW("RSComposerAdapter::DumpLayersToFile: Open failed!");
221 continue;
222 }
223 rawDataFile.write(static_cast<const char *>(buffer->GetVirAddr()), buffer->GetSize());
224 rawDataFile.close();
225 }
226 }
227
228 // private func
IsOutOfScreenRegion(const ComposeInfo & info) const229 bool RSComposerAdapter::IsOutOfScreenRegion(const ComposeInfo& info) const
230 {
231 int32_t boundWidth = static_cast<int32_t>(screenInfo_.width);
232 int32_t boundHeight = static_cast<int32_t>(screenInfo_.height);
233 ScreenRotation rotation = screenInfo_.rotation;
234 if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
235 std::swap(boundWidth, boundHeight);
236 }
237
238 const auto& dstRect = info.dstRect;
239 if (dstRect.x + dstRect.w <= 0 ||
240 dstRect.x >= boundWidth ||
241 dstRect.y + dstRect.h <= 0 ||
242 dstRect.y >= boundHeight) {
243 return true;
244 }
245
246 return false;
247 }
248
DealWithNodeGravity(const RSSurfaceRenderNode & node,ComposeInfo & info) const249 void RSComposerAdapter::DealWithNodeGravity(const RSSurfaceRenderNode& node, ComposeInfo& info) const
250 {
251 if (!info.buffer) {
252 RS_LOGE("RSComposerAdapter::DealWithNodeGravity failed, info buffer is nullptr");
253 return;
254 }
255 const auto& property = node.GetRenderProperties();
256 const auto frameWidth = info.buffer->GetSurfaceBufferWidth();
257 const auto frameHeight = info.buffer->GetSurfaceBufferHeight();
258 const int boundsWidth = static_cast<int>(property.GetBoundsWidth());
259 const int boundsHeight = static_cast<int>(property.GetBoundsHeight());
260 const Gravity frameGravity = property.GetFrameGravity();
261 // we do not need to do additional works for Gravity::RESIZE and if frameSize == boundsSize.
262 if (frameGravity == Gravity::RESIZE || (frameWidth == boundsWidth && frameHeight == boundsHeight)) {
263 return;
264 }
265 RS_TRACE_NAME_FMT("%s DealWithNodeGravity %d", node.GetName().c_str(), static_cast<int>(frameGravity));
266 // get current node's translate matrix and calculate gravity matrix.
267 Drawing::Matrix translateMatrix;
268 translateMatrix.Translate(
269 std::ceil(node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_X)),
270 std::ceil(node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_Y)));
271 Drawing::Matrix gravityMatrix;
272 (void)RSPropertiesPainter::GetGravityMatrix(frameGravity,
273 RectF {0.0f, 0.0f, boundsWidth, boundsHeight}, frameWidth, frameHeight, gravityMatrix);
274
275 // create a canvas to calculate new dstRect and new srcRect
276 int32_t screenWidth = screenInfo_.width;
277 int32_t screenHeight = screenInfo_.height;
278 const auto screenRotation = screenInfo_.rotation;
279 if (screenRotation == ScreenRotation::ROTATION_90 || screenRotation == ScreenRotation::ROTATION_270) {
280 std::swap(screenWidth, screenHeight);
281 }
282 auto canvas = std::make_unique<Rosen::Drawing::Canvas>(screenWidth, screenHeight);
283 canvas->ConcatMatrix(translateMatrix);
284 Drawing::Rect clipRect;
285 Drawing::Rect srcRect(0, 0, frameWidth, frameHeight);
286 gravityMatrix.MapRect(clipRect, srcRect);
287 canvas->ClipRect(clipRect, Drawing::ClipOp::INTERSECT, false);
288 canvas->ConcatMatrix(gravityMatrix);
289 Drawing::RectI newDstRect = canvas->GetDeviceClipBounds();
290 // we make the newDstRect as the intersection of new and old dstRect when frameSize > boundsSize.
291 newDstRect.Intersect(Drawing::RectI(info.dstRect.x, info.dstRect.y,
292 info.dstRect.w + info.dstRect.x, info.dstRect.h + info.dstRect.y));
293 auto localRect = canvas->GetLocalClipBounds();
294 int left = std::clamp<int>(localRect.GetLeft(), 0, frameWidth);
295 int top = std::clamp<int>(localRect.GetTop(), 0, frameHeight);
296 int width = std::clamp<int>(localRect.GetWidth(), 0, frameWidth - left);
297 int height = std::clamp<int>(localRect.GetHeight(), 0, frameHeight - top);
298 GraphicIRect newSrcRect = {left, top, width, height};
299
300 RS_LOGD("RsDebug DealWithNodeGravity: name[%{public}s], gravity[%{public}d], oldDstRect[%{public}d"
301 " %{public}d %{public}d %{public}d], newDstRect[%{public}d %{public}d %{public}d %{public}d],"\
302 " oldSrcRect[%{public}d %{public}d %{public}d %{public}d], newSrcRect[%{public}d %{public}d"
303 " %{public}d %{public}d].", node.GetName().c_str(), static_cast<int>(frameGravity),
304 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
305 newDstRect.GetLeft(), newDstRect.GetTop(), newDstRect.GetWidth(), newDstRect.GetHeight(),
306 info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
307 newSrcRect.x, newSrcRect.y, newSrcRect.w, newSrcRect.h);
308 info.dstRect = {newDstRect.GetLeft(), newDstRect.GetTop(), newDstRect.GetWidth(), newDstRect.GetHeight()};
309 info.srcRect = newSrcRect;
310 }
311
GetComposerInfoSrcRect(ComposeInfo & info,const RSSurfaceRenderNode & node)312 void RSComposerAdapter::GetComposerInfoSrcRect(ComposeInfo& info, const RSSurfaceRenderNode& node)
313 {
314 if (!info.buffer) {
315 RS_LOGE("RSComposerAdapter::GetComposerInfoSrcRect failed, info buffer is nullptr");
316 return;
317 }
318 const auto& property = node.GetRenderProperties();
319 const auto bufferWidth = info.buffer->GetSurfaceBufferWidth();
320 const auto bufferHeight = info.buffer->GetSurfaceBufferHeight();
321 const int boundsWidth = static_cast<int>(property.GetBoundsWidth());
322 const int boundsHeight = static_cast<int>(property.GetBoundsHeight());
323 if (bufferWidth != boundsWidth || bufferHeight != boundsHeight) {
324 // float will cause loss of accuracy, and the result will 1 pixel less
325 double xScale = (ROSEN_EQ(boundsWidth, 0) ? 1.0 : 1.0 * bufferWidth / boundsWidth);
326 double yScale = (ROSEN_EQ(boundsHeight, 0) ? 1.0 : 1.0 * bufferHeight / boundsHeight);
327 info.srcRect.x = info.srcRect.x * xScale;
328 info.srcRect.y = info.srcRect.y * yScale;
329 info.srcRect.w = std::min(static_cast<int32_t>(info.srcRect.w * xScale), bufferWidth);
330 info.srcRect.h = std::min(static_cast<int32_t>(info.srcRect.h * yScale), bufferHeight);
331 }
332 }
333
GetComposerInfoNeedClient(const ComposeInfo & info,RSSurfaceRenderNode & node) const334 bool RSComposerAdapter::GetComposerInfoNeedClient(const ComposeInfo& info, RSSurfaceRenderNode& node) const
335 {
336 bool needClient = RSBaseRenderUtil::IsNeedClient(node, info);
337 if (info.buffer &&
338 info.buffer->GetSurfaceBufferColorGamut() != static_cast<GraphicColorGamut>(screenInfo_.colorGamut)) {
339 needClient = true;
340 }
341 if (colorFilterMode_ == ColorFilterMode::INVERT_COLOR_ENABLE_MODE) {
342 needClient = true;
343 }
344 return needClient;
345 }
346
347 // private func, for RSSurfaceRenderNode.
BuildComposeInfo(RSSurfaceRenderNode & node,bool isTunnelCheck) const348 ComposeInfo RSComposerAdapter::BuildComposeInfo(RSSurfaceRenderNode& node, bool isTunnelCheck) const
349 {
350 float offsetX = 0.0f;
351 float offsetY = 0.0f;
352 if (mirroredScreenInfo_.id != INVALID_SCREEN_ID) {
353 // align center
354 offsetX =
355 (screenInfo_.GetRotatedWidth() - mirroredScreenInfo_.GetRotatedWidth() * mirrorAdaptiveCoefficient_) / 2.0f;
356 offsetY =
357 (screenInfo_.GetRotatedHeight() - mirroredScreenInfo_.GetRotatedHeight() * mirrorAdaptiveCoefficient_) /
358 2.0f;
359 }
360
361 const auto& dstRect = node.GetDstRect();
362 const auto& srcRect = node.GetSrcRect();
363 ComposeInfo info {};
364 auto surfaceHandler = node.GetRSSurfaceHandler();
365 info.srcRect = GraphicIRect {srcRect.left_, srcRect.top_, srcRect.width_, srcRect.height_};
366 info.dstRect = GraphicIRect {
367 static_cast<int32_t>(static_cast<float>(dstRect.left_) * mirrorAdaptiveCoefficient_ + offsetX),
368 static_cast<int32_t>(static_cast<float>(dstRect.top_) * mirrorAdaptiveCoefficient_ + offsetY),
369 static_cast<int32_t>(static_cast<float>(dstRect.width_) * mirrorAdaptiveCoefficient_),
370 static_cast<int32_t>(static_cast<float>(dstRect.height_) * mirrorAdaptiveCoefficient_)
371 };
372 info.zOrder = static_cast<int32_t>(surfaceHandler->GetGlobalZOrder());
373 info.alpha.enGlobalAlpha = true;
374 info.alpha.gAlpha = node.GetGlobalAlpha() * 255; // map gAlpha from float(0, 1) to uint8_t(0, 255).
375 info.fence = surfaceHandler->GetAcquireFence();
376 info.blendType = node.GetBlendType();
377
378 info.dstRect.x -= static_cast<int32_t>(static_cast<float>(offsetX_) * mirrorAdaptiveCoefficient_);
379 info.dstRect.y -= static_cast<int32_t>(static_cast<float>(offsetY_) * mirrorAdaptiveCoefficient_);
380 info.visibleRect = info.dstRect;
381 std::vector<GraphicIRect> dirtyRects;
382 dirtyRects.emplace_back(info.srcRect);
383 info.dirtyRects = dirtyRects;
384 if (!isTunnelCheck) {
385 const auto& buffer = surfaceHandler->GetBuffer();
386 info.buffer = buffer;
387 GetComposerInfoSrcRect(info, node);
388 info.needClient = GetComposerInfoNeedClient(info, node);
389 DealWithNodeGravity(node, info);
390 } else {
391 info.needClient = false;
392 }
393 return info;
394 }
395
396 // private func, for RSDisplayRenderNode
BuildComposeInfo(RSDisplayRenderNode & node) const397 ComposeInfo RSComposerAdapter::BuildComposeInfo(RSDisplayRenderNode& node) const
398 {
399 ComposeInfo info {};
400 auto drawable = node.GetRenderDrawable();
401 if (!drawable) {
402 return info;
403 }
404 auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
405 auto surfaceHandler = displayDrawable->GetRSSurfaceHandlerOnDraw();
406 const auto& buffer = surfaceHandler->GetBuffer(); // we guarantee the buffer is valid.
407 info.srcRect = GraphicIRect {0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight()};
408 info.dstRect = GraphicIRect {
409 0,
410 0,
411 static_cast<int32_t>(static_cast<float>(screenInfo_.GetRotatedWidth()) * mirrorAdaptiveCoefficient_),
412 static_cast<int32_t>(static_cast<float>(screenInfo_.GetRotatedHeight()) * mirrorAdaptiveCoefficient_)
413 };
414 info.visibleRect = GraphicIRect {info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h};
415 std::vector<GraphicIRect> dirtyRects;
416 dirtyRects.emplace_back(info.srcRect);
417 info.dirtyRects = dirtyRects;
418 info.zOrder = static_cast<int32_t>(surfaceHandler->GetGlobalZOrder());
419 info.alpha.enGlobalAlpha = false;
420 info.buffer = buffer;
421 info.fence = surfaceHandler->GetAcquireFence();
422 info.blendType = GRAPHIC_BLEND_NONE;
423 info.needClient = false;
424 return info;
425 }
426
SetComposeInfoToLayer(const LayerInfoPtr & layer,const ComposeInfo & info,const sptr<IConsumerSurface> & surface,RSBaseRenderNode * node) const427 void RSComposerAdapter::SetComposeInfoToLayer(
428 const LayerInfoPtr& layer,
429 const ComposeInfo& info,
430 const sptr<IConsumerSurface>& surface,
431 RSBaseRenderNode* node) const
432 {
433 if (layer == nullptr || surface == nullptr || node == nullptr) {
434 RS_LOGE("RSComposerAdapter::SetComposeInfoToLayer failed, layer or surface or node is nullptr");
435 return;
436 }
437 layer->SetSurface(surface);
438 layer->SetBuffer(info.buffer, info.fence);
439 layer->SetZorder(info.zOrder);
440 layer->SetAlpha(info.alpha);
441 layer->SetLayerSize(info.dstRect);
442 layer->SetNodeId(node->GetId());
443 layer->SetCompositionType(info.needClient ?
444 GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT : GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE);
445 std::vector<GraphicIRect> visibleRegions;
446 visibleRegions.emplace_back(info.visibleRect);
447 layer->SetVisibleRegions(visibleRegions);
448 layer->SetDirtyRegions(info.dirtyRects);
449 layer->SetBlendType(info.blendType);
450 layer->SetCropRect(info.srcRect);
451 if (node->GetTunnelHandleChange()) {
452 layer->SetTunnelHandleChange(true);
453 layer->SetTunnelHandle(surface->GetTunnelHandle());
454 node->SetTunnelHandleChange(false);
455 }
456 if (surface->GetTunnelHandle() != nullptr) {
457 return;
458 }
459 SetMetaDataInfoToLayer(layer, info, surface);
460 }
461
SetMetaDataInfoToLayer(const LayerInfoPtr & layer,const ComposeInfo & info,const sptr<IConsumerSurface> & surface) const462 void RSComposerAdapter::SetMetaDataInfoToLayer(const LayerInfoPtr& layer, const ComposeInfo& info,
463 const sptr<IConsumerSurface>& surface) const
464 {
465 HDRMetaDataType type;
466 if (!surface || !info.buffer || surface->QueryMetaDataType(info.buffer->GetSeqNum(), type) != GSERROR_OK) {
467 RS_LOGE("RSComposerAdapter::SetComposeInfoToLayer: QueryMetaDataType failed");
468 return;
469 }
470 switch (type) {
471 case HDRMetaDataType::HDR_META_DATA: {
472 std::vector<GraphicHDRMetaData> metaData;
473 if (surface->GetMetaData(info.buffer->GetSeqNum(), metaData) != GSERROR_OK) {
474 RS_LOGE("RSComposerAdapter::SetComposeInfoToLayer: GetMetaData failed");
475 return;
476 }
477 layer->SetMetaData(metaData);
478 break;
479 }
480 case HDRMetaDataType::HDR_META_DATA_SET: {
481 GraphicHDRMetadataKey key;
482 std::vector<uint8_t> metaData;
483 if (surface->GetMetaDataSet(info.buffer->GetSeqNum(), key, metaData) != GSERROR_OK) {
484 RS_LOGE("RSComposerAdapter::SetComposeInfoToLayer: GetMetaDataSet failed");
485 return;
486 }
487 GraphicHDRMetaDataSet metaDataSet;
488 metaDataSet.key = key;
489 metaDataSet.metaData = metaData;
490 layer->SetMetaDataSet(metaDataSet);
491 break;
492 }
493 case HDRMetaDataType::HDR_NOT_USED: {
494 break;
495 }
496 default: {
497 break;
498 }
499 }
500 }
501
CheckStatusBeforeCreateLayer(RSSurfaceRenderNode & node,bool isTunnelCheck) const502 bool RSComposerAdapter::CheckStatusBeforeCreateLayer(RSSurfaceRenderNode& node, bool isTunnelCheck) const
503 {
504 if (output_ == nullptr) {
505 RS_LOGE("RSComposerAdapter::CheckStatusBeforeCreateLayer: output is nullptr");
506 return false;
507 }
508 const auto buffer = node.GetRSSurfaceHandler()->GetBuffer();
509 if (isTunnelCheck == false && buffer == nullptr) {
510 RS_LOGD("RsDebug RSComposerAdapter::CheckStatusBeforeCreateLayer:node(%{public}" PRIu64 ") has"
511 " no available buffer.", node.GetId());
512 return false;
513 }
514
515 const auto& dstRect = node.GetDstRect();
516 const auto& srcRect = node.GetSrcRect();
517 // check if the node's srcRect and dstRect are valid.
518 if (srcRect.width_ <= 0 || srcRect.height_ <= 0 || dstRect.width_ <= 0 || dstRect.height_ <= 0) {
519 return false;
520 }
521
522 auto& geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
523 if (geoPtr == nullptr) {
524 RS_LOGW("RsDebug RSComposerAdapter::CheckStatusBeforeCreateLayer: node(%{public}" PRIu64 ")'s"
525 " geoPtr is nullptr!", node.GetId());
526 return false;
527 }
528
529 if (!node.IsNotifyRTBufferAvailable()) {
530 // Only ipc for one time.
531 RS_LOGD("RsDebug RSPhysicalScreenProcessor::ProcessSurface id = %{public}" PRIu64 " Notify RT buffer available",
532 node.GetId());
533 node.NotifyRTBufferAvailable();
534 }
535 return true;
536 }
537
CreateBufferLayer(RSSurfaceRenderNode & node) const538 LayerInfoPtr RSComposerAdapter::CreateBufferLayer(RSSurfaceRenderNode& node) const
539 {
540 if (!CheckStatusBeforeCreateLayer(node)) {
541 return nullptr;
542 }
543 auto surfaceHandler = node.GetRSSurfaceHandler();
544 ComposeInfo info = BuildComposeInfo(node);
545 if (IsOutOfScreenRegion(info)) {
546 RS_LOGD("RsDebug RSComposerAdapter::CreateBufferLayer: node(%{public}" PRIu64
547 ") out of screen region, no need to composite.",
548 node.GetId());
549 return nullptr;
550 }
551 std::string traceInfo;
552 AppendFormat(traceInfo, "ProcessSurfaceNode:%s XYWH[%d %d %d %d]", node.GetName().c_str(),
553 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h);
554 RS_TRACE_NAME(traceInfo.c_str());
555 RS_LOGD(
556 "RsDebug RSComposerAdapter::CreateBufferLayer surfaceNode id:%{public}" PRIu64 " name:[%{public}s]"
557 " dst [%{public}d %{public}d %{public}d %{public}d] SrcRect [%{public}d %{public}d] rawbuffer"
558 " [%{public}d %{public}d] surfaceBuffer [%{public}d %{public}d], z:%{public}f, globalZOrder:%{public}d,"
559 " blendType = %{public}d",
560 node.GetId(), node.GetName().c_str(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
561 info.srcRect.w, info.srcRect.h, info.buffer->GetWidth(), info.buffer->GetHeight(),
562 info.buffer->GetSurfaceBufferWidth(), info.buffer->GetSurfaceBufferHeight(),
563 surfaceHandler->GetGlobalZOrder(), info.zOrder, info.blendType);
564 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
565 SetComposeInfoToLayer(layer, info, surfaceHandler->GetConsumer(), &node);
566 LayerRotate(layer, node);
567 LayerCrop(layer);
568 LayerScaleDown(layer);
569 return layer;
570 }
571
CreateTunnelLayer(RSSurfaceRenderNode & node) const572 LayerInfoPtr RSComposerAdapter::CreateTunnelLayer(RSSurfaceRenderNode& node) const
573 {
574 if (!CheckStatusBeforeCreateLayer(node, true)) {
575 return nullptr;
576 }
577 auto surfaceHandler = node.GetRSSurfaceHandler();
578 ComposeInfo info = BuildComposeInfo(node, true);
579 if (IsOutOfScreenRegion(info)) {
580 RS_LOGD("RsDebug RSComposerAdapter::CreateTunnelLayer: node(%{public}" PRIu64
581 ") out of screen region, no need to composite.",
582 node.GetId());
583 return nullptr;
584 }
585 std::string traceInfo;
586 AppendFormat(traceInfo, "ProcessSurfaceNode:%s XYWH[%d %d %d %d]", node.GetName().c_str(),
587 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h);
588 RS_TRACE_NAME(traceInfo.c_str());
589 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
590 SetComposeInfoToLayer(layer, info, surfaceHandler->GetConsumer(), &node);
591 LayerRotate(layer, node);
592 RS_LOGD("RsDebug RSComposerAdapter::CreateTunnelLayer surfaceNode id:%{public}" PRIu64 " name:[%{public}s] dst"
593 " [%{public}d %{public}d %{public}d %{public}d]"
594 "SrcRect [%{public}d %{public}d], z:%{public}f, globalZOrder:%{public}d, blendType = %{public}d",
595 node.GetId(), node.GetName().c_str(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
596 info.srcRect.w, info.srcRect.h, surfaceHandler->GetGlobalZOrder(), info.zOrder, info.blendType);
597 return layer;
598 }
599
CreateLayer(RSSurfaceRenderNode & node) const600 LayerInfoPtr RSComposerAdapter::CreateLayer(RSSurfaceRenderNode& node) const
601 {
602 auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
603 if (consumer == nullptr) {
604 RS_LOGE("RSComposerAdapter::CreateLayer get consumer fail");
605 return nullptr;
606 }
607 sptr<SurfaceTunnelHandle> handle = consumer->GetTunnelHandle();
608 if (handle != nullptr) {
609 return CreateTunnelLayer(node);
610 } else {
611 return CreateBufferLayer(node);
612 }
613 }
614
CreateLayer(RSDisplayRenderNode & node) const615 LayerInfoPtr RSComposerAdapter::CreateLayer(RSDisplayRenderNode& node) const
616 {
617 if (output_ == nullptr) {
618 RS_LOGE("RSComposerAdapter::CreateLayer: output is nullptr");
619 return nullptr;
620 }
621 auto drawable = node.GetRenderDrawable();
622 if (!drawable) {
623 return nullptr;
624 }
625 auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
626 auto surfaceHandler = displayDrawable->GetMutableRSSurfaceHandlerOnDraw();
627 if (!RSBaseRenderUtil::ConsumeAndUpdateBuffer(*surfaceHandler)) {
628 RS_LOGE("RSComposerAdapter::CreateLayer consume buffer failed.");
629 return nullptr;
630 }
631
632 if (surfaceHandler->GetBuffer() == nullptr) {
633 RS_LOGE("RSComposerAdapter::CreateLayer buffer is nullptr.");
634 return nullptr;
635 }
636
637 ComposeInfo info = BuildComposeInfo(node);
638 RS_LOGD("RSComposerAdapter::ProcessSurface displayNode id:%{public}" PRIu64 " dst [%{public}d"
639 " %{public}d %{public}d %{public}d] SrcRect [%{public}d %{public}d] rawbuffer [%{public}d %{public}d]"
640 " surfaceBuffer [%{public}d %{public}d], globalZOrder:%{public}d, blendType = %{public}d",
641 node.GetId(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h, info.srcRect.w, info.srcRect.h,
642 info.buffer->GetWidth(), info.buffer->GetHeight(), info.buffer->GetSurfaceBufferWidth(),
643 info.buffer->GetSurfaceBufferHeight(), info.zOrder, info.blendType);
644 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
645 SetComposeInfoToLayer(layer, info, surfaceHandler->GetConsumer(), &node);
646 LayerRotate(layer, node);
647 // do not crop or scale down for displayNode's layer.
648 return layer;
649 }
650
SetColorFilterMode(ColorFilterMode colorFilterMode)651 void RSComposerAdapter::SetColorFilterMode(ColorFilterMode colorFilterMode)
652 {
653 colorFilterMode_ = colorFilterMode;
654 }
655
GetSurfaceNodeRotation(RSBaseRenderNode & node)656 static int GetSurfaceNodeRotation(RSBaseRenderNode& node)
657 {
658 // only surface render node has the ability to rotate
659 // the rotation of display render node is calculated as screen rotation
660 if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
661 return 0;
662 }
663
664 auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
665 auto matrix = surfaceNode.GetTotalMatrix();
666 Drawing::Matrix::Buffer value;
667 matrix.GetAll(value);
668
669 int rAngle = static_cast<int>(
670 -round(atan2(value[Drawing::Matrix::SKEW_X], value[Drawing::Matrix::SCALE_X]) * (180 / PI)));
671 // transfer the result to anti-clockwise degrees
672 // only rotation with 90°, 180°, 270° are composed through hardware,
673 // in which situation the transformation of the layer needs to be set.
674 static const std::map<int, int> supportedDegrees = {{90, 270}, {180, 180}, {-90, 90}};
675 auto iter = supportedDegrees.find(rAngle);
676 return iter != supportedDegrees.end() ? iter->second : 0;
677 }
678
SetLayerTransform(const LayerInfoPtr & layer,RSBaseRenderNode & node,const sptr<IConsumerSurface> & surface,ScreenRotation screenRotation)679 static void SetLayerTransform(const LayerInfoPtr& layer, RSBaseRenderNode& node,
680 const sptr<IConsumerSurface>& surface, ScreenRotation screenRotation)
681 {
682 // screenRotation: anti-clockwise, surfaceNodeRotation: anti-clockwise, surfaceTransform: anti-clockwise
683 // layerTransform: clockwise
684 int surfaceNodeRotation = GetSurfaceNodeRotation(node);
685 int totalRotation = (RSBaseRenderUtil::RotateEnumToInt(screenRotation) + surfaceNodeRotation +
686 RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(surface->GetTransform()))) % 360;
687 GraphicTransformType rotateEnum = RSBaseRenderUtil::RotateEnumToInt(totalRotation,
688 RSBaseRenderUtil::GetFlipTransform(surface->GetTransform()));
689 layer->SetTransform(rotateEnum);
690 }
691
SetLayerSize(const LayerInfoPtr & layer,const ScreenInfo & screenInfo)692 static void SetLayerSize(const LayerInfoPtr& layer, const ScreenInfo& screenInfo)
693 {
694 const auto screenWidth = static_cast<int32_t>(screenInfo.width);
695 const auto screenHeight = static_cast<int32_t>(screenInfo.height);
696 const auto screenRotation = screenInfo.rotation;
697 const auto rect = layer->GetLayerSize();
698 // screenRotation: anti-clockwise, surfaceTransform: anti-clockwise, layerTransform: clockwise
699 switch (screenRotation) {
700 case ScreenRotation::ROTATION_90: {
701 RS_LOGD("RsDebug ScreenRotation 90, Before Rotate layer size [%{public}d %{public}d"
702 " %{public}d %{public}d]", rect.x, rect.y, rect.w, rect.h);
703 layer->SetLayerSize(GraphicIRect {rect.y, screenHeight - rect.x - rect.w, rect.h, rect.w});
704 RS_LOGD("RsDebug ScreenRotation 90, After Rotate layer size [%{public}d %{public}d %{public}d %{public}d]",
705 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
706 break;
707 }
708 case ScreenRotation::ROTATION_180: {
709 RS_LOGD("RsDebug ScreenRotation 180, Before Rotate layer size [%{public}d %{public}d %{public}d"
710 " %{public}d]", rect.x, rect.y, rect.w, rect.h);
711 layer->SetLayerSize(
712 GraphicIRect {screenWidth - rect.x - rect.w, screenHeight - rect.y - rect.h, rect.w, rect.h});
713 RS_LOGD("RsDebug ScreenRotation 180,After Rotate layer size [%{public}d %{public}d %{public}d %{public}d]",
714 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
715 break;
716 }
717 case ScreenRotation::ROTATION_270: {
718 RS_LOGD("RsDebug ScreenRotation 270, Before Rotate layer size [%{public}d %{public}d %{public}d"
719 " %{public}d]", rect.x, rect.y, rect.w, rect.h);
720 layer->SetLayerSize(GraphicIRect {screenWidth - rect.y - rect.h, rect.x, rect.h, rect.w});
721 RS_LOGD("RsDebug ScreenRotation 270,After Rotate layer size [%{public}d %{public}d %{public}d %{public}d]",
722 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
723 break;
724 }
725 default: {
726 break;
727 }
728 }
729 }
730
731 // private func, guarantee the layer is valid
LayerRotate(const LayerInfoPtr & layer,RSBaseRenderNode & node) const732 void RSComposerAdapter::LayerRotate(const LayerInfoPtr& layer, RSBaseRenderNode& node) const
733 {
734 auto surface = layer->GetSurface();
735 if (surface == nullptr) {
736 return;
737 }
738 SetLayerSize(layer, screenInfo_);
739 SetLayerTransform(layer, node, surface, screenInfo_.rotation);
740 }
741
742 // private func, guarantee the layer is valid
LayerCrop(const LayerInfoPtr & layer) const743 void RSComposerAdapter::LayerCrop(const LayerInfoPtr& layer) const
744 {
745 GraphicIRect dstRect = layer->GetLayerSize();
746 GraphicIRect srcRect = layer->GetCropRect();
747 GraphicIRect originSrcRect = srcRect;
748
749 RectI dstRectI(dstRect.x, dstRect.y, dstRect.w, dstRect.h);
750 int32_t screenWidth = static_cast<int32_t>(screenInfo_.width);
751 int32_t screenHeight = static_cast<int32_t>(screenInfo_.height);
752 RectI screenRectI(0, 0, screenWidth, screenHeight);
753 RectI resDstRect = dstRectI.IntersectRect(screenRectI);
754 if (resDstRect == dstRectI) {
755 return;
756 }
757 dstRect = {resDstRect.left_, resDstRect.top_, resDstRect.width_, resDstRect.height_};
758 srcRect.x = (resDstRect.IsEmpty() || dstRectI.IsEmpty()) ? 0 : std::ceil((resDstRect.left_ - dstRectI.left_) *
759 originSrcRect.w / dstRectI.width_);
760 srcRect.y = (resDstRect.IsEmpty() || dstRectI.IsEmpty()) ? 0 : std::ceil((resDstRect.top_ - dstRectI.top_) *
761 originSrcRect.h / dstRectI.height_);
762 srcRect.w = dstRectI.IsEmpty() ? 0 : originSrcRect.w * resDstRect.width_ / dstRectI.width_;
763 srcRect.h = dstRectI.IsEmpty() ? 0 : originSrcRect.h * resDstRect.height_ / dstRectI.height_;
764 layer->SetLayerSize(dstRect);
765 std::vector<GraphicIRect> dirtyRegions;
766 dirtyRegions.emplace_back(srcRect);
767 layer->SetDirtyRegions(dirtyRegions);
768 layer->SetCropRect(srcRect);
769 RS_LOGD("RsDebug RSComposerAdapter::LayerCrop layer has been cropped dst[%{public}d %{public}d %{public}d"
770 " %{public}d] src[%{public}d %{public}d %{public}d %{public}d]",
771 dstRect.x, dstRect.y, dstRect.w, dstRect.h, srcRect.x, srcRect.y, srcRect.w, srcRect.h);
772 }
773
774 // private func, guarantee the layer is valid
LayerScaleDown(const LayerInfoPtr & layer)775 void RSComposerAdapter::LayerScaleDown(const LayerInfoPtr& layer)
776 {
777 ScalingMode scalingMode = ScalingMode::SCALING_MODE_SCALE_TO_WINDOW;
778 const auto& buffer = layer->GetBuffer();
779 const auto& surface = layer->GetSurface();
780 if (buffer == nullptr || surface == nullptr) {
781 return;
782 }
783
784 if (surface->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK &&
785 scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
786 GraphicIRect dstRect = layer->GetLayerSize();
787 GraphicIRect srcRect = layer->GetCropRect();
788
789 int32_t newWidth = srcRect.w;
790 int32_t newHeight = srcRect.h;
791
792 if (dstRect.w <= 0 || dstRect.h <= 0 || srcRect.w <= 0 || srcRect.h <= 0) {
793 // invalid rect size
794 RS_LOGE("RSComposerAdapter::LayerScaleDown : Invalid rect size.");
795 return;
796 }
797
798 if (newWidth * dstRect.h > newHeight * dstRect.w) {
799 newWidth = dstRect.w * newHeight / dstRect.h;
800 } else if (newWidth * dstRect.h < newHeight * dstRect.w) {
801 newHeight = dstRect.h * newWidth / dstRect.w;
802 } else {
803 return;
804 }
805
806 int32_t currentWidth = srcRect.w;
807 int32_t currentHeight = srcRect.h;
808
809 if (newWidth < currentWidth) {
810 // the crop is too wide
811 int32_t dw = currentWidth - newWidth;
812 auto halfdw = dw / 2;
813 srcRect.x += halfdw;
814 srcRect.w = newWidth;
815 } else {
816 // thr crop is too tall
817 int32_t dh = currentHeight - newHeight;
818 auto halfdh = dh / 2;
819 srcRect.y += halfdh;
820 srcRect.h = newHeight;
821 }
822 std::vector<GraphicIRect> dirtyRegions;
823 dirtyRegions.emplace_back(srcRect);
824 layer->SetDirtyRegions(dirtyRegions);
825 layer->SetCropRect(srcRect);
826 RS_LOGD("RsDebug RSComposerAdapter::LayerScaleDown layer has been scaledown dst[%{public}d %{public}d"
827 " %{public}d %{public}d] src[%{public}d %{public}d %{public}d %{public}d]",
828 dstRect.x, dstRect.y, dstRect.w, dstRect.h, srcRect.x, srcRect.y, srcRect.w, srcRect.h);
829 }
830 }
831
832 // private func, guarantee the layer and surface are valid
LayerPresentTimestamp(const LayerInfoPtr & layer,const sptr<IConsumerSurface> & surface)833 void RSComposerAdapter::LayerPresentTimestamp(const LayerInfoPtr& layer, const sptr<IConsumerSurface>& surface)
834 {
835 if (!layer->IsSupportedPresentTimestamp()) {
836 return;
837 }
838 const auto& buffer = layer->GetBuffer();
839 if (buffer == nullptr) {
840 return;
841 }
842 if (surface->SetPresentTimestamp(buffer->GetSeqNum(), layer->GetPresentTimestamp()) != GSERROR_OK) {
843 RS_LOGD("RsDebug RSComposerAdapter::LayerPresentTimestamp: SetPresentTimestamp failed");
844 }
845 }
846
OnPrepareComplete(sptr<Surface> & surface,const PrepareCompleteParam & param,void * data)847 void RSComposerAdapter::OnPrepareComplete(sptr<Surface>& surface, const PrepareCompleteParam& param, void* data)
848 {
849 // unused data.
850 (void)(data);
851
852 if (!param.needFlushFramebuffer) {
853 return;
854 }
855
856 if (fallbackCb_ != nullptr) {
857 fallbackCb_(surface, param.layers);
858 }
859 }
860
SetHdiBackendDevice(HdiDevice * device)861 void RSComposerAdapter::SetHdiBackendDevice(HdiDevice* device)
862 {
863 if (hdiBackend_) {
864 hdiBackend_->SetHdiBackendDevice(device);
865 }
866 }
867
SetMirroredScreenInfo(const ScreenInfo & mirroredScreenInfo)868 void RSComposerAdapter::SetMirroredScreenInfo(const ScreenInfo& mirroredScreenInfo)
869 {
870 mirroredScreenInfo_ = mirroredScreenInfo;
871 }
872
873 } // namespace Rosen
874 } // namespace OHOS
875