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