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