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