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 #ifndef RENDER_SERVICE_CORE_PIPELINE_RS_UNI_RENDER_UTIL_H
17 #define RENDER_SERVICE_CORE_PIPELINE_RS_UNI_RENDER_UTIL_H
18 
19 #include <list>
20 #include <mutex>
21 #include <set>
22 #include <unordered_map>
23 
24 #include "surface.h"
25 #include "surface_type.h"
26 #include "sync_fence.h"
27 
28 #include "common/rs_obj_abs_geometry.h"
29 #include "drawable/rs_surface_render_node_drawable.h"
30 #include "params/rs_display_render_params.h"
31 #include "pipeline/rs_base_render_engine.h"
32 #include "pipeline/rs_base_render_util.h"
33 #include "pipeline/rs_display_render_node.h"
34 #include "pipeline/rs_paint_filter_canvas.h"
35 #include "pipeline/rs_render_node_map.h"
36 #include "pipeline/rs_surface_render_node.h"
37 #include "transaction/rs_uiextension_data.h"
38 #include "utils/matrix.h"
39 
40 namespace OHOS {
41 namespace Rosen {
42 class RSUniRenderUtil {
43 public:
44     // merge history dirty region of current display node and its child surfacenode(app windows)
45     // for mirror display, call this function twice will introduce additional dirtyhistory in dirtymanager
46     static void MergeDirtyHistoryForDrawable(DrawableV2::RSDisplayRenderNodeDrawable& drawable, int32_t bufferAge,
47         RSDisplayRenderParams& params, bool useAlignedDirtyRegion = false);
48     static void SetAllSurfaceDrawableGlobalDityRegion(
49         std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceDrawables,
50         const Occlusion::Region& globalDirtyRegion);
51     /* we want to set visible dirty region of each surfacenode into DamageRegionKHR interface, hence
52      * occlusion is calculated.
53      * make sure this function is called after merge dirty history
54      */
55     static Occlusion::Region MergeVisibleDirtyRegion(
56         std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceNodeDrawables,
57         std::vector<NodeId>& hasVisibleDirtyRegionSurfaceVec, bool useAlignedDirtyRegion = false);
58     static void MergeDirtyHistoryInVirtual(
59         DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable, int32_t bufferAge, bool renderParallel = false);
60     static Occlusion::Region MergeVisibleDirtyRegionInVirtual(
61         std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceNodeDrawables);
62     static std::vector<RectI> ScreenIntersectDirtyRects(const Occlusion::Region &region, ScreenInfo& screenInfo);
63     static std::vector<RectI> GetFilpDirtyRects(const std::vector<RectI>& srcRects, const ScreenInfo& screenInfo);
64     static std::vector<RectI> FilpRects(const std::vector<RectI>& srcRects, const ScreenInfo& screenInfo);
65     static bool HandleSubThreadNode(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas);
66     static bool HandleCaptureNode(RSRenderNode& node, RSPaintFilterCanvas& canvas);
67     // This is used for calculate matrix from buffer coordinate to window's relative coordinate
68     static Drawing::Matrix GetMatrixOfBufferToRelRect(const RSSurfaceRenderNode& node);
69     static void SrcRectScaleDown(BufferDrawParam& params, const sptr<SurfaceBuffer>& buffer,
70         const sptr<IConsumerSurface>& surface, RectF& localBounds);
71     static void SrcRectScaleFit(BufferDrawParam& params, const sptr<SurfaceBuffer>& buffer,
72         const sptr<IConsumerSurface>& surface, RectF& localBounds);
73     static BufferDrawParam CreateBufferDrawParam(const RSSurfaceRenderNode& node,
74         bool forceCPU, uint32_t threadIndex = UNI_RENDER_THREAD_INDEX, bool useRenderParams = false);
75     static BufferDrawParam CreateBufferDrawParam(const RSDisplayRenderNode& node, bool forceCPU);
76     static BufferDrawParam CreateBufferDrawParam(const RSSurfaceHandler& surfaceHandler, bool forceCPU);
77     static BufferDrawParam CreateBufferDrawParam(
78         const DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, bool forceCPU, uint32_t threadIndex);
79     static BufferDrawParam CreateBufferDrawParamForRotationFixed(
80         const DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, RSSurfaceRenderParams& renderParams);
81     static BufferDrawParam CreateLayerBufferDrawParam(const LayerInfoPtr& layer, bool forceCPU);
82     static void DealWithRotationAndGravityForRotationFixed(GraphicTransformType transform, Gravity gravity,
83         RectF& localBounds, BufferDrawParam& params);
84     static bool IsNeedClient(RSSurfaceRenderNode& node, const ComposeInfo& info);
85     static void DrawRectForDfx(RSPaintFilterCanvas& canvas, const RectI& rect, Drawing::Color color,
86         float alpha, const std::string& extraInfo = "");
87     static Occlusion::Region AlignedDirtyRegion(const Occlusion::Region& dirtyRegion, int32_t alignedBits = 32);
88     static int TransferToAntiClockwiseDegrees(int angle);
89     static int GetRotationFromMatrix(Drawing::Matrix matrix);
90     static int GetRotationDegreeFromMatrix(Drawing::Matrix matrix);
91     static bool Is3DRotation(Drawing::Matrix matrix);
92 
93     static void AssignWindowNodes(const std::shared_ptr<RSDisplayRenderNode>& displayNode,
94         std::list<std::shared_ptr<RSSurfaceRenderNode>>& mainThreadNodes,
95         std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes);
96     static void ClearSurfaceIfNeed(const RSRenderNodeMap& map, const std::shared_ptr<RSDisplayRenderNode>& displayNode,
97         std::set<std::shared_ptr<RSBaseRenderNode>>& oldChildren, DeviceType deviceType = DeviceType::PHONE);
98     static void ClearCacheSurface(RSRenderNode& node, uint32_t threadIndex, bool isClearCompletedCacheSurface = true);
99     static void ClearNodeCacheSurface(std::shared_ptr<Drawing::Surface>&& cacheSurface,
100         std::shared_ptr<Drawing::Surface>&& cacheCompletedSurface,
101         uint32_t cacheSurfaceThreadIndex, uint32_t completedSurfaceThreadIndex);
102     static void CacheSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>>& oldSubThreadNodes,
103         std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes);
104     static bool IsNodeAssignSubThread(std::shared_ptr<RSSurfaceRenderNode> node, bool isDisplayRotation);
105 #ifdef RS_ENABLE_VK
106     static uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
107     static void SetVkImageInfo(std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo,
108         const VkImageCreateInfo& imageInfo);
109     static Drawing::BackendTexture MakeBackendTexture(uint32_t width, uint32_t height,
110         VkFormat format = VK_FORMAT_R8G8B8A8_UNORM);
111 #endif
112     static void UpdateRealSrcRect(RSSurfaceRenderNode& node, const RectI& absRect);
113     static void DealWithNodeGravity(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo);
114     static void DealWithScalingMode(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo);
115     static void CheckForceHardwareAndUpdateDstRect(RSSurfaceRenderNode& node);
116     static void LayerRotate(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo);
117     static void LayerCrop(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo);
118     static void LayerScaleDown(RSSurfaceRenderNode& node);
119     static void LayerScaleFit(RSSurfaceRenderNode& node);
120     static GraphicTransformType GetLayerTransform(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo);
121     static void OptimizedFlushAndSubmit(std::shared_ptr<Drawing::Surface>& surface,
122         Drawing::GPUContext* const grContext, bool optFenceWait = true);
123     static void AccumulateMatrixAndAlpha(std::shared_ptr<RSSurfaceRenderNode>& hwcNode,
124         Drawing::Matrix& matrix, float& alpha);
125     static SecRectInfo GenerateSecRectInfoFromNode(RSRenderNode& node, RectI rect);
126     static SecSurfaceInfo GenerateSecSurfaceInfoFromNode(
127         NodeId uiExtensionId, NodeId hostId, SecRectInfo uiExtensionRectInfo);
128     static void UIExtensionFindAndTraverseAncestor(
129         const RSRenderNodeMap& nodeMap, UIExtensionCallbackData& callbackData);
130     static void TraverseAndCollectUIExtensionInfo(std::shared_ptr<RSRenderNode> node,
131         Drawing::Matrix parentMatrix, NodeId hostId, UIExtensionCallbackData& callbackData);
132     static void ProcessCacheImage(RSPaintFilterCanvas& canvas, Drawing::Image& cacheImageProcessed);
133     template<typename... Callbacks>
TraverseParentNodeAndReduce(std::shared_ptr<RSSurfaceRenderNode> hwcNode,Callbacks &&...callbacks)134     static void TraverseParentNodeAndReduce(std::shared_ptr<RSSurfaceRenderNode> hwcNode, Callbacks&&... callbacks)
135     {
136         static_assert((std::is_invocable<Callbacks, std::shared_ptr<RSRenderNode>>::value && ...),
137                     "uninvocable callback");
138         if (!hwcNode) {
139             return;
140         }
141         auto parent = std::static_pointer_cast<RSRenderNode>(hwcNode);
142         while (static_cast<bool>(parent = parent->GetParent().lock())) {
143             (std::invoke(callbacks, parent), ...);
144             if (parent->GetType() == RSRenderNodeType::DISPLAY_NODE) {
145                 break;
146             }
147         }
148     }
149     static std::optional<Drawing::Matrix> GetMatrix(std::shared_ptr<RSRenderNode> hwcNode);
150     // RTthread needs to draw one more frame when screen is turned off. For other threads, use extraframe default value.
151     static bool CheckRenderSkipIfScreenOff(bool extraFrame = false, std::optional<ScreenId> screenId = std::nullopt);
152 
153 private:
154     static RectI SrcRectRotateTransform(RSSurfaceRenderNode& node, GraphicTransformType transformType);
155     static void AssignMainThreadNode(std::list<std::shared_ptr<RSSurfaceRenderNode>>& mainThreadNodes,
156         const std::shared_ptr<RSSurfaceRenderNode>& node);
157     static void AssignSubThreadNode(std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes,
158         const std::shared_ptr<RSSurfaceRenderNode>& node);
159     static void SortSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes);
160     static void HandleHardwareNode(const std::shared_ptr<RSSurfaceRenderNode>& node);
161     static void PostReleaseSurfaceTask(std::shared_ptr<Drawing::Surface>&& surface, uint32_t threadIndex);
162     static GraphicTransformType GetRotateTransformForRotationFixed(RSSurfaceRenderNode& node,
163         sptr<IConsumerSurface> consumer);
164     static inline int currentUIExtensionIndex_ = -1;
165     static inline const std::string RELEASE_SURFACE_TASK = "releaseSurface";
166 };
167 }
168 }
169 #endif // RENDER_SERVICE_CORE_PIPELINE_RS_UNI_RENDER_UTIL_H
170