• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "pipeline/rs_pointer_window_manager.h"
17 #include "feature/hwc/rs_uni_hwc_compute_util.h"
18 #include "common/rs_optional_trace.h"
19 #include "feature_cfg/graphic_feature_param_manager.h"
20 #include "pipeline/main_thread/rs_main_thread.h"
21 #ifdef RS_ENABLE_GPU
22 #include "pipeline/render_thread/rs_uni_render_util.h"
23 #include "screen_manager/screen_types.h"
24 #endif
25 namespace OHOS {
26 namespace Rosen {
27 namespace {
28 constexpr int MIN_LAYER_WIDTH = 2;
29 constexpr int MIN_LAYER_HEIGHT = 2;
30 }
Instance()31 RSPointerWindowManager& RSPointerWindowManager::Instance()
32 {
33     static RSPointerWindowManager instance;
34     return instance;
35 }
36 
RSPointerWindowManager()37 RSPointerWindowManager::RSPointerWindowManager()
38 {
39     isHardCursorEnable_ = RSPointerWindowManager::GetHardCursorEnabledPass();
40 }
41 
UpdatePointerDirtyToGlobalDirty(std::shared_ptr<RSSurfaceRenderNode> & pointWindow,std::shared_ptr<RSScreenRenderNode> & curScreenNode)42 void RSPointerWindowManager::UpdatePointerDirtyToGlobalDirty(std::shared_ptr<RSSurfaceRenderNode>& pointWindow,
43     std::shared_ptr<RSScreenRenderNode>& curScreenNode)
44 {
45     if (pointWindow == nullptr || curScreenNode == nullptr) {
46         return;
47     }
48     auto dirtyManager = pointWindow->GetDirtyManager();
49     if (dirtyManager && pointWindow->GetHardCursorStatus()) {
50         if (!pointWindow->GetHardCursorLastStatus()) {
51             RectI lastFrameSurfacePos = curScreenNode->GetLastFrameSurfacePos(pointWindow->GetId());
52             curScreenNode->GetDirtyManager()->MergeDirtyRect(lastFrameSurfacePos);
53         }
54         auto pointerWindowDirtyRegion = dirtyManager->GetCurrentFrameDirtyRegion();
55         if (!pointerWindowDirtyRegion.IsEmpty()) {
56             curScreenNode->GetDirtyManager()->MergeHwcDirtyRect(pointerWindowDirtyRegion);
57             dirtyManager->SetCurrentFrameDirtyRect(RectI());
58             isNeedForceCommitByPointer_ = true;
59         } else {
60             isNeedForceCommitByPointer_ = false;
61         }
62     }
63 }
64 
GetHardCursorEnabledPass()65 bool RSPointerWindowManager::GetHardCursorEnabledPass()
66 {
67     auto hardCursorFeatureParam = GraphicFeatureParamManager::GetInstance().GetFeatureParam("HardCursorConfig");
68     auto hardCursorFeature = std::static_pointer_cast<HardCursorParam>(hardCursorFeatureParam);
69     if (hardCursorFeature != nullptr) {
70         return hardCursorFeature->IsHardCursorEnable();
71     }
72     return false;
73 }
74 
UpdatePointerInfo()75 void RSPointerWindowManager::UpdatePointerInfo()
76 {
77 #ifdef RS_ENABLE_GPU
78     int64_t rsNodeId = 0;
79     BoundParam boundTemp = {0.0f, 0.0f, 0.0f, 0.0f};
80     {
81         std::lock_guard<std::mutex> lock(mtx_);
82         if (!BoundHasUpdateCompareChange(true, false)) {
83             return;
84         }
85         rsNodeId = GetRsNodeId();
86         boundTemp = GetBound();
87     }
88 
89     if (rsNodeId <= 0) {
90         return;
91     }
92 
93     // prepare
94     auto node = RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode(rsNodeId);
95     if (node == nullptr) {
96         return;
97     }
98     auto& properties = node->GetMutableRenderProperties();
99     properties.SetBounds({boundTemp.x, boundTemp.y, boundTemp.z, boundTemp.w});
100     node->SetDirty();
101     properties.OnApplyModifiers();
102     node->OnApplyModifiers();
103     node->AddToPendingSyncList();
104 
105     // 1.Set TotalMatrix
106     auto surfaceNode = node->ReinterpretCastTo<RSSurfaceRenderNode>();
107     if (surfaceNode == nullptr) {
108         return;
109     }
110     RSUniHwcComputeUtil::UpdateHwcNodeProperty(surfaceNode);
111 
112     // 2.update (layerInfo.matrix = TotalMatrix)
113     if (surfaceNode->GetScreenId() != INVALID_SCREEN_ID) {
114         auto screenManager = CreateOrGetScreenManager();
115         if (!screenManager) {
116             RS_LOGE("RSPointerWindowManager::UpdatePointerInfo screenManager is null!");
117             return;
118         }
119         auto screenInfo = screenManager->QueryScreenInfo(surfaceNode->GetScreenId());
120         auto transform = RSUniHwcComputeUtil::GetLayerTransform(*surfaceNode, screenInfo);
121         surfaceNode->UpdateHwcNodeLayerInfo(transform, isPointerEnableHwc_);
122     }
123 #endif
124 }
125 
SetHwcNodeBounds(int64_t rsNodeId,float positionX,float positionY,float positionZ,float positionW)126 void RSPointerWindowManager::SetHwcNodeBounds(int64_t rsNodeId, float positionX, float positionY,
127     float positionZ, float positionW)
128 {
129 #ifdef RS_ENABLE_GPU
130     // record status here
131     {
132         std::lock_guard<std::mutex> lock(mtx_);
133         SetBound({positionX, positionY, positionZ, positionW});
134         SetRsNodeId(rsNodeId);
135     }
136     SetBoundHasUpdate(true);
137 #endif
138 }
139 
SetHardCursorNodeInfo(std::shared_ptr<RSSurfaceRenderNode> hardCursorNode)140 void RSPointerWindowManager::SetHardCursorNodeInfo(std::shared_ptr<RSSurfaceRenderNode> hardCursorNode)
141 {
142     if (!hardCursorNode) {
143         return;
144     }
145     if (!hardCursorNode->IsHardwareEnabledTopSurface() ||
146         (!hardCursorNode->ShouldPaint() && !hardCursorNode->GetHardCursorStatus())) {
147         return;
148     }
149     if (hardCursorNode->IsOnTheTree()) {
150         auto nodeId = hardCursorNode->GetId();
151         hardCursorNodeMap_.emplace(nodeId, hardCursorNode);
152     }
153 }
154 
GetHardCursorNode() const155 const std::map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>& RSPointerWindowManager::GetHardCursorNode() const
156 {
157     return hardCursorNodeMap_;
158 }
159 
HardCursorCreateLayerForDirect(std::shared_ptr<RSProcessor> processor)160 void RSPointerWindowManager::HardCursorCreateLayerForDirect(std::shared_ptr<RSProcessor> processor)
161 {
162 #ifdef RS_ENABLE_GPU
163     auto& hardCursorNodeMap = GetHardCursorNode();
164     for (auto& [_, hardCursorNode] :  hardCursorNodeMap) {
165         if (hardCursorNode && hardCursorNode->IsHardwareEnabledTopSurface()) {
166             auto surfaceHandler = hardCursorNode->GetRSSurfaceHandler();
167             if (!surfaceHandler) {
168                 continue;
169             }
170             auto params = static_cast<RSSurfaceRenderParams *>(hardCursorNode->GetStagingRenderParams().get());
171             if (!params) {
172                 continue;
173             }
174             if (!surfaceHandler->IsCurrentFrameBufferConsumed() && params->GetPreBuffer() != nullptr) {
175                 params->SetPreBuffer(nullptr);
176                 hardCursorNode->AddToPendingSyncList();
177             }
178             processor->CreateLayer(*hardCursorNode, *params);
179         }
180     }
181 #endif
182 }
183 
CheckHardCursorSupport(uint32_t screenId)184 bool RSPointerWindowManager::CheckHardCursorSupport(uint32_t screenId)
185 {
186     if (!isHardCursorEnable_) {
187         return false;
188     }
189     auto screenManager = CreateOrGetScreenManager();
190     if (!screenManager) {
191         return false;
192     }
193     return screenManager->GetDisplayPropertyForHardCursor(screenId);
194 }
195 
HasMirrorDisplay() const196 bool RSPointerWindowManager::HasMirrorDisplay() const
197 {
198     const std::shared_ptr<RSBaseRenderNode> rootNode =
199         RSMainThread::Instance()->GetContext().GetGlobalRootRenderNode();
200     if (rootNode == nullptr || rootNode->GetChildrenCount() <= 1) {
201         return false;
202     }
203     for (auto& child : *rootNode->GetSortedChildren()) {
204         if (!child || !child->IsInstanceOf<RSScreenRenderNode>()) {
205             continue;
206         }
207         auto screenNode = child->ReinterpretCastTo<RSScreenRenderNode>();
208         if (!screenNode) {
209             continue;
210         }
211         if (screenNode->IsMirrorScreen()) {
212             return true;
213         }
214     }
215     return false;
216 }
217 
CollectAllHardCursor(RSSurfaceRenderNode & hardCursorNode,std::shared_ptr<RSScreenRenderNode> & curScreenNode,std::shared_ptr<RSLogicalDisplayRenderNode> & curDisplayNode)218 void RSPointerWindowManager::CollectAllHardCursor(
219     RSSurfaceRenderNode& hardCursorNode, std::shared_ptr<RSScreenRenderNode>& curScreenNode,
220     std::shared_ptr<RSLogicalDisplayRenderNode>& curDisplayNode)
221 {
222     if (hardCursorNode.IsHardwareEnabledTopSurface() &&
223         (hardCursorNode.ShouldPaint() || hardCursorNode.GetHardCursorStatus())) {
224         auto surfaceNodeDrawable =
225             std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(hardCursorNode.GetRenderDrawable());
226         if (surfaceNodeDrawable && hardCursorNode.IsOnTheTree()) {
227             hardCursorDrawableVec_.emplace_back(curScreenNode->GetId(),
228                 curDisplayNode->GetId(), hardCursorNode.GetRenderDrawable());
229         }
230     }
231 }
232 
GetHardCursorDrawable(NodeId id)233 std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> RSPointerWindowManager::GetHardCursorDrawable(NodeId id)
234 {
235     auto& renderThreadParams = RSUniRenderThread::Instance().GetRSRenderThreadParams();
236     if (!renderThreadParams) {
237         return nullptr;
238     }
239     auto& hardCursorDrawables = renderThreadParams->GetHardCursorDrawables();
240     if (hardCursorDrawables.empty()) {
241         return nullptr;
242     }
243     auto iter = std::find_if(hardCursorDrawables.begin(), hardCursorDrawables.end(), [id](const auto& node) {
244         return id == std::get<0>(node);
245     });
246     if (iter == hardCursorDrawables.end()) {
247         return nullptr;
248     }
249     auto& hardCursorDrawable = std::get<2>(*iter);
250     if (!hardCursorDrawable) {
251         return nullptr;
252     }
253     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(hardCursorDrawable->GetRenderParams().get());
254     if (!surfaceParams) {
255         return nullptr;
256     }
257     auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(hardCursorDrawable);
258     if (surfaceDrawable && surfaceParams->GetHardCursorStatus()) {
259         return std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(surfaceDrawable);
260     }
261     return nullptr;
262 }
263 
CheckHardCursorValid(const RSSurfaceRenderNode & node)264 void RSPointerWindowManager::CheckHardCursorValid(const RSSurfaceRenderNode& node)
265 {
266     if (!node.GetHardCursorStatus()) {
267         return;
268     }
269     // DSS Hardware don't support the synthesis of layers with length and width not larger than 2
270     auto srcRect = node.GetSrcRect();
271     if (srcRect.GetWidth() <= MIN_LAYER_WIDTH || srcRect.GetHeight() <= MIN_LAYER_WIDTH) {
272         const auto& property = node.GetRenderProperties();
273         auto buffer = node.GetRSSurfaceHandler()->GetBuffer();
274         if (buffer == nullptr) {
275             RS_LOGE("RSPointerWindowManager::CheckHardCursorValid: buffer is nullptr");
276             return;
277         }
278         auto bufferWidth = buffer->GetSurfaceBufferWidth();
279         auto bufferHeight = buffer->GetSurfaceBufferHeight();
280         const auto boundsWidth = property.GetBoundsWidth();
281         const auto boundsHeight = property.GetBoundsHeight();
282         RS_LOGE("hardcursor srcRect error, %{public}d, %{public}d, %{public}f, %{public}f",
283             bufferWidth, bufferHeight, boundsWidth, boundsHeight);
284     }
285 }
286 } // namespace Rosen
287 } // namespace OHOS