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