• 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_uni_render_util.h"
17 
18 #include <cstdint>
19 #include <memory>
20 #include <parameter.h>
21 #include <parameters.h>
22 #include <string>
23 #include <unordered_set>
24 
25 #include "rs_trace.h"
26 #include "scene_board_judgement.h"
27 
28 #include "common/rs_optional_trace.h"
29 #include "common/rs_rectangles_merger.h"
30 #include "drawable/dfx/rs_dirty_rects_dfx.h"
31 #include "drawable/rs_display_render_node_drawable.h"
32 #include "drawable/rs_surface_render_node_drawable.h"
33 #include "feature/uifirst/rs_sub_thread_manager.h"
34 #ifdef RS_ENABLE_OVERLAY_DISPLAY
35 #include "feature/overlay_display/rs_overlay_display_manager.h"
36 #endif
37 #include "info_collection/rs_gpu_dirty_region_collection.h"
38 #include "params/rs_display_render_params.h"
39 #include "params/rs_surface_render_params.h"
40 #include "rs_base_render_util.h"
41 #include "pipeline/main_thread/rs_main_thread.h"
42 #include "pipeline/rs_render_node.h"
43 #include "pipeline/rs_surface_render_node.h"
44 #include "platform/common/rs_log.h"
45 #include "property/rs_properties.h"
46 #include "render/rs_drawing_filter.h"
47 #include "render/rs_maskcolor_shader_filter.h"
48 #include "render/rs_material_filter.h"
49 #include "render/rs_path.h"
50 
51 #ifdef RS_ENABLE_VK
52 #include "include/gpu/GrBackendSurface.h"
53 #include "platform/ohos/backend/native_buffer_utils.h"
54 #include "platform/ohos/backend/rs_surface_ohos_vulkan.h"
55 #include "platform/ohos/backend/rs_vulkan_context.h"
56 #endif
57 
58 #ifdef SOC_PERF_ENABLE
59 #include "socperf_client.h"
60 #endif
61 #include "render_frame_trace.h"
62 
63 namespace OHOS {
64 namespace Rosen {
65 namespace {
66 constexpr const char* CAPTURE_WINDOW_NAME = "CapsuleWindow";
67 constexpr float GAMMA2_2 = 2.2f;
68 constexpr int64_t PERF_TIME_OUT = 950;
69 constexpr uint32_t PERF_LEVEL_INTERVAL = 10;
70 constexpr uint32_t PERF_LAYER_START_NUM = 12;
71 constexpr uint32_t PERF_LEVEL_0 = 0;
72 constexpr uint32_t PERF_LEVEL_1 = 1;
73 constexpr uint32_t PERF_LEVEL_2 = 2;
74 constexpr int32_t PERF_LEVEL_1_REQUESTED_CODE = 10013;
75 constexpr int32_t PERF_LEVEL_2_REQUESTED_CODE = 10014;
76 constexpr int32_t PERF_LEVEL_3_REQUESTED_CODE = 10015;
77 constexpr int MAX_DIRTY_ALIGNMENT_SIZE = 128;
PerfRequest(int32_t perfRequestCode,bool onOffTag)78 void PerfRequest(int32_t perfRequestCode, bool onOffTag)
79 {
80 #ifdef SOC_PERF_ENABLE
81     OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(perfRequestCode, onOffTag, "");
82     RS_LOGD("RSProcessor::soc perf info [%{public}d %{public}d]", perfRequestCode, onOffTag);
83 #endif
84 }
85 }
MergeDirtyRectAfterMergeHistory(std::shared_ptr<RSDirtyRegionManager> dirtyManager,Occlusion::Region & dirtyRegion)86 void RSUniRenderUtil::MergeDirtyRectAfterMergeHistory(
87     std::shared_ptr<RSDirtyRegionManager> dirtyManager, Occlusion::Region& dirtyRegion)
88 {
89     const auto clipRectThreshold = RSSystemProperties::GetClipRectThreshold();
90     if (clipRectThreshold < 1.f) {
91         Occlusion::Region allDirtyRegion{ Occlusion::Rect{ dirtyManager->GetDirtyRegion() } };
92         allDirtyRegion.OrSelf(dirtyRegion);
93         auto bound = allDirtyRegion.GetBound();
94         if (allDirtyRegion.GetSize() > 1 && !bound.IsEmpty() &&
95             allDirtyRegion.Area() > bound.Area() * clipRectThreshold) {
96             dirtyManager->MergeDirtyRectAfterMergeHistory(bound.ToRectI());
97             RS_OPTIONAL_TRACE_NAME_FMT("dirty expand: %s to %s",
98                 allDirtyRegion.GetRegionInfo().c_str(), bound.GetRectInfo().c_str());
99         }
100     }
101 }
102 
MergeDirtyHistory(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,int32_t bufferAge,ScreenInfo & screenInfo,RSDirtyRectsDfx & rsDirtyRectsDfx,RSDisplayRenderParams & params)103 std::vector<RectI> RSUniRenderUtil::MergeDirtyHistory(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable,
104     int32_t bufferAge, ScreenInfo& screenInfo, RSDirtyRectsDfx& rsDirtyRectsDfx, RSDisplayRenderParams& params)
105 {
106     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
107     // renderThreadParams/dirtyManager not null in caller
108     auto dirtyManager = displayDrawable.GetSyncDirtyManager();
109     auto& curAllSurfaceDrawables = params.GetAllMainAndLeashSurfaceDrawables();
110     RSUniRenderUtil::MergeDirtyHistoryForDrawable(displayDrawable, bufferAge, params, false);
111     Occlusion::Region dirtyRegion = RSUniRenderUtil::MergeVisibleAdvancedDirtyRegion(
112         curAllSurfaceDrawables, RSUniRenderThread::Instance().GetDrawStatusVec());
113     if (uniParam->GetAdvancedDirtyType() == AdvancedDirtyRegionType::DISABLED &&
114         !uniParam->IsDirtyAlignEnabled()) {
115         MergeDirtyRectAfterMergeHistory(dirtyManager, dirtyRegion);
116     }
117     RectI screenRectI(0, 0, static_cast<int32_t>(screenInfo.phyWidth), static_cast<int32_t>(screenInfo.phyHeight));
118 #ifdef RS_ENABLE_OVERLAY_DISPLAY
119     // overlay display expand dirty region
120     RSOverlayDisplayManager::Instance().ExpandDirtyRegion(*dirtyManager, screenInfo, dirtyRegion);
121 #endif
122     Occlusion::Region globalDirtyRegion;
123     for (const auto& rect : dirtyManager->GetAdvancedDirtyRegion()) {
124         Occlusion::Region region = Occlusion::Region(Occlusion::Rect(rect));
125         globalDirtyRegion.OrSelf(region);
126         GpuDirtyRegionCollection::GetInstance().UpdateGlobalDirtyInfoForDFX(rect.IntersectRect(screenRectI));
127     }
128     Occlusion::Region damageRegion;
129     switch (uniParam->GetAdvancedDirtyType()) {
130         case AdvancedDirtyRegionType::DISABLED:
131             damageRegion = dirtyRegion.Or(globalDirtyRegion);
132             break;
133         case AdvancedDirtyRegionType::SET_ADVANCED_SURFACE_AND_DISPLAY:
134             damageRegion = RSUniRenderUtil::MergeDirtyRects(dirtyRegion.Or(globalDirtyRegion));
135             break;
136         case AdvancedDirtyRegionType::SET_ADVANCED_DISPLAY:
137             damageRegion = RSUniRenderUtil::MergeDirtyRects(globalDirtyRegion);
138             damageRegion.OrSelf(dirtyRegion);
139             break;
140         default:
141             damageRegion = dirtyRegion.Or(globalDirtyRegion);
142             RS_LOGI("RSUniRenderUtil::MergeDirtyHistory unsupported advanced dirty region type");
143             RS_TRACE_NAME_FMT("RSUniRenderUtil::MergeDirtyHistory unsupported advanced dirty region type");
144             break;
145     }
146     Occlusion::Region drawnRegion;
147     if (screenInfo.isSamplingOn && screenInfo.samplingScale > 0) {
148         GetSampledDamageAndDrawnRegion(screenInfo, damageRegion, uniParam->IsDirtyAlignEnabled(),
149             damageRegion, drawnRegion);
150     } else {
151         drawnRegion = uniParam->IsDirtyAlignEnabled() ?
152             damageRegion.GetAlignedRegion(MAX_DIRTY_ALIGNMENT_SIZE) : damageRegion;
153     }
154     RSUniRenderUtil::SetDrawRegionForQuickReject(curAllSurfaceDrawables, drawnRegion);
155     rsDirtyRectsDfx.SetDirtyRegion(drawnRegion);
156     auto damageRegionRects = RSUniRenderUtil::ScreenIntersectDirtyRects(damageRegion, screenInfo);
157     if (damageRegionRects.empty()) {
158         // When damageRegionRects is empty, SetDamageRegion function will not take effect and buffer will
159         // full screen refresh. Therefore, we need to insert an empty rect into the damageRegionRects array
160         damageRegionRects.emplace_back(RectI(0, 0, 0, 0));
161     }
162     return damageRegionRects;
163 }
164 
MergeDirtyHistoryInVirtual(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,int32_t bufferAge,ScreenInfo & screenInfo)165 std::vector<RectI> RSUniRenderUtil::MergeDirtyHistoryInVirtual(
166     DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable, int32_t bufferAge, ScreenInfo& screenInfo)
167 {
168     auto params = static_cast<RSDisplayRenderParams*>(displayDrawable.GetRenderParams().get());
169     auto& renderThreadParams = RSUniRenderThread::Instance().GetRSRenderThreadParams();
170     if (!renderThreadParams || !params) {
171         return {};
172     }
173     auto& curAllSurfaceDrawables = params->GetAllMainAndLeashSurfaceDrawables();
174     auto dirtyManager = displayDrawable.GetSyncDirtyManager();
175     RSUniRenderUtil::MergeDirtyHistoryInVirtual(displayDrawable, bufferAge);
176     Occlusion::Region dirtyRegion = RSUniRenderUtil::MergeVisibleDirtyRegionInVirtual(curAllSurfaceDrawables);
177 
178     RectI rect = dirtyManager->GetRectFlipWithinSurface(dirtyManager->GetDirtyRegionInVirtual());
179     auto rects = RSUniRenderUtil::ScreenIntersectDirtyRects(dirtyRegion, screenInfo);
180     if (!rect.IsEmpty()) {
181         rects.emplace_back(rect);
182     }
183     if (screenInfo.isSamplingOn && screenInfo.samplingScale > 0) {
184         std::vector<RectI> dstDamageRegionrects;
185         for (const auto& rect : rects) {
186             Drawing::Matrix scaleMatrix;
187             scaleMatrix.SetScaleTranslate(screenInfo.samplingScale, screenInfo.samplingScale,
188                 screenInfo.samplingTranslateX, screenInfo.samplingTranslateY);
189             RectI mappedRect = RSObjAbsGeometry::MapRect(rect.ConvertTo<float>(), scaleMatrix);
190             const Vector4<int> expandSize{screenInfo.samplingDistance, screenInfo.samplingDistance,
191                 screenInfo.samplingDistance, screenInfo.samplingDistance};
192             dstDamageRegionrects.emplace_back(mappedRect.MakeOutset(expandSize));
193         }
194         return dstDamageRegionrects;
195     }
196     return rects;
197 }
198 
MergeDirtyHistoryForDrawable(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,int32_t bufferAge,RSDisplayRenderParams & params,bool useAlignedDirtyRegion)199 void RSUniRenderUtil::MergeDirtyHistoryForDrawable(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable,
200     int32_t bufferAge, RSDisplayRenderParams& params, bool useAlignedDirtyRegion)
201 {
202     auto& curAllSurfaceDrawables = params.GetAllMainAndLeashSurfaceDrawables();
203     // update all child surfacenode history
204     for (auto it = curAllSurfaceDrawables.rbegin(); it != curAllSurfaceDrawables.rend(); ++it) {
205         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
206         if (surfaceNodeDrawable == nullptr) {
207             continue;
208         }
209         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
210         if (surfaceParams == nullptr || !surfaceParams->IsAppWindow()) {
211             continue;
212         }
213         // for cross-display surface, only merge dirty history once.
214         if (surfaceParams->IsFirstLevelCrossNode() && !params.IsFirstVisitCrossNodeDisplay()) {
215             continue;
216         }
217         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
218         if (surfaceDirtyManager == nullptr) {
219             continue;
220         }
221         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderUtil::MergeDirtyHistory for surfaceNode %" PRIu64"",
222             surfaceParams->GetId());
223         if (!surfaceDirtyManager->SetBufferAge(bufferAge)) {
224             ROSEN_LOGW("RSUniRenderUtil::MergeDirtyHistory with invalid buffer age %{public}d", bufferAge);
225         }
226         surfaceDirtyManager->IntersectDirtyRect(surfaceParams->GetOldDirtyInSurface());
227         surfaceDirtyManager->UpdateDirty(useAlignedDirtyRegion);
228     }
229 
230     // update display dirtymanager
231     if (auto dirtyManager = displayDrawable.GetSyncDirtyManager()) {
232         dirtyManager->SetBufferAge(bufferAge);
233         dirtyManager->UpdateDirty(useAlignedDirtyRegion);
234     }
235 }
236 
MergeVisibleDirtyRegion(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceNodeDrawables,std::vector<NodeId> & hasVisibleDirtyRegionSurfaceVec,bool useAlignedDirtyRegion)237 Occlusion::Region RSUniRenderUtil::MergeVisibleDirtyRegion(
238     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceNodeDrawables,
239     std::vector<NodeId>& hasVisibleDirtyRegionSurfaceVec, bool useAlignedDirtyRegion)
240 {
241     Occlusion::Region allSurfaceVisibleDirtyRegion;
242     for (auto it = allSurfaceNodeDrawables.rbegin(); it != allSurfaceNodeDrawables.rend(); ++it) {
243         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
244         if (surfaceNodeDrawable == nullptr) {
245             RS_LOGI("MergeVisibleDirtyRegion surfaceNodeDrawable is nullptr");
246             continue;
247         }
248         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
249         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
250         if (!surfaceParams || !surfaceDirtyManager) {
251             RS_LOGI("RSUniRenderUtil::MergeVisibleDirtyRegion node(%{public}" PRIu64") params or "
252                 "dirty manager is nullptr", surfaceNodeDrawable->GetId());
253             continue;
254         }
255         if (!surfaceParams->IsAppWindow() || surfaceParams->GetDstRect().IsEmpty()) {
256             continue;
257         }
258         // for cross-display surface, only consider the dirty region on the first display (use global dirty for others).
259         if (surfaceParams->IsFirstLevelCrossNode() &&
260             !RSUniRenderThread::Instance().GetRSRenderThreadParams()->IsFirstVisitCrossNodeDisplay()) {
261             continue;
262         }
263         auto surfaceDirtyRect = surfaceDirtyManager->GetDirtyRegion();
264         Occlusion::Rect dirtyRect { surfaceDirtyRect.left_, surfaceDirtyRect.top_, surfaceDirtyRect.GetRight(),
265             surfaceDirtyRect.GetBottom() };
266         auto visibleRegion = surfaceParams->GetVisibleRegion();
267         Occlusion::Region surfaceDirtyRegion { dirtyRect };
268         Occlusion::Region surfaceVisibleDirtyRegion = surfaceDirtyRegion.And(visibleRegion);
269 
270         surfaceNodeDrawable->SetVisibleDirtyRegion(surfaceVisibleDirtyRegion);
271         if (!surfaceVisibleDirtyRegion.IsEmpty()) {
272             hasVisibleDirtyRegionSurfaceVec.emplace_back(surfaceParams->GetId());
273         }
274         if (useAlignedDirtyRegion) {
275             Occlusion::Region alignedRegion = AlignedDirtyRegion(surfaceVisibleDirtyRegion);
276             surfaceNodeDrawable->SetAlignedVisibleDirtyRegion(alignedRegion);
277             allSurfaceVisibleDirtyRegion.OrSelf(alignedRegion);
278             GpuDirtyRegionCollection::GetInstance().UpdateActiveDirtyInfoForDFX(surfaceParams->GetId(),
279                 surfaceNodeDrawable->GetName(), alignedRegion.GetRegionRectIs());
280         } else {
281             allSurfaceVisibleDirtyRegion = allSurfaceVisibleDirtyRegion.Or(surfaceVisibleDirtyRegion);
282             GpuDirtyRegionCollection::GetInstance().UpdateActiveDirtyInfoForDFX(surfaceParams->GetId(),
283                 surfaceNodeDrawable->GetName(), surfaceVisibleDirtyRegion.GetRegionRectIs());
284         }
285     }
286     return allSurfaceVisibleDirtyRegion;
287 }
288 
MergeVisibleAdvancedDirtyRegion(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceNodeDrawables,std::vector<NodeId> & hasVisibleDirtyRegionSurfaceVec)289 Occlusion::Region RSUniRenderUtil::MergeVisibleAdvancedDirtyRegion(
290     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceNodeDrawables,
291     std::vector<NodeId>& hasVisibleDirtyRegionSurfaceVec)
292 {
293     Occlusion::Region allSurfaceVisibleDirtyRegion;
294     for (auto it = allSurfaceNodeDrawables.rbegin(); it != allSurfaceNodeDrawables.rend(); ++it) {
295         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
296         if (surfaceNodeDrawable == nullptr) {
297             RS_LOGI("RSUniRenderUtil::MergeVisibleDirtyRegion surfaceNodeDrawable is nullptr");
298             continue;
299         }
300         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
301         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
302         if (!surfaceParams || !surfaceDirtyManager) {
303             RS_LOGI("RSUniRenderUtil::MergeVisibleDirtyRegion node(%{public}" PRIu64") params or"
304                 "dirty manager is nullptr", surfaceNodeDrawable->GetId());
305             continue;
306         }
307         if (!surfaceParams->IsAppWindow() || surfaceParams->GetDstRect().IsEmpty()) {
308             continue;
309         }
310         //for cross-display surface, only consider the dirty region on the first display (use global dirty for others).
311         if (surfaceParams->IsFirstLevelCrossNode() &&
312             !RSUniRenderThread::Instance().GetRSRenderThreadParams()->IsFirstVisitCrossNodeDisplay()) {
313             continue;
314         }
315         Occlusion::Region surfaceAdvancedDirtyRegion = Occlusion::Region();
316         for (const auto& rect : surfaceDirtyManager->GetAdvancedDirtyRegion()) {
317             Occlusion::Region region = Occlusion::Region(Occlusion::Rect(rect));
318             surfaceAdvancedDirtyRegion.OrSelf(region);
319         }
320         auto visibleRegion = surfaceParams->GetVisibleRegion();
321         Occlusion::Region surfaceVisibleDirtyRegion = surfaceAdvancedDirtyRegion.And(visibleRegion);
322         surfaceNodeDrawable->SetVisibleDirtyRegion(surfaceVisibleDirtyRegion);
323         if (!surfaceVisibleDirtyRegion.IsEmpty()) {
324             hasVisibleDirtyRegionSurfaceVec.emplace_back(surfaceParams->GetId());
325         }
326         allSurfaceVisibleDirtyRegion = allSurfaceVisibleDirtyRegion.Or(surfaceVisibleDirtyRegion);
327         GpuDirtyRegionCollection::GetInstance().UpdateActiveDirtyInfoForDFX(surfaceParams->GetId(),
328             surfaceNodeDrawable->GetName(), surfaceVisibleDirtyRegion.GetRegionRectIs());
329     }
330     return allSurfaceVisibleDirtyRegion;
331 }
332 
MergeDirtyRects(Occlusion::Region dirtyRegion)333 Occlusion::Region RSUniRenderUtil::MergeDirtyRects(Occlusion::Region dirtyRegion)
334 {
335     RectsMerger merger(RSAdvancedDirtyConfig::RECT_NUM_MERGING_ALL, RSAdvancedDirtyConfig::RECT_NUM_MERGING_BY_LEVEL);
336     auto mergedRects = merger.MergeAllRects(dirtyRegion.GetRegionRects(),
337         RSAdvancedDirtyConfig::EXPECTED_OUTPUT_NUM, RSAdvancedDirtyConfig::MAX_TOLERABLE_COST);
338     Occlusion::Region results = {};
339     for (const auto& rect : mergedRects) {
340         Occlusion::Region region = Occlusion::Region(rect);
341         results.OrSelf(region);
342     }
343     return results;
344 }
345 
SetDrawRegionForQuickReject(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceDrawables,const Occlusion::Region mergedDirtyRects)346 void RSUniRenderUtil::SetDrawRegionForQuickReject(
347     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceDrawables,
348     const Occlusion::Region mergedDirtyRects)
349 {
350     auto rectsForQuickReject = mergedDirtyRects.GetRegionRectIs();
351     for (const auto& rect : mergedDirtyRects.GetRegionRects()) {
352         rectsForQuickReject.push_back(rect.ToRectI());
353     }
354     for (auto it = allSurfaceDrawables.rbegin(); it != allSurfaceDrawables.rend(); ++it) {
355         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
356         if (surfaceNodeDrawable == nullptr) {
357             continue;
358         }
359         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
360         if (!surfaceParams || !surfaceParams->IsMainWindowType()) {
361             continue;
362         }
363         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
364         if (surfaceDirtyManager == nullptr) {
365             continue;
366         }
367         surfaceDirtyManager->SetDirtyRegionForQuickReject(rectsForQuickReject);
368     }
369 }
370 
MergeDirtyHistoryInVirtual(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,int32_t bufferAge,bool renderParallel)371 void RSUniRenderUtil::MergeDirtyHistoryInVirtual(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable,
372     int32_t bufferAge, bool renderParallel)
373 {
374     (void)renderParallel;
375     auto& params = displayDrawable.GetRenderParams();
376     if (!params) {
377         RS_LOGE("RSUniRenderUtil::MergeDirtyHistory params is nullptr");
378         return;
379     }
380     auto& curAllSurfaceDrawables = params->GetAllMainAndLeashSurfaceDrawables();
381     for (auto it = curAllSurfaceDrawables.rbegin(); it != curAllSurfaceDrawables.rend(); ++it) {
382         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
383         if (surfaceNodeDrawable == nullptr) {
384             continue;
385         }
386         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
387         if (surfaceParams == nullptr || !surfaceParams->IsAppWindow()) {
388             continue;
389         }
390         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderUtil::MergeDirtyHistory for surfaceNode %" PRIu64"",
391             surfaceParams->GetId());
392         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
393         surfaceDirtyManager->MergeDirtyHistoryInVirtual(bufferAge);
394     }
395     // update display dirtymanager
396     auto displayDirtyManager = displayDrawable.GetSyncDirtyManager();
397     displayDirtyManager->MergeDirtyHistoryInVirtual(bufferAge);
398 }
399 
MergeVisibleDirtyRegionInVirtual(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceNodeDrawables)400 Occlusion::Region RSUniRenderUtil::MergeVisibleDirtyRegionInVirtual(
401     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceNodeDrawables)
402 {
403     Occlusion::Region allSurfaceVisibleDirtyRegion;
404     for (auto it = allSurfaceNodeDrawables.rbegin(); it != allSurfaceNodeDrawables.rend(); ++it) {
405         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
406         if (surfaceNodeDrawable == nullptr) {
407             RS_LOGI("MergeVisibleDirtyRegion surfaceNodeDrawable is nullptr");
408             continue;
409         }
410         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
411         if (!surfaceParams) {
412             RS_LOGI("RSUniRenderUtil::MergeVisibleDirtyRegion surface params is nullptr");
413             continue;
414         }
415         if (!surfaceParams->IsAppWindow() || surfaceParams->GetDstRect().IsEmpty() ||
416             surfaceParams->GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos ||
417             surfaceParams->GetSpecialLayerMgr().Find(SpecialLayerType::SKIP)) {
418             continue;
419         }
420         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
421         auto surfaceDirtyRect = surfaceDirtyManager->GetDirtyRegionInVirtual();
422         Occlusion::Rect dirtyRect { surfaceDirtyRect.left_, surfaceDirtyRect.top_,
423             surfaceDirtyRect.GetRight(), surfaceDirtyRect.GetBottom() };
424         auto visibleRegion = surfaceParams->GetVisibleRegionInVirtual();
425         Occlusion::Region surfaceDirtyRegion { dirtyRect };
426         Occlusion::Region surfaceVisibleDirtyRegion = surfaceDirtyRegion.And(visibleRegion);
427         allSurfaceVisibleDirtyRegion = allSurfaceVisibleDirtyRegion.Or(surfaceVisibleDirtyRegion);
428     }
429     return allSurfaceVisibleDirtyRegion;
430 }
431 
GetCurrentFrameVisibleDirty(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,ScreenInfo & screenInfo,RSDisplayRenderParams & params)432 std::vector<RectI> RSUniRenderUtil::GetCurrentFrameVisibleDirty(
433     DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable, ScreenInfo& screenInfo, RSDisplayRenderParams& params)
434 {
435     Occlusion::Region damageRegions;
436     auto& curAllSurfaceDrawables = params.GetAllMainAndLeashSurfaceDrawables();
437     // update all child surfacenode history
438     for (auto it = curAllSurfaceDrawables.rbegin(); it != curAllSurfaceDrawables.rend(); ++it) {
439         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
440         if (surfaceNodeDrawable == nullptr) {
441             RS_LOGI("GetCurrentFrameVisibleDirty surfaceNodeDrawable is nullptr");
442             continue;
443         }
444         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
445         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
446         if (!surfaceParams || !surfaceDirtyManager) {
447             RS_LOGI("RSUniRenderUtil::GetCurrentFrameVisibleDirty node(%{public}" PRIu64") params or "
448                 "dirty manager is nullptr", surfaceNodeDrawable->GetId());
449             continue;
450         }
451         if (!surfaceParams->IsAppWindow() || surfaceParams->GetDstRect().IsEmpty()) {
452             continue;
453         }
454         // for cross-display surface, only consider the dirty region on the first display (use global dirty for others).
455         if (surfaceParams->IsFirstLevelCrossNode() &&
456             !RSUniRenderThread::Instance().GetRSRenderThreadParams()->IsFirstVisitCrossNodeDisplay()) {
457             continue;
458         }
459         auto visibleRegion = surfaceParams->GetVisibleRegion();
460         auto surfaceCurrentFrameDirtyRegion = surfaceDirtyManager->GetCurrentFrameDirtyRegion();
461         Occlusion::Region currentFrameDirtyRegion { Occlusion::Rect {
462             surfaceCurrentFrameDirtyRegion.left_, surfaceCurrentFrameDirtyRegion.top_,
463             surfaceCurrentFrameDirtyRegion.GetRight(), surfaceCurrentFrameDirtyRegion.GetBottom() } };
464         Occlusion::Region damageRegion = currentFrameDirtyRegion.And(visibleRegion);
465         damageRegions.OrSelf(damageRegion);
466     }
467     auto rects = RSUniRenderUtil::ScreenIntersectDirtyRects(damageRegions, screenInfo);
468     RectI rect = displayDrawable.GetSyncDirtyManager()->GetDirtyRegionFlipWithinSurface();
469     if (!rect.IsEmpty()) {
470         rects.emplace_back(rect);
471     }
472     return rects;
473 }
474 
SetAllSurfaceDrawableGlobalDirtyRegion(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceDrawables,const Occlusion::Region & globalDirtyRegion)475 void RSUniRenderUtil::SetAllSurfaceDrawableGlobalDirtyRegion(
476     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceDrawables,
477     const Occlusion::Region& globalDirtyRegion)
478 {
479     // Set Surface Global Dirty Region
480     for (auto it = allSurfaceDrawables.rbegin(); it != allSurfaceDrawables.rend(); ++it) {
481         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
482         if (surfaceNodeDrawable == nullptr) {
483             continue;
484         }
485         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
486         if (!surfaceParams) {
487             RS_LOGW("RSUniRenderUtil::MergeVisibleDirtyRegion surface params is nullptr");
488             continue;
489         }
490         if (!surfaceParams->IsMainWindowType()) {
491             continue;
492         }
493         // set display dirty region to surfaceNodeDrawable
494         surfaceNodeDrawable->SetGlobalDirtyRegion(globalDirtyRegion);
495         surfaceNodeDrawable->SetDirtyRegionAlignedEnable(false);
496     }
497     Occlusion::Region curVisibleDirtyRegion;
498     for (auto& it : allSurfaceDrawables) {
499         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(it);
500         if (surfaceNodeDrawable == nullptr) {
501             continue;
502         }
503         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
504         if (!surfaceParams) {
505             RS_LOGE("RSUniRenderUtil::MergeVisibleDirtyRegion surface params is nullptr");
506             continue;
507         }
508         if (!surfaceParams->IsMainWindowType()) {
509             continue;
510         }
511         // set display dirty region to surfaceNodeDrawable
512         surfaceNodeDrawable->SetDirtyRegionBelowCurrentLayer(curVisibleDirtyRegion);
513         auto visibleDirtyRegion = surfaceNodeDrawable->GetVisibleDirtyRegion();
514         curVisibleDirtyRegion = curVisibleDirtyRegion.Or(visibleDirtyRegion);
515     }
516 }
517 
ScreenIntersectDirtyRects(const Occlusion::Region & region,ScreenInfo & screenInfo)518 std::vector<RectI> RSUniRenderUtil::ScreenIntersectDirtyRects(const Occlusion::Region &region, ScreenInfo& screenInfo)
519 {
520     const std::vector<Occlusion::Rect>& rects = region.GetRegionRects();
521     std::vector<RectI> retRects;
522     for (const Occlusion::Rect& rect : rects) {
523         // origin transformation
524 #ifdef RS_ENABLE_VK
525         if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
526             RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
527             retRects.emplace_back(RectI(rect.left_, rect.top_,
528                 rect.right_ - rect.left_, rect.bottom_ - rect.top_));
529         } else {
530             retRects.emplace_back(RectI(rect.left_, screenInfo.GetRotatedHeight() - rect.bottom_,
531                 rect.right_ - rect.left_, rect.bottom_ - rect.top_));
532         }
533 #else
534         retRects.emplace_back(RectI(rect.left_, screenInfo.GetRotatedHeight() - rect.bottom_,
535             rect.right_ - rect.left_, rect.bottom_ - rect.top_));
536 #endif
537     }
538     RS_LOGD("ScreenIntersectDirtyRects size %{public}d %{public}s", region.GetSize(), region.GetRegionInfo().c_str());
539     return retRects;
540 }
541 
GetFilpDirtyRects(const std::vector<RectI> & srcRects,const ScreenInfo & screenInfo)542 std::vector<RectI> RSUniRenderUtil::GetFilpDirtyRects(const std::vector<RectI>& srcRects, const ScreenInfo& screenInfo)
543 {
544 #ifdef RS_ENABLE_VK
545     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
546         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
547         return srcRects;
548     }
549 #endif
550 
551     return FilpRects(srcRects, screenInfo);
552 }
553 
FilpRects(const std::vector<RectI> & srcRects,const ScreenInfo & screenInfo)554 std::vector<RectI> RSUniRenderUtil::FilpRects(const std::vector<RectI>& srcRects, const ScreenInfo& screenInfo)
555 {
556     std::vector<RectI> retRects;
557     for (const RectI& rect : srcRects) {
558         retRects.emplace_back(RectI(rect.left_, screenInfo.GetRotatedHeight() - rect.top_ - rect.height_,
559             rect.width_, rect.height_));
560     }
561     return retRects;
562 }
563 
IntersectRect(const GraphicIRect & first,const GraphicIRect & second)564 GraphicIRect RSUniRenderUtil::IntersectRect(const GraphicIRect& first, const GraphicIRect& second)
565 {
566     int left = std::max(first.x, second.x);
567     int top = std::max(first.y, second.y);
568     int right = std::min(first.x + first.w, second.x + second.w);
569     int bottom = std::min(first.y + first.h, second.y + second.h);
570     int width = right - left;
571     int height = bottom - top;
572 
573     if (width <= 0 || height <= 0) {
574         return GraphicIRect { 0, 0, 0, 0 };
575     } else {
576         return GraphicIRect { left, top, width, height };
577     }
578 }
579 
SrcRectScaleFit(BufferDrawParam & params,const sptr<SurfaceBuffer> & buffer,const sptr<IConsumerSurface> & surface,RectF & localBounds)580 void RSUniRenderUtil::SrcRectScaleFit(BufferDrawParam& params, const sptr<SurfaceBuffer>& buffer,
581     const sptr<IConsumerSurface>& surface, RectF& localBounds)
582 {
583     if (buffer == nullptr || surface == nullptr) {
584         RS_LOGE("buffer or surface is nullptr");
585         return;
586     }
587     uint32_t srcWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
588     uint32_t srcHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
589     float newWidth = 0.0f;
590     float newHeight = 0.0f;
591     // Canvas is able to handle the situation when the window is out of screen, using bounds instead of dst.
592     uint32_t boundsWidth = static_cast<uint32_t>(localBounds.GetWidth());
593     uint32_t boundsHeight = static_cast<uint32_t>(localBounds.GetHeight());
594     if (boundsWidth == 0 || boundsHeight == 0 || srcWidth == 0 || srcHeight == 0) {
595         return;
596     }
597 
598     if (srcWidth * boundsHeight > srcHeight * boundsWidth) {
599         newWidth = boundsWidth;
600         newHeight = srcHeight * newWidth / srcWidth;
601     } else if (srcWidth * boundsHeight < srcHeight * boundsWidth) {
602         newHeight = boundsHeight;
603         newWidth = newHeight * srcWidth / srcHeight;
604     } else {
605         newWidth = boundsWidth;
606         newHeight = boundsHeight;
607     }
608     newHeight = newHeight * srcHeight / boundsHeight;
609     newWidth = newWidth * srcWidth / boundsWidth;
610     if (newWidth < srcWidth) {
611         float halfdw = (srcWidth - newWidth) / 2;
612         params.dstRect =
613             Drawing::Rect(params.srcRect.GetLeft() + halfdw, params.srcRect.GetTop(),
614                 params.srcRect.GetLeft() + halfdw + newWidth,
615                 params.srcRect.GetTop() + params.srcRect.GetHeight());
616     } else if (newHeight < srcHeight) {
617         float halfdh = (srcHeight - newHeight) / 2;
618         params.dstRect =
619             Drawing::Rect(params.srcRect.GetLeft(), params.srcRect.GetTop() + halfdh,
620                 params.srcRect.GetLeft() + params.srcRect.GetWidth(),
621                 params.srcRect.GetTop() + halfdh + newHeight);
622     }
623     RS_LOGD("RsDebug RSUniRenderUtil::SrcRectScaleFit name:%{public}s,"
624         " dstRect [%{public}f %{public}f %{public}f %{public}f]",
625         surface->GetName().c_str(), params.dstRect.GetLeft(), params.dstRect.GetTop(),
626         params.dstRect.GetWidth(), params.dstRect.GetHeight());
627 }
628 
SrcRectScaleDown(BufferDrawParam & params,const sptr<SurfaceBuffer> & buffer,const sptr<IConsumerSurface> & surface,RectF & localBounds)629 void RSUniRenderUtil::SrcRectScaleDown(BufferDrawParam& params, const sptr<SurfaceBuffer>& buffer,
630     const sptr<IConsumerSurface>& surface, RectF& localBounds)
631 {
632     if (buffer == nullptr || surface == nullptr) {
633         return;
634     }
635     // Canvas is able to handle the situation when the window is out of screen, using bounds instead of dst.
636     uint32_t boundsWidth = static_cast<uint32_t>(localBounds.GetWidth());
637     uint32_t boundsHeight = static_cast<uint32_t>(localBounds.GetHeight());
638     if (boundsWidth == 0 || boundsHeight == 0) {
639         RS_LOGE("RSUniRenderUtil::SrcRectScaleDown: boundsWidth or boundsHeight is 0");
640         return;
641     }
642     uint32_t newWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
643     uint32_t newHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
644 
645     uint32_t newWidthBoundsHeight = newWidth * boundsHeight;
646     uint32_t newHeightBoundsWidth = newHeight * boundsWidth;
647 
648     if (newWidthBoundsHeight > newHeightBoundsWidth) {
649         newWidth = boundsWidth * newHeight / boundsHeight;
650     } else if (newWidthBoundsHeight < newHeightBoundsWidth) {
651         newHeight = boundsHeight * newWidth / boundsWidth;
652     } else {
653         return;
654     }
655 
656     uint32_t currentWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
657     uint32_t currentHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
658     if (newWidth < currentWidth) {
659         // the crop is too wide
660         uint32_t dw = currentWidth - newWidth;
661         auto halfdw = dw / 2;
662         params.srcRect =
663             Drawing::Rect(params.srcRect.GetLeft() + static_cast<int32_t>(halfdw), params.srcRect.GetTop(),
664                 params.srcRect.GetLeft() + static_cast<int32_t>(halfdw) + static_cast<int32_t>(newWidth),
665                 params.srcRect.GetTop() + params.srcRect.GetHeight());
666     } else {
667         // thr crop is too tall
668         uint32_t dh = currentHeight - newHeight;
669         auto halfdh = dh / 2;
670         params.srcRect =
671             Drawing::Rect(params.srcRect.GetLeft(), params.srcRect.GetTop() + static_cast<int32_t>(halfdh),
672                 params.srcRect.GetLeft() + params.srcRect.GetWidth(),
673                 params.srcRect.GetTop() + static_cast<int32_t>(halfdh) + static_cast<int32_t>(newHeight));
674     }
675     RS_LOGD("RsDebug RSUniRenderUtil::SrcRectScaleDown name:%{public}s,"
676         " srcRect [%{public}f %{public}f %{public}f %{public}f]",
677         surface->GetName().c_str(), params.srcRect.GetLeft(), params.srcRect.GetTop(),
678         params.srcRect.GetWidth(), params.srcRect.GetHeight());
679 }
680 
SetSrcRect(BufferDrawParam & params,const sptr<SurfaceBuffer> & buffer)681 void RSUniRenderUtil::SetSrcRect(BufferDrawParam& params, const sptr<SurfaceBuffer>& buffer)
682 {
683     Rect crop = {0, 0, 0, 0};
684     params.hasCropMetadata = buffer->GetCropMetadata(crop);
685 
686     if (UNLIKELY(params.hasCropMetadata)) {
687         RS_LOGD("buffer has crop metadata, "
688             "left = %{public}u, right = %{public}u, width = %{public}u, height = %{public}u",
689             crop.x, crop.y, crop.w, crop.h);
690         params.srcRect = Drawing::Rect(crop.x, crop.y, crop.x + crop.w, crop.y + crop.h);
691     } else {
692         params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
693     }
694 }
695 
GetMatrixOfBufferToRelRect(const RSSurfaceRenderNode & node)696 Drawing::Matrix RSUniRenderUtil::GetMatrixOfBufferToRelRect(const RSSurfaceRenderNode& node)
697 {
698     const sptr<SurfaceBuffer> buffer = node.GetRSSurfaceHandler()->GetBuffer();
699     if (buffer == nullptr) {
700         return Drawing::Matrix();
701     }
702 
703     auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
704     if (consumer == nullptr) {
705         return Drawing::Matrix();
706     }
707 
708     BufferDrawParam params;
709     params.buffer = buffer;
710     params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
711     const RSProperties& property = node.GetRenderProperties();
712     params.dstRect = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
713     auto transform = RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, buffer);
714     RectF localBounds = { 0.0f, 0.0f, property.GetBoundsWidth(), property.GetBoundsHeight() };
715     auto& renderParams = const_cast<RSSurfaceRenderNode&>(node).GetStagingRenderParams();
716     auto surfaceRenderParams = renderParams == nullptr
717                             ? nullptr
718                             : static_cast<RSSurfaceRenderParams*>(renderParams.get());
719     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, property.GetFrameGravity(), localBounds, params,
720         surfaceRenderParams);
721     RSBaseRenderUtil::FlipMatrix(transform, params);
722     return params.matrix;
723 }
724 
CreateBufferDrawParam(const RSSurfaceRenderNode & node,bool forceCPU,uint32_t threadIndex,bool useRenderParams)725 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(
726     const RSSurfaceRenderNode& node, bool forceCPU, uint32_t threadIndex, bool useRenderParams)
727 {
728     BufferDrawParam params;
729 
730     auto drawable = node.GetRenderDrawable();
731     if (useRenderParams && !drawable) {
732         return params;
733     }
734     auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
735     auto& nodeParams = surfaceDrawable->GetRenderParams();
736     if (useRenderParams && !nodeParams) {
737         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam RenderThread nodeParams is nullptr");
738         return params;
739     }
740     auto surfaceHandler = node.GetRSSurfaceHandler();
741     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(nodeParams.get());
742     const RSProperties& property = node.GetRenderProperties();
743 
744     params.threadIndex = threadIndex;
745     params.useBilinearInterpolation = useRenderParams ?
746         surfaceParams->NeedBilinearInterpolation() : node.NeedBilinearInterpolation();
747     params.useCPU = forceCPU;
748     Drawing::Filter filter;
749     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
750     params.paint.SetFilter(filter);
751 
752     auto boundWidth = useRenderParams ? nodeParams->GetBounds().GetWidth() : property.GetBoundsWidth();
753     auto boundHeight = useRenderParams ? nodeParams->GetBounds().GetHeight() : property.GetBoundsHeight();
754     params.dstRect = Drawing::Rect(0, 0, boundWidth, boundHeight);
755 
756     const sptr<SurfaceBuffer> buffer = useRenderParams ? surfaceParams->GetBuffer() : surfaceHandler->GetBuffer();
757     if (buffer == nullptr) {
758         return params;
759     }
760     params.buffer = buffer;
761     params.acquireFence = useRenderParams ? nodeParams->GetAcquireFence() : surfaceHandler->GetAcquireFence();
762     SetSrcRect(params, buffer);
763     auto consumer = useRenderParams ? surfaceDrawable->GetConsumerOnDraw() : surfaceHandler->GetConsumer();
764     if (consumer == nullptr) {
765         return params;
766     }
767     auto transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
768     if (consumer->GetSurfaceBufferTransformType(buffer, &transform) != GSERROR_OK) {
769         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam GetSurfaceBufferTransformType failed");
770     }
771     RectF localBounds = { 0.0f, 0.0f, boundWidth, boundHeight };
772     auto gravity = useRenderParams ? nodeParams->GetFrameGravity() : property.GetFrameGravity();
773     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, gravity, localBounds, params, surfaceParams);
774     RSBaseRenderUtil::FlipMatrix(transform, params);
775     ScalingMode scalingMode = buffer->GetSurfaceBufferScalingMode();
776     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
777         SrcRectScaleDown(params, buffer, consumer, localBounds);
778     } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
779         SrcRectScaleFit(params, buffer, consumer, localBounds);
780     }
781     return params;
782 }
783 
CreateBufferDrawParam(const DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable,bool forceCPU,uint32_t threadIndex)784 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(
785     const DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, bool forceCPU, uint32_t threadIndex)
786 {
787     BufferDrawParam params;
788     auto& nodeParams = surfaceDrawable.GetRenderParams();
789     if (!nodeParams) {
790         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam RenderThread nodeParams is nullptr");
791         return params;
792     }
793     auto surfaceNodeParams = static_cast<RSSurfaceRenderParams*>(nodeParams.get());
794     params.threadIndex = threadIndex;
795     params.useBilinearInterpolation = surfaceNodeParams->NeedBilinearInterpolation();
796     params.useCPU = forceCPU;
797     Drawing::Filter filter;
798     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
799     params.paint.SetFilter(filter);
800 
801     auto boundWidth = nodeParams->GetBounds().GetWidth();
802     auto boundHeight = nodeParams->GetBounds().GetHeight();
803     params.dstRect = Drawing::Rect(0, 0, boundWidth, boundHeight);
804 
805     const sptr<SurfaceBuffer> buffer = nodeParams->GetBuffer();
806     if (buffer == nullptr) {
807         return params;
808     }
809     params.buffer = buffer;
810     params.acquireFence = nodeParams->GetAcquireFence();
811     SetSrcRect(params, buffer);
812     auto consumer = surfaceDrawable.GetConsumerOnDraw();
813     if (consumer == nullptr) {
814         return params;
815     }
816     auto transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
817     if (consumer->GetSurfaceBufferTransformType(buffer, &transform) != GSERROR_OK) {
818         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam GetSurfaceBufferTransformType failed");
819     }
820     params.preRotation = consumer->GetSurfaceAppFrameworkType() == "fixed-rotation" ? true : false;
821 
822     RectF localBounds = { 0.0f, 0.0f, boundWidth, boundHeight };
823     auto gravity = nodeParams->GetFrameGravity();
824     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, gravity, localBounds, params, surfaceNodeParams);
825     RSBaseRenderUtil::FlipMatrix(transform, params);
826     ScalingMode scalingMode = buffer->GetSurfaceBufferScalingMode();
827     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
828         SrcRectScaleDown(params, buffer, consumer, localBounds);
829     } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
830         SrcRectScaleFit(params, buffer, consumer, localBounds);
831     }
832     return params;
833 }
834 
CreateBufferDrawParamForRotationFixed(const DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable,RSSurfaceRenderParams & renderParams)835 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParamForRotationFixed(
836     const DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, RSSurfaceRenderParams& renderParams)
837 {
838     BufferDrawParam params;
839     params.threadIndex = static_cast<uint32_t>(gettid());
840     params.useBilinearInterpolation = renderParams.NeedBilinearInterpolation();
841     params.useCPU = false;
842     params.targetColorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
843 #ifdef USE_VIDEO_PROCESSING_ENGINE
844     params.sdrNits = renderParams.GetSdrNit();
845     params.tmoNits = renderParams.GetDisplayNit();
846     params.displayNits = params.tmoNits / std::pow(renderParams.GetBrightnessRatio(), GAMMA2_2); // gamma 2.2
847     params.layerLinearMatrix = renderParams.GetLayerLinearMatrix();
848 #endif
849 
850     Drawing::Filter filter;
851     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
852     params.paint.SetFilter(filter);
853 
854     auto buffer = renderParams.GetBuffer();
855     if (buffer == nullptr) {
856         return params;
857     }
858     params.buffer = buffer;
859     params.acquireFence = renderParams.GetAcquireFence();
860     auto srcRect = renderParams.GetLayerInfo().srcRect;
861     params.srcRect = Drawing::Rect(srcRect.x, srcRect.y, srcRect.x + srcRect.w, srcRect.y + srcRect.h);
862 
863     auto dstRect = renderParams.GetLayerInfo().dstRect;
864     params.matrix = Drawing::Matrix();
865     params.matrix.PreTranslate(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y));
866 
867     auto layerTransform = renderParams.GetLayerInfo().transformType;
868     int realRotation = RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(layerTransform));
869     auto flip = RSBaseRenderUtil::GetFlipTransform(layerTransform);
870     // calculate transform in anti-clockwise
871     auto transform = RSBaseRenderUtil::RotateEnumToInt(realRotation, flip);
872 
873     RectF localBounds = { 0.0f, 0.0f,
874         static_cast<float>(dstRect.w), static_cast<float>(dstRect.h) };
875     DealWithRotationAndGravityForRotationFixed(transform, renderParams.GetFrameGravity(), localBounds, params);
876     RSBaseRenderUtil::FlipMatrix(transform, params);
877     return params;
878 }
879 
DealWithRotationAndGravityForRotationFixed(GraphicTransformType transform,Gravity gravity,RectF & localBounds,BufferDrawParam & params)880 void RSUniRenderUtil::DealWithRotationAndGravityForRotationFixed(GraphicTransformType transform, Gravity gravity,
881     RectF& localBounds, BufferDrawParam& params)
882 {
883     auto rotationTransform = RSBaseRenderUtil::GetRotateTransform(transform);
884     params.matrix.PreConcat(RSBaseRenderUtil::GetSurfaceTransformMatrixForRotationFixed(
885         rotationTransform, localBounds));
886     if (rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_90 ||
887         rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_270) {
888         // after rotate, we should swap dstRect and bound's width and height.
889         std::swap(localBounds.width_, localBounds.height_);
890     }
891     params.dstRect = Drawing::Rect(0, 0, params.srcRect.GetWidth(), params.srcRect.GetHeight());
892 
893     Drawing::Matrix gravityMatrix;
894     if (!RSPropertiesPainter::GetGravityMatrix(gravity, localBounds,
895         params.srcRect.GetWidth(), params.srcRect.GetHeight(), gravityMatrix)) {
896         RS_LOGD("RSUniRenderUtil::DealWithRotationAndGravityForRotationFixed did not obtain gravity matrix.");
897     }
898     params.matrix.PreConcat(gravityMatrix);
899 }
900 
CreateBufferDrawParam(const RSDisplayRenderNode & node,bool forceCPU)901 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(const RSDisplayRenderNode& node, bool forceCPU)
902 {
903     BufferDrawParam params;
904     params.useCPU = forceCPU;
905     Drawing::Filter filter;
906     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
907     params.paint.SetFilter(filter);
908 
909     auto drawable = node.GetRenderDrawable();
910     if (!drawable) {
911         return params;
912     }
913     auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
914     auto surfaceHandler = displayDrawable->GetRSSurfaceHandlerOnDraw();
915     const sptr<SurfaceBuffer> buffer = surfaceHandler->GetBuffer();
916     if (!buffer) {
917         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam buffer is null.");
918         return params;
919     }
920     params.buffer = buffer;
921     params.acquireFence = surfaceHandler->GetAcquireFence();
922     SetSrcRect(params, buffer);
923     params.dstRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
924     return params;
925 }
926 
CreateBufferDrawParam(const RSSurfaceHandler & surfaceHandler,bool forceCPU)927 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(const RSSurfaceHandler& surfaceHandler, bool forceCPU)
928 {
929     BufferDrawParam bufferDrawParam;
930     bufferDrawParam.useCPU = forceCPU;
931     Drawing::Filter filter;
932     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
933     bufferDrawParam.paint.SetFilter(filter);
934 
935     const sptr<SurfaceBuffer> buffer = surfaceHandler.GetBuffer();
936     if (!buffer) {
937         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam buffer is null.");
938         return bufferDrawParam;
939     }
940     bufferDrawParam.buffer = buffer;
941     bufferDrawParam.acquireFence = surfaceHandler.GetAcquireFence();
942     SetSrcRect(bufferDrawParam, buffer);
943     bufferDrawParam.dstRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
944     return bufferDrawParam;
945 }
946 
CreateLayerBufferDrawParam(const LayerInfoPtr & layer,bool forceCPU)947 BufferDrawParam RSUniRenderUtil::CreateLayerBufferDrawParam(const LayerInfoPtr& layer, bool forceCPU)
948 {
949     BufferDrawParam params;
950     if (layer == nullptr) {
951         return params;
952     }
953     params.useCPU = forceCPU;
954     params.useBilinearInterpolation = layer->GetNeedBilinearInterpolation();
955     Drawing::Filter filter;
956     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
957     params.paint.SetFilter(filter);
958     params.paint.SetAlpha(layer->GetAlpha().gAlpha);
959     sptr<SurfaceBuffer> buffer = layer->GetBuffer();
960     if (buffer == nullptr) {
961         return params;
962     }
963     params.acquireFence = layer->GetAcquireFence();
964     params.buffer = buffer;
965     SetSrcRect(params, buffer);
966     auto boundRect = layer->GetBoundSize();
967     params.dstRect = Drawing::Rect(0, 0, boundRect.w, boundRect.h);
968 
969     auto layerMatrix = layer->GetMatrix();
970     params.matrix = Drawing::Matrix();
971     bool rotationFixed = layer->GetRotationFixed();
972     auto dstRect = layer->GetLayerSize();
973     if (rotationFixed) {
974         // if rotation fixed, not use [total matrix + bounds] to draw buffer, use [src + dst + transform]
975         params.matrix.PreTranslate(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y));
976         auto srcRect = layer->GetCropRect();
977         params.srcRect = Drawing::Rect(srcRect.x, srcRect.y, srcRect.x + srcRect.w, srcRect.y + srcRect.h);
978     } else {
979         params.matrix.SetMatrix(layerMatrix.scaleX, layerMatrix.skewX, layerMatrix.transX, layerMatrix.skewY,
980             layerMatrix.scaleY, layerMatrix.transY, layerMatrix.pers0, layerMatrix.pers1, layerMatrix.pers2);
981     }
982     // rotation degree anti-clockwise
983     int nodeRotation = rotationFixed ? 0 : RSUniRenderUtil::GetRotationFromMatrix(params.matrix);
984     auto layerTransform = layer->GetTransformType();
985     // calculate clockwise rotation degree excluded rotation in total matrix
986     int realRotation = (nodeRotation +
987         RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(layerTransform))) % 360;
988     auto flip = RSBaseRenderUtil::GetFlipTransform(layerTransform);
989     // calculate transform in anti-clockwise
990     auto transform = RSBaseRenderUtil::RotateEnumToInt(realRotation, flip);
991 
992     RectF localBounds = { 0.0f, 0.0f,
993         rotationFixed ? static_cast<float>(dstRect.w) : static_cast<float>(boundRect.w),
994         rotationFixed ? static_cast<float>(dstRect.h) : static_cast<float>(boundRect.h) };
995     if (rotationFixed) {
996         DealWithRotationAndGravityForRotationFixed(transform, static_cast<Gravity>(layer->GetGravity()), localBounds,
997             params);
998     } else {
999         RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, static_cast<Gravity>(layer->GetGravity()),
1000             localBounds, params);
1001     }
1002     RSBaseRenderUtil::FlipMatrix(transform, params);
1003     if (rotationFixed) {
1004         // if rotation fixed, no need to calculate scaling mode, it is contained in dstRect
1005         return params;
1006     }
1007     const auto& surface = layer->GetSurface();
1008     if (surface == nullptr) {
1009         RS_LOGE("buffer or surface is nullptr");
1010         return params;
1011     }
1012 
1013     ScalingMode scalingMode = buffer->GetSurfaceBufferScalingMode();
1014     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
1015         SrcRectScaleDown(params, buffer, surface, localBounds);
1016     } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
1017         SrcRectScaleFit(params, buffer, surface, localBounds);
1018     }
1019     return params;
1020 }
1021 
IsNeedClient(RSSurfaceRenderNode & node,const ComposeInfo & info)1022 bool RSUniRenderUtil::IsNeedClient(RSSurfaceRenderNode& node, const ComposeInfo& info)
1023 {
1024     if (RSSystemProperties::IsForceClient()) {
1025         RS_LOGD("RSUniRenderUtil::IsNeedClient: force client.");
1026         return true;
1027     }
1028     const auto& property = node.GetRenderProperties();
1029     if (!ROSEN_EQ(property.GetRotation(), 0.f) || !ROSEN_EQ(property.GetRotationX(), 0.f) ||
1030         !ROSEN_EQ(property.GetRotationY(), 0.f) || property.GetQuaternion() != Quaternion()) {
1031         RS_LOGD("RSUniRenderUtil::IsNeedClient need client with RSSurfaceRenderNode rotation");
1032         return true;
1033     }
1034     return false;
1035 }
1036 
AlignedDirtyRegion(const Occlusion::Region & dirtyRegion,int32_t alignedBits)1037 Occlusion::Region RSUniRenderUtil::AlignedDirtyRegion(const Occlusion::Region& dirtyRegion, int32_t alignedBits)
1038 {
1039     Occlusion::Region alignedRegion;
1040     if (alignedBits <= 1) {
1041         return dirtyRegion;
1042     }
1043     for (const auto& dirtyRect : dirtyRegion.GetRegionRects()) {
1044         int32_t left = (dirtyRect.left_ / alignedBits) * alignedBits;
1045         int32_t top = (dirtyRect.top_ / alignedBits) * alignedBits;
1046         int32_t width = ((dirtyRect.right_ + alignedBits - 1) / alignedBits) * alignedBits - left;
1047         int32_t height = ((dirtyRect.bottom_ + alignedBits - 1) / alignedBits) * alignedBits - top;
1048         Occlusion::Rect rect = { left, top, left + width, top + height };
1049         Occlusion::Region singleAlignedRegion(rect);
1050         alignedRegion.OrSelf(singleAlignedRegion);
1051     }
1052     return alignedRegion;
1053 }
1054 
TransferToAntiClockwiseDegrees(int angle)1055 int RSUniRenderUtil::TransferToAntiClockwiseDegrees(int angle)
1056 {
1057     static const std::map<int, int> supportedDegrees = { { 90, 270 }, { 180, 180 }, { -90, 90 }, { -180, 180 },
1058         { 270, 90 }, { -270, 270 } };
1059     auto iter = supportedDegrees.find(angle);
1060     return iter != supportedDegrees.end() ? iter->second : 0;
1061 }
1062 
GetRotationFromMatrix(Drawing::Matrix matrix)1063 int RSUniRenderUtil::GetRotationFromMatrix(Drawing::Matrix matrix)
1064 {
1065     Drawing::Matrix::Buffer value;
1066     matrix.GetAll(value);
1067 
1068     int rAngle = static_cast<int>(-round(atan2(value[Drawing::Matrix::Index::SKEW_X],
1069         value[Drawing::Matrix::Index::SCALE_X]) * (180 / PI)));
1070     // transfer the result to anti-clockwise degrees
1071     // only rotation with 90°, 180°, 270° are composed through hardware,
1072     // in which situation the transformation of the layer needs to be set.
1073     return TransferToAntiClockwiseDegrees(rAngle);
1074 }
1075 
GetRotationDegreeFromMatrix(Drawing::Matrix matrix)1076 int RSUniRenderUtil::GetRotationDegreeFromMatrix(Drawing::Matrix matrix)
1077 {
1078     Drawing::Matrix::Buffer value;
1079     matrix.GetAll(value);
1080     return static_cast<int>(-round(atan2(value[Drawing::Matrix::Index::SKEW_X],
1081         value[Drawing::Matrix::Index::SCALE_X]) * (RS_ROTATION_180 / PI)));
1082 }
1083 
GetFloatRotationDegreeFromMatrix(Drawing::Matrix matrix)1084 float RSUniRenderUtil::GetFloatRotationDegreeFromMatrix(Drawing::Matrix matrix)
1085 {
1086     Drawing::Matrix::Buffer value;
1087     matrix.GetAll(value);
1088     return atan2(value[Drawing::Matrix::Index::SKEW_X], value[Drawing::Matrix::Index::SCALE_X]) *
1089         (RS_ROTATION_180 / PI);
1090 }
1091 
HasNonZRotationTransform(Drawing::Matrix matrix)1092 bool RSUniRenderUtil::HasNonZRotationTransform(Drawing::Matrix matrix)
1093 {
1094     Drawing::Matrix::Buffer value;
1095     matrix.GetAll(value);
1096     if (!ROSEN_EQ(value[Drawing::Matrix::Index::PERSP_0], 0.f) ||
1097         !ROSEN_EQ(value[Drawing::Matrix::Index::PERSP_1], 0.f)) {
1098         return true;
1099     }
1100     int rotation = static_cast<int>(round(value[Drawing::Matrix::Index::SCALE_X] *
1101         value[Drawing::Matrix::Index::SKEW_Y] +
1102         value[Drawing::Matrix::Index::SCALE_Y] *
1103         value[Drawing::Matrix::Index::SKEW_X]));
1104     if (rotation != 0) {
1105         return true;
1106     }
1107     int vectorZ = value[Drawing::Matrix::Index::SCALE_X] * value[Drawing::Matrix::Index::SCALE_Y] -
1108         value[Drawing::Matrix::Index::SKEW_Y] * value[Drawing::Matrix::Index::SKEW_X];
1109     return vectorZ < 0;
1110 }
1111 
SortSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>> & subThreadNodes)1112 void RSUniRenderUtil::SortSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes)
1113 {
1114     // sort subThreadNodes by priority and z-order
1115     subThreadNodes.sort([](const auto& first, const auto& second) -> bool {
1116         auto node1 = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(first);
1117         auto node2 = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(second);
1118         if (node1 == nullptr || node2 == nullptr) {
1119             ROSEN_LOGE(
1120                 "RSUniRenderUtil::SortSubThreadNodes sort nullptr found in subThreadNodes, this should not happen");
1121             return false;
1122         }
1123         if (node1->GetPriority() == node2->GetPriority()) {
1124             return node2->GetRenderProperties().GetPositionZ() < node1->GetRenderProperties().GetPositionZ();
1125         } else {
1126             return node1->GetPriority() < node2->GetPriority();
1127         }
1128     });
1129 }
1130 
CacheSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>> & oldSubThreadNodes,std::list<std::shared_ptr<RSSurfaceRenderNode>> & subThreadNodes)1131 void RSUniRenderUtil::CacheSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>>& oldSubThreadNodes,
1132     std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes)
1133 {
1134     std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>> nodes(subThreadNodes.begin(), subThreadNodes.end());
1135     for (auto node : oldSubThreadNodes) {
1136         if (nodes.count(node) > 0) {
1137             continue;
1138         }
1139         // The node being processed by sub thread may have been removed.
1140         if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) {
1141             subThreadNodes.emplace_back(node);
1142         }
1143     }
1144     oldSubThreadNodes.clear();
1145     oldSubThreadNodes = subThreadNodes;
1146 }
1147 
HandleHardwareNode(const std::shared_ptr<RSSurfaceRenderNode> & node)1148 void RSUniRenderUtil::HandleHardwareNode(const std::shared_ptr<RSSurfaceRenderNode>& node)
1149 {
1150     if (node == nullptr || !node->HasHardwareNode()) {
1151         return;
1152     }
1153     auto appWindow = node;
1154     if (node->IsLeashWindow()) {
1155         for (auto& child : *node->GetSortedChildren()) {
1156             auto surfaceNodePtr = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1157             if (surfaceNodePtr && surfaceNodePtr->IsAppWindow()) {
1158                 appWindow = surfaceNodePtr;
1159                 break;
1160             }
1161         }
1162     }
1163     auto hardwareEnabledNodes = appWindow->GetChildHardwareEnabledNodes();
1164     for (auto& hardwareEnabledNode : hardwareEnabledNodes) {
1165         auto hardwareEnabledNodePtr = hardwareEnabledNode.lock();
1166         if (hardwareEnabledNodePtr) {
1167             hardwareEnabledNodePtr->SetHardwareDisabledByCache(false);
1168         }
1169     }
1170 }
1171 
ClearCacheSurface(RSRenderNode & node,uint32_t threadIndex,bool isClearCompletedCacheSurface)1172 void RSUniRenderUtil::ClearCacheSurface(RSRenderNode& node, uint32_t threadIndex, bool isClearCompletedCacheSurface)
1173 {
1174     RS_LOGD("ClearCacheSurface node: [%{public}" PRIu64 "]", node.GetId());
1175     uint32_t cacheSurfaceThreadIndex = node.GetCacheSurfaceThreadIndex();
1176     uint32_t completedSurfaceThreadIndex = node.GetCompletedSurfaceThreadIndex();
1177     if (cacheSurfaceThreadIndex == threadIndex && completedSurfaceThreadIndex == threadIndex) {
1178         node.ClearCacheSurface(isClearCompletedCacheSurface);
1179         return;
1180     }
1181     std::shared_ptr<Drawing::Surface> completedCacheSurface = isClearCompletedCacheSurface ?
1182         node.GetCompletedCacheSurface(threadIndex, false, true) : nullptr;
1183     ClearNodeCacheSurface(node.GetCacheSurface(threadIndex, false, true),
1184         std::move(completedCacheSurface), cacheSurfaceThreadIndex, completedSurfaceThreadIndex);
1185     node.ClearCacheSurface(isClearCompletedCacheSurface);
1186 }
1187 
ClearNodeCacheSurface(std::shared_ptr<Drawing::Surface> && cacheSurface,std::shared_ptr<Drawing::Surface> && cacheCompletedSurface,uint32_t cacheSurfaceThreadIndex,uint32_t completedSurfaceThreadIndex)1188 void RSUniRenderUtil::ClearNodeCacheSurface(std::shared_ptr<Drawing::Surface>&& cacheSurface,
1189     std::shared_ptr<Drawing::Surface>&& cacheCompletedSurface,
1190     uint32_t cacheSurfaceThreadIndex, uint32_t completedSurfaceThreadIndex)
1191 {
1192     PostReleaseSurfaceTask(std::move(cacheSurface), cacheSurfaceThreadIndex);
1193     PostReleaseSurfaceTask(std::move(cacheCompletedSurface), completedSurfaceThreadIndex);
1194 }
1195 
PostReleaseSurfaceTask(std::shared_ptr<Drawing::Surface> && surface,uint32_t threadIndex)1196 void RSUniRenderUtil::PostReleaseSurfaceTask(std::shared_ptr<Drawing::Surface>&& surface, uint32_t threadIndex)
1197 {
1198     if (surface == nullptr) {
1199         return;
1200     }
1201 
1202     if (threadIndex == UNI_MAIN_THREAD_INDEX || threadIndex == UNI_RENDER_THREAD_INDEX) {
1203         if (RSUniRenderJudgement::IsUniRender()) {
1204             auto instance = &(RSUniRenderThread::Instance());
1205             instance->AddToReleaseQueue(std::move(surface));
1206             instance->PostTask(([instance] () { instance->ReleaseSurface(); }),
1207                 RELEASE_SURFACE_TASK, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
1208         } else {
1209             auto instance = RSMainThread::Instance();
1210             instance->AddToReleaseQueue(std::move(surface));
1211             instance->PostTask(([instance] () { instance->ReleaseSurface(); }),
1212                 RELEASE_SURFACE_TASK, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
1213         }
1214     } else {
1215 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
1216         auto instance = RSSubThreadManager::Instance();
1217         instance->AddToReleaseQueue(std::move(surface), threadIndex);
1218         instance->ReleaseSurface(threadIndex);
1219 #endif
1220     }
1221 }
1222 
DrawRectForDfx(RSPaintFilterCanvas & canvas,const RectI & rect,Drawing::Color color,float alpha,const std::string & extraInfo)1223 void RSUniRenderUtil::DrawRectForDfx(RSPaintFilterCanvas& canvas, const RectI& rect, Drawing::Color color,
1224     float alpha, const std::string& extraInfo)
1225 {
1226     if (rect.width_ <= 0 || rect.height_ <= 0) {
1227         RS_LOGD("DrawRectForDfx rect is invalid.");
1228         return;
1229     }
1230     RS_LOGD("DrawRectForDfx current rect = %{public}s", rect.ToString().c_str());
1231     auto dstRect = Drawing::Rect(rect.left_, rect.top_,
1232         rect.left_ + rect.width_, rect.top_ + rect.height_);
1233 
1234     std::string position = rect.ToString() + extraInfo;
1235 
1236     const int defaultTextOffsetX = 6; // text position is 6 pixelSize right side of the Rect
1237     const int defaultTextOffsetY = 30; // text position has 30 pixelSize under the Rect
1238     Drawing::Brush rectBrush;
1239     std::shared_ptr<Drawing::Typeface> typeFace = nullptr;
1240 
1241     // font size: 24
1242     std::shared_ptr<Drawing::TextBlob> textBlob =
1243         Drawing::TextBlob::MakeFromString(position.c_str(), Drawing::Font(typeFace, 24.0f, 1.0f, 0.0f));
1244 
1245     rectBrush.SetColor(color);
1246     rectBrush.SetAntiAlias(true);
1247     rectBrush.SetAlphaF(alpha);
1248     canvas.AttachBrush(rectBrush);
1249     canvas.DrawRect(dstRect);
1250     canvas.DetachBrush();
1251     canvas.AttachBrush(Drawing::Brush());
1252     canvas.DrawTextBlob(textBlob.get(), rect.left_ + defaultTextOffsetX, rect.top_ + defaultTextOffsetY);
1253     canvas.DetachBrush();
1254 }
1255 
1256 #ifdef RS_ENABLE_VK
FindMemoryType(uint32_t typeFilter,VkMemoryPropertyFlags properties)1257 uint32_t RSUniRenderUtil::FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
1258 {
1259     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
1260         OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
1261         return UINT32_MAX;
1262     }
1263     auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton().GetRsVulkanInterface();
1264     VkPhysicalDevice physicalDevice = vkContext.GetPhysicalDevice();
1265 
1266     VkPhysicalDeviceMemoryProperties memProperties;
1267     vkContext.vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
1268 
1269     for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
1270         if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
1271             return i;
1272         }
1273     }
1274 
1275     return UINT32_MAX;
1276 }
1277 
SetVkImageInfo(std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo,const VkImageCreateInfo & imageInfo)1278 void RSUniRenderUtil::SetVkImageInfo(std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo,
1279     const VkImageCreateInfo& imageInfo)
1280 {
1281     if (vkImageInfo == nullptr) {
1282         return;
1283     }
1284     vkImageInfo->imageTiling = imageInfo.tiling;
1285     vkImageInfo->imageLayout = imageInfo.initialLayout;
1286     vkImageInfo->format = imageInfo.format;
1287     vkImageInfo->imageUsageFlags = imageInfo.usage;
1288     vkImageInfo->levelCount = imageInfo.mipLevels;
1289     vkImageInfo->currentQueueFamily = VK_QUEUE_FAMILY_EXTERNAL;
1290     vkImageInfo->ycbcrConversionInfo = {};
1291     vkImageInfo->sharingMode = imageInfo.sharingMode;
1292 }
1293 
MakeBackendTexture(uint32_t width,uint32_t height,VkFormat format)1294 Drawing::BackendTexture RSUniRenderUtil::MakeBackendTexture(uint32_t width, uint32_t height, VkFormat format)
1295 {
1296     VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
1297     VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1298         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1299     VkImageCreateInfo imageInfo {
1300         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1301         .pNext = nullptr,
1302         .flags = 0,
1303         .imageType = VK_IMAGE_TYPE_2D,
1304         .format = format,
1305         .extent = {width, height, 1},
1306         .mipLevels = 1,
1307         .arrayLayers = 1,
1308         .samples = VK_SAMPLE_COUNT_1_BIT,
1309         .tiling = tiling,
1310         .usage = usage,
1311         .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
1312         .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
1313     };
1314 
1315     auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton().GetRsVulkanInterface();
1316     VkDevice device = vkContext.GetDevice();
1317     VkImage image = VK_NULL_HANDLE;
1318     VkDeviceMemory memory = VK_NULL_HANDLE;
1319 
1320     if (width * height > OHOS::Rosen::NativeBufferUtils::VKIMAGE_LIMIT_SIZE) {
1321         ROSEN_LOGE(
1322             "RSUniRenderUtil::MakeBackendTexture failed, image is too large, width:%{public}u, height::%{public}u",
1323             width, height);
1324         return {};
1325     }
1326 
1327     if (vkContext.vkCreateImage(device, &imageInfo, nullptr, &image) != VK_SUCCESS) {
1328         return {};
1329     }
1330 
1331     VkMemoryRequirements memRequirements;
1332     vkContext.vkGetImageMemoryRequirements(device, image, &memRequirements);
1333 
1334     VkMemoryAllocateInfo allocInfo{};
1335     allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1336     allocInfo.allocationSize = memRequirements.size;
1337     allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1338     if (allocInfo.memoryTypeIndex == UINT32_MAX) {
1339         return {};
1340     }
1341 
1342     if (vkContext.vkAllocateMemory(device, &allocInfo, nullptr, &memory) != VK_SUCCESS) {
1343         return {};
1344     }
1345 
1346     vkContext.vkBindImageMemory(device, image, memory, 0);
1347 
1348     OHOS::Rosen::Drawing::BackendTexture backendTexture(true);
1349     OHOS::Rosen::Drawing::TextureInfo textureInfo;
1350     textureInfo.SetWidth(width);
1351     textureInfo.SetHeight(height);
1352 
1353     std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo =
1354         std::make_shared<OHOS::Rosen::Drawing::VKTextureInfo>();
1355     vkImageInfo->vkImage = image;
1356     vkImageInfo->vkAlloc.memory = memory;
1357     vkImageInfo->vkAlloc.size = memRequirements.size;
1358 
1359     SetVkImageInfo(vkImageInfo, imageInfo);
1360     textureInfo.SetVKTextureInfo(vkImageInfo);
1361     backendTexture.SetTextureInfo(textureInfo);
1362     return backendTexture;
1363 }
1364 #endif
1365 
GetRotateTransformForRotationFixed(RSSurfaceRenderNode & node,sptr<IConsumerSurface> consumer)1366 GraphicTransformType RSUniRenderUtil::GetRotateTransformForRotationFixed(RSSurfaceRenderNode& node,
1367     sptr<IConsumerSurface> consumer)
1368 {
1369     auto transformType = RSBaseRenderUtil::GetRotateTransform(RSBaseRenderUtil::GetSurfaceBufferTransformType(
1370         node.GetRSSurfaceHandler()->GetConsumer(), node.GetRSSurfaceHandler()->GetBuffer()));
1371     int extraRotation = 0;
1372     int degree = static_cast<int>(round(node.GetAbsRotation()));
1373     auto surfaceParams = node.GetStagingRenderParams() == nullptr
1374                              ? nullptr
1375                              : static_cast<RSSurfaceRenderParams*>(node.GetStagingRenderParams().get());
1376     int32_t rotationDegree = RSBaseRenderUtil::GetScreenRotationOffset(surfaceParams);
1377     extraRotation = (degree - rotationDegree) % ROUND_ANGLE;
1378     transformType = static_cast<GraphicTransformType>(
1379         (transformType + extraRotation / RS_ROTATION_90 + SCREEN_ROTATION_NUM) % SCREEN_ROTATION_NUM);
1380     return transformType;
1381 }
1382 
UpdateRealSrcRect(RSSurfaceRenderNode & node,const RectI & absRect)1383 void RSUniRenderUtil::UpdateRealSrcRect(RSSurfaceRenderNode& node, const RectI& absRect)
1384 {
1385     auto surfaceHandler = node.GetRSSurfaceHandler();
1386     auto consumer = surfaceHandler->GetConsumer();
1387     auto buffer = surfaceHandler->GetBuffer();
1388     if (!consumer || !buffer) {
1389         return;
1390     }
1391     auto bufferRotateTransformType = node.GetFixRotationByUser() ?
1392         RSUniRenderUtil::GetRotateTransformForRotationFixed(node, consumer) :
1393         RSBaseRenderUtil::GetRotateTransform(RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, buffer));
1394     const auto& property = node.GetRenderProperties();
1395     auto bufferWidth = buffer->GetSurfaceBufferWidth();
1396     auto bufferHeight = buffer->GetSurfaceBufferHeight();
1397     const auto boundsWidth = property.GetBoundsWidth();
1398     const auto boundsHeight = property.GetBoundsHeight();
1399     auto srcRect = node.GetSrcRect();
1400     if (bufferRotateTransformType == GraphicTransformType::GRAPHIC_ROTATE_90 ||
1401         bufferRotateTransformType == GraphicTransformType::GRAPHIC_ROTATE_270) {
1402         std::swap(bufferWidth, bufferHeight);
1403     }
1404     if ((bufferWidth != boundsWidth || bufferHeight != boundsHeight) &&
1405         node.GetRenderProperties().GetFrameGravity() != Gravity::TOP_LEFT) {
1406         float xScale = (ROSEN_EQ(boundsWidth, 0.0f) ? 1.0f : bufferWidth / boundsWidth);
1407         float yScale = (ROSEN_EQ(boundsHeight, 0.0f) ? 1.0f : bufferHeight / boundsHeight);
1408         if (absRect == node.GetDstRect()) {
1409             // If the SurfaceRenderNode is completely in the DisplayRenderNode,
1410             // we do not need to crop the buffer.
1411             srcRect.width_ = bufferWidth;
1412             srcRect.height_ = bufferHeight;
1413         } else {
1414             srcRect.left_ = srcRect.left_ * xScale;
1415             srcRect.top_ = srcRect.top_ * yScale;
1416             srcRect.width_ = std::min(static_cast<int32_t>(std::ceil(srcRect.width_ * xScale)), bufferWidth);
1417             srcRect.height_ = std::min(static_cast<int32_t>(std::ceil(srcRect.height_ * yScale)), bufferHeight);
1418         }
1419     }
1420     RectI bufferRect(0, 0, bufferWidth, bufferHeight);
1421     RectI calibratedSrcRect = srcRect.IntersectRect(bufferRect);
1422     if (bufferRotateTransformType == GraphicTransformType::GRAPHIC_ROTATE_90 ||
1423         bufferRotateTransformType == GraphicTransformType::GRAPHIC_ROTATE_270) {
1424         std::swap(calibratedSrcRect.left_, calibratedSrcRect.top_);
1425         std::swap(calibratedSrcRect.width_, calibratedSrcRect.height_);
1426     }
1427     auto newSrcRect = SrcRectRotateTransform(*buffer, bufferRotateTransformType, calibratedSrcRect);
1428     node.SetSrcRect(newSrcRect);
1429 }
1430 
GetConsumerTransform(const RSSurfaceRenderNode & node,const sptr<SurfaceBuffer> buffer,const sptr<IConsumerSurface> consumer)1431 GraphicTransformType RSUniRenderUtil::GetConsumerTransform(const RSSurfaceRenderNode& node,
1432     const sptr<SurfaceBuffer> buffer, const sptr<IConsumerSurface> consumer)
1433 {
1434     auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
1435     if (consumer != nullptr && buffer != nullptr) {
1436         if (consumer->GetSurfaceBufferTransformType(buffer, &transformType) != GSERROR_OK) {
1437             RS_LOGE("RSUniRenderUtil::GetConsumerTransform GetSurfaceBufferTransformType failed");
1438         }
1439     }
1440     GraphicTransformType consumerTransform = RSBaseRenderUtil::GetRotateTransform(transformType);
1441     return consumerTransform;
1442 }
1443 
CalcSrcRectByBufferFlip(RSSurfaceRenderNode & node,const ScreenInfo & screenInfo)1444 void RSUniRenderUtil::CalcSrcRectByBufferFlip(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo)
1445 {
1446     auto surfaceHandler = node.GetRSSurfaceHandler();
1447     auto consumer = surfaceHandler->GetConsumer();
1448     auto buffer = surfaceHandler->GetBuffer();
1449     if (!consumer || !buffer) {
1450         return;
1451     }
1452     const auto bufferWidth = buffer->GetSurfaceBufferWidth();
1453     const auto bufferHeight = buffer->GetSurfaceBufferHeight();
1454     const auto dstRect = node.GetDstRect();
1455     RectI srcRect = node.GetSrcRect();
1456     auto bufferFlipTransformType =
1457         RSBaseRenderUtil::GetFlipTransform(RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, buffer));
1458     switch (bufferFlipTransformType) {
1459         case GraphicTransformType::GRAPHIC_FLIP_H: {
1460             if (srcRect.left_ >= 0) {
1461                 srcRect.left_ = bufferWidth - srcRect.left_ - srcRect.width_;
1462             } else if (dstRect.left_ + dstRect.width_ >= static_cast<int32_t>(screenInfo.width)) {
1463                 srcRect.left_ = bufferWidth - srcRect.width_;
1464             }
1465             break;
1466         }
1467         case GraphicTransformType::GRAPHIC_FLIP_V: {
1468             if (srcRect.top_ >= 0) {
1469                 srcRect.top_ = bufferHeight - srcRect.top_ - srcRect.height_;
1470             } else if (dstRect.top_ + dstRect.height_ >= static_cast<int32_t>(screenInfo.height)) {
1471                 srcRect.top_ = bufferHeight - srcRect.height_;
1472             }
1473             break;
1474         }
1475         default:
1476             break;
1477     }
1478     node.SetSrcRect(srcRect);
1479 }
1480 
SrcRectRotateTransform(const SurfaceBuffer & buffer,const GraphicTransformType bufferRotateTransformType,const RectI & newSrcRect)1481 RectI RSUniRenderUtil::SrcRectRotateTransform(const SurfaceBuffer& buffer,
1482     const GraphicTransformType bufferRotateTransformType, const RectI& newSrcRect)
1483 {
1484     const auto bufferWidth = buffer.GetSurfaceBufferWidth();
1485     const auto bufferHeight = buffer.GetSurfaceBufferHeight();
1486     int left = newSrcRect.GetLeft();
1487     int top = newSrcRect.GetTop();
1488     int width = newSrcRect.GetWidth();
1489     int height = newSrcRect.GetHeight();
1490     RectI srcRect(newSrcRect);
1491     switch (bufferRotateTransformType) {
1492         case GraphicTransformType::GRAPHIC_ROTATE_90: {
1493             srcRect = RectI {bufferWidth - width - left, top, width, height};
1494             break;
1495         }
1496         case GraphicTransformType::GRAPHIC_ROTATE_180: {
1497             srcRect = RectI {bufferWidth - width - left, bufferHeight - height - top, width, height};
1498             break;
1499         }
1500         case GraphicTransformType::GRAPHIC_ROTATE_270: {
1501             srcRect = RectI {left, bufferHeight - height - top, width, height};
1502             break;
1503         }
1504         default:
1505             break;
1506     }
1507     return srcRect;
1508 }
1509 
CalcSrcRectByBufferRotation(const SurfaceBuffer & buffer,const GraphicTransformType consumerTransformType,Drawing::Rect newSrcRect)1510 Drawing::Rect RSUniRenderUtil::CalcSrcRectByBufferRotation(const SurfaceBuffer& buffer,
1511     const GraphicTransformType consumerTransformType, Drawing::Rect newSrcRect)
1512 {
1513     const float frameWidth = buffer.GetSurfaceBufferWidth();
1514     const float frameHeight = buffer.GetSurfaceBufferHeight();
1515     int left = std::clamp<int>(newSrcRect.GetLeft(), 0, frameWidth);
1516     int top = std::clamp<int>(newSrcRect.GetTop(), 0, frameHeight);
1517     int width = std::clamp<int>(newSrcRect.GetWidth(), 0, frameWidth - left);
1518     int height = std::clamp<int>(newSrcRect.GetHeight(), 0, frameHeight - top);
1519     switch (consumerTransformType) {
1520         case GraphicTransformType::GRAPHIC_ROTATE_NONE: {
1521             newSrcRect = Drawing::Rect(left, top, left + width, top + height);
1522             break;
1523         }
1524         case GraphicTransformType::GRAPHIC_ROTATE_90: {
1525             newSrcRect = Drawing::Rect(frameWidth - width - left, top, frameWidth - left, top + height);
1526             break;
1527         }
1528         case GraphicTransformType::GRAPHIC_ROTATE_180: {
1529             newSrcRect = Drawing::Rect(frameWidth - width - left, frameHeight - height - top,
1530                 frameWidth - left, frameHeight - top);
1531             break;
1532         }
1533         case GraphicTransformType::GRAPHIC_ROTATE_270: {
1534             newSrcRect = Drawing::Rect(left, frameHeight - height - top, left + width, frameHeight - top);
1535             break;
1536         }
1537         default:
1538             break;
1539     }
1540     return newSrcRect;
1541 }
1542 
IsHwcEnabledByGravity(RSSurfaceRenderNode & node,const Gravity frameGravity)1543 bool RSUniRenderUtil::IsHwcEnabledByGravity(RSSurfaceRenderNode& node, const Gravity frameGravity)
1544 {
1545     // When renderfit mode is not Gravity::RESIZE or Gravity::TOP_LEFT,
1546     // we currently disable hardware composer.
1547     if (frameGravity != Gravity::RESIZE && frameGravity != Gravity::TOP_LEFT) {
1548         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 "disabled by frameGravity[%d]",
1549             node.GetName().c_str(), node.GetId(), static_cast<int>(frameGravity));
1550         node.SetHardwareForcedDisabledState(true);
1551         return false;
1552     }
1553     return true;
1554 }
1555 
DealWithNodeGravity(RSSurfaceRenderNode & node,const Drawing::Matrix & totalMatrix)1556 void RSUniRenderUtil::DealWithNodeGravity(RSSurfaceRenderNode& node, const Drawing::Matrix& totalMatrix)
1557 {
1558     auto surfaceHandler = node.GetRSSurfaceHandler();
1559     if (!surfaceHandler) {
1560         return;
1561     }
1562     const auto buffer = surfaceHandler->GetBuffer();
1563     const auto consumer = surfaceHandler->GetConsumer();
1564     if (!consumer || !buffer) {
1565         return;
1566     }
1567     float bufferWidth = buffer->GetSurfaceBufferWidth();
1568     float bufferHeight = buffer->GetSurfaceBufferHeight();
1569     const float boundsWidth = node.GetRenderProperties().GetBoundsWidth();
1570     const float boundsHeight = node.GetRenderProperties().GetBoundsHeight();
1571     const Gravity frameGravity = node.GetRenderProperties().GetFrameGravity();
1572     const GraphicTransformType consumerTransformType = node.GetFixRotationByUser() ?
1573         GetRotateTransformForRotationFixed(node, consumer) : GetConsumerTransform(node, buffer, consumer);
1574     CheckForceHardwareAndUpdateDstRect(node);
1575     if (consumerTransformType == GraphicTransformType::GRAPHIC_ROTATE_90 ||
1576         consumerTransformType == GraphicTransformType::GRAPHIC_ROTATE_270) {
1577         std::swap(bufferWidth, bufferHeight);
1578     }
1579     Drawing::Matrix gravityMatrix;
1580     RSPropertiesPainter::GetGravityMatrix(frameGravity,
1581         {0.f, 0.f, boundsWidth, boundsHeight}, bufferWidth, bufferHeight, gravityMatrix);
1582     Drawing::Matrix inverseTotalMatrix;
1583     Drawing::Matrix inverseGravityMatrix;
1584     // We don't have to do additional works when renderfit mode is Gravity::RESIZE or frameSize == boundsSize.
1585     if (frameGravity == Gravity::RESIZE ||
1586         (ROSEN_EQ(bufferWidth, boundsWidth) && ROSEN_EQ(bufferHeight, boundsHeight)) ||
1587         !totalMatrix.Invert(inverseTotalMatrix) || !gravityMatrix.Invert(inverseGravityMatrix) ||
1588         !IsHwcEnabledByGravity(node, frameGravity)) {
1589         return;
1590     }
1591     Drawing::Rect bound = Drawing::Rect(0.f, 0.f, boundsWidth, boundsHeight);
1592     Drawing::Rect frame = Drawing::Rect(0.f, 0.f, bufferWidth, bufferHeight);
1593     Drawing::Rect localIntersectRect;
1594     gravityMatrix.MapRect(localIntersectRect, frame);
1595     localIntersectRect.Intersect(bound);
1596     Drawing::Rect absIntersectRect;
1597     totalMatrix.MapRect(absIntersectRect, localIntersectRect);
1598     const RectI dstRect = node.GetDstRect();
1599     Drawing::Rect newDstRect(dstRect.left_, dstRect.top_, dstRect.GetRight(), dstRect.GetBottom());
1600     newDstRect.Intersect(absIntersectRect);
1601     node.SetDstRect({std::floor(newDstRect.GetLeft()), std::floor(newDstRect.GetTop()),
1602         std::ceil(newDstRect.GetWidth()), std::ceil(newDstRect.GetHeight())});
1603     Drawing::Rect newSrcRect;
1604     inverseTotalMatrix.MapRect(newSrcRect, newDstRect);
1605     inverseGravityMatrix.MapRect(newSrcRect, newSrcRect);
1606     if (consumerTransformType == GraphicTransformType::GRAPHIC_ROTATE_90 ||
1607         consumerTransformType == GraphicTransformType::GRAPHIC_ROTATE_270) {
1608         std::swap(newSrcRect.left_, newSrcRect.top_);
1609         std::swap(newSrcRect.right_, newSrcRect.bottom_);
1610     }
1611     newSrcRect = CalcSrcRectByBufferRotation(*buffer, consumerTransformType, newSrcRect);
1612     node.SetSrcRect({newSrcRect.GetLeft(), newSrcRect.GetTop(), newSrcRect.GetWidth(), newSrcRect.GetHeight()});
1613 }
1614 
DealWithNodeGravityOldVersion(RSSurfaceRenderNode & node,const ScreenInfo & screenInfo)1615 void RSUniRenderUtil::DealWithNodeGravityOldVersion(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo)
1616 {
1617     auto buffer = node.GetRSSurfaceHandler()->GetBuffer();
1618     if (!buffer) {
1619         return;
1620     }
1621     const auto& property = node.GetRenderProperties();
1622     const float frameWidth = buffer->GetSurfaceBufferWidth();
1623     const float frameHeight = buffer->GetSurfaceBufferHeight();
1624     const float boundsWidth = property.GetBoundsWidth();
1625     const float boundsHeight = property.GetBoundsHeight();
1626     const Gravity frameGravity = property.GetFrameGravity();
1627 
1628     CheckForceHardwareAndUpdateDstRect(node);
1629     // we do not need to do additional works for Gravity::RESIZE and if frameSize == boundsSize.
1630     if (frameGravity == Gravity::RESIZE || (ROSEN_EQ(frameWidth, boundsWidth) && ROSEN_EQ(frameHeight, boundsHeight)) ||
1631         frameGravity == Gravity::TOP_LEFT) {
1632         return;
1633     }
1634 
1635     // get current node's translate matrix and calculate gravity matrix.
1636     auto translateMatrix = Drawing::Matrix();
1637     translateMatrix.Translate(node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_X),
1638         std::ceil(node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_Y)));
1639     Drawing::Matrix gravityMatrix;
1640     (void)RSPropertiesPainter::GetGravityMatrix(frameGravity,
1641         RectF {0.0f, 0.0f, boundsWidth, boundsHeight}, frameWidth, frameHeight, gravityMatrix);
1642     // create a canvas to calculate new dstRect and new srcRect
1643     int32_t screenWidth = screenInfo.phyWidth;
1644     int32_t screenHeight = screenInfo.phyHeight;
1645     const auto screenRotation = screenInfo.rotation;
1646     if (screenRotation == ScreenRotation::ROTATION_90 || screenRotation == ScreenRotation::ROTATION_270) {
1647         std::swap(screenWidth, screenHeight);
1648     }
1649 
1650     auto canvas = std::make_unique<Drawing::Canvas>(screenWidth, screenHeight);
1651     canvas->ConcatMatrix(translateMatrix);
1652     canvas->ConcatMatrix(gravityMatrix);
1653     Drawing::Rect clipRect;
1654     gravityMatrix.MapRect(clipRect, Drawing::Rect(0, 0, frameWidth, frameHeight));
1655     canvas->ClipRect(Drawing::Rect(0, 0, clipRect.GetWidth(), clipRect.GetHeight()), Drawing::ClipOp::INTERSECT);
1656     Drawing::RectI newDstRect = canvas->GetDeviceClipBounds();
1657     auto dstRect = node.GetDstRect();
1658     // we make the newDstRect as the intersection of new and old dstRect,
1659     // to deal with the situation that frameSize > boundsSize.
1660     newDstRect.Intersect(Drawing::RectI(
1661         dstRect.left_, dstRect.top_, dstRect.width_ + dstRect.left_, dstRect.height_ + dstRect.top_));
1662     auto localRect = canvas->GetLocalClipBounds();
1663     int left = std::clamp<int>(localRect.GetLeft(), 0, frameWidth);
1664     int top = std::clamp<int>(localRect.GetTop(), 0, frameHeight);
1665     int width = std::clamp<int>(localRect.GetWidth(), 0, frameWidth - left);
1666     int height = std::clamp<int>(localRect.GetHeight(), 0, frameHeight - top);
1667 
1668     node.SetDstRect({newDstRect.GetLeft(), newDstRect.GetTop(), newDstRect.GetWidth(), newDstRect.GetHeight()});
1669     node.SetSrcRect({left, top, width, height});
1670 }
1671 
CheckForceHardwareAndUpdateDstRect(RSSurfaceRenderNode & node)1672 void RSUniRenderUtil::CheckForceHardwareAndUpdateDstRect(RSSurfaceRenderNode& node)
1673 {
1674     auto surfaceHandler = node.GetRSSurfaceHandler();
1675     if (!surfaceHandler->GetConsumer() || !node.IsInFixedRotation() || !surfaceHandler->GetBuffer()) {
1676         return;
1677     }
1678     node.SetSrcRect(node.GetOriginalSrcRect());
1679     auto dstRect = node.GetDstRect();
1680     auto originalDstRect = node.GetOriginalDstRect();
1681     dstRect.left_ += (dstRect.width_ - originalDstRect.width_) / 2;
1682     dstRect.top_ += (dstRect.height_ - originalDstRect.height_) / 2;
1683     dstRect.width_ = originalDstRect.width_;
1684     dstRect.height_ = originalDstRect.height_;
1685     node.SetDstRect(dstRect);
1686 }
1687 
LayerRotate(RSSurfaceRenderNode & node,const ScreenInfo & screenInfo)1688 void RSUniRenderUtil::LayerRotate(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo)
1689 {
1690     const auto screenWidth = static_cast<int32_t>(screenInfo.width);
1691     const auto screenHeight = static_cast<int32_t>(screenInfo.height);
1692     const auto screenRotation = screenInfo.rotation;
1693     const auto rect = node.GetDstRect();
1694     switch (screenRotation) {
1695         case ScreenRotation::ROTATION_90: {
1696             node.SetDstRect({rect.top_, screenHeight - rect.left_ - rect.width_, rect.height_, rect.width_});
1697             break;
1698         }
1699         case ScreenRotation::ROTATION_180: {
1700             node.SetDstRect({screenWidth - rect.left_ - rect.width_, screenHeight - rect.top_ - rect.height_,
1701                 rect.width_, rect.height_});
1702             break;
1703         }
1704         case ScreenRotation::ROTATION_270: {
1705             node.SetDstRect({screenWidth - rect.top_ - rect.height_, rect.left_, rect.height_, rect.width_});
1706             break;
1707         }
1708         default:  {
1709             break;
1710         }
1711     }
1712 }
1713 
GetLayerTransform(RSSurfaceRenderNode & node,const ScreenInfo & screenInfo)1714 GraphicTransformType RSUniRenderUtil::GetLayerTransform(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo)
1715 {
1716     auto surfaceHandler = node.GetRSSurfaceHandler();
1717     if (!surfaceHandler) {
1718         return GraphicTransformType::GRAPHIC_ROTATE_NONE;
1719     }
1720     auto consumer = surfaceHandler->GetConsumer();
1721     auto surfaceParams = node.GetStagingRenderParams() == nullptr
1722                              ? nullptr
1723                              : static_cast<RSSurfaceRenderParams*>(node.GetStagingRenderParams().get());
1724     int32_t rotationDegree = RSBaseRenderUtil::GetScreenRotationOffset(surfaceParams);
1725     int surfaceNodeRotation = 0;
1726     if (node.GetFixRotationByUser()) {
1727         surfaceNodeRotation = -1 * rotationDegree;
1728     } else {
1729         surfaceNodeRotation =
1730             TransferToAntiClockwiseDegrees(static_cast<int>(round(node.GetAbsRotation())) % ROUND_ANGLE);
1731     }
1732     auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
1733     auto buffer = node.GetRSSurfaceHandler()->GetBuffer();
1734     if (consumer != nullptr && buffer != nullptr) {
1735         if (consumer->GetSurfaceBufferTransformType(buffer, &transformType) != GSERROR_OK) {
1736             RS_LOGE("RSUniRenderUtil::GetLayerTransform GetSurfaceBufferTransformType failed");
1737         }
1738     }
1739     int consumerTransform = RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(transformType));
1740     GraphicTransformType consumerFlip = RSBaseRenderUtil::GetFlipTransform(transformType);
1741     int totalRotation =
1742         (RSBaseRenderUtil::RotateEnumToInt(screenInfo.rotation) + surfaceNodeRotation + consumerTransform + 360) % 360;
1743     GraphicTransformType rotateEnum = RSBaseRenderUtil::RotateEnumToInt(totalRotation, consumerFlip);
1744 
1745     RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderUtil::GetLayerTransform nodeId:[%llu] fixRotationByUser:[%s] "
1746                                "surfaceNodeRotation:[%d] consumerTransform:[%d] rotateEnum:[%d]",
1747                                node.GetId(), std::to_string(node.GetFixRotationByUser()).c_str(),
1748                                surfaceNodeRotation, consumerTransform, rotateEnum);
1749 
1750     return rotateEnum;
1751 }
1752 
LayerCrop(RSSurfaceRenderNode & node,const ScreenInfo & screenInfo)1753 void RSUniRenderUtil::LayerCrop(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo)
1754 {
1755     auto dstRect = node.GetDstRect();
1756     auto srcRect = node.GetSrcRect();
1757     auto originSrcRect = srcRect;
1758 
1759     RectI dstRectI(dstRect.left_, dstRect.top_, dstRect.width_, dstRect.height_);
1760     int32_t screenWidth = static_cast<int32_t>(screenInfo.phyWidth);
1761     int32_t screenHeight = static_cast<int32_t>(screenInfo.phyHeight);
1762     RectI screenRectI(0, 0, screenWidth, screenHeight);
1763     RectI resDstRect = dstRectI.IntersectRect(screenRectI);
1764     if (resDstRect == dstRectI) {
1765         return;
1766     }
1767     if (node.IsInFixedRotation()) {
1768         node.SetDstRect(resDstRect);
1769         return;
1770     }
1771     dstRect = {resDstRect.left_, resDstRect.top_, resDstRect.width_, resDstRect.height_};
1772     srcRect.left_ = (resDstRect.IsEmpty() || dstRectI.IsEmpty()) ? 0 : std::ceil((resDstRect.left_ - dstRectI.left_) *
1773         originSrcRect.width_ / dstRectI.width_);
1774     srcRect.top_ = (resDstRect.IsEmpty() || dstRectI.IsEmpty()) ? 0 : std::ceil((resDstRect.top_ - dstRectI.top_) *
1775         originSrcRect.height_ / dstRectI.height_);
1776     srcRect.width_ = dstRectI.IsEmpty() ? 0 : originSrcRect.width_ * resDstRect.width_ / dstRectI.width_;
1777     srcRect.height_ = dstRectI.IsEmpty() ? 0 : originSrcRect.height_ * resDstRect.height_ / dstRectI.height_;
1778     node.SetDstRect(dstRect);
1779     node.SetSrcRect(srcRect);
1780 }
1781 
IsHwcEnabledByScalingMode(RSSurfaceRenderNode & node,const ScalingMode scalingMode)1782 bool RSUniRenderUtil::IsHwcEnabledByScalingMode(RSSurfaceRenderNode& node, const ScalingMode scalingMode)
1783 {
1784     // We temporarily disabled HWC when scalingMode is freeze or no_scale_crop
1785     if (scalingMode == ScalingMode::SCALING_MODE_FREEZE || scalingMode == ScalingMode::SCALING_MODE_NO_SCALE_CROP) {
1786         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 "disabled by scalingMode[%d]",
1787             node.GetName().c_str(), node.GetId(), static_cast<int>(scalingMode));
1788         node.SetHardwareForcedDisabledState(true);
1789         return false;
1790     }
1791     return true;
1792 }
1793 
DealWithScalingMode(RSSurfaceRenderNode & node,const Drawing::Matrix & totalMatrix)1794 void RSUniRenderUtil::DealWithScalingMode(RSSurfaceRenderNode& node, const Drawing::Matrix& totalMatrix)
1795 {
1796     auto surfaceHandler = node.GetRSSurfaceHandler();
1797     if (!surfaceHandler) {
1798         return;
1799     }
1800     const auto buffer = surfaceHandler->GetBuffer();
1801     const auto consumer = surfaceHandler->GetConsumer();
1802     if (!consumer || !buffer) {
1803         return;
1804     }
1805     float bufferWidth = buffer->GetSurfaceBufferWidth();
1806     float bufferHeight = buffer->GetSurfaceBufferHeight();
1807     const float boundsWidth = node.GetRenderProperties().GetBoundsWidth();
1808     const float boundsHeight = node.GetRenderProperties().GetBoundsHeight();
1809     const GraphicTransformType consumerTransformType = node.GetFixRotationByUser() ?
1810         GetRotateTransformForRotationFixed(node, consumer) : GetConsumerTransform(node, buffer, consumer);
1811     const Gravity frameGravity = node.GetRenderProperties().GetFrameGravity();
1812     const ScalingMode scalingMode = buffer->GetSurfaceBufferScalingMode();
1813     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_TO_WINDOW || !IsHwcEnabledByScalingMode(node, scalingMode) ||
1814         !IsHwcEnabledByGravity(node, frameGravity)) {
1815         return;
1816     }
1817     if (consumerTransformType == GraphicTransformType::GRAPHIC_ROTATE_90 ||
1818         consumerTransformType == GraphicTransformType::GRAPHIC_ROTATE_270) {
1819         std::swap(bufferWidth, bufferHeight);
1820     }
1821     Drawing::Matrix gravityMatrix;
1822     RSPropertiesPainter::GetGravityMatrix(frameGravity,
1823         {0.f, 0.f, boundsWidth, boundsHeight}, bufferWidth, bufferHeight, gravityMatrix);
1824     Drawing::Matrix rawScalingModeMatrix;
1825     RSPropertiesPainter::GetScalingModeMatrix(scalingMode,
1826         {0.f, 0.f, boundsWidth, boundsHeight}, bufferWidth, bufferHeight, rawScalingModeMatrix);
1827     Drawing::Rect rawSrcRect;
1828     rawScalingModeMatrix.MapRect(rawSrcRect, Drawing::Rect(0.f, 0.f, bufferWidth, bufferHeight));
1829     float xScale = ROSEN_EQ(boundsWidth, 0.f) ? 1.0f : rawSrcRect.GetWidth() / boundsWidth;
1830     float yScale = ROSEN_EQ(boundsHeight, 0.f) ? 1.0f : rawSrcRect.GetHeight() / boundsHeight;
1831     Drawing::Matrix scalingModeMatrix;
1832     scalingModeMatrix.PostScale(xScale, yScale);
1833     Drawing::Rect adjustedSrcRect;
1834     scalingModeMatrix.MapRect(adjustedSrcRect, Drawing::Rect(0.f, 0.f, bufferWidth, bufferHeight));
1835     float xTranslate = (bufferWidth - adjustedSrcRect.GetWidth()) / 2.0f;
1836     float yTranslate = (bufferHeight - adjustedSrcRect.GetHeight()) / 2.0f;
1837     scalingModeMatrix.PostTranslate(xTranslate, yTranslate);
1838     UpdateHwcNodeByScalingMode(node, totalMatrix, gravityMatrix, scalingModeMatrix);
1839 }
1840 
UpdateHwcNodeByScalingMode(RSSurfaceRenderNode & node,const Drawing::Matrix & totalMatrix,const Drawing::Matrix & gravityMatrix,const Drawing::Matrix & scalingModeMatrix)1841 void RSUniRenderUtil::UpdateHwcNodeByScalingMode(RSSurfaceRenderNode& node, const Drawing::Matrix& totalMatrix,
1842     const Drawing::Matrix& gravityMatrix, const Drawing::Matrix& scalingModeMatrix)
1843 {
1844     auto surfaceHandler = node.GetRSSurfaceHandler();
1845     const auto& property = node.GetRenderProperties();
1846     const auto buffer = surfaceHandler->GetBuffer();
1847     const auto consumer = surfaceHandler->GetConsumer();
1848     float bufferWidth = buffer->GetSurfaceBufferWidth();
1849     float bufferHeight = buffer->GetSurfaceBufferHeight();
1850     const GraphicTransformType consumerTransformType = node.GetFixRotationByUser() ?
1851         GetRotateTransformForRotationFixed(node, consumer) : GetConsumerTransform(node, buffer, consumer);
1852     Drawing::Matrix inverseScalingModeMatrix;
1853     Drawing::Matrix inverseGravityMatrix;
1854     Drawing::Matrix inverseTotalMatrix;
1855     if (!totalMatrix.Invert(inverseTotalMatrix) || !scalingModeMatrix.Invert(inverseScalingModeMatrix) ||
1856         !gravityMatrix.Invert(inverseGravityMatrix)) {
1857         return;
1858     }
1859     if (consumerTransformType == GraphicTransformType::GRAPHIC_ROTATE_90 ||
1860         consumerTransformType == GraphicTransformType::GRAPHIC_ROTATE_270) {
1861         std::swap(bufferWidth, bufferHeight);
1862     }
1863     Drawing::Rect newDstRect;
1864     scalingModeMatrix.MapRect(newDstRect, Drawing::Rect(0.f, 0.f, bufferWidth, bufferHeight));
1865     gravityMatrix.MapRect(newDstRect, newDstRect);
1866     totalMatrix.MapRect(newDstRect, newDstRect);
1867     Drawing::Rect dstRectWithoutScaling;
1868     gravityMatrix.MapRect(dstRectWithoutScaling, Drawing::Rect(0.f, 0.f, bufferWidth, bufferHeight));
1869     totalMatrix.MapRect(dstRectWithoutScaling, dstRectWithoutScaling);
1870     newDstRect.Intersect(dstRectWithoutScaling);
1871     Drawing::Rect bounds = node.GetDstRectWithoutRenderFit();
1872     newDstRect.Intersect(bounds);
1873     node.SetDstRect({std::floor(newDstRect.GetLeft()), std::floor(newDstRect.GetTop()),
1874         std::ceil(newDstRect.GetWidth()), std::ceil(newDstRect.GetHeight())});
1875     Drawing::Rect newSrcRect;
1876     inverseTotalMatrix.MapRect(newSrcRect, newDstRect);
1877     inverseGravityMatrix.MapRect(newSrcRect, newSrcRect);
1878     inverseScalingModeMatrix.MapRect(newSrcRect, newSrcRect);
1879     if (consumerTransformType == GraphicTransformType::GRAPHIC_ROTATE_90 ||
1880         consumerTransformType == GraphicTransformType::GRAPHIC_ROTATE_270) {
1881         std::swap(newSrcRect.left_, newSrcRect.top_);
1882         std::swap(newSrcRect.right_, newSrcRect.bottom_);
1883     }
1884     newSrcRect = CalcSrcRectByBufferRotation(*buffer, consumerTransformType, newSrcRect);
1885     node.SetSrcRect({newSrcRect.GetLeft(), newSrcRect.GetTop(), newSrcRect.GetWidth(), newSrcRect.GetHeight()});
1886 }
1887 
OptimizedFlushAndSubmit(std::shared_ptr<Drawing::Surface> & surface,Drawing::GPUContext * const grContext,bool optFenceWait)1888 void RSUniRenderUtil::OptimizedFlushAndSubmit(std::shared_ptr<Drawing::Surface>& surface,
1889     Drawing::GPUContext* const grContext, bool optFenceWait)
1890 {
1891     if (!surface || !grContext) {
1892         RS_LOGE("RSUniRenderUtil::OptimizedFlushAndSubmit cacheSurface or grContext are nullptr");
1893         return;
1894     }
1895     RS_TRACE_NAME_FMT("Render surface flush and submit");
1896     RS_LOGD("RSUniRenderUtil::optimized flush and submit GpuApiType:%{public}d",
1897         RSSystemProperties::GetGpuApiType());
1898 #ifdef RS_ENABLE_VK
1899     if ((RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
1900         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) && optFenceWait) {
1901         auto& vkContext = RsVulkanContext::GetSingleton().GetRsVulkanInterface();
1902 
1903         VkExportSemaphoreCreateInfo exportSemaphoreCreateInfo;
1904         exportSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
1905         exportSemaphoreCreateInfo.pNext = nullptr;
1906         exportSemaphoreCreateInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
1907 
1908         VkSemaphoreCreateInfo semaphoreInfo;
1909         semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1910         semaphoreInfo.pNext = &exportSemaphoreCreateInfo;
1911         semaphoreInfo.flags = 0;
1912         VkSemaphore semaphore;
1913         vkContext.vkCreateSemaphore(vkContext.GetDevice(), &semaphoreInfo, nullptr, &semaphore);
1914         GrBackendSemaphore backendSemaphore;
1915         backendSemaphore.initVulkan(semaphore);
1916 
1917         DestroySemaphoreInfo* destroyInfo =
1918             new DestroySemaphoreInfo(vkContext.vkDestroySemaphore, vkContext.GetDevice(), semaphore);
1919 
1920         Drawing::FlushInfo drawingFlushInfo;
1921         drawingFlushInfo.backendSurfaceAccess = true;
1922         drawingFlushInfo.numSemaphores = 1;
1923         drawingFlushInfo.backendSemaphore = static_cast<void*>(&backendSemaphore);
1924         drawingFlushInfo.finishedProc = [](void *context) {
1925             DestroySemaphoreInfo::DestroySemaphore(context);
1926         };
1927         drawingFlushInfo.finishedContext = destroyInfo;
1928         surface->Flush(&drawingFlushInfo);
1929         grContext->Submit();
1930         DestroySemaphoreInfo::DestroySemaphore(destroyInfo);
1931     } else {
1932         surface->FlushAndSubmit(true);
1933     }
1934 #else
1935     surface->FlushAndSubmit(true);
1936 #endif
1937 }
1938 
AccumulateMatrixAndAlpha(std::shared_ptr<RSSurfaceRenderNode> & hwcNode,Drawing::Matrix & matrix,float & alpha)1939 void RSUniRenderUtil::AccumulateMatrixAndAlpha(std::shared_ptr<RSSurfaceRenderNode>& hwcNode,
1940     Drawing::Matrix& matrix, float& alpha)
1941 {
1942     if (hwcNode == nullptr) {
1943         return;
1944     }
1945     const auto& property = hwcNode->GetRenderProperties();
1946     alpha = property.GetAlpha();
1947     matrix = property.GetBoundsGeometry()->GetMatrix();
1948     auto parent = hwcNode->GetParent().lock();
1949     while (parent && parent->GetType() != RSRenderNodeType::DISPLAY_NODE) {
1950         const auto& curProperty = parent->GetRenderProperties();
1951         alpha *= curProperty.GetAlpha();
1952         matrix.PostConcat(curProperty.GetBoundsGeometry()->GetMatrix());
1953         parent = parent->GetParent().lock();
1954     }
1955     if (!parent) {
1956         return;
1957     }
1958     const auto& parentProperty = parent->GetRenderProperties();
1959     alpha *= parentProperty.GetAlpha();
1960     matrix.PostConcat(parentProperty.GetBoundsGeometry()->GetMatrix());
1961 }
1962 
GenerateSecRectInfoFromNode(RSRenderNode & node,RectI rect)1963 SecRectInfo RSUniRenderUtil::GenerateSecRectInfoFromNode(RSRenderNode& node, RectI rect)
1964 {
1965     SecRectInfo uiExtensionRectInfo;
1966     uiExtensionRectInfo.relativeCoords = rect;
1967     uiExtensionRectInfo.scale = node.GetRenderProperties().GetScale();
1968     return uiExtensionRectInfo;
1969 }
1970 
GenerateSecSurfaceInfoFromNode(NodeId uiExtensionId,NodeId hostId,SecRectInfo uiExtensionRectInfo)1971 SecSurfaceInfo RSUniRenderUtil::GenerateSecSurfaceInfoFromNode(
1972     NodeId uiExtensionId, NodeId hostId, SecRectInfo uiExtensionRectInfo)
1973 {
1974     SecSurfaceInfo secSurfaceInfo;
1975     secSurfaceInfo.uiExtensionRectInfo = uiExtensionRectInfo;
1976     secSurfaceInfo.uiExtensionPid = ExtractPid(uiExtensionId);
1977     secSurfaceInfo.hostPid = ExtractPid(hostId);
1978     secSurfaceInfo.uiExtensionNodeId = uiExtensionId;
1979     secSurfaceInfo.hostNodeId = hostId;
1980     return secSurfaceInfo;
1981 }
1982 
UIExtensionFindAndTraverseAncestor(const RSRenderNodeMap & nodeMap,UIExtensionCallbackData & callbackData,bool isUnobscured)1983 void RSUniRenderUtil::UIExtensionFindAndTraverseAncestor(
1984     const RSRenderNodeMap& nodeMap, UIExtensionCallbackData& callbackData, bool isUnobscured)
1985 {
1986     const auto& secUIExtensionNodes = RSSurfaceRenderNode::GetSecUIExtensionNodes();
1987     for (auto it = secUIExtensionNodes.begin(); it != secUIExtensionNodes.end(); ++it) {
1988         currentUIExtensionIndex_ = -1;
1989         // only traverse host node one time, even if it has multiple uiextension children.
1990         if (callbackData.find(it->second) != callbackData.end()) {
1991             continue;
1992         }
1993         auto hostNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(it->second));
1994         if (!hostNode || !hostNode->GetSortedChildren()) {
1995             RS_LOGE("RSUniRenderUtil::UIExtensionFindAndTraverseAncestor failed to get host node or its children.");
1996             return;
1997         }
1998         for (const auto& child : *hostNode->GetSortedChildren()) {
1999             TraverseAndCollectUIExtensionInfo(child, Drawing::Matrix(), hostNode->GetId(), callbackData, isUnobscured);
2000         }
2001     }
2002 }
2003 
TraverseAndCollectUIExtensionInfo(std::shared_ptr<RSRenderNode> node,Drawing::Matrix parentMatrix,NodeId hostId,UIExtensionCallbackData & callbackData,bool isUnobscured)2004 void RSUniRenderUtil::TraverseAndCollectUIExtensionInfo(std::shared_ptr<RSRenderNode> node,
2005     Drawing::Matrix parentMatrix, NodeId hostId, UIExtensionCallbackData& callbackData, bool isUnobscured)
2006 {
2007     if (!node) {
2008         return;
2009     }
2010     // update position relative to host app window node.
2011     std::optional<Drawing::Point> offset;
2012     auto parent = node->GetParent().lock();
2013     if (parent && !(node->IsInstanceOf<RSSurfaceRenderNode>())) {
2014         const auto& parentRenderProperties = parent->GetRenderProperties();
2015         offset = Drawing::Point { parentRenderProperties.GetFrameOffsetX(), parentRenderProperties.GetFrameOffsetY() };
2016     }
2017     const auto& nodeRenderProperties = node->GetRenderProperties();
2018     RSObjAbsGeometry boundsGeo = nodeRenderProperties.GetBoundsGeometry() == nullptr ?
2019         RSObjAbsGeometry() : *(nodeRenderProperties.GetBoundsGeometry());
2020     boundsGeo.UpdateMatrix(&parentMatrix, offset);
2021     auto rect = boundsGeo.MapAbsRect(node->GetSelfDrawRect().JoinRect(node->GetChildrenRect().ConvertTo<float>()));
2022     // if node is UIExtension type, update its own info, and skip its children.
2023     if (auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node)) {
2024         if ((surfaceNode->IsSecureUIExtension() && !isUnobscured) ||
2025             (surfaceNode->IsUnobscuredUIExtensionNode() && isUnobscured)) {
2026             currentUIExtensionIndex_++;
2027             // if host node is not recorded in callbackData, insert it.
2028             auto [iter, inserted] = callbackData.insert(std::pair(hostId, std::vector<SecSurfaceInfo>{}));
2029             if (iter != callbackData.end()) {
2030                 iter->second.push_back(GenerateSecSurfaceInfoFromNode(
2031                     surfaceNode->GetId(), hostId, GenerateSecRectInfoFromNode(*surfaceNode, rect)));
2032             }
2033             if (surfaceNode->ChildrenHasUIExtension()) {
2034                 RS_LOGW("RSUniRenderUtil::TraverseAndCollectUIExtensionInfo UIExtension node [%{public}" PRIu64 "]"
2035                     " has children UIExtension, not surpported!", surfaceNode->GetId());
2036             }
2037             return;
2038         }
2039     }
2040     // if the node is traversed after a UIExtension, collect it and skip its children (except it has UIExtension child.)
2041     auto iter = callbackData.find(hostId);
2042     if (iter != callbackData.end() && currentUIExtensionIndex_ != -1 &&
2043         currentUIExtensionIndex_ < static_cast<int>((iter->second).size())) {
2044         (iter->second)[currentUIExtensionIndex_].upperNodes.push_back(GenerateSecRectInfoFromNode(*node, rect));
2045         if (!node->ChildrenHasUIExtension()) {
2046             return;
2047         }
2048     }
2049     // continue to traverse.
2050     for (const auto& child : *node->GetSortedChildren()) {
2051         TraverseAndCollectUIExtensionInfo(child, boundsGeo.GetAbsMatrix(), hostId, callbackData, isUnobscured);
2052     }
2053 }
2054 
ProcessCacheImage(RSPaintFilterCanvas & canvas,Drawing::Image & cacheImageProcessed)2055 void RSUniRenderUtil::ProcessCacheImage(RSPaintFilterCanvas& canvas, Drawing::Image& cacheImageProcessed)
2056 {
2057     Drawing::Brush brush;
2058     brush.SetAntiAlias(true);
2059     canvas.AttachBrush(brush);
2060     // Be cautious when changing FilterMode and MipmapMode that may affect clarity
2061     auto sampling = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NEAREST);
2062     canvas.DrawImage(cacheImageProcessed, 0, 0, sampling);
2063     canvas.DetachBrush();
2064 }
2065 
ProcessCacheImageRect(RSPaintFilterCanvas & canvas,Drawing::Image & cacheImageProcessed,const Drawing::Rect & src,const Drawing::Rect & dst)2066 void RSUniRenderUtil::ProcessCacheImageRect(RSPaintFilterCanvas& canvas, Drawing::Image& cacheImageProcessed,
2067     const Drawing::Rect& src, const Drawing::Rect& dst)
2068 {
2069     Drawing::Brush brush;
2070     brush.SetAntiAlias(true);
2071     canvas.AttachBrush(brush);
2072     // Be cautious when changing FilterMode and MipmapMode that may affect clarity
2073     auto sampling = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NEAREST);
2074     canvas.DrawImageRect(cacheImageProcessed, src, dst, sampling, Drawing::SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
2075     canvas.DetachBrush();
2076 }
2077 
ProcessCacheImageForMultiScreenView(RSPaintFilterCanvas & canvas,Drawing::Image & cacheImageProcessed,const RectF & rect)2078 void RSUniRenderUtil::ProcessCacheImageForMultiScreenView(RSPaintFilterCanvas& canvas,
2079     Drawing::Image& cacheImageProcessed, const RectF& rect)
2080 {
2081     if (cacheImageProcessed.GetWidth() == 0 || cacheImageProcessed.GetHeight() == 0) {
2082         RS_TRACE_NAME("ProcessCacheImageForMultiScreenView cacheImageProcessed is invalid");
2083         return;
2084     }
2085     Drawing::Brush brush;
2086     brush.SetAntiAlias(true);
2087     canvas.AttachBrush(brush);
2088     // Be cautious when changing FilterMode and MipmapMode that may affect clarity
2089     auto sampling = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NEAREST);
2090     canvas.Save();
2091     // Use Fill Mode
2092     const float scaleX = rect.GetWidth() / cacheImageProcessed.GetWidth();
2093     const float scaleY = rect.GetHeight() / cacheImageProcessed.GetHeight();
2094     canvas.Scale(scaleX, scaleY);
2095     canvas.DrawImage(cacheImageProcessed, 0, 0, sampling);
2096     canvas.Restore();
2097     canvas.DetachBrush();
2098 }
2099 
FlushDmaSurfaceBuffer(Media::PixelMap * pixelMap)2100 void RSUniRenderUtil::FlushDmaSurfaceBuffer(Media::PixelMap* pixelMap)
2101 {
2102     if (!pixelMap || pixelMap->GetAllocatorType() != Media::AllocatorType::DMA_ALLOC) {
2103         return;
2104     }
2105     SurfaceBuffer* surfaceBuffer = reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd());
2106     if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
2107         GSError err = surfaceBuffer->Map();
2108         if (err != GSERROR_OK) {
2109             RS_LOGE("RSUniRenderUtil::FlushDmaSurfaceBuffer Map failed, GSError=%{public}d", err);
2110             return;
2111         }
2112         err = surfaceBuffer->InvalidateCache();
2113         if (err != GSERROR_OK) {
2114             RS_LOGE("RSUniRenderUtil::FlushDmaSurfaceBuffer InvalidateCache failed, GSError=%{public}d", err);
2115         }
2116     }
2117 }
2118 
GetMatrix(std::shared_ptr<RSRenderNode> hwcNode)2119 std::optional<Drawing::Matrix> RSUniRenderUtil::GetMatrix(
2120     std::shared_ptr<RSRenderNode> hwcNode)
2121 {
2122     if (!hwcNode) {
2123         return std::nullopt;
2124     }
2125     auto relativeMat = Drawing::Matrix();
2126     auto& property = hwcNode->GetRenderProperties();
2127     if (auto geo = property.GetBoundsGeometry()) {
2128         if (LIKELY(!property.GetSandBox().has_value())) {
2129             relativeMat = geo->GetMatrix();
2130         } else {
2131             auto parent = hwcNode->GetParent().lock();
2132             if (!parent) {
2133                 return std::nullopt;
2134             }
2135             if (auto parentGeo = parent->GetRenderProperties().GetBoundsGeometry()) {
2136                 auto invertAbsParentMatrix = Drawing::Matrix();
2137                 parentGeo->GetAbsMatrix().Invert(invertAbsParentMatrix);
2138                 relativeMat = geo->GetAbsMatrix();
2139                 relativeMat.PostConcat(invertAbsParentMatrix);
2140             }
2141         }
2142     } else {
2143         return std::nullopt;
2144     }
2145     return relativeMat;
2146 }
2147 
CheckRenderSkipIfScreenOff(bool extraFrame,std::optional<ScreenId> screenId)2148 bool RSUniRenderUtil::CheckRenderSkipIfScreenOff(bool extraFrame, std::optional<ScreenId> screenId)
2149 {
2150     if (!RSSystemProperties::GetSkipDisplayIfScreenOffEnabled()) {
2151         return false;
2152     }
2153     auto screenManager = CreateOrGetScreenManager();
2154     if (!screenManager) {
2155         RS_LOGE("RSUniRenderUtil::CheckRenderSkipIfScreenOff, failed to get screen manager!");
2156         return false;
2157     }
2158     // in certain cases such as wireless display, render skipping may be disabled.
2159     auto disableRenderControlScreensCount = screenManager->GetDisableRenderControlScreensCount();
2160     auto isScreenOff = screenId.has_value() ?
2161         screenManager->IsScreenPowerOff(screenId.value()) : screenManager->IsAllScreensPowerOff();
2162     RS_TRACE_NAME_FMT("CheckRenderSkipIfScreenOff disableRenderControl:[%d], PowerOff:[%d]",
2163         disableRenderControlScreensCount, isScreenOff);
2164     if (disableRenderControlScreensCount != 0 || !isScreenOff) {
2165         return false;
2166     }
2167     if (extraFrame && screenManager->GetPowerOffNeedProcessOneFrame()) {
2168         RS_LOGI("RSUniRenderUtil::CheckRenderSkipIfScreenOff screen power off, one more frame.");
2169         screenManager->ResetPowerOffNeedProcessOneFrame();
2170         return false;
2171     } else {
2172         return !screenManager->GetPowerOffNeedProcessOneFrame();
2173     }
2174 }
2175 
UpdateHwcNodeProperty(std::shared_ptr<RSSurfaceRenderNode> hwcNode)2176 void RSUniRenderUtil::UpdateHwcNodeProperty(std::shared_ptr<RSSurfaceRenderNode> hwcNode)
2177 {
2178     if (hwcNode == nullptr) {
2179         RS_LOGE("hwcNode is null.");
2180         return;
2181     }
2182     auto hwcNodeGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2183     if (!hwcNodeGeo) {
2184         RS_LOGE("hwcNode Geometry is not prepared.");
2185         return;
2186     }
2187     bool hasCornerRadius = !hwcNode->GetRenderProperties().GetCornerRadius().IsZero();
2188     std::vector<RectI> currIntersectedRoundCornerAABBs = {};
2189     float alpha = hwcNode->GetRenderProperties().GetAlpha();
2190     Drawing::Matrix totalMatrix = hwcNodeGeo->GetMatrix();
2191     auto hwcNodeRect = hwcNodeGeo->GetAbsRect();
2192     bool isNodeRenderByDrawingCache = false;
2193     bool isNodeRenderBySaveLayer = false;
2194     hwcNode->SetAbsRotation(hwcNode->GetRenderProperties().GetRotation());
2195     RSUniRenderUtil::TraverseParentNodeAndReduce(
2196         hwcNode,
2197         [&isNodeRenderByDrawingCache](std::shared_ptr<RSRenderNode> parent) {
2198             if (isNodeRenderByDrawingCache) {
2199                 return;
2200             }
2201             // if the parent node of hwcNode is marked freeze or nodegroup, RS closes hardware composer of hwcNode.
2202             isNodeRenderByDrawingCache = isNodeRenderByDrawingCache || parent->IsStaticCached() ||
2203                 (parent->GetNodeGroupType() != RSRenderNode::NodeGroupType::NONE);
2204         },
2205         [&alpha](std::shared_ptr<RSRenderNode> parent) {
2206             auto& parentProperty = parent->GetRenderProperties();
2207             alpha *= parentProperty.GetAlpha();
2208         },
2209         [&totalMatrix](std::shared_ptr<RSRenderNode> parent) {
2210             if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
2211                 totalMatrix.PostConcat(opt.value());
2212             } else {
2213                 return;
2214             }
2215         },
2216         [&currIntersectedRoundCornerAABBs, hwcNodeRect](std::shared_ptr<RSRenderNode> parent) {
2217             auto& parentProperty = parent->GetRenderProperties();
2218             auto cornerRadius = parentProperty.GetCornerRadius();
2219             auto maxCornerRadius = *std::max_element(std::begin(cornerRadius.data_), std::end(cornerRadius.data_));
2220             auto parentGeo = parentProperty.GetBoundsGeometry();
2221             static const std::array offsetVecs {
2222                 UIPoint { 0, 0 },
2223                 UIPoint { 1, 0 },
2224                 UIPoint { 0, 1 },
2225                 UIPoint { 1, 1 }
2226             };
2227 
2228             // The logic here is to calculate whether the HWC Node affects
2229             // the round corner property of the parent node.
2230             // The method is calculating the rounded AABB of each HWC node
2231             // with respect to all parent nodes above it and storing the results.
2232             // When a HWC node is found below, the AABBs and the HWC node
2233             // are checked for intersection. If there is an intersection,
2234             // the node above it is disabled from taking the HWC pipeline.
2235             auto checkIntersectWithRoundCorner = [&currIntersectedRoundCornerAABBs, hwcNodeRect](
2236                 const RectI& rect, float radiusX, float radiusY) {
2237                 if (radiusX <= 0 || radiusY <= 0) {
2238                     return;
2239                 }
2240                 UIPoint offset { rect.GetWidth() - radiusX, rect.GetHeight() - radiusY };
2241                 UIPoint anchorPoint { rect.GetLeft(), rect.GetTop() };
2242                 std::for_each(std::begin(offsetVecs), std::end(offsetVecs),
2243                     [&currIntersectedRoundCornerAABBs, hwcNodeRect, offset,
2244                         radiusX, radiusY, anchorPoint](auto offsetVec) {
2245                         auto res = anchorPoint + offset * offsetVec;
2246                         auto roundCornerAABB = RectI(res.x_, res.y_, radiusX, radiusY);
2247                         if (!roundCornerAABB.IntersectRect(hwcNodeRect).IsEmpty()) {
2248                             currIntersectedRoundCornerAABBs.push_back(roundCornerAABB);
2249                         }
2250                     }
2251                 );
2252             };
2253             if (parentGeo) {
2254                 auto parentRect = parentGeo->GetAbsRect();
2255                 checkIntersectWithRoundCorner(parentRect, maxCornerRadius, maxCornerRadius);
2256 
2257                 if (parentProperty.GetClipToRRect()) {
2258                     RRect parentClipRRect = parentProperty.GetClipRRect();
2259                     RectI parentClipRect = parentGeo->MapAbsRect(parentClipRRect.rect_);
2260                     float maxClipRRectCornerRadiusX = 0;
2261                     float maxClipRRectCornerRadiusY = 0;
2262                     constexpr size_t radiusVecSize = 4;
2263                     for (size_t i = 0; i < radiusVecSize; ++i) {
2264                         maxClipRRectCornerRadiusX = std::max(maxClipRRectCornerRadiusX, parentClipRRect.radius_[i].x_);
2265                         maxClipRRectCornerRadiusY = std::max(maxClipRRectCornerRadiusY, parentClipRRect.radius_[i].y_);
2266                     }
2267                     checkIntersectWithRoundCorner(parentClipRect, maxClipRRectCornerRadiusX, maxClipRRectCornerRadiusY);
2268                 }
2269             }
2270         },
2271         [hwcNode](std::shared_ptr<RSRenderNode> parent) {
2272             hwcNode->SetAbsRotation(hwcNode->GetAbsRotation() + parent->GetRenderProperties().GetRotation());
2273         },
2274         [&isNodeRenderBySaveLayer](std::shared_ptr<RSRenderNode> parent) {
2275             if (isNodeRenderBySaveLayer) {
2276                 return;
2277             }
2278             const auto& parentProperty = parent->GetRenderProperties();
2279             isNodeRenderBySaveLayer = isNodeRenderBySaveLayer ||
2280                 (parentProperty.IsColorBlendApplyTypeOffscreen() && !parentProperty.IsColorBlendModeNone());
2281         });
2282     if (isNodeRenderByDrawingCache || isNodeRenderBySaveLayer) {
2283         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by drawing cache or save layer, ",
2284             "isNodeRenderByDrawingCache[%d] isNodeRenderBySaveLayer[%d]",
2285             hwcNode->GetName().c_str(), hwcNode->GetId(), isNodeRenderByDrawingCache, isNodeRenderBySaveLayer);
2286         hwcNode->SetHardwareForcedDisabledState(true);
2287     }
2288     hwcNode->SetTotalMatrix(totalMatrix);
2289     hwcNode->SetGlobalAlpha(alpha);
2290     hwcNode->SetIntersectedRoundCornerAABBs(std::move(currIntersectedRoundCornerAABBs));
2291 }
2292 
2293 #ifdef FRAME_AWARE_TRACE
FrameAwareTraceBoost(size_t layerNum)2294 bool RSUniRenderUtil::FrameAwareTraceBoost(size_t layerNum)
2295 {
2296     using namespace FRAME_TRACE;
2297     constexpr uint32_t FRAME_TRACE_LAYER_NUM_1 = 11;
2298     constexpr uint32_t FRAME_TRACE_LAYER_NUM_2 = 13;
2299     constexpr int32_t FRAME_TRACE_PERF_REQUESTED_CODE = 10024;
2300     RenderFrameTrace& ft = RenderFrameTrace::GetInstance();
2301     if (layerNum != FRAME_TRACE_LAYER_NUM_1 && layerNum != FRAME_TRACE_LAYER_NUM_2) {
2302         if (ft.RenderFrameTraceIsOpen()) {
2303             ft.RenderFrameTraceClose();
2304             PerfRequest(FRAME_TRACE_PERF_REQUESTED_CODE, false);
2305             RS_LOGD("RsDebug RSUniRenderUtil::Perf: FrameTrace 0");
2306         }
2307         return false;
2308     }
2309 
2310     static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
2311     auto currentTime = std::chrono::steady_clock::now();
2312     bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
2313         count() > PERF_TIME_OUT;
2314     if (isTimeOut || !ft.RenderFrameTraceIsOpen()) {
2315         if (!ft.RenderFrameTraceOpen()) {
2316             return false;
2317         }
2318         PerfRequest(FRAME_TRACE_PERF_REQUESTED_CODE, true);
2319         RS_LOGD("RsDebug RSProcessor::Perf: FrameTrace 1");
2320         lastRequestPerfTime = currentTime;
2321     }
2322     return true;
2323 }
2324 #endif
2325 
RequestPerf(uint32_t layerLevel,bool onOffTag)2326 void RSUniRenderUtil::RequestPerf(uint32_t layerLevel, bool onOffTag)
2327 {
2328     switch (layerLevel) {
2329         case PERF_LEVEL_0: {
2330             // do nothing
2331             RS_LOGD("RsDebug RSProcessor::perf do nothing");
2332             break;
2333         }
2334         case PERF_LEVEL_1: {
2335             PerfRequest(PERF_LEVEL_1_REQUESTED_CODE, onOffTag);
2336             RS_LOGD("RsDebug RSProcessor::Perf: level1 %{public}d", onOffTag);
2337             break;
2338         }
2339         case PERF_LEVEL_2: {
2340             PerfRequest(PERF_LEVEL_2_REQUESTED_CODE, onOffTag);
2341             RS_LOGD("RsDebug RSProcessor::Perf: level2 %{public}d", onOffTag);
2342             break;
2343         }
2344         default: {
2345             PerfRequest(PERF_LEVEL_3_REQUESTED_CODE, onOffTag);
2346             RS_LOGD("RsDebug RSProcessor::Perf: level3 %{public}d", onOffTag);
2347             break;
2348         }
2349     }
2350 }
2351 
MultiLayersPerf(size_t layerNum)2352 void RSUniRenderUtil::MultiLayersPerf(size_t layerNum)
2353 {
2354     RS_LOGD("FrameAwareTraceBoost return false");
2355     static uint32_t lastLayerLevel = 0;
2356     constexpr uint32_t PERF_LEVEL_INTERVAL = 10;
2357     static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
2358     auto curLayerLevel = layerNum / PERF_LEVEL_INTERVAL;
2359     if (curLayerLevel == 0 && layerNum >= PERF_LAYER_START_NUM) {
2360         curLayerLevel = 1;
2361     }
2362     auto currentTime = std::chrono::steady_clock::now();
2363     bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
2364         count() > PERF_TIME_OUT;
2365     if (curLayerLevel != lastLayerLevel || isTimeOut) {
2366         if (!isTimeOut) {
2367             RequestPerf(lastLayerLevel, false);
2368         }
2369         RequestPerf(curLayerLevel, true);
2370         lastLayerLevel = curLayerLevel;
2371         lastRequestPerfTime = currentTime;
2372     }
2373 }
2374 
GetImageRegions(float screenWidth,float screenHeight,float realImageWidth,float realImageHeight)2375 Drawing::Rect RSUniRenderUtil::GetImageRegions(float screenWidth, float screenHeight,
2376     float realImageWidth, float realImageHeight)
2377 {
2378     auto dstRect = Drawing::Rect(0, 0, screenWidth, screenHeight);
2379     if (ROSEN_EQ(realImageWidth, 0.0f) || ROSEN_EQ(realImageHeight, 0.0f)) {
2380         return dstRect;
2381     }
2382     float imageScaleWidth = screenWidth / static_cast<float>(realImageWidth);
2383     float imageScaleHeight = screenHeight / static_cast<float>(realImageHeight);
2384     auto imageWidth = realImageWidth * imageScaleHeight;
2385     auto imageHeight = realImageHeight * imageScaleWidth;
2386     // Ensure that the security mask is located in the middle of the virtual screen.
2387     if (imageScaleWidth > imageScaleHeight) {
2388         // Left and right set black
2389         float halfBoundWidthLeft = (screenWidth - imageWidth) / 2;
2390         float halfBoundWidthRight = halfBoundWidthLeft + imageWidth;
2391         dstRect = Drawing::Rect(halfBoundWidthLeft, 0, halfBoundWidthRight, screenHeight);
2392         return dstRect;
2393     }
2394 
2395     if (imageScaleWidth < imageScaleHeight) {
2396         // Up and down set black
2397         float halfBoundHeightTop = (screenHeight - imageHeight) / 2;
2398         float halfBoundHeightBottom = halfBoundHeightTop + imageHeight;
2399         dstRect = Drawing::Rect(0, halfBoundHeightTop, screenWidth, halfBoundHeightBottom);
2400         return dstRect;
2401     }
2402     return dstRect;
2403 }
2404 
GetSampledDamageAndDrawnRegion(const ScreenInfo & screenInfo,const Occlusion::Region & srcDamageRegion,bool isDirtyAlignEnabled,Occlusion::Region & sampledDamageRegion,Occlusion::Region & sampledDrawnRegion)2405 void RSUniRenderUtil::GetSampledDamageAndDrawnRegion(const ScreenInfo& screenInfo,
2406     const Occlusion::Region& srcDamageRegion, bool isDirtyAlignEnabled, Occlusion::Region& sampledDamageRegion,
2407     Occlusion::Region& sampledDrawnRegion)
2408 {
2409     Drawing::Matrix scaleMatrix;
2410     scaleMatrix.SetScaleTranslate(screenInfo.samplingScale, screenInfo.samplingScale,
2411         screenInfo.samplingTranslateX, screenInfo.samplingTranslateY);
2412     const Vector4<int> expandSize{screenInfo.samplingDistance, screenInfo.samplingDistance,
2413         screenInfo.samplingDistance, screenInfo.samplingDistance};
2414     auto rects = srcDamageRegion.GetRegionRectIs();
2415     sampledDamageRegion.Reset();
2416     for (const auto& rect : rects) {
2417         RectI mappedRect = RSObjAbsGeometry::MapRect(rect.ConvertTo<float>(), scaleMatrix);
2418         Occlusion::Region mappedAndExpandedRegion{mappedRect.MakeOutset(expandSize)};
2419         sampledDamageRegion.OrSelf(mappedAndExpandedRegion);
2420     }
2421 
2422     Occlusion::Region drawnRegion = isDirtyAlignEnabled ?
2423         sampledDamageRegion.GetAlignedRegion(MAX_DIRTY_ALIGNMENT_SIZE) : sampledDamageRegion;
2424 
2425     Drawing::Matrix invertedScaleMatrix;
2426     if (!scaleMatrix.Invert(invertedScaleMatrix)) {
2427         RS_LOGW("%{public}s, invert scaleMatrix failed", __func__);
2428         sampledDrawnRegion = drawnRegion;
2429         return;
2430     }
2431     sampledDrawnRegion.Reset();
2432     for (const auto& rect : drawnRegion.GetRegionRectIs()) {
2433         RectI mappedRect = RSObjAbsGeometry::MapRect(rect.ConvertTo<float>(), invertedScaleMatrix);
2434         Occlusion::Region mappedRegion{mappedRect};
2435         sampledDrawnRegion.OrSelf(mappedRegion);
2436     }
2437 }
2438 } // namespace Rosen
2439 } // namespace OHOS
2440