• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_drm_util.h"
17 #include <parameters.h>
18 #include "common/rs_background_thread.h"
19 #include "pipeline/hardware_thread/rs_hardware_thread.h"
20 #include "pipeline/render_thread/rs_uni_render_thread.h"
21 #include "pipeline/render_thread/rs_uni_render_util.h"
22 #include "pipeline/rs_effect_render_node.h"
23 #include "graphic_feature_param_manager.h"
24 
25 namespace OHOS {
26 namespace Rosen {
27 constexpr const int BLUR_MIN_ALPHA = 100;
28 
ClearDrmNodes()29 void RSDrmUtil::ClearDrmNodes()
30 {
31     drmNodes_.clear();
32 }
CollectDrmNodes(const std::shared_ptr<RSSurfaceRenderNode> & surfaceNode)33 void RSDrmUtil::CollectDrmNodes(const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode)
34 {
35     auto firstLevelNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
36         surfaceNode->GetFirstLevelNode());
37     if (firstLevelNode && firstLevelNode->IsOnTheTree()) {
38         drmNodes_[firstLevelNode->GetId()].push_back(surfaceNode);
39     }
40 }
41 
AddDrmCloneCrossNode(const std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,DrawablesVec & hardwareEnabledDrawables)42 void RSDrmUtil::AddDrmCloneCrossNode(const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
43     DrawablesVec& hardwareEnabledDrawables)
44 {
45     auto sourceNode = surfaceNode->GetSourceCrossNode().lock();
46     auto sourceSurface = sourceNode == nullptr ? nullptr : sourceNode->ReinterpretCastTo<RSSurfaceRenderNode>();
47     auto leashWindowNode = sourceSurface == nullptr ? nullptr :
48         RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(sourceSurface->GetFirstLevelNode());
49     if (leashWindowNode && leashWindowNode->GetSpecialLayerMgr().Find(SpecialLayerType::HAS_PROTECTED) &&
50         surfaceNode->GetScreenNodeId() != INVALID_NODEID) {
51         if (const auto it = drmNodes_.find(leashWindowNode->GetId()); it != drmNodes_.end()) {
52             for (const auto& node : it->second) {
53                 if (node->IsOnTheTree()) {
54                     hardwareEnabledDrawables.emplace_back(surfaceNode->GetScreenNodeId(),
55                         node->GetLogicalDisplayNodeId(), node->GetRenderDrawable());
56                 }
57             }
58         }
59     }
60 }
61 
DRMCreateLayer(std::shared_ptr<RSProcessor> processor,Drawing::Matrix canvasMatrix)62 void RSDrmUtil::DRMCreateLayer(std::shared_ptr<RSProcessor> processor, Drawing::Matrix canvasMatrix)
63 {
64     auto& hardwareDrawables =
65         RSUniRenderThread::Instance().GetRSRenderThreadParams()->GetHardwareEnabledTypeDrawables();
66     for (const auto& [screenNodeId, _, drawable] : hardwareDrawables) {
67         if (UNLIKELY(!drawable) || !drawable->GetRenderParams()) {
68             continue;
69         }
70         auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
71         auto& params = surfaceDrawable->GetRenderParams();
72         if (UNLIKELY(!params)) {
73             continue;
74         }
75         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(params.get());
76         if (UNLIKELY(!surfaceParams) || !surfaceParams->GetSpecialLayerMgr().Find(SpecialLayerType::HAS_PROTECTED)) {
77             continue;
78         }
79         // calculate matrix
80         auto layerInfo = surfaceParams->GetLayerInfo();
81         Drawing::Matrix tmpMatrix = surfaceParams->GetTotalMatrix();
82         tmpMatrix.PostConcat(canvasMatrix);
83         layerInfo.matrix = tmpMatrix;
84         // calculate dstRect
85         Drawing::Rect absRect;
86         tmpMatrix.MapRect(absRect, surfaceParams->GetBounds());
87         layerInfo.dstRect.x = absRect.left_;
88         layerInfo.dstRect.y = absRect.top_;
89         layerInfo.dstRect.w = absRect.right_ - absRect.left_;
90         layerInfo.dstRect.h = absRect.bottom_ - absRect.top_;
91         // calculate transformType
92         GraphicTransformType rotateEnum =
93             RSBaseRenderUtil::RotateEnumToInt(RSUniRenderUtil::GetRotationFromMatrix(tmpMatrix) % 360,
94                 RSBaseRenderUtil::GetFlipTransform(layerInfo.transformType));
95         layerInfo.transformType = rotateEnum;
96         surfaceParams->SetLayerInfo(layerInfo);
97         processor->CreateLayerForRenderThread(*surfaceDrawable);
98     }
99 }
100 
PreAllocateProtectedBuffer(const std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,const std::shared_ptr<RSSurfaceHandler> & surfaceHandler)101 void RSDrmUtil::PreAllocateProtectedBuffer(const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
102     const std::shared_ptr<RSSurfaceHandler>& surfaceHandler)
103 {
104     auto displayLock = surfaceNode->GetAncestorScreenNode().lock();
105     std::shared_ptr<RSScreenRenderNode> ancestor = nullptr;
106     if (displayLock != nullptr) {
107         ancestor = displayLock->ReinterpretCastTo<RSScreenRenderNode>();
108     }
109     if (ancestor == nullptr) {
110         return;
111     }
112     auto protectedLayerScreenId = ancestor->GetScreenId();
113     auto screenManager = CreateOrGetScreenManager();
114 
115     auto output = screenManager->GetOutput(ToScreenPhysicalId(protectedLayerScreenId));
116     if (UNLIKELY(output == nullptr)) {
117         RS_LOGE("output is NULL");
118         return;
119     }
120     if (output->GetProtectedFrameBufferState()) {
121         return;
122     }
123     auto protectedBuffer = surfaceHandler->GetBuffer();
124     if (UNLIKELY(protectedBuffer == nullptr)) {
125         RS_LOGE("buffer is NULL");
126         return;
127     }
128     auto preAllocateProtectedBufferTask = [buffer = protectedBuffer, screenId = protectedLayerScreenId]() {
129         RSHardwareThread::Instance().PreAllocateProtectedBuffer(buffer, screenId);
130     };
131     RSBackgroundThread::Instance().PostTask(preAllocateProtectedBufferTask);
132 }
133 
MarkBlurIntersectWithDRM(const std::shared_ptr<RSRenderNode> & node,const std::vector<std::weak_ptr<RSSurfaceRenderNode>> & drmNodes,const std::shared_ptr<RSScreenRenderNode> & curScreenNode)134 void RSDrmUtil::MarkBlurIntersectWithDRM(const std::shared_ptr<RSRenderNode>& node,
135     const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& drmNodes,
136     const std::shared_ptr<RSScreenRenderNode>& curScreenNode)
137 {
138     static bool isDrmMarkAllParentBlurEnable = DRMParam::IsDrmMarkAllParentBlurEnable();
139     if (isDrmMarkAllParentBlurEnable) {
140         MarkBlurIntersectWithDRMForAllParentFilter(node, drmNodes, curScreenNode);
141     } else {
142         MarkBlurIntersectWithDRM(node, drmNodes);
143     }
144 }
145 
MarkBlurIntersectWithDRMForAllParentFilter(const std::shared_ptr<RSRenderNode> & node,const std::vector<std::weak_ptr<RSSurfaceRenderNode>> & drmNodes,const std::shared_ptr<RSScreenRenderNode> & curScreenNode)146 void RSDrmUtil::MarkBlurIntersectWithDRMForAllParentFilter(const std::shared_ptr<RSRenderNode>& node,
147     const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& drmNodes,
148     const std::shared_ptr<RSScreenRenderNode>& curScreenNode)
149 {
150     if (node->GetRenderProperties().GetBackgroundBlurMaskColor().GetAlpha() >= BLUR_MIN_ALPHA) {
151         return;
152     }
153     auto appWindowNodeId = node->GetInstanceRootNodeId();
154     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
155     auto appWindowNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
156     if (appWindowNode == nullptr) {
157         return;
158     }
159     static std::vector<std::string> drmKeyWins = DRMParam::GetBlackList();
160     for (const auto& win : drmKeyWins) {
161         if (appWindowNode->GetName().find(win) != std::string::npos) {
162             return;
163         }
164     }
165     for (auto& drmNode : drmNodes) {
166         auto drmNodePtr = drmNode.lock();
167         if (drmNodePtr == nullptr) {
168             continue;
169         }
170         bool isIntersect =
171             drmNodePtr->GetRenderProperties().GetBoundsGeometry()->GetAbsRect().Intersect(node->GetFilterRegion());
172         bool isVisible = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
173             drmNodePtr->GetInstanceRootNode())->GetVisibleRegion().IsEmpty();
174         if (isIntersect && !isVisible && IsDRMBelowFilter(curScreenNode, appWindowNode, drmNodePtr)) {
175             node->MarkBlurIntersectWithDRM(true, GetDarkColorMode(node, appWindowNode));
176         }
177     }
178 }
179 
MarkBlurIntersectWithDRM(const std::shared_ptr<RSRenderNode> & node,const std::vector<std::weak_ptr<RSSurfaceRenderNode>> & drmNodes)180 void RSDrmUtil::MarkBlurIntersectWithDRM(const std::shared_ptr<RSRenderNode>& node,
181     const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& drmNodes)
182 {
183     auto appWindowNodeId = node->GetInstanceRootNodeId();
184     const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
185     auto appWindowNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
186     if (appWindowNode == nullptr) {
187         return;
188     }
189     static std::vector<std::string> drmKeyWins = DRMParam::GetWhiteList();
190     auto effectNode = node->ReinterpretCastTo<RSEffectRenderNode>() ?
191         node->ReinterpretCastTo<RSEffectRenderNode>() : nullptr;
192     if (effectNode) {
193         effectNode->SetEffectIntersectWithDRM(false);
194         effectNode->SetDarkColorMode(RSMainThread::Instance()->GetGlobalDarkColorMode());
195     }
196     for (const auto& win : drmKeyWins) {
197         if (appWindowNode->GetName().find(win) == std::string::npos) {
198             continue;
199         }
200         for (auto& drmNode : drmNodes) {
201             auto drmNodePtr = drmNode.lock();
202             if (drmNodePtr == nullptr) {
203                 continue;
204             }
205             bool isIntersect =
206                 drmNodePtr->GetRenderProperties().GetBoundsGeometry()->GetAbsRect().Intersect(node->GetFilterRegion());
207             if (!isIntersect) {
208                 continue;
209             }
210             node->MarkBlurIntersectWithDRM(true, RSMainThread::Instance()->GetGlobalDarkColorMode());
211             if (effectNode) {
212                 effectNode->SetEffectIntersectWithDRM(true);
213             }
214         }
215     }
216 }
217 
IsDRMBelowFilter(const std::shared_ptr<RSScreenRenderNode> & curScreenNode,const std::shared_ptr<RSSurfaceRenderNode> & appWindowNode,const std::shared_ptr<RSSurfaceRenderNode> & drmNode)218 bool RSDrmUtil::IsDRMBelowFilter(const std::shared_ptr<RSScreenRenderNode>& curScreenNode,
219     const std::shared_ptr<RSSurfaceRenderNode>& appWindowNode,
220     const std::shared_ptr<RSSurfaceRenderNode>& drmNode)
221 {
222     auto& curMainAndLeashSurfaces = curScreenNode->GetAllMainAndLeashSurfaces();
223     auto filterNodeIndex = 0;
224     auto drmNodeIndex = 0;
225     for (size_t i = 0; i < curMainAndLeashSurfaces.size(); ++i) {
226         auto leashWindowNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(curMainAndLeashSurfaces[i]);
227         if (appWindowNode == leashWindowNode) {
228             filterNodeIndex = i;
229         }
230         auto drmLeashNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(drmNode->GetInstanceRootNode());
231         if (drmLeashNode == leashWindowNode) {
232             drmNodeIndex = i;
233             break;
234         }
235     }
236     return drmNodeIndex > filterNodeIndex;
237 }
238 
GetDarkColorMode(const std::shared_ptr<RSRenderNode> & node,const std::shared_ptr<RSSurfaceRenderNode> & appWindowNode)239 bool RSDrmUtil::GetDarkColorMode(const std::shared_ptr<RSRenderNode>& node,
240     const std::shared_ptr<RSSurfaceRenderNode>& appWindowNode)
241 {
242     bool isDarkColorMode = RSMainThread::Instance()->GetGlobalDarkColorMode();
243     if (appWindowNode->GetName().find("SCBSmartDock") != std::string::npos) {
244         float saturation = node->GetRenderProperties().GetBgBrightnessSaturation();
245         isDarkColorMode = ROSEN_GNE(saturation, 1.4f) ? false : true;
246     }
247     return isDarkColorMode;
248 }
249 } // namespace Rosen
250 } // namespace OHOS