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