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 "common/rs_common_def.h"
19 #include "common/rs_obj_abs_geometry.h"
20 #include "platform/common/rs_log.h"
21 #include "rs_base_render_util.h"
22 #include "rs_divided_render_util.h"
23 #include "rs_trace.h"
24 #include "string_utils.h"
25
26 namespace OHOS {
27 namespace Rosen {
Init(const ScreenInfo & screenInfo,int32_t offsetX,int32_t offsetY,float mirrorAdaptiveCoefficient,const FallbackCallback & cb)28 bool RSComposerAdapter::Init(const ScreenInfo& screenInfo, int32_t offsetX, int32_t offsetY,
29 float mirrorAdaptiveCoefficient, const FallbackCallback& cb)
30 {
31 hdiBackend_ = HdiBackend::GetInstance();
32 if (hdiBackend_ == nullptr) {
33 RS_LOGE("RSComposerAdapter::Init: hdiBackend is nullptr");
34 return false;
35 }
36 auto screenManager = CreateOrGetScreenManager();
37 if (screenManager == nullptr) {
38 RS_LOGE("RSComposerAdapter::Init: ScreenManager is nullptr");
39 return false;
40 }
41 output_ = screenManager->GetOutput(ToScreenPhysicalId(screenInfo.id));
42 if (output_ == nullptr) {
43 RS_LOGE("RSComposerAdapter::Init: output_ is nullptr");
44 return false;
45 }
46
47 fallbackCb_ = cb;
48 auto onPrepareCompleteFunc = [this](auto& surface, const auto& param, void* data) {
49 OnPrepareComplete(surface, param, data);
50 };
51 hdiBackend_->RegPrepareComplete(onPrepareCompleteFunc, this);
52
53 offsetX_ = offsetX;
54 offsetY_ = offsetY;
55 mirrorAdaptiveCoefficient_ = mirrorAdaptiveCoefficient;
56 screenInfo_ = screenInfo;
57
58 IRect damageRect {0, 0, static_cast<int32_t>(screenInfo_.width), static_cast<int32_t>(screenInfo_.height)};
59 output_->SetOutputDamage(1, damageRect);
60 bool directClientCompEnableStatus = RSSystemProperties::GetDirectClientCompEnableStatus();
61 output_->SetDirectClientCompEnableStatus(directClientCompEnableStatus);
62
63 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
64 // enable direct GPU composition.
65 output_->SetLayerCompCapacity(LAYER_COMPOSITION_CAPACITY);
66 #else // (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
67 output_->SetLayerCompCapacity(LAYER_COMPOSITION_CAPACITY_INVALID);
68 #endif // (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
69
70 return true;
71 }
72
CommitLayers(const std::vector<LayerInfoPtr> & layers)73 void RSComposerAdapter::CommitLayers(const std::vector<LayerInfoPtr>& layers)
74 {
75 if (hdiBackend_ == nullptr) {
76 RS_LOGE("RSComposerAdapter::CommitLayers: backend is nullptr");
77 return;
78 }
79
80 if (output_ == nullptr) {
81 RS_LOGE("RSComposerAdapter::CommitLayers: output is nullptr");
82 return;
83 }
84
85 // do composition.
86 output_->SetLayerInfo(layers);
87 std::vector<std::shared_ptr<HdiOutput>> outputs {output_};
88 hdiBackend_->Repaint(outputs);
89
90 // get present timestamp from and set present timestamp to surface
91 for (const auto& layer : layers) {
92 if (layer == nullptr || layer->GetSurface() == nullptr) {
93 RS_LOGW("RSComposerAdapter::CommitLayers: layer or layer's cSurface is nullptr");
94 continue;
95 }
96 LayerPresentTimestamp(layer, layer->GetSurface());
97 }
98
99 // set all layers' releaseFence.
100 const auto layersReleaseFence = hdiBackend_->GetLayersReleaseFence(output_);
101 for (const auto& [layer, fence] : layersReleaseFence) {
102 if (layer == nullptr) {
103 continue;
104 }
105
106 auto nodePtr = static_cast<RSBaseRenderNode*>(layer->GetLayerAdditionalInfo());
107 if (nodePtr == nullptr) {
108 RS_LOGW("RSComposerAdapter::PostProcess: layer's node is nullptr.");
109 continue;
110 }
111
112 RSSurfaceHandler* surfaceHandler = nullptr;
113 if (nodePtr->IsInstanceOf<RSSurfaceRenderNode>()) {
114 auto surfaceNode = static_cast<RSSurfaceRenderNode*>(nodePtr);
115 surfaceHandler = static_cast<RSSurfaceHandler*>(surfaceNode);
116 } else if (nodePtr->IsInstanceOf<RSDisplayRenderNode>()) {
117 auto displayNode = static_cast<RSDisplayRenderNode*>(nodePtr);
118 surfaceHandler = static_cast<RSSurfaceHandler*>(displayNode);
119 }
120 if (surfaceHandler == nullptr) {
121 continue;
122 }
123 surfaceHandler->SetReleaseFence(fence);
124 }
125 }
126
127 // private func
IsOutOfScreenRegion(const ComposeInfo & info) const128 bool RSComposerAdapter::IsOutOfScreenRegion(const ComposeInfo& info) const
129 {
130 int32_t boundWidth = static_cast<int32_t>(screenInfo_.width);
131 int32_t boundHeight = static_cast<int32_t>(screenInfo_.height);
132 ScreenRotation rotation = screenInfo_.rotation;
133 if (rotation == ScreenRotation::ROTATION_90 || rotation == ScreenRotation::ROTATION_270) {
134 std::swap(boundWidth, boundHeight);
135 }
136
137 const auto& dstRect = info.dstRect;
138 if (dstRect.x + dstRect.w <= 0 ||
139 dstRect.x >= boundWidth ||
140 dstRect.y + dstRect.h <= 0 ||
141 dstRect.y >= boundHeight) {
142 return true;
143 }
144
145 return false;
146 }
147
DealWithNodeGravity(const RSSurfaceRenderNode & node,ComposeInfo & info) const148 void RSComposerAdapter::DealWithNodeGravity(const RSSurfaceRenderNode& node, ComposeInfo& info) const
149 {
150 const auto& property = node.GetRenderProperties();
151 const float frameWidth = info.buffer->GetSurfaceBufferWidth();
152 const float frameHeight = info.buffer->GetSurfaceBufferHeight();
153 const float boundsWidth = property.GetBoundsWidth();
154 const float boundsHeight = property.GetBoundsHeight();
155 const Gravity frameGravity = property.GetFrameGravity();
156 // we do not need to do additional works for Gravity::RESIZE and if frameSize == boundsSize.
157 if (frameGravity == Gravity::RESIZE || (frameWidth == boundsWidth && frameHeight == boundsHeight)) {
158 return;
159 }
160
161 auto traceInfo = node.GetName() + " DealWithNodeGravity " + std::to_string(static_cast<int>(frameGravity));
162 RS_TRACE_NAME(traceInfo.c_str());
163
164 // get current node's translate matrix and calculate gravity matrix.
165 auto translateMatrix = SkMatrix::MakeTrans(
166 std::ceil(node.GetTotalMatrix().getTranslateX()), std::ceil(node.GetTotalMatrix().getTranslateY()));
167 SkMatrix gravityMatrix;
168 (void)RSPropertiesPainter::GetGravityMatrix(frameGravity,
169 RectF {0.0f, 0.0f, boundsWidth, boundsHeight}, frameWidth, frameHeight, gravityMatrix);
170
171 // create a canvas to calculate new dstRect and new srcRect
172 int32_t screenWidth = screenInfo_.width;
173 int32_t screenHeight = screenInfo_.height;
174 const auto screenRotation = screenInfo_.rotation;
175 if (screenRotation == ScreenRotation::ROTATION_90 || screenRotation == ScreenRotation::ROTATION_270) {
176 std::swap(screenWidth, screenHeight);
177 }
178 auto canvas = std::make_unique<SkCanvas>(screenWidth, screenHeight);
179 canvas->concat(translateMatrix);
180 canvas->concat(gravityMatrix);
181 SkRect clipRect;
182 gravityMatrix.mapRect(&clipRect, SkRect::MakeWH(frameWidth, frameHeight));
183 canvas->clipRect(SkRect::MakeWH(clipRect.width(), clipRect.height()));
184 SkIRect newDstRect = canvas->getDeviceClipBounds();
185 // we make the newDstRect as the intersection of new and old dstRect,
186 // to deal with the situation that frameSize > boundsSize.
187 newDstRect.intersect(SkIRect::MakeXYWH(info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h));
188 auto localRect = canvas->getLocalClipBounds();
189 int left = std::clamp<int>(localRect.left(), 0, frameWidth);
190 int top = std::clamp<int>(localRect.top(), 0, frameHeight);
191 int width = std::clamp<int>(localRect.width(), 0, frameWidth - left);
192 int height = std::clamp<int>(localRect.height(), 0, frameHeight - top);
193 IRect newSrcRect = {left, top, width, height};
194
195 // log and apply new dstRect and srcRect
196 RS_LOGD("RsDebug DealWithNodeGravity: name[%s], gravity[%d], oldDstRect[%d %d %d %d], newDstRect[%d %d %d %d],"\
197 " oldSrcRect[%d %d %d %d], newSrcRect[%d %d %d %d].",
198 node.GetName().c_str(), static_cast<int>(frameGravity),
199 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
200 newDstRect.left(), newDstRect.top(), newDstRect.width(), newDstRect.height(),
201 info.srcRect.x, info.srcRect.y, info.srcRect.w, info.srcRect.h,
202 newSrcRect.x, newSrcRect.y, newSrcRect.w, newSrcRect.h);
203 info.dstRect = {newDstRect.left(), newDstRect.top(), newDstRect.width(), newDstRect.height()};
204 info.srcRect = newSrcRect;
205 }
206
GetComposerInfoSrcRect(ComposeInfo & info,const RSSurfaceRenderNode & node)207 void RSComposerAdapter::GetComposerInfoSrcRect(ComposeInfo &info, const RSSurfaceRenderNode& node)
208 {
209 const auto& property = node.GetRenderProperties();
210 const auto bufferWidth = info.buffer->GetSurfaceBufferWidth();
211 const auto bufferHeight = info.buffer->GetSurfaceBufferHeight();
212 const auto boundsWidth = property.GetBoundsWidth();
213 const auto boundsHeight = property.GetBoundsHeight();
214 if (bufferWidth != boundsWidth || bufferHeight != boundsHeight) {
215 float xScale = (ROSEN_EQ(boundsWidth, 0.0f) ? 1.0f : bufferWidth / boundsWidth);
216 float yScale = (ROSEN_EQ(boundsHeight, 0.0f) ? 1.0f : bufferHeight / boundsHeight);
217 info.srcRect.x = info.srcRect.x * xScale;
218 info.srcRect.y = info.srcRect.y * yScale;
219 info.srcRect.w = info.srcRect.w * xScale;
220 info.srcRect.h = info.srcRect.h * yScale;
221 }
222 }
223
GetComposerInfoNeedClient(const ComposeInfo & info,RSSurfaceRenderNode & node) const224 bool RSComposerAdapter::GetComposerInfoNeedClient(const ComposeInfo &info, RSSurfaceRenderNode& node) const
225 {
226 bool needClient = RSDividedRenderUtil::IsNeedClient(node, info);
227 if (info.buffer->GetSurfaceBufferColorGamut() != static_cast<GraphicColorGamut>(screenInfo_.colorGamut)) {
228 needClient = true;
229 }
230 return needClient;
231 }
232
233 // private func, for RSSurfaceRenderNode.
BuildComposeInfo(RSSurfaceRenderNode & node,bool isTunnelCheck) const234 ComposeInfo RSComposerAdapter::BuildComposeInfo(RSSurfaceRenderNode& node, bool isTunnelCheck) const
235 {
236 const auto& dstRect = node.GetDstRect();
237 const auto& srcRect = node.GetSrcRect();
238 ComposeInfo info {};
239 info.srcRect = IRect {srcRect.left_, srcRect.top_, srcRect.width_, srcRect.height_};
240 info.dstRect = IRect {
241 static_cast<int32_t>(static_cast<float>(dstRect.left_) * mirrorAdaptiveCoefficient_),
242 static_cast<int32_t>(static_cast<float>(dstRect.top_) * mirrorAdaptiveCoefficient_),
243 static_cast<int32_t>(static_cast<float>(dstRect.width_) * mirrorAdaptiveCoefficient_),
244 static_cast<int32_t>(static_cast<float>(dstRect.height_) * mirrorAdaptiveCoefficient_)
245 };
246 info.zOrder = static_cast<int32_t>(node.GetGlobalZOrder());
247 info.alpha.enGlobalAlpha = true;
248 info.alpha.gAlpha = node.GetGlobalAlpha() * 255; // map gAlpha from float(0, 1) to uint8_t(0, 255).
249 info.fence = node.GetAcquireFence();
250 info.blendType = node.GetBlendType();
251
252 info.dstRect.x -= static_cast<int32_t>(static_cast<float>(offsetX_) * mirrorAdaptiveCoefficient_);
253 info.dstRect.y -= static_cast<int32_t>(static_cast<float>(offsetY_) * mirrorAdaptiveCoefficient_);
254 info.visibleRect = info.dstRect;
255 if (!isTunnelCheck) {
256 const auto& buffer = node.GetBuffer();
257 info.buffer = buffer;
258 GetComposerInfoSrcRect(info, node);
259 info.needClient = GetComposerInfoNeedClient(info, node);
260 DealWithNodeGravity(node, info);
261 } else {
262 info.needClient = false;
263 }
264 return info;
265 }
266
267 // private func, for RSDisplayRenderNode
BuildComposeInfo(RSDisplayRenderNode & node) const268 ComposeInfo RSComposerAdapter::BuildComposeInfo(RSDisplayRenderNode& node) const
269 {
270 const auto& buffer = node.GetBuffer(); // we guarantee the buffer is valid.
271 ComposeInfo info {};
272 info.srcRect = IRect {0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight()};
273 info.dstRect = IRect {
274 0,
275 0,
276 static_cast<int32_t>(static_cast<float>(screenInfo_.GetRotatedWidth()) * mirrorAdaptiveCoefficient_),
277 static_cast<int32_t>(static_cast<float>(screenInfo_.GetRotatedHeight()) * mirrorAdaptiveCoefficient_)
278 };
279 info.visibleRect = IRect {info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h};
280 info.zOrder = static_cast<int32_t>(node.GetGlobalZOrder());
281 info.alpha.enGlobalAlpha = false;
282 info.buffer = buffer;
283 info.fence = node.GetAcquireFence();
284 info.blendType = GRAPHIC_BLEND_NONE;
285 info.needClient = false;
286 return info;
287 }
288
SetComposeInfoToLayer(const LayerInfoPtr & layer,const ComposeInfo & info,const sptr<Surface> & surface,RSBaseRenderNode * node)289 void RSComposerAdapter::SetComposeInfoToLayer(
290 const LayerInfoPtr& layer,
291 const ComposeInfo& info,
292 const sptr<Surface>& surface,
293 RSBaseRenderNode* node)
294 {
295 if (layer == nullptr) {
296 return;
297 }
298 layer->SetSurface(surface);
299 layer->SetBuffer(info.buffer, info.fence);
300 layer->SetZorder(info.zOrder);
301 layer->SetAlpha(info.alpha);
302 layer->SetLayerSize(info.dstRect);
303 layer->SetLayerAdditionalInfo(node);
304 layer->SetCompositionType(info.needClient ?
305 GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT : GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE);
306 layer->SetVisibleRegion(1, info.visibleRect);
307 layer->SetDirtyRegion(info.srcRect);
308 layer->SetBlendType(info.blendType);
309 layer->SetCropRect(info.srcRect);
310 if (node -> GetTunnelHandleChange()) {
311 layer->SetTunnelHandleChange(true);
312 layer->SetTunnelHandle(surface->GetTunnelHandle());
313 node ->SetTunnelHandleChange(false);
314 }
315 HDRMetaDataType type;
316 if (surface->QueryMetaDataType(info.buffer->GetSeqNum(), type) != GSERROR_OK) {
317 RS_LOGE("RSComposerAdapter::SetComposeInfoToLayer: QueryMetaDataType failed");
318 return;
319 }
320 switch (type) {
321 case HDRMetaDataType::HDR_META_DATA: {
322 std::vector<GraphicHDRMetaData> metaData;
323 if (surface->GetMetaData(info.buffer->GetSeqNum(), metaData) != GSERROR_OK) {
324 RS_LOGE("RSComposerAdapter::SetComposeInfoToLayer: GetMetaData failed");
325 return;
326 }
327 layer->SetMetaData(metaData);
328 break;
329 }
330 case HDRMetaDataType::HDR_META_DATA_SET: {
331 GraphicHDRMetadataKey key;
332 std::vector<uint8_t> metaData;
333 if (surface->GetMetaDataSet(info.buffer->GetSeqNum(), key, metaData) != GSERROR_OK) {
334 RS_LOGE("RSComposerAdapter::SetComposeInfoToLayer: GetMetaDataSet failed");
335 return;
336 }
337 GraphicHDRMetaDataSet metaDataSet;
338 metaDataSet.key = key;
339 metaDataSet.metaData = metaData;
340 layer->SetMetaDataSet(metaDataSet);
341 break;
342 }
343 case HDRMetaDataType::HDR_NOT_USED: {
344 RS_LOGD("RSComposerAdapter::SetComposeInfoToLayer: HDR is not used");
345 break;
346 }
347 default: {
348 break;
349 }
350 }
351 }
352
CheckStatusBeforeCreateLayer(RSSurfaceRenderNode & node,bool isTunnelCheck) const353 bool RSComposerAdapter::CheckStatusBeforeCreateLayer(RSSurfaceRenderNode& node, bool isTunnelCheck) const
354 {
355 if (output_ == nullptr) {
356 RS_LOGE("RSComposerAdapter::CheckStatusBeforeCreateLayer: output is nullptr");
357 return false;
358 }
359
360 const auto& buffer = node.GetBuffer();
361 if (isTunnelCheck == false && buffer == nullptr) {
362 RS_LOGD("RsDebug RSComposerAdapter::CheckStatusBeforeCreateLayer:node(%" PRIu64 ") has no available buffer.",
363 node.GetId());
364 return false;
365 }
366
367 const auto& dstRect = node.GetDstRect();
368 const auto& srcRect = node.GetSrcRect();
369 // check if the node's srcRect and dstRect are valid.
370 if (srcRect.width_ <= 0 || srcRect.height_ <= 0 || dstRect.width_ <= 0 || dstRect.height_ <= 0) {
371 return false;
372 }
373
374 auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(node.GetRenderProperties().GetBoundsGeometry());
375 if (geoPtr == nullptr) {
376 RS_LOGW("RsDebug RSComposerAdapter::CheckStatusBeforeCreateLayer: node(%" PRIu64 ")'s geoPtr is nullptr!",
377 node.GetId());
378 return false;
379 }
380
381 if (!node.IsNotifyRTBufferAvailable()) {
382 // Only ipc for one time.
383 RS_LOGD("RsDebug RSPhysicalScreenProcessor::ProcessSurface id = %" PRIu64 " Notify RT buffer available",
384 node.GetId());
385 node.NotifyRTBufferAvailable();
386 }
387 return true;
388 }
389
CreateBufferLayer(RSSurfaceRenderNode & node) const390 LayerInfoPtr RSComposerAdapter::CreateBufferLayer(RSSurfaceRenderNode& node) const
391 {
392 if (!CheckStatusBeforeCreateLayer(node)) {
393 return nullptr;
394 }
395 ComposeInfo info = BuildComposeInfo(node);
396 if (IsOutOfScreenRegion(info)) {
397 RS_LOGD("RsDebug RSComposerAdapter::CreateBufferLayer: node(%" PRIu64
398 ") out of screen region, no need to composite.",
399 node.GetId());
400 return nullptr;
401 }
402 std::string traceInfo;
403 AppendFormat(traceInfo, "ProcessSurfaceNode:%s XYWH[%d %d %d %d]", node.GetName().c_str(),
404 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h);
405 RS_TRACE_NAME(traceInfo.c_str());
406 RS_LOGD(
407 "RsDebug RSComposerAdapter::CreateBufferLayer surfaceNode id:%" PRIu64 " name:[%s] dst [%d %d %d %d]"
408 "SrcRect [%d %d] rawbuffer [%d %d] surfaceBuffer [%d %d] buffaddr:%p, z:%f, globalZOrder:%d, blendType = %d",
409 node.GetId(), node.GetName().c_str(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
410 info.srcRect.w, info.srcRect.h, info.buffer->GetWidth(), info.buffer->GetHeight(),
411 info.buffer->GetSurfaceBufferWidth(), info.buffer->GetSurfaceBufferHeight(), info.buffer.GetRefPtr(),
412 node.GetGlobalZOrder(), info.zOrder, info.blendType);
413 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
414 SetComposeInfoToLayer(layer, info, node.GetConsumer(), &node);
415 LayerRotate(layer, node);
416 LayerCrop(layer);
417 LayerScaleDown(layer);
418 return layer;
419 }
420
CreateTunnelLayer(RSSurfaceRenderNode & node) const421 LayerInfoPtr RSComposerAdapter::CreateTunnelLayer(RSSurfaceRenderNode& node) const
422 {
423 if (!CheckStatusBeforeCreateLayer(node, true)) {
424 return nullptr;
425 }
426 ComposeInfo info = BuildComposeInfo(node, true);
427 if (IsOutOfScreenRegion(info)) {
428 RS_LOGD("RsDebug RSComposerAdapter::CreateTunnelLayer: node(%" PRIu64
429 ") out of screen region, no need to composite.",
430 node.GetId());
431 return nullptr;
432 }
433 std::string traceInfo;
434 AppendFormat(traceInfo, "ProcessSurfaceNode:%s XYWH[%d %d %d %d]", node.GetName().c_str(),
435 info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h);
436 RS_TRACE_NAME(traceInfo.c_str());
437 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
438 SetComposeInfoToLayer(layer, info, node.GetConsumer(), &node);
439 LayerRotate(layer, node);
440 RS_LOGD("RsDebug RSComposerAdapter::CreateTunnelLayer surfaceNode id:%" PRIu64 " name:[%s] dst [%d %d %d %d]"
441 "SrcRect [%d %d], z:%f, globalZOrder:%d, blendType = %d",
442 node.GetId(), node.GetName().c_str(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h,
443 info.srcRect.w, info.srcRect.h, node.GetGlobalZOrder(), info.zOrder, info.blendType);
444 return layer;
445 }
446
CreateLayer(RSSurfaceRenderNode & node)447 LayerInfoPtr RSComposerAdapter::CreateLayer(RSSurfaceRenderNode& node)
448 {
449 auto& consumer = node.GetConsumer();
450 if (consumer == nullptr) {
451 RS_LOGE("RSComposerAdapter::CreateLayer get consumer fail");
452 return nullptr;
453 }
454 sptr<SurfaceTunnelHandle> handle = consumer->GetTunnelHandle();
455 if (handle != nullptr) {
456 return CreateTunnelLayer(node);
457 } else {
458 return CreateBufferLayer(node);
459 }
460 }
461
CreateLayer(RSDisplayRenderNode & node)462 LayerInfoPtr RSComposerAdapter::CreateLayer(RSDisplayRenderNode& node)
463 {
464 if (output_ == nullptr) {
465 RS_LOGE("RSComposerAdapter::CreateLayer: output is nullptr");
466 return nullptr;
467 }
468
469 RS_LOGD("RSComposerAdapter::CreateLayer displayNode id:%" PRIu64 " available buffer:%d", node.GetId(),
470 node.GetAvailableBufferCount());
471 if (!RSBaseRenderUtil::ConsumeAndUpdateBuffer(node)) {
472 RS_LOGE("RSComposerAdapter::CreateLayer consume buffer failed.");
473 return nullptr;
474 }
475
476 if (node.GetBuffer() == nullptr) {
477 RS_LOGE("RSComposerAdapter::CreateLayer buffer is nullptr.");
478 return nullptr;
479 }
480
481 ComposeInfo info = BuildComposeInfo(node);
482 RS_LOGD("RSComposerAdapter::ProcessSurface displayNode id:%" PRIu64 " dst [%d %d %d %d]"
483 "SrcRect [%d %d] rawbuffer [%d %d] surfaceBuffer [%d %d] buffaddr:%p, globalZOrder:%d, blendType = %d",
484 node.GetId(), info.dstRect.x, info.dstRect.y, info.dstRect.w, info.dstRect.h, info.srcRect.w, info.srcRect.h,
485 info.buffer->GetWidth(), info.buffer->GetHeight(), info.buffer->GetSurfaceBufferWidth(),
486 info.buffer->GetSurfaceBufferHeight(), info.buffer.GetRefPtr(), info.zOrder, info.blendType);
487 LayerInfoPtr layer = HdiLayerInfo::CreateHdiLayerInfo();
488 SetComposeInfoToLayer(layer, info, node.GetConsumer(), &node);
489 LayerRotate(layer, node);
490 // do not crop or scale down for displayNode's layer.
491 return layer;
492 }
493
GetSurfaceNodeRotation(RSBaseRenderNode & node)494 static int GetSurfaceNodeRotation(RSBaseRenderNode& node)
495 {
496 // only surface render node has the ability to rotate
497 // the rotation of display render node is calculated as screen rotation
498 if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
499 return 0;
500 }
501
502 auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
503 auto matrix = surfaceNode.GetTotalMatrix();
504 float value[9];
505 matrix.get9(value);
506
507 int rAngle = static_cast<int>(-round(atan2(value[SkMatrix::kMSkewX], value[SkMatrix::kMScaleX]) * (180 / PI)));
508 // transfer the result to anti-clockwise degrees
509 // only rotation with 90°, 180°, 270° are composed through hardware,
510 // in which situation the transformation of the layer needs to be set.
511 static const std::map<int, int> supportedDegrees = {{90, 270}, {180, 180}, {-90, 90}};
512 auto iter = supportedDegrees.find(rAngle);
513 return iter != supportedDegrees.end() ? iter->second : 0;
514 }
515
RotateEnumToInt(ScreenRotation rotation)516 static inline int RotateEnumToInt(ScreenRotation rotation)
517 {
518 static const std::map<ScreenRotation, int> screenRotationEnumToIntMap = {
519 {ScreenRotation::ROTATION_0, 0}, {ScreenRotation::ROTATION_90, 90},
520 {ScreenRotation::ROTATION_180, 180}, {ScreenRotation::ROTATION_270, 270}};
521 auto iter = screenRotationEnumToIntMap.find(rotation);
522 return iter != screenRotationEnumToIntMap.end() ? iter->second : 0;
523 }
524
RotateEnumToInt(GraphicTransformType rotation)525 static inline int RotateEnumToInt(GraphicTransformType rotation)
526 {
527 static const std::map<GraphicTransformType, int> transformTypeEnumToIntMap = {
528 {GraphicTransformType::GRAPHIC_ROTATE_NONE, 0}, {GraphicTransformType::GRAPHIC_ROTATE_90, 90},
529 {GraphicTransformType::GRAPHIC_ROTATE_180, 180}, {GraphicTransformType::GRAPHIC_ROTATE_270, 270}};
530 auto iter = transformTypeEnumToIntMap.find(rotation);
531 return iter != transformTypeEnumToIntMap.end() ? iter->second : 0;
532 }
533
RotateEnumToInt(int angle,GraphicTransformType flip=GraphicTransformType::GRAPHIC_ROTATE_NONE)534 static inline GraphicTransformType RotateEnumToInt(int angle,
535 GraphicTransformType flip = GraphicTransformType::GRAPHIC_ROTATE_NONE)
536 {
537 static const std::map<int, GraphicTransformType> intToEnumMap = {
538 {0, GraphicTransformType::GRAPHIC_ROTATE_NONE}, {90, GraphicTransformType::GRAPHIC_ROTATE_270},
539 {180, GraphicTransformType::GRAPHIC_ROTATE_180}, {270, GraphicTransformType::GRAPHIC_ROTATE_90}};
540
541 static const std::map<std::pair<int, GraphicTransformType>, GraphicTransformType> pairToEnumMap = {
542 {{0, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_H},
543 {{0, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_V},
544 {{90, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_V_ROT90},
545 {{90, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_H_ROT90},
546 {{180, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_V},
547 {{180, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_H},
548 {{270, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_H_ROT90},
549 {{270, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_V_ROT90},
550 };
551
552 if (flip != GraphicTransformType::GRAPHIC_FLIP_H && flip != GraphicTransformType::GRAPHIC_FLIP_V) {
553 auto iter = intToEnumMap.find(angle);
554 return iter != intToEnumMap.end() ? iter->second : GraphicTransformType::GRAPHIC_ROTATE_NONE;
555 } else {
556 auto iter = pairToEnumMap.find({angle, flip});
557 return iter != pairToEnumMap.end() ? iter->second : GraphicTransformType::GRAPHIC_ROTATE_NONE;
558 }
559 }
560
SetLayerTransform(const LayerInfoPtr & layer,RSBaseRenderNode & node,const sptr<Surface> & surface,ScreenRotation screenRotation)561 static void SetLayerTransform(const LayerInfoPtr& layer, RSBaseRenderNode& node,
562 const sptr<Surface>& surface, ScreenRotation screenRotation)
563 {
564 // screenRotation: anti-clockwise, surfaceNodeRotation: anti-clockwise, surfaceTransform: anti-clockwise
565 // layerTransform: clockwise
566 int surfaceNodeRotation = GetSurfaceNodeRotation(node);
567 int totalRotation = (RotateEnumToInt(screenRotation) + surfaceNodeRotation +
568 RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(surface->GetTransform()))) % 360;
569 GraphicTransformType rotateEnum = RotateEnumToInt(totalRotation,
570 RSBaseRenderUtil::GetFlipTransform(surface->GetTransform()));
571 layer->SetTransform(rotateEnum);
572 }
573
SetLayerSize(const LayerInfoPtr & layer,const ScreenInfo & screenInfo)574 static void SetLayerSize(const LayerInfoPtr& layer, const ScreenInfo& screenInfo)
575 {
576 const auto screenWidth = static_cast<int32_t>(screenInfo.width);
577 const auto screenHeight = static_cast<int32_t>(screenInfo.height);
578 const auto screenRotation = screenInfo.rotation;
579 const auto rect = layer->GetLayerSize();
580 // screenRotation: anti-clockwise, surfaceTransform: anti-clockwise, layerTransform: clockwise
581 switch (screenRotation) {
582 case ScreenRotation::ROTATION_90: {
583 RS_LOGD("RsDebug ScreenRotation 90, Before Rotate layer size [%d %d %d %d]",
584 rect.x, rect.y, rect.w, rect.h);
585 layer->SetLayerSize(IRect {rect.y, screenHeight - rect.x - rect.w, rect.h, rect.w});
586 RS_LOGD("RsDebug ScreenRotation 90, After Rotate layer size [%d %d %d %d]",
587 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
588 break;
589 }
590 case ScreenRotation::ROTATION_180: {
591 RS_LOGD("RsDebug ScreenRotation 180, Before Rotate layer size [%d %d %d %d]",
592 rect.x, rect.y, rect.w, rect.h);
593 layer->SetLayerSize(
594 IRect {screenWidth - rect.x - rect.w, screenHeight - rect.y - rect.h, rect.w, rect.h});
595 RS_LOGD("RsDebug ScreenRotation 180, After Rotate layer size [%d %d %d %d]",
596 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
597 break;
598 }
599 case ScreenRotation::ROTATION_270: {
600 RS_LOGD("RsDebug ScreenRotation 270, Before Rotate layer size [%d %d %d %d]",
601 rect.x, rect.y, rect.w, rect.h);
602 layer->SetLayerSize(IRect {screenWidth - rect.y - rect.h, rect.x, rect.h, rect.w});
603 RS_LOGD("RsDebug ScreenRotation 270, After Rotate layer size [%d %d %d %d]",
604 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
605 break;
606 }
607 default: {
608 break;
609 }
610 }
611 }
612
613 // private func, guarantee the layer is valid
LayerRotate(const LayerInfoPtr & layer,RSBaseRenderNode & node) const614 void RSComposerAdapter::LayerRotate(const LayerInfoPtr& layer, RSBaseRenderNode& node) const
615 {
616 auto surface = layer->GetSurface();
617 if (surface == nullptr) {
618 return;
619 }
620 SetLayerSize(layer, screenInfo_);
621 SetLayerTransform(layer, node, surface, screenInfo_.rotation);
622 }
623
624 // private func, guarantee the layer is valid
LayerCrop(const LayerInfoPtr & layer) const625 void RSComposerAdapter::LayerCrop(const LayerInfoPtr& layer) const
626 {
627 IRect dstRect = layer->GetLayerSize();
628 IRect srcRect = layer->GetCropRect();
629 IRect originSrcRect = srcRect;
630
631 RectI dstRectI(dstRect.x, dstRect.y, dstRect.w, dstRect.h);
632 int32_t screenWidth = static_cast<int32_t>(screenInfo_.width);
633 int32_t screenHeight = static_cast<int32_t>(screenInfo_.height);
634 RectI screenRectI(0, 0, screenWidth, screenHeight);
635 RectI resDstRect = dstRectI.IntersectRect(screenRectI);
636 if (resDstRect == dstRectI) {
637 return;
638 }
639 dstRect = {resDstRect.left_, resDstRect.top_, resDstRect.width_, resDstRect.height_};
640 srcRect.x = resDstRect.IsEmpty() ? 0 : std::ceil((resDstRect.left_ - dstRectI.left_) *
641 originSrcRect.w / dstRectI.width_);
642 srcRect.y = resDstRect.IsEmpty() ? 0 : std::ceil((resDstRect.top_ - dstRectI.top_) *
643 originSrcRect.h / dstRectI.height_);
644 srcRect.w = dstRectI.IsEmpty() ? 0 : originSrcRect.w * resDstRect.width_ / dstRectI.width_;
645 srcRect.h = dstRectI.IsEmpty() ? 0 : originSrcRect.h * resDstRect.height_ / dstRectI.height_;
646 layer->SetLayerSize(dstRect);
647 layer->SetDirtyRegion(srcRect);
648 layer->SetCropRect(srcRect);
649 RS_LOGD("RsDebug RSComposerAdapter::LayerCrop layer has been cropped dst[%d %d %d %d] src[%d %d %d %d]",
650 dstRect.x, dstRect.y, dstRect.w, dstRect.h, srcRect.x, srcRect.y, srcRect.w, srcRect.h);
651 }
652
653 // private func, guarantee the layer is valid
LayerScaleDown(const LayerInfoPtr & layer)654 void RSComposerAdapter::LayerScaleDown(const LayerInfoPtr& layer)
655 {
656 ScalingMode scalingMode = ScalingMode::SCALING_MODE_SCALE_TO_WINDOW;
657 const auto& buffer = layer->GetBuffer();
658 const auto& surface = layer->GetSurface();
659 if (buffer == nullptr || surface == nullptr) {
660 return;
661 }
662
663 if (surface->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK &&
664 scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
665 IRect dstRect = layer->GetLayerSize();
666 IRect srcRect = layer->GetCropRect();
667
668 uint32_t newWidth = static_cast<uint32_t>(srcRect.w);
669 uint32_t newHeight = static_cast<uint32_t>(srcRect.h);
670
671 if (newWidth * dstRect.h > newHeight * dstRect.w) {
672 // too wide
673 newWidth = dstRect.w * newHeight / dstRect.h;
674 } else if (newWidth * dstRect.h < newHeight * dstRect.w) {
675 // too tall
676 newHeight = dstRect.h * newWidth / dstRect.w;
677 } else {
678 return;
679 }
680
681 uint32_t currentWidth = static_cast<uint32_t>(srcRect.w);
682 uint32_t currentHeight = static_cast<uint32_t>(srcRect.h);
683
684 if (newWidth < currentWidth) {
685 // the crop is too wide
686 uint32_t dw = currentWidth - newWidth;
687 auto halfdw = dw / 2;
688 srcRect.x += halfdw;
689 srcRect.w = newWidth;
690 } else {
691 // thr crop is too tall
692 uint32_t dh = currentHeight - newHeight;
693 auto halfdh = dh / 2;
694 srcRect.y += halfdh;
695 srcRect.h = newHeight;
696 }
697 layer->SetDirtyRegion(srcRect);
698 layer->SetCropRect(srcRect);
699 RS_LOGD("RsDebug RSComposerAdapter::LayerScaleDown layer has been scaledown dst[%d %d %d %d]"\
700 "src[%d %d %d %d]", dstRect.x, dstRect.y, dstRect.w, dstRect.h,
701 srcRect.x, srcRect.y, srcRect.w, srcRect.h);
702 }
703 }
704
705 // private func, guarantee the layer and surface are valid
LayerPresentTimestamp(const LayerInfoPtr & layer,const sptr<Surface> & surface)706 void RSComposerAdapter::LayerPresentTimestamp(const LayerInfoPtr& layer, const sptr<Surface>& surface)
707 {
708 if (!layer->IsSupportedPresentTimestamp()) {
709 return;
710 }
711 const auto& buffer = layer->GetBuffer();
712 if (buffer == nullptr) {
713 return;
714 }
715 if (surface->SetPresentTimestamp(buffer->GetSeqNum(), layer->GetPresentTimestamp()) != GSERROR_OK) {
716 RS_LOGD("RsDebug RSComposerAdapter::LayerPresentTimestamp: SetPresentTimestamp failed");
717 }
718 }
719
OnPrepareComplete(sptr<Surface> & surface,const PrepareCompleteParam & param,void * data)720 void RSComposerAdapter::OnPrepareComplete(sptr<Surface>& surface, const PrepareCompleteParam& param, void* data)
721 {
722 // unused data.
723 (void)(data);
724
725 if (!param.needFlushFramebuffer) {
726 RS_LOGD("RsDebug RSComposerAdapter::OnPrepareComplete: no need to flush frame buffer");
727 return;
728 }
729
730 if (fallbackCb_ != nullptr) {
731 fallbackCb_(surface, param.layers);
732 }
733 }
734 } // namespace Rosen
735 } // namespace OHOS
736