• 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 "drawable/rs_display_render_node_drawable.h"
30 #include "drawable/rs_surface_render_node_drawable.h"
31 #include "info_collection/rs_gpu_dirty_region_collection.h"
32 #include "params/rs_display_render_params.h"
33 #include "params/rs_surface_render_params.h"
34 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
35 #include "pipeline/rs_base_render_util.h"
36 #include "pipeline/rs_main_thread.h"
37 #include "pipeline/rs_render_node.h"
38 #include "pipeline/rs_surface_render_node.h"
39 #include "platform/common/rs_log.h"
40 #include "property/rs_properties.h"
41 #include "render/rs_drawing_filter.h"
42 #include "render/rs_maskcolor_shader_filter.h"
43 #include "render/rs_material_filter.h"
44 #include "render/rs_path.h"
45 
46 #ifdef RS_ENABLE_VK
47 #include "include/gpu/GrBackendSurface.h"
48 #include "platform/ohos/backend/native_buffer_utils.h"
49 #include "platform/ohos/backend/rs_surface_ohos_vulkan.h"
50 #include "platform/ohos/backend/rs_vulkan_context.h"
51 #endif
52 
53 namespace OHOS {
54 namespace Rosen {
55 namespace {
56 constexpr const char* CAPTURE_WINDOW_NAME = "CapsuleWindow";
57 constexpr float GAMMA2_2 = 2.2f;
58 }
MergeDirtyHistory(std::shared_ptr<RSDisplayRenderNode> & node,int32_t bufferAge,bool useAlignedDirtyRegion)59 void RSUniRenderUtil::MergeDirtyHistory(std::shared_ptr<RSDisplayRenderNode>& node, int32_t bufferAge,
60     bool useAlignedDirtyRegion)
61 {
62     auto& curAllSurfaces = node->GetCurAllSurfaces();
63     // update all child surfacenode history
64     for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
65         auto surfaceNode = RSRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
66         if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
67             continue;
68         }
69         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderUtil::MergeDirtyHistory for surfaceNode %" PRIu64"",
70             surfaceNode->GetId());
71         auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
72         if (UNLIKELY(!surfaceDirtyManager)) {
73             continue;
74         }
75         if (!surfaceDirtyManager->SetBufferAge(bufferAge)) {
76             ROSEN_LOGE("RSUniRenderUtil::MergeDirtyHistory with invalid buffer age %{public}d", bufferAge);
77         }
78         surfaceDirtyManager->IntersectDirtyRect(surfaceNode->GetOldDirtyInSurface());
79         surfaceDirtyManager->UpdateDirty(useAlignedDirtyRegion);
80     }
81 
82     // update display dirtymanager
83     node->UpdateDisplayDirtyManager(bufferAge, useAlignedDirtyRegion);
84 }
85 
MergeDirtyHistoryForDrawable(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,int32_t bufferAge,RSDisplayRenderParams & params,bool useAlignedDirtyRegion)86 void RSUniRenderUtil::MergeDirtyHistoryForDrawable(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable,
87     int32_t bufferAge, RSDisplayRenderParams& params, bool useAlignedDirtyRegion)
88 {
89     auto& curAllSurfaceDrawables = params.GetAllMainAndLeashSurfaceDrawables();
90     // update all child surfacenode history
91     for (auto it = curAllSurfaceDrawables.rbegin(); it != curAllSurfaceDrawables.rend(); ++it) {
92         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
93         if (surfaceNodeDrawable == nullptr) {
94             continue;
95         }
96         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
97         if (surfaceParams == nullptr || !surfaceParams->IsAppWindow()) {
98             continue;
99         }
100         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
101         if (surfaceDirtyManager == nullptr) {
102             continue;
103         }
104         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderUtil::MergeDirtyHistory for surfaceNode %" PRIu64"",
105             surfaceParams->GetId());
106         if (!surfaceDirtyManager->SetBufferAge(bufferAge)) {
107             ROSEN_LOGW("RSUniRenderUtil::MergeDirtyHistory with invalid buffer age %{public}d", bufferAge);
108         }
109         surfaceDirtyManager->IntersectDirtyRect(surfaceParams->GetOldDirtyInSurface());
110         surfaceDirtyManager->UpdateDirty(useAlignedDirtyRegion);
111     }
112 
113     // update display dirtymanager
114     if (auto dirtyManager = displayDrawable.GetSyncDirtyManager()) {
115         dirtyManager->SetBufferAge(bufferAge);
116         dirtyManager->UpdateDirty(useAlignedDirtyRegion);
117     }
118 }
119 
MergeVisibleDirtyRegion(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceNodeDrawables,std::vector<NodeId> & hasVisibleDirtyRegionSurfaceVec,bool useAlignedDirtyRegion)120 Occlusion::Region RSUniRenderUtil::MergeVisibleDirtyRegion(
121     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceNodeDrawables,
122     std::vector<NodeId>& hasVisibleDirtyRegionSurfaceVec, bool useAlignedDirtyRegion)
123 {
124     Occlusion::Region allSurfaceVisibleDirtyRegion;
125     for (auto it = allSurfaceNodeDrawables.rbegin(); it != allSurfaceNodeDrawables.rend(); ++it) {
126         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
127         if (surfaceNodeDrawable == nullptr) {
128             RS_LOGI("MergeVisibleDirtyRegion surfaceNodeDrawable is nullptr");
129             continue;
130         }
131         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
132         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
133         if (!surfaceParams || !surfaceDirtyManager) {
134             RS_LOGI("RSUniRenderUtil::MergeVisibleDirtyRegion node(%{public}" PRIu64") params or "
135                 "dirty manager is nullptr", surfaceNodeDrawable->GetId());
136             continue;
137         }
138         if (!surfaceParams->IsAppWindow() || surfaceParams->GetDstRect().IsEmpty()) {
139             continue;
140         }
141         auto surfaceDirtyRect = surfaceDirtyManager->GetDirtyRegion();
142         Occlusion::Rect dirtyRect { surfaceDirtyRect.left_, surfaceDirtyRect.top_, surfaceDirtyRect.GetRight(),
143             surfaceDirtyRect.GetBottom() };
144         auto visibleRegion = surfaceParams->GetVisibleRegion();
145         Occlusion::Region surfaceDirtyRegion { dirtyRect };
146         Occlusion::Region surfaceVisibleDirtyRegion = surfaceDirtyRegion.And(visibleRegion);
147 
148         surfaceNodeDrawable->SetVisibleDirtyRegion(surfaceVisibleDirtyRegion);
149         if (!surfaceVisibleDirtyRegion.IsEmpty()) {
150             hasVisibleDirtyRegionSurfaceVec.emplace_back(surfaceParams->GetId());
151         }
152         if (useAlignedDirtyRegion) {
153             Occlusion::Region alignedRegion = AlignedDirtyRegion(surfaceVisibleDirtyRegion);
154             surfaceNodeDrawable->SetAlignedVisibleDirtyRegion(alignedRegion);
155             allSurfaceVisibleDirtyRegion.OrSelf(alignedRegion);
156             GpuDirtyRegionCollection::GetInstance().UpdateActiveDirtyInfoForDFX(surfaceParams->GetId(),
157                 surfaceNodeDrawable->GetName(), alignedRegion.GetRegionRectIs());
158         } else {
159             allSurfaceVisibleDirtyRegion = allSurfaceVisibleDirtyRegion.Or(surfaceVisibleDirtyRegion);
160             GpuDirtyRegionCollection::GetInstance().UpdateActiveDirtyInfoForDFX(surfaceParams->GetId(),
161                 surfaceNodeDrawable->GetName(), surfaceVisibleDirtyRegion.GetRegionRectIs());
162         }
163     }
164     return allSurfaceVisibleDirtyRegion;
165 }
166 
MergeDirtyHistoryInVirtual(DrawableV2::RSDisplayRenderNodeDrawable & displayDrawable,int32_t bufferAge,bool renderParallel)167 void RSUniRenderUtil::MergeDirtyHistoryInVirtual(DrawableV2::RSDisplayRenderNodeDrawable& displayDrawable,
168     int32_t bufferAge, bool renderParallel)
169 {
170     (void)renderParallel;
171     auto& params = displayDrawable.GetRenderParams();
172     if (!params) {
173         RS_LOGE("RSUniRenderUtil::MergeDirtyHistory params is nullptr");
174         return;
175     }
176     auto& curAllSurfaceDrawables = params->GetAllMainAndLeashSurfaceDrawables();
177     for (auto it = curAllSurfaceDrawables.rbegin(); it != curAllSurfaceDrawables.rend(); ++it) {
178         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
179         if (surfaceNodeDrawable == nullptr) {
180             continue;
181         }
182         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
183         if (surfaceParams == nullptr || !surfaceParams->IsAppWindow()) {
184             continue;
185         }
186         RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderUtil::MergeDirtyHistory for surfaceNode %" PRIu64"",
187             surfaceParams->GetId());
188         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
189         surfaceDirtyManager->MergeDirtyHistoryInVirtual(bufferAge);
190     }
191     // update display dirtymanager
192     auto displayDirtyManager = displayDrawable.GetSyncDirtyManager();
193     displayDirtyManager->MergeDirtyHistoryInVirtual(bufferAge);
194 }
195 
MergeVisibleDirtyRegionInVirtual(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceNodeDrawables)196 Occlusion::Region RSUniRenderUtil::MergeVisibleDirtyRegionInVirtual(
197     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceNodeDrawables)
198 {
199     Occlusion::Region allSurfaceVisibleDirtyRegion;
200     for (auto it = allSurfaceNodeDrawables.rbegin(); it != allSurfaceNodeDrawables.rend(); ++it) {
201         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
202         if (surfaceNodeDrawable == nullptr) {
203             RS_LOGI("MergeVisibleDirtyRegion surfaceNodeDrawable is nullptr");
204             continue;
205         }
206         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
207         if (!surfaceParams) {
208             RS_LOGI("RSUniRenderUtil::MergeVisibleDirtyRegion surface params is nullptr");
209             continue;
210         }
211         if (!surfaceParams->IsAppWindow() || surfaceParams->GetDstRect().IsEmpty() ||
212             surfaceParams->GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos ||
213             surfaceParams->GetIsSkipLayer()) {
214             continue;
215         }
216         auto surfaceDirtyManager = surfaceNodeDrawable->GetSyncDirtyManager();
217         auto surfaceDirtyRect = surfaceDirtyManager->GetDirtyRegionInVirtual();
218         Occlusion::Rect dirtyRect { surfaceDirtyRect.left_, surfaceDirtyRect.top_,
219             surfaceDirtyRect.GetRight(), surfaceDirtyRect.GetBottom() };
220         auto visibleRegion = surfaceParams->GetVisibleRegionInVirtual();
221         Occlusion::Region surfaceDirtyRegion { dirtyRect };
222         Occlusion::Region surfaceVisibleDirtyRegion = surfaceDirtyRegion.And(visibleRegion);
223         allSurfaceVisibleDirtyRegion = allSurfaceVisibleDirtyRegion.Or(surfaceVisibleDirtyRegion);
224     }
225     return allSurfaceVisibleDirtyRegion;
226 }
227 
SetAllSurfaceDrawableGlobalDityRegion(std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr> & allSurfaceDrawables,const Occlusion::Region & globalDirtyRegion)228 void RSUniRenderUtil::SetAllSurfaceDrawableGlobalDityRegion(
229     std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& allSurfaceDrawables,
230     const Occlusion::Region& globalDirtyRegion)
231 {
232     // Set Surface Global Dirty Region
233     for (auto it = allSurfaceDrawables.rbegin(); it != allSurfaceDrawables.rend(); ++it) {
234         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(*it);
235         if (surfaceNodeDrawable == nullptr) {
236             continue;
237         }
238         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
239         if (!surfaceParams) {
240             RS_LOGW("RSUniRenderUtil::MergeVisibleDirtyRegion surface params is nullptr");
241             continue;
242         }
243         if (!surfaceParams->IsMainWindowType()) {
244             continue;
245         }
246         // set display dirty region to surfaceNodeDrawable
247         surfaceNodeDrawable->SetGlobalDirtyRegion(globalDirtyRegion);
248         surfaceNodeDrawable->SetDirtyRegionAlignedEnable(false);
249     }
250     Occlusion::Region curVisibleDirtyRegion;
251     for (auto& it : allSurfaceDrawables) {
252         auto surfaceNodeDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(it);
253         if (surfaceNodeDrawable == nullptr) {
254             continue;
255         }
256         auto surfaceParams = static_cast<RSSurfaceRenderParams*>(surfaceNodeDrawable->GetRenderParams().get());
257         if (!surfaceParams) {
258             RS_LOGE("RSUniRenderUtil::MergeVisibleDirtyRegion surface params is nullptr");
259             continue;
260         }
261         if (!surfaceParams->IsMainWindowType()) {
262             continue;
263         }
264         // set display dirty region to surfaceNodeDrawable
265         surfaceNodeDrawable->SetDirtyRegionBelowCurrentLayer(curVisibleDirtyRegion);
266         auto visibleDirtyRegion = surfaceNodeDrawable->GetVisibleDirtyRegion();
267         curVisibleDirtyRegion = curVisibleDirtyRegion.Or(visibleDirtyRegion);
268     }
269 }
270 
ScreenIntersectDirtyRects(const Occlusion::Region & region,ScreenInfo & screenInfo)271 std::vector<RectI> RSUniRenderUtil::ScreenIntersectDirtyRects(const Occlusion::Region &region, ScreenInfo& screenInfo)
272 {
273     const std::vector<Occlusion::Rect>& rects = region.GetRegionRects();
274     std::vector<RectI> retRects;
275     for (const Occlusion::Rect& rect : rects) {
276         // origin transformation
277 #ifdef RS_ENABLE_VK
278         if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
279             RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
280             retRects.emplace_back(RectI(rect.left_, rect.top_,
281                 rect.right_ - rect.left_, rect.bottom_ - rect.top_));
282         } else {
283             retRects.emplace_back(RectI(rect.left_, screenInfo.GetRotatedHeight() - rect.bottom_,
284                 rect.right_ - rect.left_, rect.bottom_ - rect.top_));
285         }
286 #else
287         retRects.emplace_back(RectI(rect.left_, screenInfo.GetRotatedHeight() - rect.bottom_,
288             rect.right_ - rect.left_, rect.bottom_ - rect.top_));
289 #endif
290     }
291     RS_LOGD("ScreenIntersectDirtyRects size %{public}d %{public}s", region.GetSize(), region.GetRegionInfo().c_str());
292     return retRects;
293 }
294 
GetFilpDirtyRects(const std::vector<RectI> & srcRects,const ScreenInfo & screenInfo)295 std::vector<RectI> RSUniRenderUtil::GetFilpDirtyRects(const std::vector<RectI>& srcRects, const ScreenInfo& screenInfo)
296 {
297 #ifdef RS_ENABLE_VK
298     if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
299         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
300         return srcRects;
301     }
302 #endif
303 
304     return FilpRects(srcRects, screenInfo);
305 }
306 
FilpRects(const std::vector<RectI> & srcRects,const ScreenInfo & screenInfo)307 std::vector<RectI> RSUniRenderUtil::FilpRects(const std::vector<RectI>& srcRects, const ScreenInfo& screenInfo)
308 {
309     std::vector<RectI> retRects;
310     for (const RectI& rect : srcRects) {
311         retRects.emplace_back(RectI(rect.left_, screenInfo.GetRotatedHeight() - rect.top_ - rect.height_,
312             rect.width_, rect.height_));
313     }
314     return retRects;
315 }
316 
SrcRectScaleFit(BufferDrawParam & params,const sptr<SurfaceBuffer> & buffer,const sptr<IConsumerSurface> & surface,RectF & localBounds)317 void RSUniRenderUtil::SrcRectScaleFit(BufferDrawParam& params, const sptr<SurfaceBuffer>& buffer,
318     const sptr<IConsumerSurface>& surface, RectF& localBounds)
319 {
320     if (buffer == nullptr || surface == nullptr) {
321         RS_LOGE("buffer or surface is nullptr");
322         return;
323     }
324     uint32_t srcWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
325     uint32_t srcHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
326     uint32_t newWidth = 0;
327     uint32_t newHeight = 0;
328     // Canvas is able to handle the situation when the window is out of screen, using bounds instead of dst.
329     uint32_t boundsWidth = static_cast<uint32_t>(localBounds.GetWidth());
330     uint32_t boundsHeight = static_cast<uint32_t>(localBounds.GetHeight());
331     if (boundsWidth == 0 || boundsHeight == 0 || srcWidth == 0 || srcHeight == 0) {
332         return;
333     }
334 
335     if (srcWidth * boundsHeight > srcHeight * boundsWidth) {
336         newWidth = boundsWidth;
337         newHeight = srcHeight * newWidth / srcWidth;
338     } else if (srcWidth * boundsHeight < srcHeight * boundsWidth) {
339         newHeight = boundsHeight;
340         newWidth = newHeight * srcWidth / srcHeight;
341     } else {
342         newWidth = boundsWidth;
343         newHeight = boundsHeight;
344     }
345     newHeight = newHeight * srcHeight / boundsHeight;
346     newWidth = newWidth * srcWidth / boundsWidth;
347     if (newWidth < srcWidth) {
348         auto halfdw = (srcWidth - newWidth) / 2;
349         params.dstRect =
350             Drawing::Rect(params.srcRect.GetLeft() + static_cast<int32_t>(halfdw), params.srcRect.GetTop(),
351                 params.srcRect.GetLeft() + static_cast<int32_t>(halfdw) + static_cast<int32_t>(newWidth),
352                 params.srcRect.GetTop() + params.srcRect.GetHeight());
353     } else if (newHeight < srcHeight) {
354         auto halfdh = (srcHeight - newHeight) / 2;
355         params.dstRect =
356             Drawing::Rect(params.srcRect.GetLeft(), params.srcRect.GetTop() + static_cast<int32_t>(halfdh),
357                 params.srcRect.GetLeft() + params.srcRect.GetWidth(),
358                 params.srcRect.GetTop() + static_cast<int32_t>(halfdh) + static_cast<int32_t>(newHeight));
359     }
360     RS_LOGD("RsDebug RSUniRenderUtil::SrcRectScaleFit name:%{public}s,"
361         " dstRect [%{public}f %{public}f %{public}f %{public}f]",
362         surface->GetName().c_str(), params.dstRect.GetLeft(), params.dstRect.GetTop(),
363         params.dstRect.GetWidth(), params.dstRect.GetHeight());
364 }
365 
SrcRectScaleDown(BufferDrawParam & params,const sptr<SurfaceBuffer> & buffer,const sptr<IConsumerSurface> & surface,RectF & localBounds)366 void RSUniRenderUtil::SrcRectScaleDown(BufferDrawParam& params, const sptr<SurfaceBuffer>& buffer,
367     const sptr<IConsumerSurface>& surface, RectF& localBounds)
368 {
369     if (buffer == nullptr || surface == nullptr) {
370         return;
371     }
372     uint32_t newWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
373     uint32_t newHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
374     // Canvas is able to handle the situation when the window is out of screen, using bounds instead of dst.
375     uint32_t boundsWidth = static_cast<uint32_t>(localBounds.GetWidth());
376     uint32_t boundsHeight = static_cast<uint32_t>(localBounds.GetHeight());
377 
378     uint32_t newWidthBoundsHeight = newWidth * boundsHeight;
379     uint32_t newHeightBoundsWidth = newHeight * boundsWidth;
380 
381     if (newWidthBoundsHeight > newHeightBoundsWidth) {
382         newWidth = boundsWidth * newHeight / boundsHeight;
383     } else if (newWidthBoundsHeight < newHeightBoundsWidth) {
384         newHeight = boundsHeight * newWidth / boundsWidth;
385     } else {
386         return;
387     }
388 
389     uint32_t currentWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
390     uint32_t currentHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
391     if (newWidth < currentWidth) {
392         // the crop is too wide
393         uint32_t dw = currentWidth - newWidth;
394         auto halfdw = dw / 2;
395         params.srcRect =
396             Drawing::Rect(params.srcRect.GetLeft() + static_cast<int32_t>(halfdw), params.srcRect.GetTop(),
397                 params.srcRect.GetLeft() + static_cast<int32_t>(halfdw) + static_cast<int32_t>(newWidth),
398                 params.srcRect.GetTop() + params.srcRect.GetHeight());
399     } else {
400         // thr crop is too tall
401         uint32_t dh = currentHeight - newHeight;
402         auto halfdh = dh / 2;
403         params.srcRect =
404             Drawing::Rect(params.srcRect.GetLeft(), params.srcRect.GetTop() + static_cast<int32_t>(halfdh),
405                 params.srcRect.GetLeft() + params.srcRect.GetWidth(),
406                 params.srcRect.GetTop() + static_cast<int32_t>(halfdh) + static_cast<int32_t>(newHeight));
407     }
408     RS_LOGD("RsDebug RSUniRenderUtil::SrcRectScaleDown name:%{public}s,"
409         " srcRect [%{public}f %{public}f %{public}f %{public}f]",
410         surface->GetName().c_str(), params.srcRect.GetLeft(), params.srcRect.GetTop(),
411         params.srcRect.GetWidth(), params.srcRect.GetHeight());
412 }
413 
GetMatrixOfBufferToRelRect(const RSSurfaceRenderNode & node)414 Drawing::Matrix RSUniRenderUtil::GetMatrixOfBufferToRelRect(const RSSurfaceRenderNode& node)
415 {
416     const sptr<SurfaceBuffer> buffer = node.GetRSSurfaceHandler()->GetBuffer();
417     if (buffer == nullptr) {
418         return Drawing::Matrix();
419     }
420 
421     auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
422     if (consumer == nullptr) {
423         return Drawing::Matrix();
424     }
425 
426     BufferDrawParam params;
427     params.buffer = buffer;
428     params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
429     const RSProperties& property = node.GetRenderProperties();
430     params.dstRect = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
431     auto transform = RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, buffer);
432     RectF localBounds = { 0.0f, 0.0f, property.GetBoundsWidth(), property.GetBoundsHeight() };
433     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, property.GetFrameGravity(), localBounds, params);
434     RSBaseRenderUtil::FlipMatrix(transform, params);
435     return params.matrix;
436 }
437 
CreateBufferDrawParam(const RSSurfaceRenderNode & node,bool forceCPU,uint32_t threadIndex,bool useRenderParams)438 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(
439     const RSSurfaceRenderNode& node, bool forceCPU, uint32_t threadIndex, bool useRenderParams)
440 {
441     BufferDrawParam params;
442 
443     auto drawable = node.GetRenderDrawable();
444     if (useRenderParams && !drawable) {
445         return params;
446     }
447     auto surfaceDrawable = std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(drawable);
448     auto& nodeParams = surfaceDrawable->GetRenderParams();
449     if (useRenderParams && !nodeParams) {
450         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam RenderThread nodeParams is nullptr");
451         return params;
452     }
453     auto surfaceHandler = node.GetRSSurfaceHandler();
454     auto surfaceParams = static_cast<RSSurfaceRenderParams*>(nodeParams.get());
455     const RSProperties& property = node.GetRenderProperties();
456 
457     params.threadIndex = threadIndex;
458     params.useBilinearInterpolation = useRenderParams ?
459         surfaceParams->NeedBilinearInterpolation() : node.NeedBilinearInterpolation();
460     params.useCPU = forceCPU;
461     Drawing::Filter filter;
462     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
463     params.paint.SetFilter(filter);
464 
465     auto boundWidth = useRenderParams ? nodeParams->GetBounds().GetWidth() : property.GetBoundsWidth();
466     auto boundHeight = useRenderParams ? nodeParams->GetBounds().GetHeight() : property.GetBoundsHeight();
467     params.dstRect = Drawing::Rect(0, 0, boundWidth, boundHeight);
468 
469     const sptr<SurfaceBuffer> buffer = useRenderParams ? surfaceParams->GetBuffer() : surfaceHandler->GetBuffer();
470     if (buffer == nullptr) {
471         return params;
472     }
473     params.buffer = buffer;
474     params.acquireFence = useRenderParams ? nodeParams->GetAcquireFence() : surfaceHandler->GetAcquireFence();
475     params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
476 
477     auto consumer = useRenderParams ? surfaceDrawable->GetConsumerOnDraw() : surfaceHandler->GetConsumer();
478     if (consumer == nullptr) {
479         return params;
480     }
481     auto transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
482     if (consumer->GetSurfaceBufferTransformType(buffer, &transform) != GSERROR_OK) {
483         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam GetSurfaceBufferTransformType failed");
484     }
485     RectF localBounds = { 0.0f, 0.0f, boundWidth, boundHeight };
486     auto gravity = useRenderParams ? nodeParams->GetFrameGravity() : property.GetFrameGravity();
487     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, gravity, localBounds, params, surfaceParams);
488     RSBaseRenderUtil::FlipMatrix(transform, params);
489     ScalingMode scalingMode = surfaceParams->GetScalingMode();
490     if (consumer->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK) {
491         surfaceParams->SetScalingMode(scalingMode);
492     }
493     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
494         SrcRectScaleDown(params, buffer, consumer, localBounds);
495     } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
496         SrcRectScaleFit(params, buffer, consumer, localBounds);
497     }
498     return params;
499 }
500 
CreateBufferDrawParam(const DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable,bool forceCPU,uint32_t threadIndex)501 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(
502     const DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, bool forceCPU, uint32_t threadIndex)
503 {
504     BufferDrawParam params;
505     auto& nodeParams = surfaceDrawable.GetRenderParams();
506     if (!nodeParams) {
507         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam RenderThread nodeParams is nullptr");
508         return params;
509     }
510     auto surfaceNodeParams = static_cast<RSSurfaceRenderParams*>(nodeParams.get());
511     params.threadIndex = threadIndex;
512     params.useBilinearInterpolation = surfaceNodeParams->NeedBilinearInterpolation();
513     params.useCPU = forceCPU;
514     Drawing::Filter filter;
515     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
516     params.paint.SetFilter(filter);
517 
518     auto boundWidth = nodeParams->GetBounds().GetWidth();
519     auto boundHeight = nodeParams->GetBounds().GetHeight();
520     params.dstRect = Drawing::Rect(0, 0, boundWidth, boundHeight);
521 
522     const sptr<SurfaceBuffer> buffer = nodeParams->GetBuffer();
523     if (buffer == nullptr) {
524         return params;
525     }
526     params.buffer = buffer;
527     params.acquireFence = nodeParams->GetAcquireFence();
528     params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
529 
530     auto consumer = surfaceDrawable.GetConsumerOnDraw();
531     if (consumer == nullptr) {
532         return params;
533     }
534     auto transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
535     if (consumer->GetSurfaceBufferTransformType(buffer, &transform) != GSERROR_OK) {
536         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam GetSurfaceBufferTransformType failed");
537     }
538     RectF localBounds = { 0.0f, 0.0f, boundWidth, boundHeight };
539     auto gravity = nodeParams->GetFrameGravity();
540     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, gravity, localBounds, params, surfaceNodeParams);
541     RSBaseRenderUtil::FlipMatrix(transform, params);
542     ScalingMode scalingMode = surfaceNodeParams->GetScalingMode();
543     if (consumer->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK) {
544         surfaceNodeParams->SetScalingMode(scalingMode);
545     }
546     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
547         SrcRectScaleDown(params, buffer, consumer, localBounds);
548     } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
549         SrcRectScaleFit(params, buffer, consumer, localBounds);
550     }
551     return params;
552 }
553 
CreateBufferDrawParamForRotationFixed(const DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable,RSSurfaceRenderParams & renderParams)554 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParamForRotationFixed(
555     const DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, RSSurfaceRenderParams& renderParams)
556 {
557     BufferDrawParam params;
558     params.threadIndex = static_cast<uint32_t>(gettid());
559     params.useBilinearInterpolation = renderParams.NeedBilinearInterpolation();
560     params.useCPU = false;
561     params.targetColorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
562 #ifdef USE_VIDEO_PROCESSING_ENGINE
563     params.sdrNits = renderParams.GetSdrNit();
564     params.tmoNits = renderParams.GetDisplayNit();
565     params.displayNits = params.tmoNits / std::pow(renderParams.GetBrightnessRatio(), GAMMA2_2); // gamma 2.2
566 #endif
567 
568     Drawing::Filter filter;
569     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
570     params.paint.SetFilter(filter);
571 
572     auto buffer = renderParams.GetBuffer();
573     if (buffer == nullptr) {
574         return params;
575     }
576     params.buffer = buffer;
577     params.acquireFence = renderParams.GetAcquireFence();
578     auto srcRect = renderParams.GetLayerInfo().srcRect;
579     params.srcRect = Drawing::Rect(srcRect.x, srcRect.y, srcRect.x + srcRect.w, srcRect.y + srcRect.h);
580 
581     auto dstRect = renderParams.GetLayerInfo().dstRect;
582     params.matrix = Drawing::Matrix();
583     params.matrix.PreTranslate(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y));
584 
585     auto layerTransform = renderParams.GetLayerInfo().transformType;
586     int realRotation = RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(layerTransform));
587     auto flip = RSBaseRenderUtil::GetFlipTransform(layerTransform);
588     // calculate transform in anti-clockwise
589     auto transform = RSBaseRenderUtil::RotateEnumToInt(realRotation, flip);
590 
591     RectF localBounds = { 0.0f, 0.0f,
592         static_cast<float>(dstRect.w), static_cast<float>(dstRect.h) };
593     DealWithRotationAndGravityForRotationFixed(transform, renderParams.GetFrameGravity(), localBounds, params);
594     RSBaseRenderUtil::FlipMatrix(transform, params);
595     return params;
596 }
597 
DealWithRotationAndGravityForRotationFixed(GraphicTransformType transform,Gravity gravity,RectF & localBounds,BufferDrawParam & params)598 void RSUniRenderUtil::DealWithRotationAndGravityForRotationFixed(GraphicTransformType transform, Gravity gravity,
599     RectF& localBounds, BufferDrawParam& params)
600 {
601     auto rotationTransform = RSBaseRenderUtil::GetRotateTransform(transform);
602     params.matrix.PreConcat(RSBaseRenderUtil::GetSurfaceTransformMatrix(rotationTransform, localBounds));
603     if (rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_90 ||
604         rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_270) {
605         // after rotate, we should swap dstRect and bound's width and height.
606         std::swap(localBounds.width_, localBounds.height_);
607     }
608     params.dstRect = Drawing::Rect(0, 0, params.srcRect.GetWidth(), params.srcRect.GetHeight());
609 
610     Drawing::Matrix gravityMatrix;
611     if (!RSPropertiesPainter::GetGravityMatrix(gravity, localBounds,
612         params.srcRect.GetWidth(), params.srcRect.GetHeight(), gravityMatrix)) {
613         RS_LOGD("RSUniRenderUtil::DealWithRotationAndGravityForRotationFixed did not obtain gravity matrix.");
614     }
615     params.matrix.PreConcat(gravityMatrix);
616 }
617 
CreateBufferDrawParam(const RSDisplayRenderNode & node,bool forceCPU)618 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(const RSDisplayRenderNode& node, bool forceCPU)
619 {
620     BufferDrawParam params;
621     params.useCPU = forceCPU;
622     Drawing::Filter filter;
623     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
624     params.paint.SetFilter(filter);
625 
626     auto drawable = node.GetRenderDrawable();
627     if (!drawable) {
628         return params;
629     }
630     auto displayDrawable = std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(drawable);
631     auto surfaceHandler = displayDrawable->GetRSSurfaceHandlerOnDraw();
632     const sptr<SurfaceBuffer> buffer = surfaceHandler->GetBuffer();
633     if (!buffer) {
634         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam buffer is null.");
635         return params;
636     }
637     params.buffer = buffer;
638     params.acquireFence = surfaceHandler->GetAcquireFence();
639     params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
640     params.dstRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
641     return params;
642 }
643 
CreateBufferDrawParam(const RSSurfaceHandler & surfaceHandler,bool forceCPU)644 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(const RSSurfaceHandler& surfaceHandler, bool forceCPU)
645 {
646     BufferDrawParam bufferDrawParam;
647     bufferDrawParam.useCPU = forceCPU;
648     Drawing::Filter filter;
649     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
650     bufferDrawParam.paint.SetFilter(filter);
651 
652     const sptr<SurfaceBuffer> buffer = surfaceHandler.GetBuffer();
653     if (!buffer) {
654         RS_LOGE("RSUniRenderUtil::CreateBufferDrawParam buffer is null.");
655         return bufferDrawParam;
656     }
657     bufferDrawParam.buffer = buffer;
658     bufferDrawParam.acquireFence = surfaceHandler.GetAcquireFence();
659     bufferDrawParam.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
660     bufferDrawParam.dstRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
661     return bufferDrawParam;
662 }
663 
CreateLayerBufferDrawParam(const LayerInfoPtr & layer,bool forceCPU)664 BufferDrawParam RSUniRenderUtil::CreateLayerBufferDrawParam(const LayerInfoPtr& layer, bool forceCPU)
665 {
666     BufferDrawParam params;
667     if (layer == nullptr) {
668         return params;
669     }
670     params.useCPU = forceCPU;
671     Drawing::Filter filter;
672     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
673     params.paint.SetFilter(filter);
674     params.paint.SetAlpha(layer->GetAlpha().gAlpha);
675     sptr<SurfaceBuffer> buffer = layer->GetBuffer();
676     if (buffer == nullptr) {
677         return params;
678     }
679     params.acquireFence = layer->GetAcquireFence();
680     params.buffer = buffer;
681     params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
682     auto boundRect = layer->GetBoundSize();
683     params.dstRect = Drawing::Rect(0, 0, boundRect.w, boundRect.h);
684 
685     auto layerMatrix = layer->GetMatrix();
686     params.matrix = Drawing::Matrix();
687     bool rotationFixed = layer->GetRotationFixed();
688     auto dstRect = layer->GetLayerSize();
689     if (rotationFixed) {
690         // if rotation fixed, not use [total matrix + bounds] to draw buffer, use [src + dst + transform]
691         params.matrix.PreTranslate(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y));
692         auto srcRect = layer->GetCropRect();
693         params.srcRect = Drawing::Rect(srcRect.x, srcRect.y, srcRect.x + srcRect.w, srcRect.y + srcRect.h);
694     } else {
695         params.matrix.SetMatrix(layerMatrix.scaleX, layerMatrix.skewX, layerMatrix.transX, layerMatrix.skewY,
696             layerMatrix.scaleY, layerMatrix.transY, layerMatrix.pers0, layerMatrix.pers1, layerMatrix.pers2);
697     }
698     // rotation degree anti-clockwise
699     int nodeRotation = rotationFixed ? 0 : RSUniRenderUtil::GetRotationFromMatrix(params.matrix);
700     auto layerTransform = layer->GetTransformType();
701     // calculate clockwise rotation degree excluded rotation in total matrix
702     int realRotation = (nodeRotation +
703         RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(layerTransform))) % 360;
704     auto flip = RSBaseRenderUtil::GetFlipTransform(layerTransform);
705     // calculate transform in anti-clockwise
706     auto transform = RSBaseRenderUtil::RotateEnumToInt(realRotation, flip);
707 
708     RectF localBounds = { 0.0f, 0.0f,
709         rotationFixed ? static_cast<float>(dstRect.w) : static_cast<float>(boundRect.w),
710         rotationFixed ? static_cast<float>(dstRect.h) : static_cast<float>(boundRect.h) };
711     if (rotationFixed) {
712         DealWithRotationAndGravityForRotationFixed(transform, static_cast<Gravity>(layer->GetGravity()), localBounds,
713             params);
714     } else {
715         RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, static_cast<Gravity>(layer->GetGravity()),
716             localBounds, params);
717     }
718     RSBaseRenderUtil::FlipMatrix(transform, params);
719     if (rotationFixed) {
720         // if rotation fixed, no need to calculate scaling mode, it is contained in dstRect
721         return params;
722     }
723     ScalingMode scalingMode = ScalingMode::SCALING_MODE_SCALE_TO_WINDOW;
724     const auto& surface = layer->GetSurface();
725     if (surface == nullptr) {
726         RS_LOGE("buffer or surface is nullptr");
727         return params;
728     }
729 
730     if (surface->GetScalingMode(buffer->GetSeqNum(), scalingMode) != GSERROR_OK) {
731         scalingMode = layer->GetScalingMode();
732     }
733 
734     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
735         SrcRectScaleDown(params, buffer, surface, localBounds);
736     } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
737         SrcRectScaleFit(params, buffer, surface, localBounds);
738     }
739     return params;
740 }
741 
IsNeedClient(RSSurfaceRenderNode & node,const ComposeInfo & info)742 bool RSUniRenderUtil::IsNeedClient(RSSurfaceRenderNode& node, const ComposeInfo& info)
743 {
744     if (RSSystemProperties::IsForceClient()) {
745         RS_LOGD("RSUniRenderUtil::IsNeedClient: force client.");
746         return true;
747     }
748     const auto& property = node.GetRenderProperties();
749     if (!ROSEN_EQ(property.GetRotation(), 0.f) || !ROSEN_EQ(property.GetRotationX(), 0.f) ||
750         !ROSEN_EQ(property.GetRotationY(), 0.f) || property.GetQuaternion() != Quaternion()) {
751         RS_LOGD("RSUniRenderUtil::IsNeedClient need client with RSSurfaceRenderNode rotation");
752         return true;
753     }
754     return false;
755 }
756 
AlignedDirtyRegion(const Occlusion::Region & dirtyRegion,int32_t alignedBits)757 Occlusion::Region RSUniRenderUtil::AlignedDirtyRegion(const Occlusion::Region& dirtyRegion, int32_t alignedBits)
758 {
759     Occlusion::Region alignedRegion;
760     if (alignedBits <= 1) {
761         return dirtyRegion;
762     }
763     for (const auto& dirtyRect : dirtyRegion.GetRegionRects()) {
764         int32_t left = (dirtyRect.left_ / alignedBits) * alignedBits;
765         int32_t top = (dirtyRect.top_ / alignedBits) * alignedBits;
766         int32_t width = ((dirtyRect.right_ + alignedBits - 1) / alignedBits) * alignedBits - left;
767         int32_t height = ((dirtyRect.bottom_ + alignedBits - 1) / alignedBits) * alignedBits - top;
768         Occlusion::Rect rect = { left, top, left + width, top + height };
769         Occlusion::Region singleAlignedRegion(rect);
770         alignedRegion.OrSelf(singleAlignedRegion);
771     }
772     return alignedRegion;
773 }
774 
HandleSubThreadNode(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas)775 bool RSUniRenderUtil::HandleSubThreadNode(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas)
776 {
777     if (node.IsMainThreadNode()) {
778         RS_LOGE("RSUniRenderUtil::HandleSubThreadNode node.IsMainThreadNode()");
779         return false;
780     } else if (RSMainThread::Instance()->GetDeviceType() == DeviceType::PC &&
781         !node.QueryIfAllHwcChildrenForceDisabledByFilter()) {
782         return false; // this node should do DSS composition in mainThread although it is assigned to subThread
783     }
784     if (!node.HasCachedTexture()) {
785         RS_TRACE_NAME_FMT("HandleSubThreadNode wait %" PRIu64 "", node.GetId());
786 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
787         RSSubThreadManager::Instance()->WaitNodeTask(node.GetId());
788         node.UpdateCompletedCacheSurface();
789 #endif
790     }
791     RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderUtil::HandleSubThreadNode %" PRIu64 "", node.GetId());
792     node.DrawCacheSurface(canvas, UNI_MAIN_THREAD_INDEX, true);
793     return true;
794 }
795 
HandleCaptureNode(RSRenderNode & node,RSPaintFilterCanvas & canvas)796 bool RSUniRenderUtil::HandleCaptureNode(RSRenderNode& node, RSPaintFilterCanvas& canvas)
797 {
798     auto surfaceNodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>();
799     if (surfaceNodePtr == nullptr ||
800         (!surfaceNodePtr->IsAppWindow() && !surfaceNodePtr->IsLeashWindow())) {
801         return false;
802     }
803 
804     auto curNode = surfaceNodePtr;
805     if (surfaceNodePtr->IsAppWindow()) {
806         auto rsParent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surfaceNodePtr->GetParent().lock());
807         if (rsParent && rsParent->IsLeashWindow()) {
808             curNode = rsParent;
809         }
810     }
811     if (!curNode->ShouldPaint()) {
812         return false;
813     }
814     if (curNode->IsOnTheTree()) {
815         return HandleSubThreadNode(*curNode, canvas);
816     } else {
817 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
818         if (curNode->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) {
819             RSSubThreadManager::Instance()->WaitNodeTask(curNode->GetId());
820         }
821 #endif
822         return false;
823     }
824     return false;
825 }
826 
GetRotationFromMatrix(Drawing::Matrix matrix)827 int RSUniRenderUtil::GetRotationFromMatrix(Drawing::Matrix matrix)
828 {
829     Drawing::Matrix::Buffer value;
830     matrix.GetAll(value);
831 
832     int rAngle = static_cast<int>(-round(atan2(value[Drawing::Matrix::Index::SKEW_X],
833         value[Drawing::Matrix::Index::SCALE_X]) * (180 / PI)));
834     // transfer the result to anti-clockwise degrees
835     // only rotation with 90°, 180°, 270° are composed through hardware,
836     // in which situation the transformation of the layer needs to be set.
837     static const std::map<int, int> supportedDegrees = {{90, 270}, {180, 180}, {-90, 90}, {-180, 180}};
838     auto iter = supportedDegrees.find(rAngle);
839     return iter != supportedDegrees.end() ? iter->second : 0;
840 }
841 
GetRotationDegreeFromMatrix(Drawing::Matrix matrix)842 int RSUniRenderUtil::GetRotationDegreeFromMatrix(Drawing::Matrix matrix)
843 {
844     Drawing::Matrix::Buffer value;
845     matrix.GetAll(value);
846     return static_cast<int>(-round(atan2(value[Drawing::Matrix::Index::SKEW_X],
847         value[Drawing::Matrix::Index::SCALE_X]) * (180 / PI)));
848 }
849 
Is3DRotation(Drawing::Matrix matrix)850 bool RSUniRenderUtil::Is3DRotation(Drawing::Matrix matrix)
851 {
852     Drawing::Matrix::Buffer value;
853     matrix.GetAll(value);
854     // ScaleX and ScaleY must have different sign
855     if (!(std::signbit(value[Drawing::Matrix::Index::SCALE_X]) ^
856         std::signbit(value[Drawing::Matrix::Index::SCALE_Y]))) {
857         return false;
858     }
859 
860     int rotateX = static_cast<int>(-round(atan2(value[Drawing::Matrix::Index::PERSP_1],
861         value[Drawing::Matrix::Index::SCALE_Y]) * (180 / PI)));
862     int rotateY = static_cast<int>(-round(atan2(value[Drawing::Matrix::Index::PERSP_0],
863         value[Drawing::Matrix::Index::SCALE_X]) * (180 / PI)));
864     return (rotateX != 0) || (rotateY != 0);
865 }
866 
IsNodeAssignSubThread(std::shared_ptr<RSSurfaceRenderNode> node,bool isDisplayRotation)867 bool RSUniRenderUtil::IsNodeAssignSubThread(std::shared_ptr<RSSurfaceRenderNode> node, bool isDisplayRotation)
868 {
869     if (node == nullptr) {
870         return false;
871     }
872     auto deviceType = RSMainThread::Instance()->GetDeviceType();
873     bool isNeedAssignToSubThread = false;
874     if (deviceType != DeviceType::PC && node->IsLeashWindow()) {
875         isNeedAssignToSubThread = (node->IsScale() || node->IsScaleInPreFrame()
876             || ROSEN_EQ(node->GetGlobalAlpha(), 0.0f) || node->GetForceUIFirst()) && !node->HasFilter();
877         RS_TRACE_NAME_FMT("Assign info: name[%s] id[%" PRIu64"]"
878             " status:%d filter:%d isScale:%d isScalePreFrame:%d forceUIFirst:%d isNeedAssign:%d",
879             node->GetName().c_str(), node->GetId(), node->GetCacheSurfaceProcessedStatus(), node->HasFilter(),
880             node->IsScale(), node->IsScaleInPreFrame(), node->GetForceUIFirst(), isNeedAssignToSubThread);
881     }
882     std::string surfaceName = node->GetName();
883     bool needFilterSCB = node->GetSurfaceWindowType() == SurfaceWindowType::SYSTEM_SCB_WINDOW;
884     RS_LOGI("RSUniRenderUtil::IsNodeAssignSubThread %s", surfaceName.c_str());
885 
886     if (needFilterSCB || node->IsSelfDrawingType()) {
887         return false;
888     }
889     if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) { // node exceed one vsync
890         return true;
891     }
892     if (deviceType != DeviceType::PC) {
893         return isNeedAssignToSubThread;
894     } else { // PC or TABLET
895         if ((node->IsFocusedNode(RSMainThread::Instance()->GetFocusNodeId()) ||
896             node->IsFocusedNode(RSMainThread::Instance()->GetFocusLeashWindowId())) &&
897             node->GetHasSharedTransitionNode()) {
898             return false;
899         }
900         return node->QuerySubAssignable(isDisplayRotation);
901     }
902 }
903 
AssignWindowNodes(const std::shared_ptr<RSDisplayRenderNode> & displayNode,std::list<std::shared_ptr<RSSurfaceRenderNode>> & mainThreadNodes,std::list<std::shared_ptr<RSSurfaceRenderNode>> & subThreadNodes)904 void RSUniRenderUtil::AssignWindowNodes(const std::shared_ptr<RSDisplayRenderNode>& displayNode,
905     std::list<std::shared_ptr<RSSurfaceRenderNode>>& mainThreadNodes,
906     std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes)
907 {
908     if (displayNode == nullptr) {
909         ROSEN_LOGE("RSUniRenderUtil::AssignWindowNodes display node is null");
910         return;
911     }
912     bool isRotation = displayNode->IsRotationChanged();
913     std::vector<RSBaseRenderNode::SharedPtr> curAllSurfaces;
914     if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
915         displayNode->CollectSurface(displayNode, curAllSurfaces, true, true);
916     } else {
917         curAllSurfaces = *displayNode->GetSortedChildren();
918     }
919 
920     for (auto iter = curAllSurfaces.begin(); iter != curAllSurfaces.end(); iter++) {
921         auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*iter);
922         if (node == nullptr) {
923             ROSEN_LOGE("RSUniRenderUtil::AssignWindowNodes nullptr found in sortedChildren, this should not happen");
924             continue;
925         }
926         // release color picker resource when thread-switching between RS and subthread
927         bool lastIsNeedAssignToSubThread = node->GetLastIsNeedAssignToSubThread();
928         bool isNodeAssignSubThread = IsNodeAssignSubThread(node, isRotation);
929         if (isNodeAssignSubThread != lastIsNeedAssignToSubThread) {
930             auto renderNode = RSBaseRenderNode::ReinterpretCast<RSRenderNode>(node);
931             node->SetLastIsNeedAssignToSubThread(isNodeAssignSubThread);
932         }
933         if (isNodeAssignSubThread) {
934             AssignSubThreadNode(subThreadNodes, node);
935         } else {
936             AssignMainThreadNode(mainThreadNodes, node);
937         }
938     }
939     SortSubThreadNodes(subThreadNodes);
940 }
941 
AssignMainThreadNode(std::list<std::shared_ptr<RSSurfaceRenderNode>> & mainThreadNodes,const std::shared_ptr<RSSurfaceRenderNode> & node)942 void RSUniRenderUtil::AssignMainThreadNode(std::list<std::shared_ptr<RSSurfaceRenderNode>>& mainThreadNodes,
943     const std::shared_ptr<RSSurfaceRenderNode>& node)
944 {
945     if (node == nullptr) {
946         ROSEN_LOGW("RSUniRenderUtil::AssignMainThreadNode node is nullptr");
947         return;
948     }
949     mainThreadNodes.emplace_back(node);
950     bool changeThread = !node->IsMainThreadNode();
951     node->SetIsMainThreadNode(true);
952     node->SetNeedSubmitSubThread(false);
953     node->SetCacheType(CacheType::NONE);
954     HandleHardwareNode(node);
955     if (changeThread) {
956         RS_LOGD("RSUniRenderUtil::AssignMainThreadNode clear cache surface:[%{public}s, %{public}" PRIu64 "]",
957             node->GetName().c_str(), node->GetId());
958         ClearCacheSurface(*node, UNI_MAIN_THREAD_INDEX);
959         node->SetIsMainThreadNode(true);
960         node->SetTextureValidFlag(false);
961     }
962 
963     if (RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) {
964         RS_TRACE_NAME_FMT("AssignMainThread: name: %s, id: %" PRIu64", [HasTransparentSurface: %d, "
965             "ChildHasVisibleFilter: %d, HasFilter: %d, QueryIfAllHwcChildrenForceDisabledByFilter: %d]",
966             node->GetName().c_str(), node->GetId(), node->GetHasTransparentSurface(),
967             node->ChildHasVisibleFilter(), node->HasFilter(),
968             node->QueryIfAllHwcChildrenForceDisabledByFilter());
969     }
970 }
971 
AssignSubThreadNode(std::list<std::shared_ptr<RSSurfaceRenderNode>> & subThreadNodes,const std::shared_ptr<RSSurfaceRenderNode> & node)972 void RSUniRenderUtil::AssignSubThreadNode(
973     std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes, const std::shared_ptr<RSSurfaceRenderNode>& node)
974 {
975     if (node == nullptr) {
976         ROSEN_LOGW("RSUniRenderUtil::AssignSubThreadNode node is nullptr");
977         return;
978     }
979     node->SetCacheType(CacheType::CONTENT);
980     node->SetIsMainThreadNode(false);
981     auto deviceType = RSMainThread::Instance()->GetDeviceType();
982     bool dirty = node->GetNeedDrawFocusChange()
983         || (!node->IsCurFrameStatic(deviceType) && !node->IsVisibleDirtyEmpty(deviceType));
984     // skip complete static window, DO NOT assign it to subthread.
985     if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DONE &&
986         node->HasCachedTexture() && node->IsUIFirstSelfDrawCheck() && !dirty) {
987         node->SetNeedSubmitSubThread(false);
988         RS_OPTIONAL_TRACE_NAME_FMT("subThreadNodes : static skip %s", node->GetName().c_str());
989     } else {
990         node->SetNeedSubmitSubThread(true);
991         node->SetNeedDrawFocusChange(false);
992         node->UpdateCacheSurfaceDirtyManager(2); // 2 means buffer age
993     }
994     node->SetLastFrameChildrenCnt(node->GetChildren()->size());
995     subThreadNodes.emplace_back(node);
996 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
997     if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DONE &&
998         node->IsCacheSurfaceValid() && node->GetCacheSurfaceNeedUpdated()) {
999         node->UpdateCompletedCacheSurface();
1000         if (node->IsAppWindow() &&
1001             !RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node->GetParent().lock())) {
1002             node->GetDirtyManager()->MergeDirtyRect(node->GetOldDirty());
1003         } else {
1004             for (auto& child : *node->GetSortedChildren()) {
1005                 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1006                 if (surfaceNode && surfaceNode->IsAppWindow()) {
1007                     surfaceNode->GetDirtyManager()->MergeDirtyRect(surfaceNode->GetOldDirty());
1008                     break;
1009                 }
1010             }
1011         }
1012         node->SetCacheSurfaceNeedUpdated(false);
1013     }
1014 #endif
1015     bool isFocus = node->IsFocusedNode(RSMainThread::Instance()->GetFocusNodeId()) ||
1016         (node->IsFocusedNode(RSMainThread::Instance()->GetFocusLeashWindowId()));
1017     if ((deviceType == DeviceType::PC || deviceType == DeviceType::TABLET) && isFocus) {
1018         node->SetPriority(NodePriorityType::SUB_FOCUSNODE_PRIORITY); // for resolving response latency
1019         return;
1020     }
1021     if (node->HasCachedTexture()) {
1022         node->SetPriority(NodePriorityType::SUB_LOW_PRIORITY);
1023     } else {
1024         node->SetPriority(NodePriorityType::SUB_HIGH_PRIORITY);
1025     }
1026 }
1027 
SortSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>> & subThreadNodes)1028 void RSUniRenderUtil::SortSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes)
1029 {
1030     // sort subThreadNodes by priority and z-order
1031     subThreadNodes.sort([](const auto& first, const auto& second) -> bool {
1032         auto node1 = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(first);
1033         auto node2 = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(second);
1034         if (node1 == nullptr || node2 == nullptr) {
1035             ROSEN_LOGE(
1036                 "RSUniRenderUtil::SortSubThreadNodes sort nullptr found in subThreadNodes, this should not happen");
1037             return false;
1038         }
1039         if (node1->GetPriority() == node2->GetPriority()) {
1040             return node2->GetRenderProperties().GetPositionZ() < node1->GetRenderProperties().GetPositionZ();
1041         } else {
1042             return node1->GetPriority() < node2->GetPriority();
1043         }
1044     });
1045 }
1046 
CacheSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>> & oldSubThreadNodes,std::list<std::shared_ptr<RSSurfaceRenderNode>> & subThreadNodes)1047 void RSUniRenderUtil::CacheSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>>& oldSubThreadNodes,
1048     std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes)
1049 {
1050     std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>> nodes(subThreadNodes.begin(), subThreadNodes.end());
1051     for (auto node : oldSubThreadNodes) {
1052         if (nodes.count(node) > 0) {
1053             continue;
1054         }
1055         // The node being processed by sub thread may have been removed.
1056         if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) {
1057             subThreadNodes.emplace_back(node);
1058         }
1059     }
1060     oldSubThreadNodes.clear();
1061     oldSubThreadNodes = subThreadNodes;
1062 }
1063 
HandleHardwareNode(const std::shared_ptr<RSSurfaceRenderNode> & node)1064 void RSUniRenderUtil::HandleHardwareNode(const std::shared_ptr<RSSurfaceRenderNode>& node)
1065 {
1066     if (node == nullptr || !node->HasHardwareNode()) {
1067         return;
1068     }
1069     auto appWindow = node;
1070     if (node->IsLeashWindow()) {
1071         for (auto& child : *node->GetSortedChildren()) {
1072             auto surfaceNodePtr = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1073             if (surfaceNodePtr && surfaceNodePtr->IsAppWindow()) {
1074                 appWindow = surfaceNodePtr;
1075                 break;
1076             }
1077         }
1078     }
1079     auto hardwareEnabledNodes = appWindow->GetChildHardwareEnabledNodes();
1080     for (auto& hardwareEnabledNode : hardwareEnabledNodes) {
1081         auto hardwareEnabledNodePtr = hardwareEnabledNode.lock();
1082         if (hardwareEnabledNodePtr) {
1083             hardwareEnabledNodePtr->SetHardwareDisabledByCache(false);
1084         }
1085     }
1086 }
1087 
ClearSurfaceIfNeed(const RSRenderNodeMap & map,const std::shared_ptr<RSDisplayRenderNode> & displayNode,std::set<std::shared_ptr<RSBaseRenderNode>> & oldChildren,DeviceType deviceType)1088 void RSUniRenderUtil::ClearSurfaceIfNeed(const RSRenderNodeMap& map,
1089     const std::shared_ptr<RSDisplayRenderNode>& displayNode,
1090     std::set<std::shared_ptr<RSBaseRenderNode>>& oldChildren,
1091     DeviceType deviceType)
1092 {
1093     if (displayNode == nullptr) {
1094         return;
1095     }
1096     std::vector<RSBaseRenderNode::SharedPtr> curAllSurfaces;
1097     if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
1098         curAllSurfaces = displayNode->GetCurAllSurfaces(true);
1099     } else {
1100         curAllSurfaces = *displayNode->GetSortedChildren();
1101     }
1102     std::set<std::shared_ptr<RSBaseRenderNode>> tmpSet(curAllSurfaces.begin(), curAllSurfaces.end());
1103     for (auto& child : oldChildren) {
1104         auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1105         if (!surface) {
1106             continue;
1107         }
1108         if (tmpSet.count(surface) == 0) {
1109             if (surface->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) {
1110                 tmpSet.emplace(surface);
1111                 continue;
1112             }
1113             if (map.GetRenderNode(surface->GetId()) != nullptr) {
1114                 RS_LOGD("RSUniRenderUtil::ClearSurfaceIfNeed clear cache surface:[%{public}s, %{public}" PRIu64 "]",
1115                     surface->GetName().c_str(), surface->GetId());
1116                 if (deviceType == DeviceType::PHONE) {
1117                     ClearCacheSurface(*surface, UNI_MAIN_THREAD_INDEX);
1118                     surface->SetIsMainThreadNode(true);
1119                     surface->SetTextureValidFlag(false);
1120                 } else {
1121                     if (RSMainThread::Instance()->IsPCThreeFingerScenesListScene()) {
1122                         ClearCacheSurface(*surface, UNI_MAIN_THREAD_INDEX, false);
1123                     } else {
1124                         ClearCacheSurface(*surface, UNI_MAIN_THREAD_INDEX);
1125                     }
1126                 }
1127             }
1128         }
1129     }
1130     oldChildren.swap(tmpSet);
1131 }
1132 
ClearCacheSurface(RSRenderNode & node,uint32_t threadIndex,bool isClearCompletedCacheSurface)1133 void RSUniRenderUtil::ClearCacheSurface(RSRenderNode& node, uint32_t threadIndex, bool isClearCompletedCacheSurface)
1134 {
1135     RS_LOGD("ClearCacheSurface node: [%{public}" PRIu64 "]", node.GetId());
1136     uint32_t cacheSurfaceThreadIndex = node.GetCacheSurfaceThreadIndex();
1137     uint32_t completedSurfaceThreadIndex = node.GetCompletedSurfaceThreadIndex();
1138     if (cacheSurfaceThreadIndex == threadIndex && completedSurfaceThreadIndex == threadIndex) {
1139         node.ClearCacheSurface(isClearCompletedCacheSurface);
1140         return;
1141     }
1142     std::shared_ptr<Drawing::Surface> completedCacheSurface = isClearCompletedCacheSurface ?
1143         node.GetCompletedCacheSurface(threadIndex, false, true) : nullptr;
1144     ClearNodeCacheSurface(node.GetCacheSurface(threadIndex, false, true),
1145         std::move(completedCacheSurface), cacheSurfaceThreadIndex, completedSurfaceThreadIndex);
1146     node.ClearCacheSurface(isClearCompletedCacheSurface);
1147 }
1148 
ClearNodeCacheSurface(std::shared_ptr<Drawing::Surface> && cacheSurface,std::shared_ptr<Drawing::Surface> && cacheCompletedSurface,uint32_t cacheSurfaceThreadIndex,uint32_t completedSurfaceThreadIndex)1149 void RSUniRenderUtil::ClearNodeCacheSurface(std::shared_ptr<Drawing::Surface>&& cacheSurface,
1150     std::shared_ptr<Drawing::Surface>&& cacheCompletedSurface,
1151     uint32_t cacheSurfaceThreadIndex, uint32_t completedSurfaceThreadIndex)
1152 {
1153     PostReleaseSurfaceTask(std::move(cacheSurface), cacheSurfaceThreadIndex);
1154     PostReleaseSurfaceTask(std::move(cacheCompletedSurface), completedSurfaceThreadIndex);
1155 }
1156 
PostReleaseSurfaceTask(std::shared_ptr<Drawing::Surface> && surface,uint32_t threadIndex)1157 void RSUniRenderUtil::PostReleaseSurfaceTask(std::shared_ptr<Drawing::Surface>&& surface, uint32_t threadIndex)
1158 {
1159     if (surface == nullptr) {
1160         return;
1161     }
1162 
1163     if (threadIndex == UNI_MAIN_THREAD_INDEX || threadIndex == UNI_RENDER_THREAD_INDEX) {
1164         if (RSUniRenderJudgement::IsUniRender()) {
1165             auto instance = &(RSUniRenderThread::Instance());
1166             instance->AddToReleaseQueue(std::move(surface));
1167             instance->PostTask(([instance] () { instance->ReleaseSurface(); }),
1168                 RELEASE_SURFACE_TASK, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
1169         } else {
1170             auto instance = RSMainThread::Instance();
1171             instance->AddToReleaseQueue(std::move(surface));
1172             instance->PostTask(([instance] () { instance->ReleaseSurface(); }),
1173                 RELEASE_SURFACE_TASK, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
1174         }
1175     } else {
1176 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
1177         auto instance = RSSubThreadManager::Instance();
1178         instance->AddToReleaseQueue(std::move(surface), threadIndex);
1179         instance->ReleaseSurface(threadIndex);
1180 #endif
1181     }
1182 }
1183 
DrawRectForDfx(RSPaintFilterCanvas & canvas,const RectI & rect,Drawing::Color color,float alpha,const std::string & extraInfo)1184 void RSUniRenderUtil::DrawRectForDfx(RSPaintFilterCanvas& canvas, const RectI& rect, Drawing::Color color,
1185     float alpha, const std::string& extraInfo)
1186 {
1187     if (rect.width_ <= 0 || rect.height_ <= 0) {
1188         RS_LOGD("DrawRectForDfx rect is invalid.");
1189         return;
1190     }
1191     RS_LOGD("DrawRectForDfx current rect = %{public}s", rect.ToString().c_str());
1192     auto dstRect = Drawing::Rect(rect.left_, rect.top_,
1193         rect.left_ + rect.width_, rect.top_ + rect.height_);
1194 
1195     std::string position = rect.ToString() + extraInfo;
1196 
1197     const int defaultTextOffsetX = 6; // text position is 6 pixelSize right side of the Rect
1198     const int defaultTextOffsetY = 30; // text position has 30 pixelSize under the Rect
1199     Drawing::Brush rectBrush;
1200     std::shared_ptr<Drawing::Typeface> typeFace = nullptr;
1201 
1202     // font size: 24
1203     std::shared_ptr<Drawing::TextBlob> textBlob =
1204         Drawing::TextBlob::MakeFromString(position.c_str(), Drawing::Font(typeFace, 24.0f, 1.0f, 0.0f));
1205 
1206     rectBrush.SetColor(color);
1207     rectBrush.SetAntiAlias(true);
1208     rectBrush.SetAlphaF(alpha);
1209     canvas.AttachBrush(rectBrush);
1210     canvas.DrawRect(dstRect);
1211     canvas.DetachBrush();
1212     canvas.AttachBrush(Drawing::Brush());
1213     canvas.DrawTextBlob(textBlob.get(), rect.left_ + defaultTextOffsetX, rect.top_ + defaultTextOffsetY);
1214     canvas.DetachBrush();
1215 }
1216 
1217 #ifdef RS_ENABLE_VK
FindMemoryType(uint32_t typeFilter,VkMemoryPropertyFlags properties)1218 uint32_t RSUniRenderUtil::FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
1219 {
1220     if (OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::VULKAN &&
1221         OHOS::Rosen::RSSystemProperties::GetGpuApiType() != OHOS::Rosen::GpuApiType::DDGR) {
1222         return UINT32_MAX;
1223     }
1224     auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton().GetRsVulkanInterface();
1225     VkPhysicalDevice physicalDevice = vkContext.GetPhysicalDevice();
1226 
1227     VkPhysicalDeviceMemoryProperties memProperties;
1228     vkContext.vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
1229 
1230     for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
1231         if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
1232             return i;
1233         }
1234     }
1235 
1236     return UINT32_MAX;
1237 }
1238 
SetVkImageInfo(std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo,const VkImageCreateInfo & imageInfo)1239 void RSUniRenderUtil::SetVkImageInfo(std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo,
1240     const VkImageCreateInfo& imageInfo)
1241 {
1242     if (vkImageInfo == nullptr) {
1243         return;
1244     }
1245     vkImageInfo->imageTiling = imageInfo.tiling;
1246     vkImageInfo->imageLayout = imageInfo.initialLayout;
1247     vkImageInfo->format = imageInfo.format;
1248     vkImageInfo->imageUsageFlags = imageInfo.usage;
1249     vkImageInfo->levelCount = imageInfo.mipLevels;
1250     vkImageInfo->currentQueueFamily = VK_QUEUE_FAMILY_EXTERNAL;
1251     vkImageInfo->ycbcrConversionInfo = {};
1252     vkImageInfo->sharingMode = imageInfo.sharingMode;
1253 }
1254 
MakeBackendTexture(uint32_t width,uint32_t height,VkFormat format)1255 Drawing::BackendTexture RSUniRenderUtil::MakeBackendTexture(uint32_t width, uint32_t height, VkFormat format)
1256 {
1257     VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
1258     VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1259         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1260     VkImageCreateInfo imageInfo {
1261         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1262         .pNext = nullptr,
1263         .flags = 0,
1264         .imageType = VK_IMAGE_TYPE_2D,
1265         .format = format,
1266         .extent = {width, height, 1},
1267         .mipLevels = 1,
1268         .arrayLayers = 1,
1269         .samples = VK_SAMPLE_COUNT_1_BIT,
1270         .tiling = tiling,
1271         .usage = usage,
1272         .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
1273         .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
1274     };
1275 
1276     auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton().GetRsVulkanInterface();
1277     VkDevice device = vkContext.GetDevice();
1278     VkImage image = VK_NULL_HANDLE;
1279     VkDeviceMemory memory = VK_NULL_HANDLE;
1280 
1281     if (width * height > VKIMAGE_LIMIT_SIZE) {
1282         ROSEN_LOGE(
1283             "RSUniRenderUtil::MakeBackendTexture failed, image is too large, width:%{public}u, height::%{public}u",
1284             width, height);
1285         return {};
1286     }
1287 
1288     if (vkContext.vkCreateImage(device, &imageInfo, nullptr, &image) != VK_SUCCESS) {
1289         return {};
1290     }
1291 
1292     VkMemoryRequirements memRequirements;
1293     vkContext.vkGetImageMemoryRequirements(device, image, &memRequirements);
1294 
1295     VkMemoryAllocateInfo allocInfo{};
1296     allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1297     allocInfo.allocationSize = memRequirements.size;
1298     allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1299     if (allocInfo.memoryTypeIndex == UINT32_MAX) {
1300         return {};
1301     }
1302 
1303     if (vkContext.vkAllocateMemory(device, &allocInfo, nullptr, &memory) != VK_SUCCESS) {
1304         return {};
1305     }
1306 
1307     vkContext.vkBindImageMemory(device, image, memory, 0);
1308 
1309     OHOS::Rosen::Drawing::BackendTexture backendTexture(true);
1310     OHOS::Rosen::Drawing::TextureInfo textureInfo;
1311     textureInfo.SetWidth(width);
1312     textureInfo.SetHeight(height);
1313 
1314     std::shared_ptr<OHOS::Rosen::Drawing::VKTextureInfo> vkImageInfo =
1315         std::make_shared<OHOS::Rosen::Drawing::VKTextureInfo>();
1316     vkImageInfo->vkImage = image;
1317     vkImageInfo->vkAlloc.memory = memory;
1318     vkImageInfo->vkAlloc.size = memRequirements.size;
1319 
1320     SetVkImageInfo(vkImageInfo, imageInfo);
1321     textureInfo.SetVKTextureInfo(vkImageInfo);
1322     backendTexture.SetTextureInfo(textureInfo);
1323     return backendTexture;
1324 }
1325 #endif
1326 
GetRotateTransformForRotationFixed(RSSurfaceRenderNode & node,sptr<IConsumerSurface> consumer)1327 GraphicTransformType RSUniRenderUtil::GetRotateTransformForRotationFixed(RSSurfaceRenderNode& node,
1328     sptr<IConsumerSurface> consumer)
1329 {
1330     auto transformType = RSBaseRenderUtil::GetRotateTransform(RSBaseRenderUtil::GetSurfaceBufferTransformType(
1331         node.GetRSSurfaceHandler()->GetConsumer(), node.GetRSSurfaceHandler()->GetBuffer()));
1332     int extraRotation = 0;
1333     int32_t rotationDegree = static_cast<int32_t>(RSSystemProperties::GetDefaultDeviceRotationOffset());
1334     int degree = RSUniRenderUtil::GetRotationDegreeFromMatrix(
1335         node.GetRenderProperties().GetBoundsGeometry()->GetAbsMatrix());
1336     extraRotation = degree - rotationDegree;
1337     transformType = static_cast<GraphicTransformType>(
1338         (transformType + extraRotation / RS_ROTATION_90 + SCREEN_ROTATION_NUM) % SCREEN_ROTATION_NUM);
1339     return transformType;
1340 }
1341 
SrcRectRotateTransform(RSSurfaceRenderNode & node,GraphicTransformType transformType)1342 RectI RSUniRenderUtil::SrcRectRotateTransform(RSSurfaceRenderNode& node, GraphicTransformType transformType)
1343 {
1344     RectI srcRect = node.GetSrcRect();
1345     int left = srcRect.GetLeft();
1346     int top = srcRect.GetTop();
1347     int width = srcRect.GetWidth();
1348     int height = srcRect.GetHeight();
1349     int boundsWidth = static_cast<int>(node.GetRenderProperties().GetBoundsWidth());
1350     int boundsHeight = static_cast<int>(node.GetRenderProperties().GetBoundsHeight());
1351     // Left > 0 means move xComponent to the left outside of the screen
1352     // Top > 0 means move xComponent to the top outside of the screen
1353     // The left and top should recalculate when transformType is not GRAPHIC_ROTATE_NONEq
1354     // The width and height should exchange when transformType is GRAPHIC_ROTATE_270 and GRAPHIC_ROTATE_90
1355     switch (transformType) {
1356         case GraphicTransformType::GRAPHIC_ROTATE_270: {
1357             left = std::max(top, 0);
1358             top = std::max(boundsWidth - width - srcRect.GetLeft(), 0);
1359             srcRect = RectI {left, top, height, width};
1360             break;
1361         }
1362         case GraphicTransformType::GRAPHIC_ROTATE_180: {
1363             left = std::max(boundsWidth - width - left, 0);
1364             top = std::max(boundsHeight - height - top, 0);
1365             srcRect = RectI {left, top, width, height};
1366             break;
1367         }
1368         case GraphicTransformType::GRAPHIC_ROTATE_90: {
1369             left = std::max(boundsHeight - height - top, 0);
1370             top = std::max(srcRect.GetLeft(), 0);
1371             srcRect = RectI {left, top, height, width};
1372             break;
1373         }
1374         default: {
1375             break;
1376         }
1377     }
1378     return srcRect;
1379 }
1380 
UpdateRealSrcRect(RSSurfaceRenderNode & node,const RectI & absRect)1381 void RSUniRenderUtil::UpdateRealSrcRect(RSSurfaceRenderNode& node, const RectI& absRect)
1382 {
1383     auto surfaceHandler = node.GetRSSurfaceHandler();
1384     auto consumer = surfaceHandler->GetConsumer();
1385     auto buffer = surfaceHandler->GetBuffer();
1386     if (!consumer || !buffer) {
1387         return;
1388     }
1389     auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
1390     if (node.GetFixRotationByUser()) {
1391         transformType = RSUniRenderUtil::GetRotateTransformForRotationFixed(node, consumer);
1392     } else {
1393         transformType = RSBaseRenderUtil::GetRotateTransform(consumer->GetTransform());
1394     }
1395     auto srcRect = SrcRectRotateTransform(node, transformType);
1396     const auto& property = node.GetRenderProperties();
1397     const auto bufferWidth = buffer->GetSurfaceBufferWidth();
1398     const auto bufferHeight = buffer->GetSurfaceBufferHeight();
1399     auto boundsWidth = property.GetBoundsWidth();
1400     auto boundsHeight = property.GetBoundsHeight();
1401     if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
1402         transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
1403         std::swap(boundsWidth, boundsHeight);
1404     }
1405     if ((bufferWidth != boundsWidth || bufferHeight != boundsHeight) &&
1406         node.GetRenderProperties().GetFrameGravity() != Gravity::TOP_LEFT) {
1407         float xScale = (ROSEN_EQ(boundsWidth, 0.0f) ? 1.0f : bufferWidth / boundsWidth);
1408         float yScale = (ROSEN_EQ(boundsHeight, 0.0f) ? 1.0f : bufferHeight / boundsHeight);
1409         const auto nodeParams = static_cast<RSSurfaceRenderParams*>(node.GetStagingRenderParams().get());
1410         // If the scaling mode is SCALING_MODE_SCALE_TO_WINDOW, the scale should use smaller one.
1411         ScalingMode scalingMode = nodeParams->GetScalingMode();
1412         if (consumer->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK) {
1413             nodeParams->SetScalingMode(scalingMode);
1414         }
1415         if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
1416             float scale = std::min(xScale, yScale);
1417             srcRect.left_ = srcRect.left_ * scale;
1418             srcRect.top_ = srcRect.top_ * scale;
1419             if (ROSEN_EQ(scale, 0.f)) {
1420                 node.SetSrcRect(srcRect);
1421                 return;
1422             }
1423             srcRect.width_ = (bufferWidth / scale - (boundsWidth - srcRect.width_)) * scale;
1424             srcRect.height_ = (bufferHeight / scale - (boundsHeight - srcRect.height_)) * scale;
1425         } else {
1426             if (absRect == node.GetDstRect()) {
1427                 // If the SurfaceRenderNode is completely in the DisplayRenderNode,
1428                 // we do not need to crop the buffer.
1429                 srcRect.width_ = bufferWidth;
1430                 srcRect.height_ = bufferHeight;
1431             } else {
1432                 srcRect.left_ = srcRect.left_ * xScale;
1433                 srcRect.top_ = srcRect.top_ * yScale;
1434                 srcRect.width_ = std::min(static_cast<int32_t>(std::ceil(srcRect.width_ * xScale)), bufferWidth);
1435                 srcRect.height_ = std::min(static_cast<int32_t>(std::ceil(srcRect.height_ * yScale)), bufferHeight);
1436             }
1437         }
1438     }
1439     RectI bufferRect(0, 0, bufferWidth, bufferHeight);
1440     RectI newSrcRect = srcRect.IntersectRect(bufferRect);
1441     node.SetSrcRect(newSrcRect);
1442 }
1443 
DealWithNodeGravity(RSSurfaceRenderNode & node,const ScreenInfo & screenInfo)1444 void RSUniRenderUtil::DealWithNodeGravity(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo)
1445 {
1446     auto buffer = node.GetRSSurfaceHandler()->GetBuffer();
1447     if (!buffer) {
1448         return;
1449     }
1450     const auto& property = node.GetRenderProperties();
1451     const float frameWidth = buffer->GetSurfaceBufferWidth();
1452     const float frameHeight = buffer->GetSurfaceBufferHeight();
1453     const float boundsWidth = property.GetBoundsWidth();
1454     const float boundsHeight = property.GetBoundsHeight();
1455     const Gravity frameGravity = property.GetFrameGravity();
1456 
1457     CheckForceHardwareAndUpdateDstRect(node);
1458     // we do not need to do additional works for Gravity::RESIZE and if frameSize == boundsSize.
1459     if (frameGravity == Gravity::RESIZE || frameGravity == Gravity::TOP_LEFT ||
1460         (ROSEN_EQ(frameWidth, boundsWidth) && ROSEN_EQ(frameHeight, boundsHeight))) {
1461         return;
1462     }
1463 
1464     // get current node's translate matrix and calculate gravity matrix.
1465     auto translateMatrix = Drawing::Matrix();
1466     translateMatrix.Translate(node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_X),
1467         std::ceil(node.GetTotalMatrix().Get(Drawing::Matrix::Index::TRANS_Y)));
1468     Drawing::Matrix gravityMatrix;
1469     (void)RSPropertiesPainter::GetGravityMatrix(frameGravity,
1470         RectF {0.0f, 0.0f, boundsWidth, boundsHeight}, frameWidth, frameHeight, gravityMatrix);
1471     // create a canvas to calculate new dstRect and new srcRect
1472     int32_t screenWidth = screenInfo.phyWidth;
1473     int32_t screenHeight = screenInfo.phyHeight;
1474     const auto screenRotation = screenInfo.rotation;
1475     if (screenRotation == ScreenRotation::ROTATION_90 || screenRotation == ScreenRotation::ROTATION_270) {
1476         std::swap(screenWidth, screenHeight);
1477     }
1478 
1479     auto canvas = std::make_unique<Drawing::Canvas>(screenWidth, screenHeight);
1480     canvas->ConcatMatrix(translateMatrix);
1481     canvas->ConcatMatrix(gravityMatrix);
1482     Drawing::Rect clipRect;
1483     gravityMatrix.MapRect(clipRect, Drawing::Rect(0, 0, frameWidth, frameHeight));
1484     canvas->ClipRect(Drawing::Rect(0, 0, clipRect.GetWidth(), clipRect.GetHeight()), Drawing::ClipOp::INTERSECT);
1485     Drawing::RectI newDstRect = canvas->GetDeviceClipBounds();
1486     auto dstRect = node.GetDstRect();
1487     // we make the newDstRect as the intersection of new and old dstRect,
1488     // to deal with the situation that frameSize > boundsSize.
1489     newDstRect.Intersect(Drawing::RectI(
1490         dstRect.left_, dstRect.top_, dstRect.width_ + dstRect.left_, dstRect.height_ + dstRect.top_));
1491     auto localRect = canvas->GetLocalClipBounds();
1492     int left = std::clamp<int>(localRect.GetLeft(), 0, frameWidth);
1493     int top = std::clamp<int>(localRect.GetTop(), 0, frameHeight);
1494     int width = std::clamp<int>(localRect.GetWidth(), 0, frameWidth - left);
1495     int height = std::clamp<int>(localRect.GetHeight(), 0, frameHeight - top);
1496 
1497     node.SetDstRect({newDstRect.GetLeft(), newDstRect.GetTop(), newDstRect.GetWidth(), newDstRect.GetHeight()});
1498     node.SetSrcRect({left, top, width, height});
1499 }
1500 
CheckForceHardwareAndUpdateDstRect(RSSurfaceRenderNode & node)1501 void RSUniRenderUtil::CheckForceHardwareAndUpdateDstRect(RSSurfaceRenderNode& node)
1502 {
1503     auto surfaceHandler = node.GetRSSurfaceHandler();
1504     if (!surfaceHandler->GetConsumer() || !node.IsInFixedRotation() || !surfaceHandler->GetBuffer()) {
1505         return;
1506     }
1507     node.SetSrcRect(node.GetOriginalSrcRect());
1508     auto dstRect = node.GetDstRect();
1509     auto originalDstRect = node.GetOriginalDstRect();
1510     dstRect.left_ += (dstRect.width_ - originalDstRect.width_) / 2;
1511     dstRect.top_ += (dstRect.height_ - originalDstRect.height_) / 2;
1512     dstRect.width_ = originalDstRect.width_;
1513     dstRect.height_ = originalDstRect.height_;
1514     node.SetDstRect(dstRect);
1515 }
1516 
LayerRotate(RSSurfaceRenderNode & node,const ScreenInfo & screenInfo)1517 void RSUniRenderUtil::LayerRotate(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo)
1518 {
1519     const auto screenWidth = static_cast<int32_t>(screenInfo.width);
1520     const auto screenHeight = static_cast<int32_t>(screenInfo.height);
1521     const auto screenRotation = screenInfo.rotation;
1522     const auto rect = node.GetDstRect();
1523     switch (screenRotation) {
1524         case ScreenRotation::ROTATION_90: {
1525             node.SetDstRect({rect.top_, screenHeight - rect.left_ - rect.width_, rect.height_, rect.width_});
1526             break;
1527         }
1528         case ScreenRotation::ROTATION_180: {
1529             node.SetDstRect({screenWidth - rect.left_ - rect.width_, screenHeight - rect.top_ - rect.height_,
1530                 rect.width_, rect.height_});
1531             break;
1532         }
1533         case ScreenRotation::ROTATION_270: {
1534             node.SetDstRect({screenWidth - rect.top_ - rect.height_, rect.left_, rect.height_, rect.width_});
1535             break;
1536         }
1537         default:  {
1538             break;
1539         }
1540     }
1541 }
1542 
GetLayerTransform(RSSurfaceRenderNode & node,const ScreenInfo & screenInfo)1543 GraphicTransformType RSUniRenderUtil::GetLayerTransform(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo)
1544 {
1545     auto surfaceHandler = node.GetRSSurfaceHandler();
1546     if (!surfaceHandler) {
1547         return GraphicTransformType::GRAPHIC_ROTATE_NONE;
1548     }
1549     auto consumer = surfaceHandler->GetConsumer();
1550     int32_t rotationDegree = static_cast<int32_t>(RSSystemProperties::GetDefaultDeviceRotationOffset());
1551     int surfaceNodeRotation = node.GetFixRotationByUser() ? -1 * rotationDegree :
1552         RSUniRenderUtil::GetRotationFromMatrix(node.GetTotalMatrix());
1553     auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
1554     auto buffer = node.GetRSSurfaceHandler()->GetBuffer();
1555     if (consumer != nullptr && buffer != nullptr) {
1556         if (consumer->GetSurfaceBufferTransformType(buffer, &transformType) != GSERROR_OK) {
1557             RS_LOGE("RSUniRenderUtil::GetLayerTransform GetSurfaceBufferTransformType failed");
1558         }
1559     }
1560     int consumerTransform = RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(transformType));
1561     GraphicTransformType consumerFlip = RSBaseRenderUtil::GetFlipTransform(transformType);
1562     int totalRotation = (RSBaseRenderUtil::RotateEnumToInt(screenInfo.rotation) +
1563         surfaceNodeRotation + consumerTransform) % 360;
1564     GraphicTransformType rotateEnum = RSBaseRenderUtil::RotateEnumToInt(totalRotation, consumerFlip);
1565     return rotateEnum;
1566 }
1567 
LayerCrop(RSSurfaceRenderNode & node,const ScreenInfo & screenInfo)1568 void RSUniRenderUtil::LayerCrop(RSSurfaceRenderNode& node, const ScreenInfo& screenInfo)
1569 {
1570     auto dstRect = node.GetDstRect();
1571     auto srcRect = node.GetSrcRect();
1572     auto originSrcRect = srcRect;
1573 
1574     RectI dstRectI(dstRect.left_, dstRect.top_, dstRect.width_, dstRect.height_);
1575     int32_t screenWidth = static_cast<int32_t>(screenInfo.phyWidth);
1576     int32_t screenHeight = static_cast<int32_t>(screenInfo.phyHeight);
1577     RectI screenRectI(0, 0, screenWidth, screenHeight);
1578     RectI resDstRect = dstRectI.IntersectRect(screenRectI);
1579     if (resDstRect == dstRectI) {
1580         return;
1581     }
1582     if (node.IsInFixedRotation()) {
1583         node.SetDstRect(resDstRect);
1584         return;
1585     }
1586     dstRect = {resDstRect.left_, resDstRect.top_, resDstRect.width_, resDstRect.height_};
1587     srcRect.left_ = (resDstRect.IsEmpty() || dstRectI.IsEmpty()) ? 0 : std::ceil((resDstRect.left_ - dstRectI.left_) *
1588         originSrcRect.width_ / dstRectI.width_);
1589     srcRect.top_ = (resDstRect.IsEmpty() || dstRectI.IsEmpty()) ? 0 : std::ceil((resDstRect.top_ - dstRectI.top_) *
1590         originSrcRect.height_ / dstRectI.height_);
1591     srcRect.width_ = dstRectI.IsEmpty() ? 0 : originSrcRect.width_ * resDstRect.width_ / dstRectI.width_;
1592     srcRect.height_ = dstRectI.IsEmpty() ? 0 : originSrcRect.height_ * resDstRect.height_ / dstRectI.height_;
1593     node.SetDstRect(dstRect);
1594     node.SetSrcRect(srcRect);
1595 }
1596 
DealWithScalingMode(RSSurfaceRenderNode & node)1597 void RSUniRenderUtil::DealWithScalingMode(RSSurfaceRenderNode& node)
1598 {
1599     const auto nodeParams = static_cast<RSSurfaceRenderParams*>(node.GetStagingRenderParams().get());
1600     const auto& buffer = node.GetRSSurfaceHandler()->GetBuffer();
1601     const auto& surface = node.GetRSSurfaceHandler()->GetConsumer();
1602     if (nodeParams == nullptr || surface == nullptr || buffer == nullptr) {
1603         RS_LOGE("nodeParams or surface or buffer is nullptr");
1604         return;
1605     }
1606 
1607     ScalingMode scalingMode = nodeParams->GetScalingMode();
1608     if (surface->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK) {
1609         nodeParams->SetScalingMode(scalingMode);
1610     }
1611     if (scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
1612         RSUniRenderUtil::LayerScaleDown(node);
1613     } else if (scalingMode == ScalingMode::SCALING_MODE_SCALE_FIT) {
1614         int degree = RSUniRenderUtil::GetRotationDegreeFromMatrix(node.GetTotalMatrix());
1615         if (degree % RS_ROTATION_90 == 0) {
1616             RSUniRenderUtil::LayerScaleFit(node);
1617         }
1618     }
1619 }
1620 
LayerScaleDown(RSSurfaceRenderNode & node)1621 void RSUniRenderUtil::LayerScaleDown(RSSurfaceRenderNode& node)
1622 {
1623     const auto& buffer = node.GetRSSurfaceHandler()->GetBuffer();
1624     const auto& surface = node.GetRSSurfaceHandler()->GetConsumer();
1625     if (buffer == nullptr || surface == nullptr) {
1626         return;
1627     }
1628     constexpr uint32_t FLAT_ANGLE = 180;
1629     auto dstRect = node.GetDstRect();
1630     auto srcRect = node.GetSrcRect();
1631 
1632     uint32_t newWidth = static_cast<uint32_t>(srcRect.width_);
1633     uint32_t newHeight = static_cast<uint32_t>(srcRect.height_);
1634     uint32_t dstWidth = static_cast<uint32_t>(dstRect.width_);
1635     uint32_t dstHeight = static_cast<uint32_t>(dstRect.height_);
1636     if (newWidth == 0 || newHeight == 0 || dstWidth == 0 || dstHeight == 0) {
1637         return;
1638     }
1639 
1640     // If surfaceRotation is not a multiple of 180, need to change the correspondence between width & height.
1641     // ScreenRotation has been processed in SetLayerSize, and do not change the width & height correspondence.
1642     int surfaceRotation = RSUniRenderUtil::GetRotationFromMatrix(node.GetTotalMatrix()) +
1643                           RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(
1644                               RSBaseRenderUtil::GetSurfaceBufferTransformType(surface, buffer)));
1645     if (surfaceRotation % FLAT_ANGLE != 0) {
1646         std::swap(dstWidth, dstHeight);
1647     }
1648 
1649     uint32_t newWidthDstHeight = newWidth * dstHeight;
1650     uint32_t newHeightDstWidth = newHeight * dstWidth;
1651 
1652     if (newWidthDstHeight > newHeightDstWidth) {
1653         // too wide
1654         newWidth = dstWidth * newHeight / dstHeight;
1655     } else if (newWidthDstHeight < newHeightDstWidth) {
1656         // too tall
1657         newHeight = dstHeight * newWidth / dstWidth;
1658     } else {
1659         return;
1660     }
1661 
1662     uint32_t currentWidth = static_cast<uint32_t>(srcRect.width_);
1663     uint32_t currentHeight = static_cast<uint32_t>(srcRect.height_);
1664 
1665     if (newWidth < currentWidth) {
1666         // the crop is too wide
1667         uint32_t dw = currentWidth - newWidth;
1668         auto halfdw = dw / 2;
1669         srcRect.left_ += static_cast<int32_t>(halfdw);
1670         srcRect.width_ = static_cast<int32_t>(newWidth);
1671     } else {
1672         // thr crop is too tall
1673         uint32_t dh = currentHeight - newHeight;
1674         auto halfdh = dh / 2;
1675         srcRect.top_ += static_cast<int32_t>(halfdh);
1676         srcRect.height_ = static_cast<int32_t>(newHeight);
1677     }
1678     node.SetSrcRect(srcRect);
1679 }
1680 
LayerScaleFit(RSSurfaceRenderNode & node)1681 void RSUniRenderUtil::LayerScaleFit(RSSurfaceRenderNode& node)
1682 {
1683     const auto& buffer = node.GetRSSurfaceHandler()->GetBuffer();
1684     const auto& surface = node.GetRSSurfaceHandler()->GetConsumer();
1685     if (buffer == nullptr || surface == nullptr) {
1686         return;
1687     }
1688     constexpr uint32_t FLAT_ANGLE = 180;
1689     auto dstRect = node.GetDstRect();
1690     auto srcRect = node.GetSrcRect();
1691 
1692     // If surfaceRotation is not a multiple of 180, need to change the correspondence between width & height.
1693     // ScreenRotation has been processed in SetLayerSize, and do not change the width & height correspondence.
1694     int surfaceRotation = RSUniRenderUtil::GetRotationFromMatrix(node.GetTotalMatrix()) +
1695                           RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(
1696                               RSBaseRenderUtil::GetSurfaceBufferTransformType(surface, buffer)));
1697     if (surfaceRotation % FLAT_ANGLE != 0) {
1698         std::swap(srcRect.width_, srcRect.height_);
1699     }
1700 
1701     uint32_t newWidth = static_cast<uint32_t>(srcRect.width_);
1702     uint32_t newHeight = static_cast<uint32_t>(srcRect.height_);
1703     uint32_t dstWidth = static_cast<uint32_t>(dstRect.width_);
1704     uint32_t dstHeight = static_cast<uint32_t>(dstRect.height_);
1705 
1706     if (newWidth == 0 || newHeight == 0 || dstWidth == 0 || dstHeight == 0) {
1707         return;
1708     }
1709 
1710     uint32_t newWidthDstHeight = newWidth * dstHeight;
1711     uint32_t newHeightDstWidth = newHeight * dstWidth;
1712 
1713     if (newWidthDstHeight > newHeightDstWidth) {
1714         newHeight = newHeight * dstWidth / newWidth;
1715         newWidth = dstWidth;
1716     } else if (newWidthDstHeight < newHeightDstWidth) {
1717         newWidth = newWidth * dstHeight / newHeight;
1718         newHeight = dstHeight;
1719     } else {
1720         newHeight = dstHeight;
1721         newWidth = dstWidth;
1722     }
1723 
1724     if (newWidth < dstWidth) {
1725         uint32_t dw = dstWidth - newWidth;
1726         auto halfdw = dw / 2;
1727         dstRect.left_ += static_cast<int32_t>(halfdw);
1728     } else if (newHeight < dstHeight) {
1729         uint32_t dh = dstHeight - newHeight;
1730         auto halfdh = dh / 2;
1731         dstRect.top_ += static_cast<int32_t>(halfdh);
1732     }
1733     dstRect.height_ = static_cast<int32_t>(newHeight);
1734     dstRect.width_ = static_cast<int32_t>(newWidth);
1735     node.SetDstRect(dstRect);
1736 
1737     RS_LOGD("RsDebug RSUniRenderUtil::LayerScaleFit layer has been scalefit dst[%{public}d %{public}d"
1738         " %{public}d %{public}d] src[%{public}d %{public}d %{public}d %{public}d]",
1739         dstRect.left_, dstRect.top_, dstRect.width_, dstRect.height_, srcRect.left_,
1740         srcRect.top_, srcRect.width_, srcRect.height_);
1741 }
1742 
OptimizedFlushAndSubmit(std::shared_ptr<Drawing::Surface> & surface,Drawing::GPUContext * const grContext,bool optFenceWait)1743 void RSUniRenderUtil::OptimizedFlushAndSubmit(std::shared_ptr<Drawing::Surface>& surface,
1744     Drawing::GPUContext* const grContext, bool optFenceWait)
1745 {
1746     if (!surface || !grContext) {
1747         RS_LOGE("RSUniRenderUtil::OptimizedFlushAndSubmit cacheSurface or grContext are nullptr");
1748         return;
1749     }
1750     RS_TRACE_NAME_FMT("Render surface flush and submit");
1751 #ifdef RS_ENABLE_VK
1752     if ((RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
1753         RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) && optFenceWait) {
1754         auto& vkContext = RsVulkanContext::GetSingleton().GetRsVulkanInterface();
1755 
1756         VkExportSemaphoreCreateInfo exportSemaphoreCreateInfo;
1757         exportSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
1758         exportSemaphoreCreateInfo.pNext = nullptr;
1759         exportSemaphoreCreateInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
1760 
1761         VkSemaphoreCreateInfo semaphoreInfo;
1762         semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1763         semaphoreInfo.pNext = &exportSemaphoreCreateInfo;
1764         semaphoreInfo.flags = 0;
1765         VkSemaphore semaphore;
1766         vkContext.vkCreateSemaphore(vkContext.GetDevice(), &semaphoreInfo, nullptr, &semaphore);
1767         GrBackendSemaphore backendSemaphore;
1768         backendSemaphore.initVulkan(semaphore);
1769 
1770         DestroySemaphoreInfo* destroyInfo =
1771             new DestroySemaphoreInfo(vkContext.vkDestroySemaphore, vkContext.GetDevice(), semaphore);
1772 
1773         Drawing::FlushInfo drawingFlushInfo;
1774         drawingFlushInfo.backendSurfaceAccess = true;
1775         drawingFlushInfo.numSemaphores = 1;
1776         drawingFlushInfo.backendSemaphore = static_cast<void*>(&backendSemaphore);
1777         drawingFlushInfo.finishedProc = [](void *context) {
1778             DestroySemaphoreInfo::DestroySemaphore(context);
1779         };
1780         drawingFlushInfo.finishedContext = destroyInfo;
1781         surface->Flush(&drawingFlushInfo);
1782         grContext->Submit();
1783         DestroySemaphoreInfo::DestroySemaphore(destroyInfo);
1784     } else {
1785         surface->FlushAndSubmit(true);
1786     }
1787 #else
1788     surface->FlushAndSubmit(true);
1789 #endif
1790 }
1791 
AccumulateMatrixAndAlpha(std::shared_ptr<RSSurfaceRenderNode> & hwcNode,Drawing::Matrix & matrix,float & alpha)1792 void RSUniRenderUtil::AccumulateMatrixAndAlpha(std::shared_ptr<RSSurfaceRenderNode>& hwcNode,
1793     Drawing::Matrix& matrix, float& alpha)
1794 {
1795     if (hwcNode == nullptr) {
1796         return;
1797     }
1798     const auto& property = hwcNode->GetRenderProperties();
1799     alpha = property.GetAlpha();
1800     matrix = property.GetBoundsGeometry()->GetMatrix();
1801     auto parent = hwcNode->GetParent().lock();
1802     while (parent && parent->GetType() != RSRenderNodeType::DISPLAY_NODE) {
1803         const auto& curProperty = parent->GetRenderProperties();
1804         alpha *= curProperty.GetAlpha();
1805         matrix.PostConcat(curProperty.GetBoundsGeometry()->GetMatrix());
1806         if (ROSEN_EQ(alpha, 1.f)) {
1807             parent->DisableDrawingCacheByHwcNode();
1808         }
1809         parent = parent->GetParent().lock();
1810     }
1811     if (!parent) {
1812         return;
1813     }
1814     const auto& parentProperty = parent->GetRenderProperties();
1815     alpha *= parentProperty.GetAlpha();
1816     matrix.PostConcat(parentProperty.GetBoundsGeometry()->GetMatrix());
1817 }
1818 
GenerateSecRectInfoFromNode(RSRenderNode & node,RectI rect)1819 SecRectInfo RSUniRenderUtil::GenerateSecRectInfoFromNode(RSRenderNode& node, RectI rect)
1820 {
1821     SecRectInfo uiExtensionRectInfo;
1822     uiExtensionRectInfo.relativeCoords = rect;
1823     uiExtensionRectInfo.scale = node.GetRenderProperties().GetScale();
1824     return uiExtensionRectInfo;
1825 }
1826 
GenerateSecSurfaceInfoFromNode(NodeId uiExtensionId,NodeId hostId,SecRectInfo uiExtensionRectInfo)1827 SecSurfaceInfo RSUniRenderUtil::GenerateSecSurfaceInfoFromNode(
1828     NodeId uiExtensionId, NodeId hostId, SecRectInfo uiExtensionRectInfo)
1829 {
1830     SecSurfaceInfo secSurfaceInfo;
1831     secSurfaceInfo.uiExtensionRectInfo = uiExtensionRectInfo;
1832     secSurfaceInfo.uiExtensionPid = ExtractPid(uiExtensionId);
1833     secSurfaceInfo.hostPid = ExtractPid(hostId);
1834     secSurfaceInfo.uiExtensionNodeId = uiExtensionId;
1835     secSurfaceInfo.hostNodeId = hostId;
1836     return secSurfaceInfo;
1837 }
1838 
UIExtensionFindAndTraverseAncestor(const RSRenderNodeMap & nodeMap,UIExtensionCallbackData & callbackData)1839 void RSUniRenderUtil::UIExtensionFindAndTraverseAncestor(
1840     const RSRenderNodeMap& nodeMap, UIExtensionCallbackData& callbackData)
1841 {
1842     const auto& secUIExtensionNodes = RSSurfaceRenderNode::GetSecUIExtensionNodes();
1843     for (auto it = secUIExtensionNodes.begin(); it != secUIExtensionNodes.end(); ++it) {
1844         currentUIExtensionIndex_ = -1;
1845         // only traverse host node one time, even if it has multiple uiextension children.
1846         if (callbackData.find(it->second) != callbackData.end()) {
1847             continue;
1848         }
1849         auto hostNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(it->second));
1850         if (!hostNode || !hostNode->GetSortedChildren()) {
1851             RS_LOGE("RSUniRenderUtil::UIExtensionFindAndTraverseAncestor failed to get host node or its children.");
1852             return;
1853         }
1854         for (const auto& child : *hostNode->GetSortedChildren()) {
1855             TraverseAndCollectUIExtensionInfo(child, Drawing::Matrix(), hostNode->GetId(), callbackData);
1856         }
1857     }
1858 }
1859 
TraverseAndCollectUIExtensionInfo(std::shared_ptr<RSRenderNode> node,Drawing::Matrix parentMatrix,NodeId hostId,UIExtensionCallbackData & callbackData)1860 void RSUniRenderUtil::TraverseAndCollectUIExtensionInfo(std::shared_ptr<RSRenderNode> node,
1861     Drawing::Matrix parentMatrix, NodeId hostId, UIExtensionCallbackData& callbackData)
1862 {
1863     if (!node) {
1864         return;
1865     }
1866     // update position relative to host app window node.
1867     std::optional<Drawing::Point> offset;
1868     auto parent = node->GetParent().lock();
1869     if (parent && !(node->IsInstanceOf<RSSurfaceRenderNode>())) {
1870         const auto& parentRenderProperties = parent->GetRenderProperties();
1871         offset = Drawing::Point { parentRenderProperties.GetFrameOffsetX(), parentRenderProperties.GetFrameOffsetY() };
1872     }
1873     const auto& nodeRenderProperties = node->GetRenderProperties();
1874     RSObjAbsGeometry boundsGeo = nodeRenderProperties.GetBoundsGeometry() == nullptr ?
1875         RSObjAbsGeometry() : *(nodeRenderProperties.GetBoundsGeometry());
1876     boundsGeo.UpdateMatrix(&parentMatrix, offset);
1877     auto rect = boundsGeo.MapAbsRect(node->GetSelfDrawRect().JoinRect(node->GetChildrenRect().ConvertTo<float>()));
1878     // if node is UIExtension type, update its own info, and skip its children.
1879     if (auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node)) {
1880         if (surfaceNode->IsSecureUIExtension()) {
1881             currentUIExtensionIndex_++;
1882             // if host node is not recorded in callbackData, insert it.
1883             auto [iter, inserted] = callbackData.insert(std::pair(hostId, std::vector<SecSurfaceInfo>{}));
1884             if (iter != callbackData.end()) {
1885                 iter->second.push_back(GenerateSecSurfaceInfoFromNode(
1886                     surfaceNode->GetId(), hostId, GenerateSecRectInfoFromNode(*surfaceNode, rect)));
1887             }
1888             if (surfaceNode->ChildrenHasUIExtension()) {
1889                 RS_LOGW("RSUniRenderUtil::TraverseAndCollectUIExtensionInfo UIExtension node [%{public}" PRIu64 "]"
1890                     " has children UIExtension, not surpported!", surfaceNode->GetId());
1891             }
1892             return;
1893         }
1894     }
1895     // if the node is traversed after a UIExtension, collect it and skip its children (except it has UIExtension child.)
1896     auto iter = callbackData.find(hostId);
1897     if (iter != callbackData.end() && currentUIExtensionIndex_ != -1 &&
1898         currentUIExtensionIndex_ < static_cast<int>((iter->second).size())) {
1899         (iter->second)[currentUIExtensionIndex_].upperNodes.push_back(GenerateSecRectInfoFromNode(*node, rect));
1900         if (!node->ChildrenHasUIExtension()) {
1901             return;
1902         }
1903     }
1904     // continue to traverse.
1905     for (const auto& child : *node->GetSortedChildren()) {
1906         TraverseAndCollectUIExtensionInfo(child, boundsGeo.GetAbsMatrix(), hostId, callbackData);
1907     }
1908 }
1909 
ProcessCacheImage(RSPaintFilterCanvas & canvas,Drawing::Image & cacheImageProcessed)1910 void RSUniRenderUtil::ProcessCacheImage(RSPaintFilterCanvas& canvas, Drawing::Image& cacheImageProcessed)
1911 {
1912     Drawing::Brush brush;
1913     brush.SetAntiAlias(true);
1914     canvas.AttachBrush(brush);
1915     // Be cautious when changing FilterMode and MipmapMode that may affect clarity
1916     auto sampling = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NEAREST);
1917     canvas.DrawImage(cacheImageProcessed, 0, 0, sampling);
1918     canvas.DetachBrush();
1919 }
1920 
GetMatrix(std::shared_ptr<RSRenderNode> hwcNode)1921 std::optional<Drawing::Matrix> RSUniRenderUtil::GetMatrix(
1922     std::shared_ptr<RSRenderNode> hwcNode)
1923 {
1924     if (!hwcNode) {
1925         return std::nullopt;
1926     }
1927     auto relativeMat = Drawing::Matrix();
1928     auto& property = hwcNode->GetRenderProperties();
1929     if (auto geo = property.GetBoundsGeometry()) {
1930         if (LIKELY(!property.GetSandBox().has_value())) {
1931             relativeMat = geo->GetMatrix();
1932         } else {
1933             auto parent = hwcNode->GetParent().lock();
1934             if (!parent) {
1935                 return std::nullopt;
1936             }
1937             if (auto parentGeo = parent->GetRenderProperties().GetBoundsGeometry()) {
1938                 auto invertAbsParentMatrix = Drawing::Matrix();
1939                 parentGeo->GetAbsMatrix().Invert(invertAbsParentMatrix);
1940                 relativeMat = geo->GetAbsMatrix();
1941                 relativeMat.PostConcat(invertAbsParentMatrix);
1942             }
1943         }
1944     } else {
1945         return std::nullopt;
1946     }
1947     return relativeMat;
1948 }
1949 
CheckRenderSkipIfScreenOff(bool extraFrame,std::optional<ScreenId> screenId)1950 bool RSUniRenderUtil::CheckRenderSkipIfScreenOff(bool extraFrame, std::optional<ScreenId> screenId)
1951 {
1952     if (!RSSystemProperties::GetSkipDisplayIfScreenOffEnabled() || RSSystemProperties::IsPcType()) {
1953         return false;
1954     }
1955     auto screenManager = CreateOrGetScreenManager();
1956     if (!screenManager) {
1957         RS_LOGE("RSUniRenderUtil::CheckRenderSkipIfScreenOff, failed to get screen manager!");
1958         return false;
1959     }
1960     // in certain cases such as wireless display, render skipping may be disabled.
1961     auto disableRenderControlScreensCount = screenManager->GetDisableRenderControlScreensCount();
1962     auto isScreenOff = screenId.has_value() ?
1963         screenManager->IsScreenPowerOff(screenId.value()) : screenManager->IsAllScreensPowerOff();
1964     RS_TRACE_NAME_FMT("CheckRenderSkipIfScreenOff disableRenderControl:[%d], PowerOff:[%d]",
1965         disableRenderControlScreensCount, isScreenOff);
1966     if (disableRenderControlScreensCount != 0 || !isScreenOff) {
1967         return false;
1968     }
1969     if (extraFrame && screenManager->GetPowerOffNeedProcessOneFrame()) {
1970         RS_LOGI("RSUniRenderUtil::CheckRenderSkipIfScreenOff screen power off, one more frame.");
1971         screenManager->ResetPowerOffNeedProcessOneFrame();
1972         return false;
1973     } else {
1974         return !screenManager->GetPowerOffNeedProcessOneFrame();
1975     }
1976 }
1977 } // namespace Rosen
1978 } // namespace OHOS
1979