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