• 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_screen_render_node_drawable.h"
32 #include "drawable/rs_surface_render_node_drawable.h"
33 #include "feature/anco_manager/rs_anco_manager.h"
34 #include "feature/dirty/rs_uni_dirty_compute_util.h"
35 #include "feature/uifirst/rs_sub_thread_manager.h"
36 #ifdef RS_ENABLE_OVERLAY_DISPLAY
37 #include "feature/overlay_display/rs_overlay_display_manager.h"
38 #endif
39 #include "graphic_feature_param_manager.h"
40 #include "info_collection/rs_gpu_dirty_region_collection.h"
41 #include "memory/rs_tag_tracker.h"
42 #include "params/rs_screen_render_params.h"
43 #include "params/rs_surface_render_params.h"
44 #include "rs_base_render_util.h"
45 #include "pipeline/main_thread/rs_main_thread.h"
46 #include "pipeline/rs_render_node.h"
47 #include "pipeline/rs_surface_render_node.h"
48 #include "platform/common/rs_log.h"
49 #include "property/rs_properties.h"
50 #include "render/rs_drawing_filter.h"
51 #include "render/rs_render_maskcolor_filter.h"
52 #include "render/rs_material_filter.h"
53 #include "render/rs_path.h"
54 
55 #ifdef RS_ENABLE_VK
56 #ifdef USE_M133_SKIA
57 #include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
58 #include "include/gpu/ganesh/vk/GrVkBackendSemaphore.h"
59 #else
60 #include "include/gpu/GrBackendSurface.h"
61 #endif
62 #include "platform/ohos/backend/native_buffer_utils.h"
63 #include "platform/ohos/backend/rs_hdr_vulkan_task.h"
64 #include "platform/ohos/backend/rs_surface_ohos_vulkan.h"
65 #include "platform/ohos/backend/rs_vulkan_context.h"
66 #endif
67 
68 #ifdef SOC_PERF_ENABLE
69 #include "socperf_client.h"
70 #endif
71 #include "hetero_hdr/rs_hdr_pattern_manager.h"
72 #include "render_frame_trace.h"
73 
74 namespace OHOS {
75 namespace Rosen {
76 namespace {
77 constexpr const char* CAPTURE_WINDOW_NAME = "CapsuleWindow";
78 constexpr float GAMMA2_2 = 2.2f;
79 constexpr int64_t PERF_TIME_OUT = 950;
80 constexpr uint32_t PERF_LEVEL_INTERVAL = 10;
81 constexpr uint32_t PERF_LAYER_START_NUM = 12;
82 constexpr uint32_t PERF_LEVEL_0 = 0;
83 constexpr uint32_t PERF_LEVEL_1 = 1;
84 constexpr uint32_t PERF_LEVEL_2 = 2;
85 constexpr int32_t PERF_LEVEL_1_REQUESTED_CODE = 10013;
86 constexpr int32_t PERF_LEVEL_2_REQUESTED_CODE = 10014;
87 constexpr int32_t PERF_LEVEL_3_REQUESTED_CODE = 10015;
PerfRequest(int32_t perfRequestCode,bool onOffTag)88 void PerfRequest(int32_t perfRequestCode, bool onOffTag)
89 {
90 #ifdef SOC_PERF_ENABLE
91     OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(perfRequestCode, onOffTag, "");
92     RS_LOGD("RSProcessor::soc perf info [%{public}d %{public}d]", perfRequestCode, onOffTag);
93 #endif
94 }
95 }
ExpandDamageRegionToSingleRect(Occlusion::Region & damageRegion)96 void RSUniRenderUtil::ExpandDamageRegionToSingleRect(Occlusion::Region& damageRegion)
97 {
98     const auto clipRectThreshold = RSSystemProperties::GetClipRectThreshold();
99     if (clipRectThreshold < 1.f) {
100         auto bound = damageRegion.GetBound();
101         // Multi-rects damage region will lead to clip path, which is performance-affecting.
102         // Within reasonable threshold, consider expanding multi-rects into one single rect for performance improvement.
103         if (damageRegion.GetSize() > 1 && !bound.IsEmpty() && damageRegion.Area() > bound.Area() * clipRectThreshold) {
104             RS_OPTIONAL_TRACE_NAME_FMT("dirty expand: %s to %s",
105                 damageRegion.GetRegionInfo().c_str(), bound.GetRectInfo().c_str());
106             damageRegion = Occlusion::Region { bound };
107         }
108     }
109 }
110 
MergeDirtyHistory(DrawableV2::RSScreenRenderNodeDrawable & screenDrawable,int32_t bufferAge,ScreenInfo & screenInfo,RSDirtyRectsDfx & rsDirtyRectsDfx,RSScreenRenderParams & params)111 std::vector<RectI> RSUniRenderUtil::MergeDirtyHistory(DrawableV2::RSScreenRenderNodeDrawable& screenDrawable,
112     int32_t bufferAge, ScreenInfo& screenInfo, RSDirtyRectsDfx& rsDirtyRectsDfx, RSScreenRenderParams& params)
113 {
114     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
115     // renderThreadParams/dirtyManager not null in caller
116     auto dirtyManager = screenDrawable.GetSyncDirtyManager();
117     auto& curAllSurfaceDrawables = params.GetAllMainAndLeashSurfaceDrawables();
118     RSUniRenderUtil::MergeDirtyHistoryForDrawable(screenDrawable, bufferAge, params, false);
119     Occlusion::Region dirtyRegion = RSUniRenderUtil::MergeVisibleAdvancedDirtyRegion(
120         curAllSurfaceDrawables, RSUniRenderThread::Instance().GetDrawStatusVec());
121 
122     RectI screenRectI(0, 0, static_cast<int32_t>(screenInfo.phyWidth), static_cast<int32_t>(screenInfo.phyHeight));
123 
124     Occlusion::Region globalDirtyRegion;
125     for (const auto& rect : dirtyManager->GetAdvancedDirtyRegion()) {
126         Occlusion::Region region = Occlusion::Region(Occlusion::Rect(rect));
127         globalDirtyRegion.OrSelf(region);
128         GpuDirtyRegionCollection::GetInstance().UpdateGlobalDirtyInfoForDFX(rect.IntersectRect(screenRectI));
129     }
130     rsDirtyRectsDfx.SetDirtyRegion(dirtyRegion);
131     Occlusion::Region damageRegion;
132     RS_TRACE_NAME_FMT("AdvancedDirtyRegionType is [%d]", static_cast<int>(uniParam->GetAdvancedDirtyType()));
133     switch (uniParam->GetAdvancedDirtyType()) {
134         case AdvancedDirtyRegionType::DISABLED:
135             damageRegion = dirtyRegion.Or(globalDirtyRegion);
136             break;
137         case AdvancedDirtyRegionType::SET_ADVANCED_SURFACE_AND_DISPLAY:
138             damageRegion = RSUniRenderUtil::MergeDirtyRects(dirtyRegion.Or(globalDirtyRegion));
139             break;
140         case AdvancedDirtyRegionType::SET_ADVANCED_DISPLAY:
141             damageRegion = RSUniRenderUtil::MergeDirtyRects(globalDirtyRegion);
142             damageRegion.OrSelf(dirtyRegion);
143             break;
144         default:
145             damageRegion = dirtyRegion.Or(globalDirtyRegion);
146             RS_LOGI("RSUniRenderUtil::MergeDirtyHistory unsupported advanced dirty region type");
147             RS_TRACE_NAME_FMT("RSUniRenderUtil::MergeDirtyHistory unsupported advanced dirty region type");
148             break;
149     }
150     if (!uniParam->IsDirtyAlignEnabled()) {
151         ExpandDamageRegionToSingleRect(damageRegion);
152     }
153     // [Attention]: Filter dirty must be the last. If sampling is needed, sample after filter dirty processing.
154     Occlusion::Region drawnRegion;
155     if (screenInfo.isSamplingOn && screenInfo.samplingScale > 0) {
156         GetSampledDamageAndDrawnRegion(screenInfo, damageRegion, uniParam->IsDirtyAlignEnabled(),
157             damageRegion, drawnRegion);
158     } else {
159         drawnRegion = uniParam->IsDirtyAlignEnabled() ?
160             damageRegion.GetAlignedRegion(MAX_DIRTY_ALIGNMENT_SIZE) : damageRegion;
161         RSUniFilterDirtyComputeUtil::DealWithFilterDirtyRegion(
162             damageRegion, drawnRegion, screenDrawable, std::nullopt, uniParam->IsDirtyAlignEnabled());
163     }
164     // [Attention]: filter dirty process must be the last step.
165     RSUniFilterDirtyComputeUtil::DealWithFilterDirtyRegion(
166         damageRegion, drawnRegion, screenDrawable, std::nullopt, uniParam->IsDirtyAlignEnabled());
167 #ifdef RS_ENABLE_OVERLAY_DISPLAY
168     // overlay display expand dirty region
169     RSOverlayDisplayManager::Instance().ExpandDirtyRegion(*dirtyManager, screenInfo, drawnRegion, damageRegion);
170 #endif
171     RSUniRenderUtil::SetDrawRegionForQuickReject(curAllSurfaceDrawables, drawnRegion);
172     rsDirtyRectsDfx.SetMergedDirtyRegion(drawnRegion);
173     params.SetDrawnRegion(drawnRegion);
174     auto damageRegionRects = RSUniDirtyComputeUtil::ScreenIntersectDirtyRects(damageRegion, screenInfo);
175     if (damageRegionRects.empty()) {
176         // When damageRegionRects is empty, SetDamageRegion function will not take effect and buffer will
177         // full screen refresh. Therefore, we need to insert an empty rect into the damageRegionRects array
178         damageRegionRects.emplace_back(RectI(0, 0, 0, 0));
179     }
180     return damageRegionRects;
181 }
182 
MergeDirtyHistoryInVirtual(DrawableV2::RSScreenRenderNodeDrawable & screenDrawable,int32_t bufferAge,const ScreenInfo & screenInfo,bool isSecScreen)183 std::vector<RectI> RSUniRenderUtil::MergeDirtyHistoryInVirtual(
184     DrawableV2::RSScreenRenderNodeDrawable& screenDrawable, int32_t bufferAge,
185     const ScreenInfo& screenInfo, bool isSecScreen)
186 {
187     auto params = static_cast<RSScreenRenderParams*>(screenDrawable.GetRenderParams().get());
188     auto& renderThreadParams = RSUniRenderThread::Instance().GetRSRenderThreadParams();
189     if (!renderThreadParams || !params) {
190         return {};
191     }
192     auto& curAllSurfaceDrawables = params->GetAllMainAndLeashSurfaceDrawables();
193     auto dirtyManager = screenDrawable.GetSyncDirtyManager();
194     RSUniRenderUtil::MergeDirtyHistoryInVirtual(screenDrawable, bufferAge);
195     Occlusion::Region dirtyRegion = RSUniRenderUtil::MergeVisibleDirtyRegionInVirtual(
196         curAllSurfaceDrawables, *params, isSecScreen);
197 
198     RectI rect = dirtyManager->GetRectFlipWithinSurface(dirtyManager->GetDirtyRegionInVirtual());
199     auto rects = RSUniDirtyComputeUtil::ScreenIntersectDirtyRects(dirtyRegion, screenInfo);
200     if (!rect.IsEmpty()) {
201         rects.emplace_back(rect);
202     }
203     if (screenInfo.isSamplingOn && screenInfo.samplingScale > 0) {
204         std::vector<RectI> dstDamageRegionrects;
205         for (const auto& rect : rects) {
206             Drawing::Matrix scaleMatrix;
207             scaleMatrix.SetScaleTranslate(screenInfo.samplingScale, screenInfo.samplingScale,
208                 screenInfo.samplingTranslateX, screenInfo.samplingTranslateY);
209             RectI mappedRect = RSObjAbsGeometry::MapRect(rect.ConvertTo<float>(), scaleMatrix);
210             const Vector4<int> expandSize{screenInfo.samplingDistance, screenInfo.samplingDistance,
211                 screenInfo.samplingDistance, screenInfo.samplingDistance};
212             dstDamageRegionrects.emplace_back(mappedRect.MakeOutset(expandSize));
213         }
214         return dstDamageRegionrects;
215     }
216     return rects;
217 }
218 
MergeDirtyHistoryForDrawable(DrawableV2::RSScreenRenderNodeDrawable & screenDrawable,int32_t bufferAge,RSScreenRenderParams & params,bool useAlignedDirtyRegion)219 void RSUniRenderUtil::MergeDirtyHistoryForDrawable(DrawableV2::RSScreenRenderNodeDrawable& screenDrawable,
220     int32_t bufferAge, RSScreenRenderParams& params, bool useAlignedDirtyRegion)
221 {
222     auto& curAllSurfaceDrawables = params.GetAllMainAndLeashSurfaceDrawables();
223     // update all child surfacenode history
224     for (auto it = curAllSurfaceDrawables.rbegin(); it != curAllSurfaceDrawables.rend(); ++it) {
225         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
226         if (surfaceNodeDrawable == nullptr) {
227             continue;
228         }
229         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
230         if (surfaceParams == nullptr || !surfaceParams->IsLeashOrMainWindow()) {
231             continue;
232         }
233         // for cross-display surface, only merge dirty history once.
234         if (surfaceParams->IsFirstLevelCrossNode() && !params.IsFirstVisitCrossNodeDisplay()) {
235             continue;
236         }
237         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
238         if (surfaceDirtyManager == nullptr) {
239             continue;
240         }
241         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderUtil::MergeDirtyHistory for surfaceNode %" PRIu64"",
242             surfaceParams->GetId());
243         if (!surfaceDirtyManager->SetBufferAge(bufferAge)) {
244             ROSEN_LOGW("RSUniRenderUtil::MergeDirtyHistory with invalid buffer age %{public}d", bufferAge);
245         }
246         surfaceDirtyManager->IntersectDirtyRect(surfaceParams->GetOldDirtyInSurface());
247         surfaceDirtyManager->UpdateDirty(useAlignedDirtyRegion);
248     }
249 
250     // update display dirtymanager
251     if (auto dirtyManager = screenDrawable.GetSyncDirtyManager()) {
252         dirtyManager->SetBufferAge(bufferAge);
253         dirtyManager->UpdateDirty(useAlignedDirtyRegion);
254     }
255 }
256 
MergeVisibleDirtyRegion(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceNodeDrawables,std::vector<NodeId> & hasVisibleDirtyRegionSurfaceVec,bool useAlignedDirtyRegion)257 Occlusion::Region RSUniRenderUtil::MergeVisibleDirtyRegion(
258     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceNodeDrawables,
259     std::vector<NodeId>& hasVisibleDirtyRegionSurfaceVec, bool useAlignedDirtyRegion)
260 {
261     Occlusion::Region allSurfaceVisibleDirtyRegion;
262     for (auto it = allSurfaceNodeDrawables.rbegin(); it != allSurfaceNodeDrawables.rend(); ++it) {
263         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
264         if (surfaceNodeDrawable == nullptr) {
265             RS_LOGI("MergeVisibleDirtyRegion surfaceNodeDrawable is nullptr");
266             continue;
267         }
268         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
269         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
270         if (!surfaceParams || !surfaceDirtyManager) {
271             RS_LOGI("RSUniRenderUtil::MergeVisibleDirtyRegion node(%{public}" PRIu64") params or "
272                 "dirty manager is nullptr", surfaceNodeDrawable->GetId());
273             continue;
274         }
275         if (!surfaceParams->IsLeashOrMainWindow() || surfaceParams->GetDstRect().IsEmpty()) {
276             continue;
277         }
278         // for cross-display surface, only consider the dirty region on the first display (use global dirty for others).
279         if (surfaceParams->IsFirstLevelCrossNode() &&
280             !RSUniRenderThread::Instance().GetRSRenderThreadParams()->IsFirstVisitCrossNodeDisplay()) {
281             continue;
282         }
283         auto surfaceDirtyRect = surfaceDirtyManager->GetDirtyRegion();
284         Occlusion::Rect dirtyRect { surfaceDirtyRect.left_, surfaceDirtyRect.top_, surfaceDirtyRect.GetRight(),
285             surfaceDirtyRect.GetBottom() };
286         auto visibleRegion = surfaceParams->GetVisibleRegion();
287         Occlusion::Region surfaceDirtyRegion { dirtyRect };
288         Occlusion::Region surfaceVisibleDirtyRegion = surfaceDirtyRegion.And(visibleRegion);
289 
290         surfaceNodeDrawable->SetVisibleDirtyRegion(surfaceVisibleDirtyRegion);
291         if (!surfaceVisibleDirtyRegion.IsEmpty()) {
292             hasVisibleDirtyRegionSurfaceVec.emplace_back(surfaceParams->GetId());
293         }
294         if (useAlignedDirtyRegion) {
295             Occlusion::Region alignedRegion = AlignedDirtyRegion(surfaceVisibleDirtyRegion);
296             surfaceNodeDrawable->SetAlignedVisibleDirtyRegion(alignedRegion);
297             allSurfaceVisibleDirtyRegion.OrSelf(alignedRegion);
298             GpuDirtyRegionCollection::GetInstance().UpdateActiveDirtyInfoForDFX(surfaceParams->GetId(),
299                 surfaceNodeDrawable->GetName(), alignedRegion.GetRegionRectIs());
300         } else {
301             allSurfaceVisibleDirtyRegion = allSurfaceVisibleDirtyRegion.Or(surfaceVisibleDirtyRegion);
302             GpuDirtyRegionCollection::GetInstance().UpdateActiveDirtyInfoForDFX(surfaceParams->GetId(),
303                 surfaceNodeDrawable->GetName(), surfaceVisibleDirtyRegion.GetRegionRectIs());
304         }
305     }
306     return allSurfaceVisibleDirtyRegion;
307 }
308 
MergeVisibleAdvancedDirtyRegion(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceNodeDrawables,std::vector<NodeId> & hasVisibleDirtyRegionSurfaceVec)309 Occlusion::Region RSUniRenderUtil::MergeVisibleAdvancedDirtyRegion(
310     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceNodeDrawables,
311     std::vector<NodeId>& hasVisibleDirtyRegionSurfaceVec)
312 {
313     Occlusion::Region allSurfaceVisibleDirtyRegion;
314     for (auto it = allSurfaceNodeDrawables.rbegin(); it != allSurfaceNodeDrawables.rend(); ++it) {
315         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
316         if (surfaceNodeDrawable == nullptr) {
317             RS_LOGI("RSUniRenderUtil::MergeVisibleDirtyRegion surfaceNodeDrawable is nullptr");
318             continue;
319         }
320         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
321         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
322         if (!surfaceParams || !surfaceDirtyManager) {
323             RS_LOGI("RSUniRenderUtil::MergeVisibleDirtyRegion node(%{public}" PRIu64") params or"
324                 "dirty manager is nullptr", surfaceNodeDrawable->GetId());
325             continue;
326         }
327         if (!surfaceParams->IsLeashOrMainWindow()) {
328             continue;
329         }
330         //for cross-display surface, only consider the dirty region on the first display (use global dirty for others).
331         if (surfaceParams->IsFirstLevelCrossNode() &&
332             !RSUniRenderThread::Instance().GetRSRenderThreadParams()->IsFirstVisitCrossNodeDisplay()) {
333             continue;
334         }
335         Occlusion::Region surfaceAdvancedDirtyRegion = Occlusion::Region();
336         for (const auto& rect : surfaceDirtyManager->GetAdvancedDirtyRegion()) {
337             Occlusion::Region region = Occlusion::Region(Occlusion::Rect(rect));
338             surfaceAdvancedDirtyRegion.OrSelf(region);
339         }
340         auto visibleRegion = surfaceParams->GetVisibleRegion();
341         Occlusion::Region surfaceVisibleDirtyRegion = surfaceAdvancedDirtyRegion.And(visibleRegion);
342         surfaceNodeDrawable->SetVisibleDirtyRegion(surfaceVisibleDirtyRegion);
343         if (!surfaceVisibleDirtyRegion.IsEmpty()) {
344             hasVisibleDirtyRegionSurfaceVec.emplace_back(surfaceParams->GetId());
345         }
346         allSurfaceVisibleDirtyRegion = allSurfaceVisibleDirtyRegion.Or(surfaceVisibleDirtyRegion);
347         GpuDirtyRegionCollection::GetInstance().UpdateActiveDirtyInfoForDFX(surfaceParams->GetId(),
348             surfaceNodeDrawable->GetName(), surfaceVisibleDirtyRegion.GetRegionRectIs());
349     }
350     return allSurfaceVisibleDirtyRegion;
351 }
352 
MergeDirtyRects(Occlusion::Region dirtyRegion)353 Occlusion::Region RSUniRenderUtil::MergeDirtyRects(Occlusion::Region dirtyRegion)
354 {
355     RectsMerger merger(RSAdvancedDirtyConfig::RECT_NUM_MERGING_ALL, RSAdvancedDirtyConfig::RECT_NUM_MERGING_BY_LEVEL);
356     auto mergedRects = merger.MergeAllRects(dirtyRegion.GetRegionRects(),
357         RSAdvancedDirtyConfig::EXPECTED_OUTPUT_NUM, RSAdvancedDirtyConfig::MAX_TOLERABLE_COST);
358     Occlusion::Region results = {};
359     for (const auto& rect : mergedRects) {
360         Occlusion::Region region = Occlusion::Region(rect);
361         results.OrSelf(region);
362     }
363     return results;
364 }
365 
SetDrawRegionForQuickReject(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceDrawables,const Occlusion::Region mergedDirtyRects)366 void RSUniRenderUtil::SetDrawRegionForQuickReject(
367     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceDrawables,
368     const Occlusion::Region mergedDirtyRects)
369 {
370     auto rectsForQuickReject = mergedDirtyRects.GetRegionRectIs();
371     for (const auto& rect : mergedDirtyRects.GetRegionRects()) {
372         rectsForQuickReject.push_back(rect.ToRectI());
373     }
374     for (auto it = allSurfaceDrawables.rbegin(); it != allSurfaceDrawables.rend(); ++it) {
375         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
376         if (surfaceNodeDrawable == nullptr) {
377             continue;
378         }
379         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
380         if (!surfaceParams || (!surfaceParams->IsMainWindowType() && !surfaceParams->IsLeashWindow())) {
381             continue;
382         }
383         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
384         if (surfaceDirtyManager == nullptr) {
385             continue;
386         }
387         surfaceDirtyManager->SetDirtyRegionForQuickReject(rectsForQuickReject);
388     }
389 }
390 
MergeDirtyHistoryInVirtual(DrawableV2::RSScreenRenderNodeDrawable & screenDrawable,int32_t bufferAge,bool renderParallel)391 void RSUniRenderUtil::MergeDirtyHistoryInVirtual(
392     DrawableV2::RSScreenRenderNodeDrawable& screenDrawable, int32_t bufferAge, bool renderParallel)
393 {
394     (void)renderParallel;
395     auto& params = screenDrawable.GetRenderParams();
396     if (!params) {
397         RS_LOGE("RSUniRenderUtil::MergeDirtyHistory params is nullptr");
398         return;
399     }
400     auto& curAllSurfaceDrawables = params->GetAllMainAndLeashSurfaceDrawables();
401     for (auto it = curAllSurfaceDrawables.rbegin(); it != curAllSurfaceDrawables.rend(); ++it) {
402         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
403         if (surfaceNodeDrawable == nullptr) {
404             continue;
405         }
406         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
407         if (surfaceParams == nullptr || !surfaceParams->IsAppWindow()) {
408             continue;
409         }
410         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderUtil::MergeDirtyHistory for surfaceNode %" PRIu64"",
411             surfaceParams->GetId());
412         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
413         surfaceDirtyManager->MergeDirtyHistoryInVirtual(bufferAge);
414     }
415     // update display dirtymanager
416     auto displayDirtyManager = screenDrawable.GetSyncDirtyManager();
417     displayDirtyManager->MergeDirtyHistoryInVirtual(bufferAge);
418 }
419 
MergeVisibleDirtyRegionInVirtual(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceNodeDrawables,RSScreenRenderParams & screenParams,bool isSecScreen)420 Occlusion::Region RSUniRenderUtil::MergeVisibleDirtyRegionInVirtual(
421     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceNodeDrawables,
422     RSScreenRenderParams& screenParams, bool isSecScreen)
423 {
424     Occlusion::Region allSurfaceVisibleDirtyRegion;
425     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
426     if (screenManager == nullptr) {
427         RS_LOGE("RSUniRenderUtil::MergeVisibleDirtyRegionInVirtual, failed to get screen manager!");
428         return allSurfaceVisibleDirtyRegion;
429     }
430     auto curBlackList = screenManager->GetVirtualScreenBlackList(screenParams.GetScreenId());
431     for (auto it = allSurfaceNodeDrawables.rbegin(); it != allSurfaceNodeDrawables.rend(); ++it) {
432         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
433         if (surfaceNodeDrawable == nullptr) {
434             RS_LOGI("MergeVisibleDirtyRegion surfaceNodeDrawable is nullptr");
435             continue;
436         }
437         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
438         if (!surfaceParams) {
439             RS_LOGI("RSUniRenderUtil::MergeVisibleDirtyRegion surface params is nullptr");
440             continue;
441         }
442         if (!surfaceParams->IsAppWindow() || surfaceParams->GetDstRect().IsEmpty()) {
443             continue;
444         }
445         if (surfaceParams->GetSpecialLayerMgr().Find(SpecialLayerType::SKIP) && !isSecScreen) {
446             continue;
447         }
448         if (curBlackList.find(surfaceParams->GetId()) != curBlackList.end()) {
449             continue;
450         }
451         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
452         auto surfaceDirtyRect = surfaceDirtyManager->GetDirtyRegionInVirtual();
453         Occlusion::Rect dirtyRect { surfaceDirtyRect.left_, surfaceDirtyRect.top_,
454             surfaceDirtyRect.GetRight(), surfaceDirtyRect.GetBottom() };
455         auto visibleRegion = surfaceParams->GetVisibleRegionInVirtual();
456         Occlusion::Region surfaceDirtyRegion { dirtyRect };
457         Occlusion::Region surfaceVisibleDirtyRegion = surfaceDirtyRegion.And(visibleRegion);
458         allSurfaceVisibleDirtyRegion = allSurfaceVisibleDirtyRegion.Or(surfaceVisibleDirtyRegion);
459     }
460     return allSurfaceVisibleDirtyRegion;
461 }
462 
SrcRectScaleFit(BufferDrawParam & params,const sptr<SurfaceBuffer> & buffer,const sptr<IConsumerSurface> & surface,RectF & localBounds)463 void RSUniRenderUtil::SrcRectScaleFit(BufferDrawParam& params, const sptr<SurfaceBuffer>& buffer,
464     const sptr<IConsumerSurface>& surface, RectF& localBounds)
465 {
466     if (buffer == nullptr || surface == nullptr) {
467         RS_LOGE("buffer or surface is nullptr");
468         return;
469     }
470     uint32_t srcWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
471     uint32_t srcHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
472     float newWidth = 0.0f;
473     float newHeight = 0.0f;
474     // Canvas is able to handle the situation when the window is out of screen, using bounds instead of dst.
475     uint32_t boundsWidth = static_cast<uint32_t>(localBounds.GetWidth());
476     uint32_t boundsHeight = static_cast<uint32_t>(localBounds.GetHeight());
477     if (boundsWidth == 0 || boundsHeight == 0 || srcWidth == 0 || srcHeight == 0) {
478         return;
479     }
480 
481     if (srcWidth * boundsHeight > srcHeight * boundsWidth) {
482         newWidth = boundsWidth;
483         newHeight = srcHeight * newWidth / srcWidth;
484     } else if (srcWidth * boundsHeight < srcHeight * boundsWidth) {
485         newHeight = boundsHeight;
486         newWidth = newHeight * srcWidth / srcHeight;
487     } else {
488         newWidth = boundsWidth;
489         newHeight = boundsHeight;
490     }
491     newHeight = newHeight * srcHeight / boundsHeight;
492     newWidth = newWidth * srcWidth / boundsWidth;
493     if (newWidth < srcWidth) {
494         float halfdw = (srcWidth - newWidth) / 2;
495         params.dstRect =
496             Drawing::Rect(params.srcRect.GetLeft() + halfdw, params.srcRect.GetTop(),
497                 params.srcRect.GetLeft() + halfdw + newWidth,
498                 params.srcRect.GetTop() + params.srcRect.GetHeight());
499     } else if (newHeight < srcHeight) {
500         float halfdh = (srcHeight - newHeight) / 2;
501         params.dstRect =
502             Drawing::Rect(params.srcRect.GetLeft(), params.srcRect.GetTop() + halfdh,
503                 params.srcRect.GetLeft() + params.srcRect.GetWidth(),
504                 params.srcRect.GetTop() + halfdh + newHeight);
505     }
506     RS_LOGD("RsDebug RSUniRenderUtil::SrcRectScaleFit name:%{public}s,"
507         " dstRect [%{public}f %{public}f %{public}f %{public}f]",
508         surface->GetName().c_str(), params.dstRect.GetLeft(), params.dstRect.GetTop(),
509         params.dstRect.GetWidth(), params.dstRect.GetHeight());
510 }
511 
SrcRectScaleDown(BufferDrawParam & params,const sptr<SurfaceBuffer> & buffer,const sptr<IConsumerSurface> & surface,RectF & localBounds)512 void RSUniRenderUtil::SrcRectScaleDown(BufferDrawParam& params, const sptr<SurfaceBuffer>& buffer,
513     const sptr<IConsumerSurface>& surface, RectF& localBounds)
514 {
515     if (buffer == nullptr || surface == nullptr) {
516         return;
517     }
518     // Canvas is able to handle the situation when the window is out of screen, using bounds instead of dst.
519     uint32_t boundsWidth = static_cast<uint32_t>(localBounds.GetWidth());
520     uint32_t boundsHeight = static_cast<uint32_t>(localBounds.GetHeight());
521     if (boundsWidth == 0 || boundsHeight == 0) {
522         RS_LOGE("RSUniRenderUtil::SrcRectScaleDown: boundsWidth or boundsHeight is 0");
523         return;
524     }
525     uint32_t newWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
526     uint32_t newHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
527 
528     uint32_t newWidthBoundsHeight = newWidth * boundsHeight;
529     uint32_t newHeightBoundsWidth = newHeight * boundsWidth;
530 
531     if (newWidthBoundsHeight > newHeightBoundsWidth) {
532         newWidth = boundsWidth * newHeight / boundsHeight;
533     } else if (newWidthBoundsHeight < newHeightBoundsWidth) {
534         newHeight = boundsHeight * newWidth / boundsWidth;
535     } else {
536         return;
537     }
538 
539     uint32_t currentWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
540     uint32_t currentHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
541     if (newWidth < currentWidth) {
542         // the crop is too wide
543         uint32_t dw = currentWidth - newWidth;
544         auto halfdw = dw / 2;
545         params.srcRect =
546             Drawing::Rect(params.srcRect.GetLeft() + static_cast<int32_t>(halfdw), params.srcRect.GetTop(),
547                 params.srcRect.GetLeft() + static_cast<int32_t>(halfdw) + static_cast<int32_t>(newWidth),
548                 params.srcRect.GetTop() + params.srcRect.GetHeight());
549     } else {
550         // thr crop is too tall
551         uint32_t dh = currentHeight - newHeight;
552         auto halfdh = dh / 2;
553         params.srcRect =
554             Drawing::Rect(params.srcRect.GetLeft(), params.srcRect.GetTop() + static_cast<int32_t>(halfdh),
555                 params.srcRect.GetLeft() + params.srcRect.GetWidth(),
556                 params.srcRect.GetTop() + static_cast<int32_t>(halfdh) + static_cast<int32_t>(newHeight));
557     }
558     RS_LOGD("RsDebug RSUniRenderUtil::SrcRectScaleDown name:%{public}s,"
559         " srcRect [%{public}f %{public}f %{public}f %{public}f]",
560         surface->GetName().c_str(), params.srcRect.GetLeft(), params.srcRect.GetTop(),
561         params.srcRect.GetWidth(), params.srcRect.GetHeight());
562 }
563 
SetSrcRect(BufferDrawParam & params,const sptr<SurfaceBuffer> & buffer)564 void RSUniRenderUtil::SetSrcRect(BufferDrawParam& params, const sptr<SurfaceBuffer>& buffer)
565 {
566     Rect crop = {0, 0, 0, 0};
567     params.hasCropMetadata = buffer->GetCropMetadata(crop);
568 
569     if (UNLIKELY(params.hasCropMetadata)) {
570         RS_LOGD("buffer has crop metadata, "
571             "left = %{public}u, right = %{public}u, width = %{public}u, height = %{public}u",
572             crop.x, crop.y, crop.w, crop.h);
573         params.srcRect = Drawing::Rect(crop.x, crop.y, crop.x + crop.w, crop.y + crop.h);
574     } else {
575         params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
576     }
577 }
578 
GetMatrixOfBufferToRelRect(const RSSurfaceRenderNode & node)579 Drawing::Matrix RSUniRenderUtil::GetMatrixOfBufferToRelRect(const RSSurfaceRenderNode& node)
580 {
581     const sptr<SurfaceBuffer> buffer = node.GetRSSurfaceHandler()->GetBuffer();
582     if (buffer == nullptr) {
583         return Drawing::Matrix();
584     }
585 
586     auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
587     if (consumer == nullptr) {
588         return Drawing::Matrix();
589     }
590 
591     BufferDrawParam params;
592     params.buffer = buffer;
593     params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
594     const RSProperties& property = node.GetRenderProperties();
595     params.dstRect = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
596     auto transform = RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, buffer);
597     RectF localBounds = { 0.0f, 0.0f, property.GetBoundsWidth(), property.GetBoundsHeight() };
598     auto& renderParams = const_cast<RSSurfaceRenderNode&>(node).GetStagingRenderParams();
599     auto surfaceRenderParams = renderParams == nullptr
600                             ? nullptr
601                             : static_cast<RSSurfaceRenderParams*>(renderParams.get());
602     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, property.GetFrameGravity(), localBounds, params,
603         surfaceRenderParams);
604     RSBaseRenderUtil::FlipMatrix(transform, params);
605     return params.matrix;
606 }
607 
CreateBufferDrawParam(const RSSurfaceRenderNode & node,bool forceCPU,uint32_t threadIndex,bool useRenderParams)608 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(
609     const RSSurfaceRenderNode& node, bool forceCPU, uint32_t threadIndex, bool useRenderParams)
610 {
611     BufferDrawParam params;
612 
613     auto drawable = node.GetRenderDrawable();
614     if (useRenderParams && !drawable) {
615         return params;
616     }
617     auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
618     auto& nodeParams = surfaceDrawable->GetRenderParams();
619     if (useRenderParams && !nodeParams) {
620         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam RenderThread nodeParams is nullptr");
621         return params;
622     }
623     auto surfaceHandler = node.GetRSSurfaceHandler();
624     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(nodeParams.get());
625     const RSProperties& property = node.GetRenderProperties();
626 
627     params.threadIndex = threadIndex;
628     params.useBilinearInterpolation = useRenderParams ?
629         surfaceParams->NeedBilinearInterpolation() : node.NeedBilinearInterpolation();
630     params.useCPU = forceCPU;
631     Drawing::Filter filter;
632     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
633     params.paint.SetFilter(filter);
634 
635     auto boundWidth = useRenderParams ? nodeParams->GetBounds().GetWidth() : property.GetBoundsWidth();
636     auto boundHeight = useRenderParams ? nodeParams->GetBounds().GetHeight() : property.GetBoundsHeight();
637     params.dstRect = Drawing::Rect(0, 0, boundWidth, boundHeight);
638 
639     const sptr<SurfaceBuffer> buffer = useRenderParams ? surfaceParams->GetBuffer() : surfaceHandler->GetBuffer();
640     if (buffer == nullptr) {
641         return params;
642     }
643     params.buffer = buffer;
644     params.acquireFence = useRenderParams ? nodeParams->GetAcquireFence() : surfaceHandler->GetAcquireFence();
645     SetSrcRect(params, buffer);
646     auto consumer = useRenderParams ? surfaceDrawable->GetConsumerOnDraw() : surfaceHandler->GetConsumer();
647     if (consumer == nullptr) {
648         return params;
649     }
650 
651     GraphicAlphaType alphaType = GraphicAlphaType::GRAPHIC_ALPHATYPE_PREMUL;
652     if (consumer->GetAlphaType(alphaType) == GSERROR_OK) {
653         params.alphaType = static_cast<Drawing::AlphaType>(alphaType);
654     }
655 
656     auto transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
657     if (consumer->GetSurfaceBufferTransformType(buffer, &transform) != GSERROR_OK) {
658         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam GetSurfaceBufferTransformType failed");
659     }
660     RectF localBounds = { 0.0f, 0.0f, boundWidth, boundHeight };
661     auto gravity = useRenderParams ? nodeParams->GetFrameGravity() : property.GetFrameGravity();
662     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, gravity, localBounds, params, surfaceParams);
663     RSBaseRenderUtil::FlipMatrix(transform, params);
664     ScalingMode scalingMode = buffer->GetSurfaceBufferScalingMode();
665     RS_LOGD_IF(DEBUG_COMPOSER,
666         "RSUniRenderUtil::CreateBufferDrawParam(RSSurfaceRenderNode): Scaling mode is %{public}d", scalingMode);
667     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
668         SrcRectScaleDown(params, buffer, consumer, localBounds);
669     } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
670         SrcRectScaleFit(params, buffer, consumer, localBounds);
671     }
672     RS_LOGD_IF(DEBUG_COMPOSER,
673         "RSUniRenderUtil::CreateBufferDrawParam(RSSurfaceRenderNode): Parameters creation completed");
674     return params;
675 }
676 
CreateBufferDrawParam(const DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable,bool forceCPU,uint32_t threadIndex)677 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(
678     const DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, bool forceCPU, uint32_t threadIndex)
679 {
680     BufferDrawParam params;
681     auto& nodeParams = surfaceDrawable.GetRenderParams();
682     if (!nodeParams) {
683         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam RenderThread nodeParams is nullptr");
684         return params;
685     }
686     auto surfaceNodeParams = static_cast<RSSurfaceRenderParams*>(nodeParams.get());
687     params.threadIndex = threadIndex;
688     params.useBilinearInterpolation = surfaceNodeParams->NeedBilinearInterpolation();
689     params.useCPU = forceCPU;
690     Drawing::Filter filter;
691     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
692     params.paint.SetFilter(filter);
693 
694     auto boundWidth = nodeParams->GetBounds().GetWidth();
695     auto boundHeight = nodeParams->GetBounds().GetHeight();
696     params.dstRect = Drawing::Rect(0, 0, boundWidth, boundHeight);
697 
698     const sptr<SurfaceBuffer> buffer = nodeParams->GetBuffer();
699     if (buffer == nullptr) {
700         return params;
701     }
702     params.buffer = buffer;
703     params.acquireFence = nodeParams->GetAcquireFence();
704     SetSrcRect(params, buffer);
705     auto consumer = surfaceDrawable.GetConsumerOnDraw();
706     if (consumer == nullptr) {
707         return params;
708     }
709 
710     GraphicAlphaType alphaType = GraphicAlphaType::GRAPHIC_ALPHATYPE_PREMUL;
711     if (consumer->GetAlphaType(alphaType) == GSERROR_OK) {
712         params.alphaType = static_cast<Drawing::AlphaType>(alphaType);
713     }
714 
715     auto transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
716     if (consumer->GetSurfaceBufferTransformType(buffer, &transform) != GSERROR_OK) {
717         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam GetSurfaceBufferTransformType failed");
718     }
719     params.preRotation = consumer->GetSurfaceAppFrameworkType() == "fixed-rotation" ? true : false;
720 
721     RectF localBounds = { 0.0f, 0.0f, boundWidth, boundHeight };
722     auto gravity = nodeParams->GetFrameGravity();
723     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, gravity, localBounds, params, surfaceNodeParams);
724     RSBaseRenderUtil::FlipMatrix(transform, params);
725     RSAncoManager::UpdateCropRectForAnco(surfaceNodeParams->GetAncoFlags(), surfaceNodeParams->GetAncoSrcCrop(),
726         { buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(), buffer->GetFormat() }, params.srcRect);
727     ScalingMode scalingMode = buffer->GetSurfaceBufferScalingMode();
728     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
729         SrcRectScaleDown(params, buffer, consumer, localBounds);
730     } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
731         SrcRectScaleFit(params, buffer, consumer, localBounds);
732     }
733     RS_LOGD_IF(DEBUG_COMPOSER, "RSUniRenderUtil::CreateBufferDrawParam(DrawableV2::RSSurfaceRenderNodeDrawable):"
734         " Parameters creation completed");
735     return params;
736 }
737 
CreateBufferDrawParamForRotationFixed(const DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable,RSSurfaceRenderParams & renderParams,uint32_t threadIndex)738 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParamForRotationFixed(
739     const DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable,
740     RSSurfaceRenderParams& renderParams, uint32_t threadIndex)
741 {
742     BufferDrawParam params;
743     params.threadIndex = threadIndex;
744     params.useBilinearInterpolation = renderParams.NeedBilinearInterpolation();
745     params.useCPU = false;
746     params.targetColorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
747 #ifdef USE_VIDEO_PROCESSING_ENGINE
748     params.sdrNits = renderParams.GetSdrNit();
749     params.tmoNits = renderParams.GetDisplayNit();
750     params.displayNits = params.tmoNits / std::pow(renderParams.GetBrightnessRatio(), GAMMA2_2); // gamma 2.2
751     params.layerLinearMatrix = renderParams.GetLayerLinearMatrix();
752 #endif
753 
754     Drawing::Filter filter;
755     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
756     params.paint.SetFilter(filter);
757 
758     auto buffer = renderParams.GetBuffer();
759     if (buffer == nullptr) {
760         return params;
761     }
762     params.buffer = buffer;
763     params.acquireFence = renderParams.GetAcquireFence();
764     auto srcRect = renderParams.GetLayerInfo().srcRect;
765     params.srcRect = Drawing::Rect(srcRect.x, srcRect.y, srcRect.x + srcRect.w, srcRect.y + srcRect.h);
766 
767     auto dstRect = renderParams.GetLayerInfo().dstRect;
768     params.matrix = Drawing::Matrix();
769     params.matrix.PreTranslate(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y));
770 
771     auto layerTransform = renderParams.GetLayerInfo().transformType;
772     int realRotation = RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(layerTransform));
773     auto flip = RSBaseRenderUtil::GetFlipTransform(layerTransform);
774     // calculate transform in anti-clockwise
775     auto transform = RSBaseRenderUtil::RotateEnumToInt(realRotation, flip);
776 
777     RectF localBounds = { 0.0f, 0.0f,
778         static_cast<float>(dstRect.w), static_cast<float>(dstRect.h) };
779     DealWithRotationAndGravityForRotationFixed(transform, renderParams.GetFrameGravity(), localBounds, params);
780     RSBaseRenderUtil::FlipMatrix(transform, params);
781     RS_LOGD_IF(DEBUG_COMPOSER,
782         "RSUniRenderUtil::CreateBufferDrawParamForRotationFixed(DrawableV2::RSSurfaceRenderNodeDrawable):"
783         " Parameters creation completed");
784     return params;
785 }
786 
DealWithRotationAndGravityForRotationFixed(GraphicTransformType transform,Gravity gravity,RectF & localBounds,BufferDrawParam & params)787 void RSUniRenderUtil::DealWithRotationAndGravityForRotationFixed(GraphicTransformType transform, Gravity gravity,
788     RectF& localBounds, BufferDrawParam& params)
789 {
790     auto rotationTransform = RSBaseRenderUtil::GetRotateTransform(transform);
791     params.matrix.PreConcat(RSBaseRenderUtil::GetSurfaceTransformMatrixForRotationFixed(
792         rotationTransform, localBounds));
793     if (rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_90 ||
794         rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_270) {
795         // after rotate, we should swap dstRect and bound's width and height.
796         std::swap(localBounds.width_, localBounds.height_);
797     }
798     params.dstRect = Drawing::Rect(0, 0, params.srcRect.GetWidth(), params.srcRect.GetHeight());
799 
800     Drawing::Matrix gravityMatrix;
801     if (!RSPropertiesPainter::GetGravityMatrix(gravity, localBounds,
802         params.srcRect.GetWidth(), params.srcRect.GetHeight(), gravityMatrix)) {
803         RS_LOGD("RSUniRenderUtil::DealWithRotationAndGravityForRotationFixed did not obtain gravity matrix.");
804     }
805     params.matrix.PreConcat(gravityMatrix);
806 }
807 
CreateBufferDrawParam(const RSScreenRenderNode & node,bool forceCPU)808 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(const RSScreenRenderNode& node, bool forceCPU)
809 {
810     BufferDrawParam params;
811     params.useCPU = forceCPU;
812     Drawing::Filter filter;
813     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
814     params.paint.SetFilter(filter);
815 
816     auto drawable = node.GetRenderDrawable();
817     if (!drawable) {
818         return params;
819     }
820     auto screenDrawable = std::static_pointer_cast<DrawableV2::RSScreenRenderNodeDrawable>(drawable);
821     auto surfaceHandler = screenDrawable->GetRSSurfaceHandlerOnDraw();
822     const sptr<SurfaceBuffer> buffer = surfaceHandler->GetBuffer();
823     if (!buffer) {
824         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam buffer is null.");
825         return params;
826     }
827     const sptr<IConsumerSurface> consumer = surfaceHandler->GetConsumer();
828     GraphicAlphaType alphaType = GraphicAlphaType::GRAPHIC_ALPHATYPE_PREMUL;
829     if (consumer && consumer->GetAlphaType(alphaType) == GSERROR_OK) {
830         params.alphaType = static_cast<Drawing::AlphaType>(alphaType);
831     }
832     params.buffer = buffer;
833     params.acquireFence = surfaceHandler->GetAcquireFence();
834     SetSrcRect(params, buffer);
835     params.dstRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
836     RS_LOGD_IF(DEBUG_COMPOSER,
837         "RSUniRenderUtil::CreateBufferDrawParam(RSScreenRenderNode): Parameters creation completed");
838     return params;
839 }
840 
CreateBufferDrawParam(const RSSurfaceHandler & surfaceHandler,bool forceCPU)841 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(const RSSurfaceHandler& surfaceHandler, bool forceCPU)
842 {
843     BufferDrawParam bufferDrawParam;
844     bufferDrawParam.useCPU = forceCPU;
845     Drawing::Filter filter;
846     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
847     bufferDrawParam.paint.SetFilter(filter);
848 
849     const sptr<SurfaceBuffer> buffer = surfaceHandler.GetBuffer();
850     if (!buffer) {
851         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam buffer is null.");
852         return bufferDrawParam;
853     }
854     const sptr<IConsumerSurface> consumer = surfaceHandler.GetConsumer();
855     GraphicAlphaType alphaType = GraphicAlphaType::GRAPHIC_ALPHATYPE_PREMUL;
856     if (consumer && consumer->GetAlphaType(alphaType) == GSERROR_OK) {
857         bufferDrawParam.alphaType = static_cast<Drawing::AlphaType>(alphaType);
858     }
859     bufferDrawParam.buffer = buffer;
860     bufferDrawParam.acquireFence = surfaceHandler.GetAcquireFence();
861     SetSrcRect(bufferDrawParam, buffer);
862     bufferDrawParam.dstRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
863     RS_LOGD_IF(DEBUG_COMPOSER,
864         "RSUniRenderUtil::CreateBufferDrawParam(RSSurfaceHandler): Parameters creation completed");
865     return bufferDrawParam;
866 }
867 
CreateLayerBufferDrawParam(const LayerInfoPtr & layer,bool forceCPU)868 BufferDrawParam RSUniRenderUtil::CreateLayerBufferDrawParam(const LayerInfoPtr& layer, bool forceCPU)
869 {
870     BufferDrawParam params;
871     if (layer == nullptr) {
872         return params;
873     }
874     params.useCPU = forceCPU;
875     params.useBilinearInterpolation = layer->GetNeedBilinearInterpolation();
876     Drawing::Filter filter;
877     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
878     params.paint.SetFilter(filter);
879     params.paint.SetAlpha(layer->GetAlpha().gAlpha);
880     sptr<SurfaceBuffer> buffer = layer->GetBuffer();
881     if (buffer == nullptr) {
882         return params;
883     }
884     params.acquireFence = layer->GetAcquireFence();
885     params.buffer = buffer;
886     SetSrcRect(params, buffer);
887     auto boundRect = layer->GetBoundSize();
888     params.dstRect = Drawing::Rect(0, 0, boundRect.w, boundRect.h);
889 
890     auto layerMatrix = layer->GetMatrix();
891     params.matrix = Drawing::Matrix();
892     bool rotationFixed = layer->GetRotationFixed();
893     auto dstRect = layer->GetLayerSize();
894     if (rotationFixed) {
895         // if rotation fixed, not use [total matrix + bounds] to draw buffer, use [src + dst + transform]
896         params.matrix.PreTranslate(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y));
897         auto srcRect = layer->GetCropRect();
898         params.srcRect = Drawing::Rect(srcRect.x, srcRect.y, srcRect.x + srcRect.w, srcRect.y + srcRect.h);
899     } else {
900         params.matrix.SetMatrix(layerMatrix.scaleX, layerMatrix.skewX, layerMatrix.transX, layerMatrix.skewY,
901             layerMatrix.scaleY, layerMatrix.transY, layerMatrix.pers0, layerMatrix.pers1, layerMatrix.pers2);
902     }
903     // rotation degree anti-clockwise
904     int nodeRotation = rotationFixed ? 0 : RSUniRenderUtil::GetRotationFromMatrix(params.matrix);
905     auto layerTransform = layer->GetTransformType();
906     // calculate clockwise rotation degree excluded rotation in total matrix
907     int realRotation = (nodeRotation +
908         RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(layerTransform))) % 360;
909     auto flip = RSBaseRenderUtil::GetFlipTransform(layerTransform);
910     // calculate transform in anti-clockwise
911     auto transform = RSBaseRenderUtil::RotateEnumToInt(realRotation, flip);
912 
913     RectF localBounds = { 0.0f, 0.0f,
914         rotationFixed ? static_cast<float>(dstRect.w) : static_cast<float>(boundRect.w),
915         rotationFixed ? static_cast<float>(dstRect.h) : static_cast<float>(boundRect.h) };
916     if (rotationFixed) {
917         DealWithRotationAndGravityForRotationFixed(transform, static_cast<Gravity>(layer->GetGravity()), localBounds,
918             params);
919     } else {
920         RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, static_cast<Gravity>(layer->GetGravity()),
921             localBounds, params);
922     }
923     RSBaseRenderUtil::FlipMatrix(transform, params);
924     if (rotationFixed) {
925         // if rotation fixed, no need to calculate scaling mode, it is contained in dstRect
926         return params;
927     }
928     const auto& surface = layer->GetSurface();
929     if (surface == nullptr) {
930         RS_LOGE("buffer or surface is nullptr");
931         return params;
932     }
933     RSAncoManager::UpdateCropRectForAnco(layer->GetAncoFlags(), layer->GetCropRect(),
934         { buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(), buffer->GetFormat() }, params.srcRect);
935     ScalingMode scalingMode = buffer->GetSurfaceBufferScalingMode();
936     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
937         SrcRectScaleDown(params, buffer, surface, localBounds);
938     } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
939         SrcRectScaleFit(params, buffer, surface, localBounds);
940     }
941     RS_LOGD_IF(DEBUG_COMPOSER,
942         "RSUniRenderUtil::CreateLayerBufferDrawParam(LayerInfoPtr): Parameters creation completed");
943     return params;
944 }
945 
AlignedDirtyRegion(const Occlusion::Region & dirtyRegion,int32_t alignedBits)946 Occlusion::Region RSUniRenderUtil::AlignedDirtyRegion(const Occlusion::Region& dirtyRegion, int32_t alignedBits)
947 {
948     Occlusion::Region alignedRegion;
949     if (alignedBits <= 1) {
950         return dirtyRegion;
951     }
952     for (const auto& dirtyRect : dirtyRegion.GetRegionRects()) {
953         int32_t left = (dirtyRect.left_ / alignedBits) * alignedBits;
954         int32_t top = (dirtyRect.top_ / alignedBits) * alignedBits;
955         int32_t width = ((dirtyRect.right_ + alignedBits - 1) / alignedBits) * alignedBits - left;
956         int32_t height = ((dirtyRect.bottom_ + alignedBits - 1) / alignedBits) * alignedBits - top;
957         Occlusion::Rect rect = { left, top, left + width, top + height };
958         Occlusion::Region singleAlignedRegion(rect);
959         alignedRegion.OrSelf(singleAlignedRegion);
960     }
961     return alignedRegion;
962 }
963 
TransferToAntiClockwiseDegrees(int angle)964 int RSUniRenderUtil::TransferToAntiClockwiseDegrees(int angle)
965 {
966     static const std::map<int, int> supportedDegrees = { { 90, 270 }, { 180, 180 }, { -90, 90 }, { -180, 180 },
967         { 270, 90 }, { -270, 270 } };
968     auto iter = supportedDegrees.find(angle);
969     return iter != supportedDegrees.end() ? iter->second : 0;
970 }
971 
GetRotationFromMatrix(Drawing::Matrix matrix)972 int RSUniRenderUtil::GetRotationFromMatrix(Drawing::Matrix matrix)
973 {
974     Drawing::Matrix::Buffer value;
975     matrix.GetAll(value);
976 
977     int rAngle = static_cast<int>(-round(atan2(value[Drawing::Matrix::Index::SKEW_X],
978         value[Drawing::Matrix::Index::SCALE_X]) * (180 / PI)));
979     // transfer the result to anti-clockwise degrees
980     // only rotation with 90°, 180°, 270° are composed through hardware,
981     // in which situation the transformation of the layer needs to be set.
982     return TransferToAntiClockwiseDegrees(rAngle);
983 }
984 
GetRotationDegreeFromMatrix(Drawing::Matrix matrix)985 int RSUniRenderUtil::GetRotationDegreeFromMatrix(Drawing::Matrix matrix)
986 {
987     Drawing::Matrix::Buffer value;
988     matrix.GetAll(value);
989     return static_cast<int>(-round(atan2(value[Drawing::Matrix::Index::SKEW_X],
990         value[Drawing::Matrix::Index::SCALE_X]) * (RS_ROTATION_180 / PI)));
991 }
992 
ClearNodeCacheSurface(std::shared_ptr<Drawing::Surface> && cacheSurface,std::shared_ptr<Drawing::Surface> && cacheCompletedSurface,uint32_t cacheSurfaceThreadIndex,uint32_t completedSurfaceThreadIndex)993 void RSUniRenderUtil::ClearNodeCacheSurface(std::shared_ptr<Drawing::Surface>&& cacheSurface,
994     std::shared_ptr<Drawing::Surface>&& cacheCompletedSurface,
995     uint32_t cacheSurfaceThreadIndex, uint32_t completedSurfaceThreadIndex)
996 {
997     PostReleaseSurfaceTask(std::move(cacheSurface), cacheSurfaceThreadIndex);
998     PostReleaseSurfaceTask(std::move(cacheCompletedSurface), completedSurfaceThreadIndex);
999 }
1000 
PostReleaseSurfaceTask(std::shared_ptr<Drawing::Surface> && surface,uint32_t threadIndex)1001 void RSUniRenderUtil::PostReleaseSurfaceTask(std::shared_ptr<Drawing::Surface>&& surface, uint32_t threadIndex)
1002 {
1003     if (surface == nullptr) {
1004         return;
1005     }
1006 
1007     if (threadIndex == UNI_MAIN_THREAD_INDEX || threadIndex == UNI_RENDER_THREAD_INDEX) {
1008         if (RSUniRenderJudgement::IsUniRender()) {
1009             auto instance = &(RSUniRenderThread::Instance());
1010             instance->AddToReleaseQueue(std::move(surface));
1011             instance->PostTask(([instance] () { instance->ReleaseSurface(); }),
1012                 RELEASE_SURFACE_TASK, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
1013         } else {
1014             auto instance = RSMainThread::Instance();
1015             instance->AddToReleaseQueue(std::move(surface));
1016             instance->PostTask(([instance] () { instance->ReleaseSurface(); }),
1017                 RELEASE_SURFACE_TASK, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
1018         }
1019     } else {
1020 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
1021         auto instance = RSSubThreadManager::Instance();
1022         instance->AddToReleaseQueue(std::move(surface), threadIndex);
1023         instance->ReleaseSurface(threadIndex);
1024 #endif
1025     }
1026 }
1027 
DrawRectForDfx(RSPaintFilterCanvas & canvas,const RectI & rect,Drawing::Color color,float alpha,const std::string & extraInfo)1028 void RSUniRenderUtil::DrawRectForDfx(RSPaintFilterCanvas& canvas, const RectI& rect, Drawing::Color color,
1029     float alpha, const std::string& extraInfo)
1030 {
1031     if (rect.width_ <= 0 || rect.height_ <= 0) {
1032         RS_LOGD("DrawRectForDfx rect is invalid.");
1033         return;
1034     }
1035     RS_LOGD("DrawRectForDfx current rect = %{public}s", rect.ToString().c_str());
1036     auto dstRect = Drawing::Rect(rect.left_, rect.top_,
1037         rect.left_ + rect.width_, rect.top_ + rect.height_);
1038 
1039     std::string position = rect.ToString() + extraInfo;
1040 
1041     const int defaultTextOffsetX = 6; // text position is 6 pixelSize right side of the Rect
1042     const int defaultTextOffsetY = 30; // text position has 30 pixelSize under the Rect
1043     Drawing::Brush rectBrush;
1044     std::shared_ptr<Drawing::Typeface> typeFace = nullptr;
1045 
1046     // font size: 24
1047     std::shared_ptr<Drawing::TextBlob> textBlob =
1048         Drawing::TextBlob::MakeFromString(position.c_str(), Drawing::Font(typeFace, 24.0f, 1.0f, 0.0f));
1049 
1050     rectBrush.SetColor(color);
1051     rectBrush.SetAntiAlias(true);
1052     rectBrush.SetAlphaF(alpha);
1053     canvas.AttachBrush(rectBrush);
1054     canvas.DrawRect(dstRect);
1055     canvas.DetachBrush();
1056     canvas.AttachBrush(Drawing::Brush());
1057     canvas.DrawTextBlob(textBlob.get(), rect.left_ + defaultTextOffsetX, rect.top_ + defaultTextOffsetY);
1058     canvas.DetachBrush();
1059 }
1060 
1061 #ifdef RS_ENABLE_VK
1062 
PrepareHdrSemaphoreVector(GrBackendSemaphore & backendSemaphore,std::shared_ptr<Drawing::Surface> & surface)1063 std::vector<GrBackendSemaphore> RSUniRenderUtil::PrepareHdrSemaphoreVector(GrBackendSemaphore& backendSemaphore,
1064     std::shared_ptr<Drawing::Surface>& surface)
1065 {
1066     VkSemaphore notifySemaphore;
1067     std::vector<GrBackendSemaphore> semphoreVec = {backendSemaphore};
1068     std::vector<uint64_t> frameIdVec = RSHDRPatternManager::Instance().MHCGetFrameIdForGpuTask();
1069 
1070     for (auto frameId : frameIdVec) {
1071         if (RSHDRVulkanTask::GetHTSNotifySemaphore(notifySemaphore, frameId)) {
1072             GrBackendSemaphore htsSemaphore;
1073             htsSemaphore.initVulkan(notifySemaphore);
1074             semphoreVec.emplace_back(std::move(htsSemaphore));
1075         }
1076         RSHDRVulkanTask::InsertHTSWaitSemaphore(surface, frameId);
1077     }
1078 
1079     return semphoreVec;
1080 }
1081 #endif
1082 
OptimizedFlushAndSubmit(std::shared_ptr<Drawing::Surface> & surface,Drawing::GPUContext * const grContext,bool optFenceWait)1083 void RSUniRenderUtil::OptimizedFlushAndSubmit(std::shared_ptr<Drawing::Surface>& surface,
1084     Drawing::GPUContext* const grContext, bool optFenceWait)
1085 {
1086     if (!surface || !grContext) {
1087         RS_LOGE("RSUniRenderUtil::OptimizedFlushAndSubmit cacheSurface or grContext are nullptr");
1088         return;
1089     }
1090     RS_TRACE_NAME_FMT("Render surface flush and submit");
1091     RS_LOGD("RSUniRenderUtil::optimized flush and submit GpuApiType:%{public}d",
1092         RSSystemProperties::GetGpuApiType());
1093 #ifdef RS_ENABLE_VK
1094     if ((RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
1095         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) && optFenceWait) {
1096         auto& vkContext = RsVulkanContext::GetSingleton().GetRsVulkanInterface();
1097 
1098         VkExportSemaphoreCreateInfo exportSemaphoreCreateInfo;
1099         exportSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
1100         exportSemaphoreCreateInfo.pNext = nullptr;
1101         exportSemaphoreCreateInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
1102 
1103         VkSemaphoreCreateInfo semaphoreInfo;
1104         semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1105         semaphoreInfo.pNext = &exportSemaphoreCreateInfo;
1106         semaphoreInfo.flags = 0;
1107         VkSemaphore semaphore;
1108         vkContext.vkCreateSemaphore(vkContext.GetDevice(), &semaphoreInfo, nullptr, &semaphore);
1109 #ifdef USE_M133_SKIA
1110         GrBackendSemaphore backendSemaphore = GrBackendSemaphores::MakeVk(semaphore);
1111 #else
1112         GrBackendSemaphore backendSemaphore;
1113         backendSemaphore.initVulkan(semaphore);
1114 #endif
1115 
1116         DestroySemaphoreInfo* destroyInfo =
1117             new DestroySemaphoreInfo(vkContext.vkDestroySemaphore, vkContext.GetDevice(), semaphore);
1118 
1119         auto semphoreVec = PrepareHdrSemaphoreVector(backendSemaphore, surface);
1120 
1121         Drawing::FlushInfo drawingFlushInfo;
1122         drawingFlushInfo.backendSurfaceAccess = true;
1123         drawingFlushInfo.numSemaphores = semphoreVec.size();
1124         drawingFlushInfo.backendSemaphore = static_cast<void*>(semphoreVec.data());
1125         drawingFlushInfo.finishedProc = [](void *context) {
1126             DestroySemaphoreInfo::DestroySemaphore(context);
1127         };
1128         drawingFlushInfo.finishedContext = destroyInfo;
1129         surface->Flush(&drawingFlushInfo);
1130         grContext->Submit();
1131         DestroySemaphoreInfo::DestroySemaphore(destroyInfo);
1132 
1133         std::vector<uint64_t> frameIdVec = RSHDRPatternManager::Instance().MHCGetFrameIdForGpuTask();
1134         for (auto frameId : frameIdVec) {
1135             RSHDRVulkanTask::SubmitWaitEventToGPU(frameId);
1136         }
1137     } else {
1138         surface->FlushAndSubmit(true);
1139     }
1140 #else
1141     surface->FlushAndSubmit(true);
1142 #endif
1143 }
1144 
GenerateSecRectInfoFromNode(RSRenderNode & node,RectI rect)1145 SecRectInfo RSUniRenderUtil::GenerateSecRectInfoFromNode(RSRenderNode& node, RectI rect)
1146 {
1147     SecRectInfo uiExtensionRectInfo;
1148     uiExtensionRectInfo.relativeCoords = rect;
1149     uiExtensionRectInfo.scale = node.GetRenderProperties().GetScale();
1150     return uiExtensionRectInfo;
1151 }
1152 
GenerateSecSurfaceInfoFromNode(NodeId uiExtensionId,NodeId hostId,SecRectInfo uiExtensionRectInfo)1153 SecSurfaceInfo RSUniRenderUtil::GenerateSecSurfaceInfoFromNode(
1154     NodeId uiExtensionId, NodeId hostId, SecRectInfo uiExtensionRectInfo)
1155 {
1156     SecSurfaceInfo secSurfaceInfo;
1157     secSurfaceInfo.uiExtensionRectInfo = uiExtensionRectInfo;
1158     secSurfaceInfo.uiExtensionPid = ExtractPid(uiExtensionId);
1159     secSurfaceInfo.hostPid = ExtractPid(hostId);
1160     secSurfaceInfo.uiExtensionNodeId = uiExtensionId;
1161     secSurfaceInfo.hostNodeId = hostId;
1162     return secSurfaceInfo;
1163 }
1164 
UIExtensionFindAndTraverseAncestor(const RSRenderNodeMap & nodeMap,UIExtensionCallbackData & callbackData,bool isUnobscured)1165 void RSUniRenderUtil::UIExtensionFindAndTraverseAncestor(
1166     const RSRenderNodeMap& nodeMap, UIExtensionCallbackData& callbackData, bool isUnobscured)
1167 {
1168     const auto& secUIExtensionNodes = RSSurfaceRenderNode::GetSecUIExtensionNodes();
1169     for (auto it = secUIExtensionNodes.begin(); it != secUIExtensionNodes.end(); ++it) {
1170         currentUIExtensionIndex_ = -1;
1171         // only traverse host node one time, even if it has multiple uiextension children.
1172         if (callbackData.find(it->second) != callbackData.end()) {
1173             continue;
1174         }
1175         auto hostNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(it->second));
1176         if (!hostNode || !hostNode->GetSortedChildren()) {
1177             RS_LOGE("RSUniRenderUtil::UIExtensionFindAndTraverseAncestor failed to get host node or its children.");
1178             return;
1179         }
1180         for (const auto& child : *hostNode->GetSortedChildren()) {
1181             TraverseAndCollectUIExtensionInfo(child, Drawing::Matrix(), hostNode->GetId(), callbackData, isUnobscured);
1182         }
1183     }
1184 }
1185 
TraverseAndCollectUIExtensionInfo(std::shared_ptr<RSRenderNode> node,Drawing::Matrix parentMatrix,NodeId hostId,UIExtensionCallbackData & callbackData,bool isUnobscured)1186 void RSUniRenderUtil::TraverseAndCollectUIExtensionInfo(std::shared_ptr<RSRenderNode> node,
1187     Drawing::Matrix parentMatrix, NodeId hostId, UIExtensionCallbackData& callbackData, bool isUnobscured)
1188 {
1189     if (!node) {
1190         return;
1191     }
1192     // update position relative to host app window node.
1193     std::optional<Drawing::Point> offset;
1194     auto parent = node->GetParent().lock();
1195     if (parent && !(node->IsInstanceOf<RSSurfaceRenderNode>())) {
1196         const auto& parentRenderProperties = parent->GetRenderProperties();
1197         offset = Drawing::Point { parentRenderProperties.GetFrameOffsetX(), parentRenderProperties.GetFrameOffsetY() };
1198     }
1199     const auto& nodeRenderProperties = node->GetRenderProperties();
1200     RSObjAbsGeometry boundsGeo = nodeRenderProperties.GetBoundsGeometry() == nullptr ?
1201         RSObjAbsGeometry() : *(nodeRenderProperties.GetBoundsGeometry());
1202     boundsGeo.UpdateMatrix(&parentMatrix, offset);
1203     auto rect = boundsGeo.MapAbsRect(node->GetSelfDrawRect().JoinRect(node->GetChildrenRect().ConvertTo<float>()));
1204     // if node is UIExtension type, update its own info, and skip its children.
1205     if (auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node)) {
1206         if ((surfaceNode->IsSecureUIExtension() && !isUnobscured) ||
1207             (surfaceNode->IsUnobscuredUIExtensionNode() && isUnobscured)) {
1208             currentUIExtensionIndex_++;
1209             // if host node is not recorded in callbackData, insert it.
1210             auto [iter, inserted] = callbackData.insert(std::pair(hostId, std::vector<SecSurfaceInfo>{}));
1211             if (iter != callbackData.end()) {
1212                 iter->second.push_back(GenerateSecSurfaceInfoFromNode(
1213                     surfaceNode->GetId(), hostId, GenerateSecRectInfoFromNode(*surfaceNode, rect)));
1214             }
1215             if (surfaceNode->ChildrenHasUIExtension()) {
1216                 RS_LOGW("RSUniRenderUtil::TraverseAndCollectUIExtensionInfo UIExtension node [%{public}" PRIu64 "]"
1217                     " has children UIExtension, not surpported!", surfaceNode->GetId());
1218             }
1219             return;
1220         }
1221     }
1222     // if the node is traversed after a UIExtension, collect it and skip its children (except it has UIExtension child.)
1223     auto iter = callbackData.find(hostId);
1224     if (iter != callbackData.end() && currentUIExtensionIndex_ != -1 &&
1225         currentUIExtensionIndex_ < static_cast<int>((iter->second).size())) {
1226         (iter->second)[currentUIExtensionIndex_].upperNodes.push_back(GenerateSecRectInfoFromNode(*node, rect));
1227         if (!node->ChildrenHasUIExtension()) {
1228             return;
1229         }
1230     }
1231     // continue to traverse.
1232     for (const auto& child : *node->GetSortedChildren()) {
1233         TraverseAndCollectUIExtensionInfo(child, boundsGeo.GetAbsMatrix(), hostId, callbackData, isUnobscured);
1234     }
1235 }
1236 
ProcessCacheImage(RSPaintFilterCanvas & canvas,Drawing::Image & cacheImageProcessed)1237 void RSUniRenderUtil::ProcessCacheImage(RSPaintFilterCanvas& canvas, Drawing::Image& cacheImageProcessed)
1238 {
1239     Drawing::Brush brush;
1240     brush.SetAntiAlias(true);
1241     canvas.AttachBrush(brush);
1242     // Be cautious when changing FilterMode and MipmapMode that may affect clarity
1243     auto sampling = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, MultiScreenParam::GetMipmapMode());
1244     canvas.DrawImage(cacheImageProcessed, 0, 0, sampling);
1245     canvas.DetachBrush();
1246 }
1247 
ProcessCacheImageRect(RSPaintFilterCanvas & canvas,Drawing::Image & cacheImageProcessed,const Drawing::Rect & src,const Drawing::Rect & dst)1248 void RSUniRenderUtil::ProcessCacheImageRect(RSPaintFilterCanvas& canvas, Drawing::Image& cacheImageProcessed,
1249     const Drawing::Rect& src, const Drawing::Rect& dst)
1250 {
1251     Drawing::Brush brush;
1252     brush.SetAntiAlias(true);
1253     canvas.AttachBrush(brush);
1254     // Be cautious when changing FilterMode and MipmapMode that may affect clarity
1255     auto sampling = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, MultiScreenParam::GetMipmapMode());
1256     canvas.DrawImageRect(cacheImageProcessed, src, dst, sampling, Drawing::SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
1257     canvas.DetachBrush();
1258 }
1259 
ProcessCacheImageForMultiScreenView(RSPaintFilterCanvas & canvas,Drawing::Image & cacheImageProcessed,const RectF & rect)1260 void RSUniRenderUtil::ProcessCacheImageForMultiScreenView(RSPaintFilterCanvas& canvas,
1261     Drawing::Image& cacheImageProcessed, const RectF& rect)
1262 {
1263     if (cacheImageProcessed.GetWidth() == 0 || cacheImageProcessed.GetHeight() == 0) {
1264         RS_TRACE_NAME("ProcessCacheImageForMultiScreenView cacheImageProcessed is invalid");
1265         return;
1266     }
1267     Drawing::Brush brush;
1268     brush.SetAntiAlias(true);
1269     canvas.AttachBrush(brush);
1270     // Be cautious when changing FilterMode and MipmapMode that may affect clarity
1271     auto sampling = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NEAREST);
1272     canvas.Save();
1273     // Use Fill Mode
1274     const float scaleX = rect.GetWidth() / cacheImageProcessed.GetWidth();
1275     const float scaleY = rect.GetHeight() / cacheImageProcessed.GetHeight();
1276     canvas.Scale(scaleX, scaleY);
1277     canvas.DrawImage(cacheImageProcessed, 0, 0, sampling);
1278     canvas.Restore();
1279     canvas.DetachBrush();
1280 }
1281 
FlushDmaSurfaceBuffer(Media::PixelMap * pixelMap)1282 void RSUniRenderUtil::FlushDmaSurfaceBuffer(Media::PixelMap* pixelMap)
1283 {
1284     if (!pixelMap || pixelMap->GetAllocatorType() != Media::AllocatorType::DMA_ALLOC) {
1285         return;
1286     }
1287     SurfaceBuffer* surfaceBuffer = reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd());
1288     if (surfaceBuffer && (surfaceBuffer->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) {
1289         GSError err = surfaceBuffer->Map();
1290         if (err != GSERROR_OK) {
1291             RS_LOGE("RSUniRenderUtil::FlushDmaSurfaceBuffer Map failed, GSError=%{public}d", err);
1292             return;
1293         }
1294         err = surfaceBuffer->InvalidateCache();
1295         if (err != GSERROR_OK) {
1296             RS_LOGE("RSUniRenderUtil::FlushDmaSurfaceBuffer InvalidateCache failed, GSError=%{public}d", err);
1297         }
1298     }
1299 }
1300 
CheckRenderSkipIfScreenOff(bool extraFrame,std::optional<ScreenId> screenId)1301 bool RSUniRenderUtil::CheckRenderSkipIfScreenOff(bool extraFrame, std::optional<ScreenId> screenId)
1302 {
1303     if (!RSSystemProperties::GetSkipDisplayIfScreenOffEnabled()) {
1304         return false;
1305     }
1306     auto screenManager = CreateOrGetScreenManager();
1307     if (!screenManager) {
1308         RS_LOGE("RSUniRenderUtil::CheckRenderSkipIfScreenOff, failed to get screen manager!");
1309         return false;
1310     }
1311     // in certain cases such as wireless display, render skipping may be disabled.
1312     auto disableRenderControlScreensCount = screenManager->GetDisableRenderControlScreensCount();
1313     auto isScreenOff = screenId.has_value() ?
1314         screenManager->IsScreenPowerOff(screenId.value()) : screenManager->IsAllScreensPowerOff();
1315     RS_TRACE_NAME_FMT("CheckRenderSkipIfScreenOff disableRenderControl:[%d], PowerOff:[%d]",
1316         disableRenderControlScreensCount, isScreenOff);
1317     if (disableRenderControlScreensCount != 0 || !isScreenOff) {
1318         return false;
1319     }
1320     if (extraFrame && screenManager->GetPowerOffNeedProcessOneFrame()) {
1321         RS_LOGI("RSUniRenderUtil::CheckRenderSkipIfScreenOff screen power off, one more frame.");
1322         screenManager->ResetPowerOffNeedProcessOneFrame();
1323         return false;
1324     } else {
1325         return !screenManager->GetPowerOffNeedProcessOneFrame();
1326     }
1327 }
1328 
1329 #ifdef FRAME_AWARE_TRACE
FrameAwareTraceBoost(size_t layerNum)1330 bool RSUniRenderUtil::FrameAwareTraceBoost(size_t layerNum)
1331 {
1332     using namespace FRAME_TRACE;
1333     constexpr uint32_t FRAME_TRACE_LAYER_NUM_1 = 11;
1334     constexpr uint32_t FRAME_TRACE_LAYER_NUM_2 = 13;
1335     constexpr int32_t FRAME_TRACE_PERF_REQUESTED_CODE = 10024;
1336     RenderFrameTrace& ft = RenderFrameTrace::GetInstance();
1337     if (layerNum != FRAME_TRACE_LAYER_NUM_1 && layerNum != FRAME_TRACE_LAYER_NUM_2) {
1338         if (ft.RenderFrameTraceIsOpen()) {
1339             ft.RenderFrameTraceClose();
1340             PerfRequest(FRAME_TRACE_PERF_REQUESTED_CODE, false);
1341             RS_LOGD("RsDebug RSUniRenderUtil::Perf: FrameTrace 0");
1342         }
1343         return false;
1344     }
1345 
1346     static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
1347     auto currentTime = std::chrono::steady_clock::now();
1348     bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
1349         count() > PERF_TIME_OUT;
1350     if (isTimeOut || !ft.RenderFrameTraceIsOpen()) {
1351         if (!ft.RenderFrameTraceOpen()) {
1352             return false;
1353         }
1354         PerfRequest(FRAME_TRACE_PERF_REQUESTED_CODE, true);
1355         RS_LOGD("RsDebug RSProcessor::Perf: FrameTrace 1");
1356         lastRequestPerfTime = currentTime;
1357     }
1358     return true;
1359 }
1360 #endif
1361 
RequestPerf(uint32_t layerLevel,bool onOffTag)1362 void RSUniRenderUtil::RequestPerf(uint32_t layerLevel, bool onOffTag)
1363 {
1364     switch (layerLevel) {
1365         case PERF_LEVEL_0: {
1366             // do nothing
1367             RS_LOGD("RsDebug RSProcessor::perf do nothing");
1368             break;
1369         }
1370         case PERF_LEVEL_1: {
1371             PerfRequest(PERF_LEVEL_1_REQUESTED_CODE, onOffTag);
1372             RS_LOGD("RsDebug RSProcessor::Perf: level1 %{public}d", onOffTag);
1373             break;
1374         }
1375         case PERF_LEVEL_2: {
1376             PerfRequest(PERF_LEVEL_2_REQUESTED_CODE, onOffTag);
1377             RS_LOGD("RsDebug RSProcessor::Perf: level2 %{public}d", onOffTag);
1378             break;
1379         }
1380         default: {
1381             PerfRequest(PERF_LEVEL_3_REQUESTED_CODE, onOffTag);
1382             RS_LOGD("RsDebug RSProcessor::Perf: level3 %{public}d", onOffTag);
1383             break;
1384         }
1385     }
1386 }
1387 
MultiLayersPerf(size_t layerNum)1388 void RSUniRenderUtil::MultiLayersPerf(size_t layerNum)
1389 {
1390     RS_LOGD("FrameAwareTraceBoost return false");
1391     static uint32_t lastLayerLevel = 0;
1392     constexpr uint32_t PERF_LEVEL_INTERVAL = 10;
1393     static std::chrono::steady_clock::time_point lastRequestPerfTime = std::chrono::steady_clock::now();
1394     auto curLayerLevel = layerNum / PERF_LEVEL_INTERVAL;
1395     if (curLayerLevel == 0 && layerNum >= PERF_LAYER_START_NUM) {
1396         curLayerLevel = 1;
1397     }
1398     auto currentTime = std::chrono::steady_clock::now();
1399     bool isTimeOut = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastRequestPerfTime).
1400         count() > PERF_TIME_OUT;
1401     if (curLayerLevel != lastLayerLevel || isTimeOut) {
1402         if (!isTimeOut) {
1403             RequestPerf(lastLayerLevel, false);
1404         }
1405         RequestPerf(curLayerLevel, true);
1406         lastLayerLevel = curLayerLevel;
1407         lastRequestPerfTime = currentTime;
1408     }
1409 }
1410 
GetImageRegions(float screenWidth,float screenHeight,float realImageWidth,float realImageHeight)1411 Drawing::Rect RSUniRenderUtil::GetImageRegions(float screenWidth, float screenHeight,
1412     float realImageWidth, float realImageHeight)
1413 {
1414     auto dstRect = Drawing::Rect(0, 0, screenWidth, screenHeight);
1415     if (ROSEN_EQ(realImageWidth, 0.0f) || ROSEN_EQ(realImageHeight, 0.0f)) {
1416         return dstRect;
1417     }
1418     float imageScaleWidth = screenWidth / static_cast<float>(realImageWidth);
1419     float imageScaleHeight = screenHeight / static_cast<float>(realImageHeight);
1420     auto imageWidth = realImageWidth * imageScaleHeight;
1421     auto imageHeight = realImageHeight * imageScaleWidth;
1422     // Ensure that the security mask is located in the middle of the virtual screen.
1423     if (imageScaleWidth > imageScaleHeight) {
1424         // Left and right set black
1425         float halfBoundWidthLeft = (screenWidth - imageWidth) / 2;
1426         float halfBoundWidthRight = halfBoundWidthLeft + imageWidth;
1427         dstRect = Drawing::Rect(halfBoundWidthLeft, 0, halfBoundWidthRight, screenHeight);
1428         return dstRect;
1429     }
1430 
1431     if (imageScaleWidth < imageScaleHeight) {
1432         // Up and down set black
1433         float halfBoundHeightTop = (screenHeight - imageHeight) / 2;
1434         float halfBoundHeightBottom = halfBoundHeightTop + imageHeight;
1435         dstRect = Drawing::Rect(0, halfBoundHeightTop, screenWidth, halfBoundHeightBottom);
1436         return dstRect;
1437     }
1438     return dstRect;
1439 }
1440 
GetSampledDamageAndDrawnRegion(const ScreenInfo & screenInfo,const Occlusion::Region & srcDamageRegion,bool isDirtyAlignEnabled,Occlusion::Region & sampledDamageRegion,Occlusion::Region & sampledDrawnRegion)1441 void RSUniRenderUtil::GetSampledDamageAndDrawnRegion(const ScreenInfo& screenInfo,
1442     const Occlusion::Region& srcDamageRegion, bool isDirtyAlignEnabled, Occlusion::Region& sampledDamageRegion,
1443     Occlusion::Region& sampledDrawnRegion)
1444 {
1445     Drawing::Matrix scaleMatrix;
1446     scaleMatrix.SetScaleTranslate(screenInfo.samplingScale, screenInfo.samplingScale,
1447         screenInfo.samplingTranslateX, screenInfo.samplingTranslateY);
1448     const Vector4<int> expandSize{screenInfo.samplingDistance, screenInfo.samplingDistance,
1449         screenInfo.samplingDistance, screenInfo.samplingDistance};
1450     auto rects = srcDamageRegion.GetRegionRectIs();
1451     sampledDamageRegion.Reset();
1452     for (const auto& rect : rects) {
1453         RectI mappedRect = RSObjAbsGeometry::MapRect(rect.ConvertTo<float>(), scaleMatrix);
1454         Occlusion::Region mappedAndExpandedRegion{mappedRect.MakeOutset(expandSize)};
1455         sampledDamageRegion.OrSelf(mappedAndExpandedRegion);
1456     }
1457 
1458     Occlusion::Region drawnRegion = isDirtyAlignEnabled ?
1459         sampledDamageRegion.GetAlignedRegion(MAX_DIRTY_ALIGNMENT_SIZE) : sampledDamageRegion;
1460 
1461     Drawing::Matrix invertedScaleMatrix;
1462     if (!scaleMatrix.Invert(invertedScaleMatrix)) {
1463         RS_LOGW("%{public}s, invert scaleMatrix failed", __func__);
1464         sampledDrawnRegion = drawnRegion;
1465         return;
1466     }
1467     sampledDrawnRegion.Reset();
1468     for (const auto& rect : drawnRegion.GetRegionRectIs()) {
1469         RectI mappedRect = RSObjAbsGeometry::MapRect(rect.ConvertTo<float>(), invertedScaleMatrix);
1470         Occlusion::Region mappedRegion{mappedRect};
1471         sampledDrawnRegion.OrSelf(mappedRegion);
1472     }
1473 }
1474 
GetYawFromQuaternion(const Quaternion & q)1475 float RSUniRenderUtil::GetYawFromQuaternion(const Quaternion& q)
1476 {
1477     // Normalized quaternion
1478     float x = q[0];
1479     float y = q[1];
1480     float z = q[2];
1481     float w = q[3];
1482     float norm = std::sqrt((x * x) + (y * y) + (z * z) + (w * w));
1483     if (ROSEN_EQ(norm, 0.f)) {
1484         RS_LOGW("RSUniRenderUtil::GetYawFromQuaternion, norm is 0");
1485         return 0;
1486     }
1487     x = x / norm;
1488     y = y / norm;
1489     z = z / norm;
1490     w = w / norm;
1491 
1492     // Hamilton(right-hand), Formula: atan2(2(wz + xy), w² + x² - y² - z²)
1493     float sinyCosp = 2.f * (w * z + x * y);
1494     float cosyCosp = (w * w + x * x) - (y * y + z * z);
1495     float yaw = std::atan2(sinyCosp, cosyCosp);
1496 
1497     return yaw * (180.f / PI);
1498 }
1499 
CollectHardwareEnabledNodeByScreenNodeId(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & enableNodes,std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & topEnabledNodes,NodeId id)1500 void RSUniRenderUtil::CollectHardwareEnabledNodeByScreenNodeId(
1501     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& enableNodes,
1502     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& topEnabledNodes, NodeId id)
1503 {
1504     enableNodes.clear();
1505     topEnabledNodes.clear();
1506 
1507     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
1508     if (!uniParam) {
1509         RS_LOGD("RSUniRenderUtil::CollectHardCursorDrawables uniParam is null");
1510         return;
1511     }
1512 
1513     auto& hardwareDrawables = uniParam->GetHardwareEnabledTypeDrawables();
1514     for (const auto& [screenNodeId, _, drawable] : hardwareDrawables) {
1515         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
1516         if (!surfaceNodeDrawable || !surfaceNodeDrawable->ShouldPaint() ||
1517             screenNodeId != id) {
1518             continue;
1519         }
1520         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
1521         if (surfaceParams == nullptr || !surfaceParams->GetHardwareEnabled()) {
1522             continue;
1523         }
1524         // To get dump image
1525         // execute "param set rosen.dumpsurfacetype.enabled 4 && setenforce 0 && param set rosen.afbc enabled 0"
1526         auto buffer = surfaceParams->GetBuffer();
1527         RSBaseRenderUtil::WriteSurfaceBufferToPng(buffer, surfaceParams->GetId());
1528         if (surfaceNodeDrawable->IsHardwareEnabledTopSurface() || surfaceParams->IsLayerTop()) {
1529             // surfaceNode which should be drawn above displayNode like pointer window
1530             topEnabledNodes.emplace_back(drawable);
1531         } else {
1532             // surfaceNode which should be drawn below displayNode
1533             enableNodes.emplace_back(drawable);
1534         }
1535     }
1536 
1537     auto& hardCursorDrawables = uniParam->GetHardCursorDrawables();
1538     auto iter = std::find_if(hardCursorDrawables.begin(), hardCursorDrawables.end(), [id](const auto& node) {
1539         return std::get<0>(node) == id;
1540     });
1541     if (iter == hardCursorDrawables.end()) {
1542         return;
1543     }
1544     auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(std::get<2>(*iter));
1545     if (!surfaceDrawable) {
1546         return;
1547     }
1548     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceDrawable->GetRenderParams().get());
1549     if (surfaceParams == nullptr) {
1550         return;
1551     }
1552     if (!RSUniRenderThread::GetCaptureParam().isSnapshot_ && surfaceParams->GetHardCursorStatus()) {
1553         topEnabledNodes.emplace_back(surfaceDrawable);
1554     }
1555 }
1556 
CollectHardwareEnabledNodesByDisplayNodeId(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & enableNodes,std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & topEnabledNodes,NodeId id)1557 void RSUniRenderUtil::CollectHardwareEnabledNodesByDisplayNodeId(
1558     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& enableNodes,
1559     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& topEnabledNodes, NodeId id)
1560 {
1561     enableNodes.clear();
1562     topEnabledNodes.clear();
1563 
1564     auto& uniParam = RSUniRenderThread::Instance().GetRSRenderThreadParams();
1565     if (!uniParam) {
1566         RS_LOGD("RSUniRenderUtil::CollectHardCursorDrawables uniParam is null");
1567         return;
1568     }
1569 
1570     auto& hardwareDrawables = uniParam->GetHardwareEnabledTypeDrawables();
1571     for (const auto& [_, displayNodeId, drawable] : hardwareDrawables) {
1572         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
1573         if (!surfaceNodeDrawable || !surfaceNodeDrawable->ShouldPaint() ||
1574             displayNodeId != id) {
1575             continue;
1576         }
1577         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
1578         if (surfaceParams == nullptr || !surfaceParams->GetHardwareEnabled()) {
1579             continue;
1580         }
1581         // To get dump image
1582         // execute "param set rosen.dumpsurfacetype.enabled 4 && setenforce 0 && param set rosen.afbc enabled 0"
1583         auto buffer = surfaceParams->GetBuffer();
1584         RSBaseRenderUtil::WriteSurfaceBufferToPng(buffer, surfaceParams->GetId());
1585         if (surfaceNodeDrawable->IsHardwareEnabledTopSurface() || surfaceParams->IsLayerTop()) {
1586             // surfaceNode which should be drawn above displayNode like pointer window
1587             topEnabledNodes.emplace_back(drawable);
1588         } else {
1589             // surfaceNode which should be drawn below displayNode
1590             enableNodes.emplace_back(drawable);
1591         }
1592     }
1593 
1594     auto& hardCursorDrawables = uniParam->GetHardCursorDrawables();
1595     auto iter = std::find_if(hardCursorDrawables.begin(), hardCursorDrawables.end(), [id](const auto& node) {
1596         return std::get<1>(node) == id;
1597     });
1598     if (iter == hardCursorDrawables.end()) {
1599         return;
1600     }
1601     auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(std::get<2>(*iter));
1602     if (!surfaceDrawable) {
1603         return;
1604     }
1605     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceDrawable->GetRenderParams().get());
1606     if (surfaceParams == nullptr) {
1607         return;
1608     }
1609     if (!RSUniRenderThread::GetCaptureParam().isSnapshot_ && surfaceParams->GetHardCursorStatus()) {
1610         topEnabledNodes.emplace_back(surfaceDrawable);
1611     }
1612 }
1613 
AdjustZOrderAndDrawSurfaceNode(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & drawables,Drawing::Canvas & canvas,RSScreenRenderParams & params)1614 void RSUniRenderUtil::AdjustZOrderAndDrawSurfaceNode(
1615     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& drawables,
1616     Drawing::Canvas& canvas, RSScreenRenderParams& params)
1617 {
1618     if (!RSSystemProperties::GetHardwareComposerEnabled()) {
1619         RS_LOGW("RSUniRenderUtil::AdjustZOrderAndDrawSurfaceNode: \
1620             HardwareComposer is not enabled.");
1621         return;
1622     }
1623     if (drawables.empty()) {
1624         return;
1625     }
1626 
1627     // sort the surfaceNodes by ZOrder
1628     std::stable_sort(drawables.begin(), drawables.end(), [](const auto& first, const auto& second) -> bool {
1629         auto firstDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(first);
1630         auto secondDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(second);
1631         if (!firstDrawable || !firstDrawable->GetRenderParams() ||
1632             !secondDrawable || !secondDrawable->GetRenderParams()) {
1633             return false;
1634         }
1635         return firstDrawable->GetRenderParams()->GetLayerInfo().zOrder <
1636                     secondDrawable->GetRenderParams()->GetLayerInfo().zOrder;
1637     });
1638 
1639     Drawing::AutoCanvasRestore acr(canvas, true);
1640     auto rscanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
1641     if (!rscanvas) {
1642         RS_LOGE("RSScreenRenderNodeDrawable::AdjustZOrderAndDrawSurfaceNode, rscanvas is nullptr");
1643         return;
1644     }
1645     // draw hardware-composition nodes
1646     for (auto& drawable : drawables) {
1647         Drawing::AutoCanvasRestore acr(canvas, true);
1648         if (!drawable || !drawable->GetRenderParams()) {
1649             RS_LOGE("RSScreenRenderNodeDrawable::AdjustZOrderAndDrawSurfaceNode surfaceParams is nullptr");
1650             continue;
1651         }
1652         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(drawable->GetRenderParams().get());
1653         // SelfDrawingNodes need to use LayerMatrix(totalMatrix) when doing capturing
1654         auto matrix = surfaceParams->GetLayerInfo().matrix;
1655         // Use for mirror screen visible rect projection
1656         if (RSUniRenderThread::Instance().GetEnableVisibleRect()) {
1657             auto rect = surfaceParams->GetLayerInfo().dstRect;
1658             auto dstRect = Drawing::RectI(rect.x, rect.y, rect.x + rect.w, rect.y + rect.h);
1659             const auto& visibleRect = RSUniRenderThread::Instance().GetVisibleRect();
1660             // samplingScale is 1.f if subsampling is off
1661             float samplingScale = params.GetScreenInfo().samplingScale;
1662             if (dstRect.Intersect(visibleRect) && ROSEN_NE(samplingScale, 0.f)) {
1663                 // correct position, devided by samplingScale when subsampling is on
1664                 matrix.PostTranslate(-visibleRect.GetLeft() / samplingScale, -visibleRect.GetTop() / samplingScale);
1665             } else {
1666                 continue;
1667             }
1668         }
1669         canvas.ConcatMatrix(matrix);
1670         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
1671         surfaceNodeDrawable->DealWithSelfDrawingNodeBuffer(*rscanvas, *surfaceParams);
1672     }
1673 }
1674 
SwitchColorFilter(RSPaintFilterCanvas & canvas,float hdrBrightnessRatio,bool displayP3Enable)1675 void RSUniRenderUtil::SwitchColorFilter(RSPaintFilterCanvas& canvas, float hdrBrightnessRatio, bool displayP3Enable)
1676 {
1677     const auto& renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1678     if (!renderEngine) {
1679         RS_LOGE("RSScreenRenderNodeDrawable::SwitchColorFilter renderEngine is null");
1680         return;
1681     }
1682     ColorFilterMode colorFilterMode = renderEngine->GetColorFilterMode();
1683     if (colorFilterMode == ColorFilterMode::INVERT_COLOR_DISABLE_MODE ||
1684         colorFilterMode >= ColorFilterMode::DALTONIZATION_NORMAL_MODE) {
1685         return;
1686     }
1687 
1688     if (displayP3Enable) {
1689         SwitchColorFilterWithP3(canvas, colorFilterMode, hdrBrightnessRatio);
1690         return;
1691     }
1692 
1693     Drawing::AutoCanvasRestore acr(canvas, true);
1694     RS_TRACE_NAME_FMT("RSScreenRenderNodeDrawable::SetColorFilterModeToPaint mode:%d",
1695         static_cast<int32_t>(colorFilterMode));
1696     Drawing::Brush brush;
1697     RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, brush, hdrBrightnessRatio);
1698 #if defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)
1699     RSTagTracker tagTacker(
1700         renderEngine->GetRenderContext()->GetSharedDrGPUContext(),
1701         RSTagTracker::TAG_SAVELAYER_COLOR_FILTER);
1702 #endif
1703     Drawing::SaveLayerOps slr(nullptr, &brush, Drawing::SaveLayerOps::INIT_WITH_PREVIOUS);
1704     canvas.SaveLayer(slr);
1705 }
1706 
SwitchColorFilterWithP3(RSPaintFilterCanvas & canvas,ColorFilterMode colorFilterMode,float hdrBrightnessRatio)1707 void RSUniRenderUtil::SwitchColorFilterWithP3(RSPaintFilterCanvas& canvas,
1708     ColorFilterMode colorFilterMode, float hdrBrightnessRatio)
1709 {
1710     RS_TRACE_NAME_FMT("RSScreenRenderNodeDrawable::SwitchColorFilterWithP3 mode:%d",
1711         static_cast<int32_t>(colorFilterMode));
1712 
1713     int32_t offscreenWidth = canvas.GetWidth();
1714     int32_t offscreenHeight = canvas.GetHeight();
1715 
1716     Drawing::ImageInfo info = Drawing::ImageInfo { offscreenWidth, offscreenHeight,
1717         Drawing::COLORTYPE_RGBA_F16, Drawing::ALPHATYPE_PREMUL, Drawing::ColorSpace::CreateSRGB()};
1718     auto offscreenSurface = canvas.GetSurface()->MakeSurface(info);
1719     auto offscreenCanvas = std::make_shared<RSPaintFilterCanvas>(offscreenSurface.get());
1720 
1721     Drawing::Brush brush;
1722     auto originSurfaceImage = canvas.GetSurface()->GetImageSnapshot();
1723     RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, brush, hdrBrightnessRatio);
1724     offscreenCanvas->AttachBrush(brush);
1725     offscreenCanvas->DrawImage(*originSurfaceImage, 0.f, 0.f, Drawing::SamplingOptions());
1726     offscreenCanvas->DetachBrush();
1727 
1728     auto offscreenImage = offscreenCanvas->GetSurface()->GetImageSnapshot();
1729     Drawing::AutoCanvasRestore acr(canvas, true);
1730     canvas.ResetMatrix();
1731     canvas.DrawImage(*offscreenImage, 0.f, 0.f, Drawing::SamplingOptions());
1732 }
1733 
1734 } // namespace Rosen
1735 } // namespace OHOS
1736