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