• 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 #include <cstdint>
18 #include <unordered_set>
19 
20 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
21 #include "pipeline/rs_main_thread.h"
22 #include "pipeline/rs_base_render_util.h"
23 #include "platform/common/rs_log.h"
24 #include "render/rs_path.h"
25 #include "rs_trace.h"
26 #include "common/rs_optional_trace.h"
27 #include "scene_board_judgement.h"
28 #include <parameter.h>
29 #include <parameters.h>
30 
31 namespace OHOS {
32 namespace Rosen {
33 namespace {
34 constexpr const char* ENTRY_VIEW = "EntryView";
35 constexpr const char* WALLPAPER_VIEW = "WallpaperView";
36 constexpr const char* SCREENLOCK_WINDOW = "ScreenLockWindow";
37 constexpr const char* SYSUI_DROPDOWN = "SysUI_Dropdown";
38 constexpr const char* SYSUI_STATUS_BAR = "SysUI_StatusBar";
39 constexpr const char* PRIVACY_INDICATOR = "PrivacyIndicator";
40 constexpr const char* SCB_DESK_TOP = "SCBDesktop2";
41 constexpr const char* SCB_WALL_PAPER = "SCBWallpaper1";
42 constexpr const char* SCB_SCREEN_LOCK = "SCBScreenLock10";
43 constexpr const char* SCB_DROP_DOWN_PANEL = "SCBDropdownPanel7";
44 constexpr const char* SCB_STATUS_BAR = "SCBStatusBar6";
45 constexpr const char* SCB_NEGATIVE_SCREEN = "SCBNegativeScreen3";
46 constexpr const char* SCB_GESTURE_BACK = "SCBGestureBack9";
47 };
MergeDirtyHistory(std::shared_ptr<RSDisplayRenderNode> & node,int32_t bufferAge,bool useAlignedDirtyRegion)48 void RSUniRenderUtil::MergeDirtyHistory(std::shared_ptr<RSDisplayRenderNode>& node, int32_t bufferAge,
49     bool useAlignedDirtyRegion)
50 {
51     // update all child surfacenode history
52     for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
53         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
54         if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
55             continue;
56         }
57         auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
58         if (!surfaceDirtyManager->SetBufferAge(bufferAge)) {
59             ROSEN_LOGE("RSUniRenderUtil::MergeVisibleDirtyRegion with invalid buffer age %d", bufferAge);
60         }
61         surfaceDirtyManager->IntersectDirtyRect(surfaceNode->GetOldDirtyInSurface());
62         surfaceDirtyManager->UpdateDirty(useAlignedDirtyRegion);
63     }
64     // update display dirtymanager
65     node->UpdateDisplayDirtyManager(bufferAge, useAlignedDirtyRegion);
66 }
67 
MergeVisibleDirtyRegion(std::shared_ptr<RSDisplayRenderNode> & node,bool useAlignedDirtyRegion)68 Occlusion::Region RSUniRenderUtil::MergeVisibleDirtyRegion(std::shared_ptr<RSDisplayRenderNode>& node,
69     bool useAlignedDirtyRegion)
70 {
71     Occlusion::Region allSurfaceVisibleDirtyRegion;
72     for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
73         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
74         if (surfaceNode == nullptr || !surfaceNode->IsAppWindow() || surfaceNode->GetDstRect().IsEmpty()) {
75             continue;
76         }
77         auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
78         auto surfaceDirtyRect = surfaceDirtyManager->GetDirtyRegion();
79         Occlusion::Rect dirtyRect { surfaceDirtyRect.left_, surfaceDirtyRect.top_,
80             surfaceDirtyRect.GetRight(), surfaceDirtyRect.GetBottom() };
81         auto visibleRegion = surfaceNode->GetVisibleRegion();
82         Occlusion::Region surfaceDirtyRegion { dirtyRect };
83         Occlusion::Region surfaceVisibleDirtyRegion = surfaceDirtyRegion.And(visibleRegion);
84         surfaceNode->SetVisibleDirtyRegion(surfaceVisibleDirtyRegion);
85         if (useAlignedDirtyRegion) {
86             Occlusion::Region alignedRegion = AlignedDirtyRegion(surfaceVisibleDirtyRegion);
87             surfaceNode->SetAlignedVisibleDirtyRegion(alignedRegion);
88             allSurfaceVisibleDirtyRegion.OrSelf(alignedRegion);
89         } else {
90             allSurfaceVisibleDirtyRegion = allSurfaceVisibleDirtyRegion.Or(surfaceVisibleDirtyRegion);
91         }
92     }
93     return allSurfaceVisibleDirtyRegion;
94 }
95 
SrcRectScaleDown(BufferDrawParam & params,const RSSurfaceRenderNode & node)96 void RSUniRenderUtil::SrcRectScaleDown(BufferDrawParam& params, const RSSurfaceRenderNode& node)
97 {
98     ScalingMode scalingMode = ScalingMode::SCALING_MODE_SCALE_TO_WINDOW;
99     const auto& buffer = node.GetBuffer();
100     const auto& surface = node.GetConsumer();
101     if (buffer == nullptr || surface == nullptr) {
102         return;
103     }
104 
105     if (surface->GetScalingMode(buffer->GetSeqNum(), scalingMode) == GSERROR_OK &&
106         scalingMode == ScalingMode::SCALING_MODE_SCALE_CROP) {
107         const RSProperties& property = node.GetRenderProperties();
108 #ifndef USE_ROSEN_DRAWING
109         uint32_t newWidth = static_cast<uint32_t>(params.srcRect.width());
110         uint32_t newHeight = static_cast<uint32_t>(params.srcRect.height());
111 #else
112         uint32_t newWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
113         uint32_t newHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
114 #endif
115         // Canvas is able to handle the situation when the window is out of screen, using bounds instead of dst.
116         uint32_t boundsWidth = static_cast<uint32_t>(property.GetBoundsWidth());
117         uint32_t boundsHeight = static_cast<uint32_t>(property.GetBoundsHeight());
118 
119         // If transformType is not a multiple of 180, need to change the correspondence between width & height.
120         GraphicTransformType transformType = RSBaseRenderUtil::GetRotateTransform(surface->GetTransform());
121         if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
122             transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
123             std::swap(boundsWidth, boundsHeight);
124         }
125 
126         if (newWidth * boundsHeight > newHeight * boundsWidth) {
127             // too wide
128             newWidth = boundsWidth * newHeight / boundsHeight;
129         } else if (newWidth * boundsHeight < newHeight * boundsWidth) {
130             // too tall
131             newHeight = boundsHeight * newWidth / boundsWidth;
132         } else {
133             return;
134         }
135 
136 #ifndef USE_ROSEN_DRAWING
137         uint32_t currentWidth = static_cast<uint32_t>(params.srcRect.width());
138         uint32_t currentHeight = static_cast<uint32_t>(params.srcRect.height());
139 #else
140         uint32_t currentWidth = static_cast<uint32_t>(params.srcRect.GetWidth());
141         uint32_t currentHeight = static_cast<uint32_t>(params.srcRect.GetHeight());
142 #endif
143         if (newWidth < currentWidth) {
144             // the crop is too wide
145             uint32_t dw = currentWidth - newWidth;
146             auto halfdw = dw / 2;
147 #ifndef USE_ROSEN_DRAWING
148             params.srcRect = SkRect::MakeXYWH(params.srcRect.left() + static_cast<int32_t>(halfdw),
149                                               params.srcRect.top(),
150                                               static_cast<int32_t>(newWidth),
151                                               params.srcRect.height());
152 #else
153             params.srcRect =
154                 Drawing::Rect(params.srcRect.GetLeft() + static_cast<int32_t>(halfdw), params.srcRect.GetTop(),
155                     params.srcRect.GetLeft() + static_cast<int32_t>(halfdw) + static_cast<int32_t>(newWidth),
156                     params.srcRect.GetTop() + params.srcRect.GetHeight());
157 #endif
158         } else {
159             // thr crop is too tall
160             uint32_t dh = currentHeight - newHeight;
161             auto halfdh = dh / 2;
162 #ifndef USE_ROSEN_DRAWING
163             params.srcRect = SkRect::MakeXYWH(params.srcRect.left(),
164                                               params.srcRect.top() + static_cast<int32_t>(halfdh),
165                                               params.srcRect.width(),
166                                               static_cast<int32_t>(newHeight));
167 #else
168             params.srcRect =
169                 Drawing::Rect(params.srcRect.GetLeft(), params.srcRect.GetTop() + static_cast<int32_t>(halfdh),
170                     params.srcRect.GetLeft() + params.srcRect.GetWidth(),
171                     params.srcRect.GetTop() + static_cast<int32_t>(halfdh) + static_cast<int32_t>(newHeight));
172 #endif
173         }
174 #ifndef USE_ROSEN_DRAWING
175         RS_LOGD("RsDebug RSUniRenderUtil::SrcRectScaleDown surfaceNode id:%" PRIu64 ", srcRect [%f %f %f %f]",
176             node.GetId(), params.srcRect.left(), params.srcRect.top(),
177             params.srcRect.width(), params.srcRect.height());
178 #else
179         RS_LOGD("RsDebug RSUniRenderUtil::SrcRectScaleDown surfaceNode id:%" PRIu64 ", srcRect [%f %f %f %f]",
180             node.GetId(), params.srcRect.GetLeft(), params.srcRect.GetTop(),
181             params.srcRect.GetWidth(), params.srcRect.GetHeight());
182 #endif
183     }
184 }
185 
CreateBufferDrawParam(const RSSurfaceRenderNode & node,bool forceCPU,uint32_t threadIndex)186 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(const RSSurfaceRenderNode& node,
187     bool forceCPU, uint32_t threadIndex)
188 {
189     BufferDrawParam params;
190     params.threadIndex = threadIndex;
191 #ifdef RS_ENABLE_EGLIMAGE
192     params.useCPU = forceCPU;
193 #else // RS_ENABLE_EGLIMAGE
194     params.useCPU = true;
195 #endif // RS_ENABLE_EGLIMAGE
196 #ifndef USE_ROSEN_DRAWING
197     params.paint.setAntiAlias(true);
198 #ifndef NEW_SKIA
199     params.paint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
200 #endif
201 
202     const RSProperties& property = node.GetRenderProperties();
203     params.dstRect = SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight());
204 #else
205     params.paint.SetAntiAlias(true);
206     Drawing::Filter filter;
207     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
208     params.paint.SetFilter(filter);
209 
210     const RSProperties& property = node.GetRenderProperties();
211     params.dstRect = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
212 #endif
213 
214     const sptr<SurfaceBuffer>& buffer = node.GetBuffer();
215     if (buffer == nullptr) {
216         return params;
217     }
218     params.buffer = buffer;
219     params.acquireFence = node.GetAcquireFence();
220 #ifndef USE_ROSEN_DRAWING
221     params.srcRect = SkRect::MakeWH(buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
222 #else
223     params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
224 #endif
225 
226     auto& consumer = node.GetConsumer();
227     if (consumer == nullptr) {
228         return params;
229     }
230     auto transform = consumer->GetTransform();
231     RectF localBounds = { 0.0f, 0.0f, property.GetBoundsWidth(), property.GetBoundsHeight() };
232     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, property.GetFrameGravity(), localBounds, params);
233     RSBaseRenderUtil::FlipMatrix(transform, params);
234     SrcRectScaleDown(params, node);
235     return params;
236 }
237 
CreateBufferDrawParam(const RSDisplayRenderNode & node,bool forceCPU)238 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(const RSDisplayRenderNode& node, bool forceCPU)
239 {
240     BufferDrawParam params;
241 #ifdef RS_ENABLE_EGLIMAGE
242     params.useCPU = forceCPU;
243 #else // RS_ENABLE_EGLIMAGE
244     params.useCPU = true;
245 #endif // RS_ENABLE_EGLIMAGE
246 #ifndef USE_ROSEN_DRAWING
247     params.paint.setAntiAlias(true);
248 #ifndef NEW_SKIA
249     params.paint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
250 #endif
251 
252     const sptr<SurfaceBuffer>& buffer = node.GetBuffer();
253     params.buffer = buffer;
254     params.acquireFence = node.GetAcquireFence();
255     params.srcRect = SkRect::MakeWH(buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
256     params.dstRect = SkRect::MakeWH(buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
257 #else
258     params.paint.SetAntiAlias(true);
259     Drawing::Filter filter;
260     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
261     params.paint.SetFilter(filter);
262 
263     const sptr<SurfaceBuffer>& buffer = node.GetBuffer();
264     params.buffer = buffer;
265     params.acquireFence = node.GetAcquireFence();
266     params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
267     params.dstRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
268 #endif
269     return params;
270 }
271 
CreateLayerBufferDrawParam(const LayerInfoPtr & layer,bool forceCPU)272 BufferDrawParam RSUniRenderUtil::CreateLayerBufferDrawParam(const LayerInfoPtr& layer, bool forceCPU)
273 {
274     BufferDrawParam params;
275 #ifdef RS_ENABLE_EGLIMAGE
276     params.useCPU = forceCPU;
277 #else // RS_ENABLE_EGLIMAGE
278     params.useCPU = true;
279 #endif // RS_ENABLE_EGLIMAGE
280 #ifndef USE_ROSEN_DRAWING
281     params.paint.setAntiAlias(true);
282 #ifndef NEW_SKIA
283     params.paint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
284 #endif
285     params.paint.setAlphaf(layer->GetAlpha().gAlpha);
286 #else
287     params.paint.SetAntiAlias(true);
288     Drawing::Filter filter;
289     filter.SetFilterQuality(Drawing::Filter::FilterQuality::LOW);
290     params.paint.SetFilter(filter);
291     params.paint.SetAlphaF(layer->GetAlpha().gAlpha);
292 #endif
293 
294     sptr<SurfaceBuffer> buffer = layer->GetBuffer();
295     if (buffer == nullptr) {
296         return params;
297     }
298     params.acquireFence = layer->GetAcquireFence();
299     params.buffer = buffer;
300 #ifndef USE_ROSEN_DRAWING
301     params.srcRect = SkRect::MakeWH(buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
302     auto boundRect = layer->GetBoundSize();
303     params.dstRect = SkRect::MakeWH(boundRect.w, boundRect.h);
304 
305     auto layerMatrix = layer->GetMatrix();
306     params.matrix = SkMatrix::MakeAll(layerMatrix.scaleX, layerMatrix.skewX, layerMatrix.transX,
307                                       layerMatrix.skewY, layerMatrix.scaleY, layerMatrix.transY,
308                                       layerMatrix.pers0, layerMatrix.pers1, layerMatrix.pers2);
309 #else
310     params.srcRect = Drawing::Rect(0, 0, buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
311     auto boundRect = layer->GetBoundSize();
312     params.dstRect = Drawing::Rect(0, 0, boundRect.w, boundRect.h);
313 
314     auto layerMatrix = layer->GetMatrix();
315     params.matrix = Drawing::Matrix();
316     params.matrix.SetMatrix(layerMatrix.scaleX, layerMatrix.skewX, layerMatrix.transX, layerMatrix.skewY,
317         layerMatrix.scaleY, layerMatrix.transY, layerMatrix.pers0, layerMatrix.pers1, layerMatrix.pers2);
318 #endif
319     int nodeRotation = RSUniRenderUtil::GetRotationFromMatrix(params.matrix); // rotation degree anti-clockwise
320     auto layerTransform = layer->GetTransformType();
321     // calculate clockwise rotation degree excluded rotation in total matrix
322     int realRotation = (nodeRotation +
323         RSBaseRenderUtil::RotateEnumToInt(RSBaseRenderUtil::GetRotateTransform(layerTransform))) % 360;
324     auto flip = RSBaseRenderUtil::GetFlipTransform(layerTransform);
325     // calculate transform in anti-clockwise
326     auto transform = RSBaseRenderUtil::RotateEnumToInt(realRotation, flip);
327 
328     RectF localBounds = { 0.0f, 0.0f, static_cast<float>(boundRect.w), static_cast<float>(boundRect.h) };
329     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(transform, static_cast<Gravity>(layer->GetGravity()),
330         localBounds, params);
331     RSBaseRenderUtil::FlipMatrix(transform, params);
332     return params;
333 }
334 
335 #ifndef USE_ROSEN_DRAWING
DrawCachedImage(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas,sk_sp<SkImage> image)336 void RSUniRenderUtil::DrawCachedImage(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas, sk_sp<SkImage> image)
337 {
338     if (image == nullptr) {
339         return;
340     }
341     canvas.save();
342     canvas.scale(node.GetRenderProperties().GetBoundsWidth() / image->width(),
343         node.GetRenderProperties().GetBoundsHeight() / image->height());
344     SkPaint paint;
345 #ifdef NEW_SKIA
346     canvas.drawImage(image.get(), 0.0, 0.0, SkSamplingOptions(), &paint);
347 #else
348     canvas.drawImage(image.get(), 0.0, 0.0, &paint);
349 #endif
350     canvas.restore();
351 }
352 #else
DrawCachedImage(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas,std::shared_ptr<Drawing::Image> image)353 void RSUniRenderUtil::DrawCachedImage(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas,
354     std::shared_ptr<Drawing::Image> image)
355 {
356     if (image == nullptr) {
357         return;
358     }
359     canvas.Save();
360     canvas.Scale(node.GetRenderProperties().GetBoundsWidth() / image->GetWidth(),
361         node.GetRenderProperties().GetBoundsHeight() / image->GetHeight());
362     Drawing::Brush brush;
363     canvas.AttachBrush(brush);
364     Drawing::SamplingOptions sampling =
365         Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NEAREST);
366     canvas.DrawImage(*image.get(), 0.0, 0.0, sampling);
367     canvas.DetachBrush();
368     canvas.Restore();
369 }
370 #endif
371 
AlignedDirtyRegion(const Occlusion::Region & dirtyRegion,int32_t alignedBits)372 Occlusion::Region RSUniRenderUtil::AlignedDirtyRegion(const Occlusion::Region& dirtyRegion, int32_t alignedBits)
373 {
374     Occlusion::Region alignedRegion;
375     if (alignedBits <= 1) {
376         return dirtyRegion;
377     }
378     for (const auto& dirtyRect : dirtyRegion.GetRegionRects()) {
379         int32_t left = (dirtyRect.left_ / alignedBits) * alignedBits;
380         int32_t top = (dirtyRect.top_ / alignedBits) * alignedBits;
381         int32_t width = ((dirtyRect.right_ + alignedBits - 1) / alignedBits) * alignedBits - left;
382         int32_t height = ((dirtyRect.bottom_ + alignedBits - 1) / alignedBits) * alignedBits - top;
383         Occlusion::Rect rect = { left, top, left + width, top + height };
384         Occlusion::Region singleAlignedRegion(rect);
385         alignedRegion.OrSelf(singleAlignedRegion);
386     }
387     return alignedRegion;
388 }
389 
HandleSubThreadNode(RSRenderNode & node,RSPaintFilterCanvas & canvas)390 bool RSUniRenderUtil::HandleSubThreadNode(RSRenderNode& node, RSPaintFilterCanvas& canvas)
391 {
392     if (node.IsMainThreadNode()) {
393         return false;
394     }
395     if (!node.HasCachedTexture()) {
396         RS_TRACE_NAME_FMT("HandleSubThreadNode wait %" PRIu64 "", node.GetId());
397 #if defined(RS_ENABLE_GL)
398         RSSubThreadManager::Instance()->WaitNodeTask(node.GetId());
399         node.UpdateCompletedCacheSurface();
400 #endif
401     }
402     RS_TRACE_NAME_FMT("RSUniRenderUtil::HandleSubThreadNode %" PRIu64 "", node.GetId());
403     node.DrawCacheSurface(canvas, UNI_MAIN_THREAD_INDEX, true);
404     return true;
405 }
406 
HandleCaptureNode(RSRenderNode & node,RSPaintFilterCanvas & canvas)407 bool RSUniRenderUtil::HandleCaptureNode(RSRenderNode& node, RSPaintFilterCanvas& canvas)
408 {
409     auto surfaceNodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>();
410     if (surfaceNodePtr == nullptr) {
411         return false;
412     }
413     if (surfaceNodePtr->IsAppWindow()) {
414         auto rsParent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surfaceNodePtr->GetParent().lock());
415         auto curNode = surfaceNodePtr;
416         if (rsParent && rsParent->IsLeashWindow()) {
417             curNode = rsParent;
418         }
419         if (!curNode->ShouldPaint()) {
420             return false;
421         }
422         if (curNode->IsOnTheTree()) {
423             return HandleSubThreadNode(*curNode, canvas);
424         } else {
425 #ifdef RS_ENABLE_GL
426             if (curNode->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) {
427                 RSSubThreadManager::Instance()->WaitNodeTask(curNode->GetId());
428             }
429 #endif
430             return false;
431         }
432     }
433     return false;
434 }
435 
436 #ifndef USE_ROSEN_DRAWING
GetRotationFromMatrix(SkMatrix matrix)437 int RSUniRenderUtil::GetRotationFromMatrix(SkMatrix matrix)
438 {
439     float value[9];
440     matrix.get9(value);
441 
442     int rAngle = static_cast<int>(-round(atan2(value[SkMatrix::kMSkewX], value[SkMatrix::kMScaleX]) * (180 / PI)));
443     // transfer the result to anti-clockwise degrees
444     // only rotation with 90°, 180°, 270° are composed through hardware,
445     // in which situation the transformation of the layer needs to be set.
446     static const std::map<int, int> supportedDegrees = {{90, 270}, {180, 180}, {-90, 90}, {-180, 180}};
447     auto iter = supportedDegrees.find(rAngle);
448     return iter != supportedDegrees.end() ? iter->second : 0;
449 }
450 #else
GetRotationFromMatrix(Drawing::Matrix matrix)451 int RSUniRenderUtil::GetRotationFromMatrix(Drawing::Matrix matrix)
452 {
453     Drawing::Matrix::Buffer value;
454     matrix.GetAll(value);
455 
456     int rAngle = static_cast<int>(-round(atan2(value[Drawing::Matrix::Index::SKEW_X],
457         value[Drawing::Matrix::Index::SCALE_X]) * (180 / PI)));
458     // transfer the result to anti-clockwise degrees
459     // only rotation with 90°, 180°, 270° are composed through hardware,
460     // in which situation the transformation of the layer needs to be set.
461     static const std::map<int, int> supportedDegrees = {{90, 270}, {180, 180}, {-90, 90}, {-180, 180}};
462     auto iter = supportedDegrees.find(rAngle);
463     return iter != supportedDegrees.end() ? iter->second : 0;
464 }
465 #endif
466 
AssignWindowNodes(const std::shared_ptr<RSDisplayRenderNode> & displayNode,std::list<std::shared_ptr<RSSurfaceRenderNode>> & mainThreadNodes,std::list<std::shared_ptr<RSSurfaceRenderNode>> & subThreadNodes,uint64_t focusNodeId,DeviceType deviceType)467 void RSUniRenderUtil::AssignWindowNodes(const std::shared_ptr<RSDisplayRenderNode>& displayNode,
468     std::list<std::shared_ptr<RSSurfaceRenderNode>>& mainThreadNodes,
469     std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes, uint64_t focusNodeId, DeviceType deviceType)
470 {
471     if (displayNode == nullptr) {
472         ROSEN_LOGE("RSUniRenderUtil::AssignWindowNodes display node is null");
473         return;
474     }
475     bool isRotation = displayNode->IsRotationChanged();
476     bool isScale = false;
477     uint32_t leashWindowCount = 0;
478     bool isFocusNodeFound = false;
479     uint64_t realFocusNodeId = 0;
480     std::string logInfo = "";
481     std::list<RSBaseRenderNode::SharedPtr> curAllSurfaces;
482     if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
483         std::vector<RSBaseRenderNode::SharedPtr> curAllSurfacesVec;
484         displayNode->CollectSurface(displayNode, curAllSurfacesVec, true, true);
485         std::copy(curAllSurfacesVec.begin(), curAllSurfacesVec.end(), std::back_inserter(curAllSurfaces));
486     } else {
487         curAllSurfaces = displayNode->GetSortedChildren();
488     }
489     for (auto iter = curAllSurfaces.begin(); iter != curAllSurfaces.end(); iter++) {
490         auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*iter);
491         if (node == nullptr) {
492             ROSEN_LOGE("RSUniRenderUtil::AssignWindowNodes nullptr found in sortedChildren, this should not happen");
493             continue;
494         }
495         if (node->IsLeashWindow()) {
496             leashWindowCount++;
497         }
498         if (node->IsLeashWindow() && node->IsScale()) {
499             isScale = true;
500         }
501         if (deviceType != DeviceType::PHONE) {
502             if (node->GetId() == focusNodeId) {
503                 isFocusNodeFound = true;
504                 realFocusNodeId = focusNodeId;
505             }
506             if (!isFocusNodeFound && node->IsLeashWindow()) {
507                 for (auto& child : node->GetSortedChildren()) {
508                     if (child && child->GetId() == focusNodeId) {
509                         isFocusNodeFound = true;
510                         realFocusNodeId = node->GetId();
511                     }
512                 }
513             }
514         }
515     }
516     // trace info for assign window nodes
517     if (Rosen::RSSystemProperties::GetDebugTraceEnabled()) {
518         logInfo += "{ isScale: " + std::to_string(isScale) + ", " +
519             "leashWindowCount: " + std::to_string(leashWindowCount) + ", " +
520             "isRotation: " + std::to_string(isRotation) + " }; " +
521             "realFocusNodeId: " + std::to_string(realFocusNodeId) + " ]";
522     }
523     for (auto iter = curAllSurfaces.begin(); iter != curAllSurfaces.end(); iter++) {
524         auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*iter);
525         if (node == nullptr) {
526             ROSEN_LOGE("RSUniRenderUtil::AssignWindowNodes nullptr found in sortedChildren, this should not happen");
527             continue;
528         }
529         // trace info for assign window nodes
530         if (Rosen::RSSystemProperties::GetDebugTraceEnabled()) {
531             logInfo += "node:[ " + node->GetName() + ", " + std::to_string(node->GetId()) + " ]" +
532                 "( " + std::to_string(static_cast<uint32_t>(node->GetCacheSurfaceProcessedStatus())) + ", " +
533                 std::to_string(node->HasFilter()) + ", " + std::to_string(node->HasAbilityComponent()) + " ); ";
534         }
535         std::string surfaceName = node->GetName();
536         bool needFilter = surfaceName == ENTRY_VIEW || surfaceName == WALLPAPER_VIEW ||
537             surfaceName == SYSUI_STATUS_BAR || surfaceName == SCREENLOCK_WINDOW ||
538             surfaceName == SYSUI_DROPDOWN || surfaceName == PRIVACY_INDICATOR;
539         bool needFilterSCB = surfaceName == SCB_DESK_TOP || surfaceName == SCB_WALL_PAPER ||
540             surfaceName == SCB_SCREEN_LOCK || surfaceName == SCB_DROP_DOWN_PANEL || surfaceName == SCB_STATUS_BAR ||
541             surfaceName == SCB_NEGATIVE_SCREEN || surfaceName == SCB_GESTURE_BACK;
542         if (needFilter || needFilterSCB || node->IsSelfDrawingType()) {
543             AssignMainThreadNode(mainThreadNodes, node);
544             continue;
545         }
546         if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) { // node exceed one vsync
547             AssignSubThreadNode(subThreadNodes, node);
548             continue;
549         }
550         if (deviceType == DeviceType::PHONE) {
551             if (isScale) { // app start or close scene
552                 if (!node->HasFilter() && !node->HasAbilityComponent() && !isRotation) {
553                     AssignSubThreadNode(subThreadNodes, node);
554                 } else {
555                     AssignMainThreadNode(mainThreadNodes, node);
556                 }
557             } else { // other scene
558                 AssignMainThreadNode(mainThreadNodes, node);
559             }
560         } else { // PC or TABLET
561             if (node->QuerySubAssignable(isRotation)) {
562                 AssignSubThreadNode(subThreadNodes, node);
563             } else {
564                 AssignMainThreadNode(mainThreadNodes, node);
565             }
566         }
567     }
568     SortSubThreadNodes(subThreadNodes);
569     RS_OPTIONAL_TRACE_NAME("RSUniRenderUtil::AssignWindowNodes:" + logInfo);
570 }
571 
AssignMainThreadNode(std::list<std::shared_ptr<RSSurfaceRenderNode>> & mainThreadNodes,const std::shared_ptr<RSSurfaceRenderNode> & node)572 void RSUniRenderUtil::AssignMainThreadNode(std::list<std::shared_ptr<RSSurfaceRenderNode>>& mainThreadNodes,
573     const std::shared_ptr<RSSurfaceRenderNode>& node)
574 {
575     if (node == nullptr) {
576         ROSEN_LOGW("RSUniRenderUtil::AssignMainThreadNode node is nullptr");
577         return;
578     }
579     mainThreadNodes.emplace_back(node);
580     bool changeThread = !node->IsMainThreadNode();
581     node->SetIsMainThreadNode(true);
582     node->SetCacheType(CacheType::NONE);
583     HandleHardwareNode(node);
584     if (changeThread) {
585         RS_LOGD("RSUniRenderUtil::AssignMainThreadNode clear cache surface:[%s, %llu]",
586             node->GetName().c_str(), node->GetId());
587         ClearCacheSurface(node, UNI_MAIN_THREAD_INDEX);
588         node->SetTextureValidFlag(false);
589     }
590 }
591 
AssignSubThreadNode(std::list<std::shared_ptr<RSSurfaceRenderNode>> & subThreadNodes,const std::shared_ptr<RSSurfaceRenderNode> & node,DeviceType deviceType)592 void RSUniRenderUtil::AssignSubThreadNode(std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes,
593     const std::shared_ptr<RSSurfaceRenderNode>& node, DeviceType deviceType)
594 {
595     if (node == nullptr) {
596         ROSEN_LOGW("RSUniRenderUtil::AssignSubThreadNode node is nullptr");
597         return;
598     }
599     if (deviceType == DeviceType::PC || deviceType == DeviceType::TABLET) {
600         node->SetCacheType(CacheType::ANIMATE_PROPERTY);
601     } else {
602         node->SetCacheType(CacheType::CONTENT);
603     }
604     node->SetIsMainThreadNode(false);
605 
606     // skip complete static window, DO NOT assign it to subthread.
607     if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DONE &&
608         node->IsCurrentFrameStatic() && node->HasCachedTexture()) {
609         RS_TRACE_NAME_FMT("subThreadNodes : static skip %s", node->GetName().c_str());
610     } else {
611         subThreadNodes.emplace_back(node);
612         node->UpdateCacheSurfaceDirtyManager(2); // 2 means buffer age
613     }
614 
615 #if defined(RS_ENABLE_GL)
616     if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DONE &&
617         node->GetCacheSurface(UNI_MAIN_THREAD_INDEX, false) && node->GetCacheSurfaceNeedUpdated()) {
618         node->UpdateCompletedCacheSurface();
619         for (auto& child : node->GetSortedChildren()) {
620             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
621             if (surfaceNode && surfaceNode->IsAppWindow()) {
622                 surfaceNode->GetDirtyManager()->MergeDirtyRect(surfaceNode->GetOldDirty());
623             }
624         }
625         node->SetCacheSurfaceNeedUpdated(false);
626     }
627 #endif
628     if (node->HasCachedTexture()) {
629         node->SetPriority(NodePriorityType::SUB_LOW_PRIORITY);
630     } else {
631         node->SetPriority(NodePriorityType::SUB_HIGH_PRIORITY);
632     }
633 }
634 
SortSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>> & subThreadNodes)635 void RSUniRenderUtil::SortSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes)
636 {
637     // sort subThreadNodes by priority and z-order
638     subThreadNodes.sort([](const auto& first, const auto& second) -> bool {
639         auto node1 = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(first);
640         auto node2 = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(second);
641         if (node1 == nullptr || node2 == nullptr) {
642             ROSEN_LOGE(
643                 "RSUniRenderUtil::SortSubThreadNodes sort nullptr found in subThreadNodes, this should not happen");
644             return false;
645         }
646         if (node1->GetPriority() == node2->GetPriority()) {
647             return node2->GetRenderProperties().GetPositionZ() < node1->GetRenderProperties().GetPositionZ();
648         } else {
649             return node1->GetPriority() < node2->GetPriority();
650         }
651     });
652 }
653 
CacheSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>> & oldSubThreadNodes,std::list<std::shared_ptr<RSSurfaceRenderNode>> & subThreadNodes)654 void RSUniRenderUtil::CacheSubThreadNodes(std::list<std::shared_ptr<RSSurfaceRenderNode>>& oldSubThreadNodes,
655     std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes)
656 {
657     std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>> nodes(subThreadNodes.begin(), subThreadNodes.end());
658     for (auto node : oldSubThreadNodes) {
659         if (nodes.count(node) > 0) {
660             continue;
661         }
662         // The node being processed by sub thread may have been removed.
663         if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) {
664             subThreadNodes.emplace_back(node);
665         }
666     }
667     oldSubThreadNodes.clear();
668     oldSubThreadNodes = subThreadNodes;
669 }
670 
HandleHardwareNode(const std::shared_ptr<RSSurfaceRenderNode> & node)671 void RSUniRenderUtil::HandleHardwareNode(const std::shared_ptr<RSSurfaceRenderNode>& node)
672 {
673     if (!node->HasHardwareNode()) {
674         return;
675     }
676     auto appWindow = node;
677     if (node->IsLeashWindow()) {
678         for (auto& child : node->GetSortedChildren()) {
679             auto surfaceNodePtr = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
680             if (surfaceNodePtr && surfaceNodePtr->IsAppWindow()) {
681                 appWindow = surfaceNodePtr;
682                 break;
683             }
684         }
685     }
686     auto hardwareEnabledNodes = appWindow->GetChildHardwareEnabledNodes();
687     for (auto& hardwareEnabledNode : hardwareEnabledNodes) {
688         auto hardwareEnabledNodePtr = hardwareEnabledNode.lock();
689         if (hardwareEnabledNodePtr) {
690             hardwareEnabledNodePtr->SetHardwareDisabledByCache(false);
691         }
692     }
693 }
694 
ClearSurfaceIfNeed(const RSRenderNodeMap & map,const std::shared_ptr<RSDisplayRenderNode> & displayNode,std::set<std::shared_ptr<RSBaseRenderNode>> & oldChildren)695 void RSUniRenderUtil::ClearSurfaceIfNeed(const RSRenderNodeMap& map,
696     const std::shared_ptr<RSDisplayRenderNode>& displayNode,
697     std::set<std::shared_ptr<RSBaseRenderNode>>& oldChildren)
698 {
699     if (displayNode == nullptr) {
700         return;
701     }
702     std::list<RSBaseRenderNode::SharedPtr> curAllSurfaces;
703     if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
704         std::vector<RSBaseRenderNode::SharedPtr> curAllSurfacesVec;
705         displayNode->CollectSurface(displayNode, curAllSurfacesVec, true, true);
706         std::copy(curAllSurfacesVec.begin(), curAllSurfacesVec.end(), std::back_inserter(curAllSurfaces));
707     } else {
708         curAllSurfaces = displayNode->GetSortedChildren();
709     }
710     std::set<std::shared_ptr<RSBaseRenderNode>> tmpSet(curAllSurfaces.begin(), curAllSurfaces.end());
711     for (auto& child : oldChildren) {
712         auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
713         if (tmpSet.count(surface) == 0) {
714             if (surface && map.GetRenderNode(surface->GetId()) != nullptr) {
715                 RS_LOGD("RSUniRenderUtil::ClearSurfaceIfNeed clear cache surface:[%s, %llu]",
716                     surface->GetName().c_str(), surface->GetId());
717                 ClearCacheSurface(surface, UNI_MAIN_THREAD_INDEX);
718                 surface->SetTextureValidFlag(false);
719             }
720         }
721     }
722     oldChildren.swap(tmpSet);
723 }
724 
725 // for ui first
ClearCacheSurface(const std::shared_ptr<RSSurfaceRenderNode> & node,uint32_t threadIndex)726 void RSUniRenderUtil::ClearCacheSurface(const std::shared_ptr<RSSurfaceRenderNode>& node, uint32_t threadIndex)
727 {
728     RS_LOGD("ClearCacheSurface node in correct thread: [%llu]", node->GetId());
729     uint32_t cacheSurfaceThreadIndex = node->GetCacheSurfaceThreadIndex();
730     if (cacheSurfaceThreadIndex == threadIndex) {
731         node->ClearCacheSurface();
732         node->SetIsMainThreadNode(true);
733         return;
734     }
735     if (cacheSurfaceThreadIndex == UNI_MAIN_THREAD_INDEX) {
736         RSMainThread::Instance()->PostTask([node]() {
737             RS_LOGD("clear node cache surface in main thread");
738             node->ClearCacheSurface();
739             node->SetIsMainThreadNode(true);
740         });
741     } else {
742 #ifdef RS_ENABLE_GL
743         RSSubThreadManager::Instance()->PostTask([node]() {
744             RS_LOGD("clear node cache surface in sub thread");
745             node->ClearCacheSurface();
746             node->SetIsMainThreadNode(true);
747         }, cacheSurfaceThreadIndex);
748 #endif
749     }
750 }
751 
ClearCacheSurface(RSRenderNode & node,uint32_t threadIndex)752 void RSUniRenderUtil::ClearCacheSurface(RSRenderNode& node, uint32_t threadIndex)
753 {
754     RS_LOGD("ClearCacheSurface node: [%llu]", node.GetId());
755     uint32_t cacheSurfaceThreadIndex = node.GetCacheSurfaceThreadIndex();
756     uint32_t completedSurfaceThreadIndex = node.GetCompletedSurfaceThreadIndex();
757     if (cacheSurfaceThreadIndex == threadIndex && completedSurfaceThreadIndex == threadIndex) {
758         node.ClearCacheSurface();
759         return;
760     }
761     auto cacheSurface = node.GetCacheSurface(threadIndex, true);
762     auto cacheCompletedSurface = node.GetCompletedCacheSurface(threadIndex, true);
763     node.ClearCacheSurface();
764     ClearNodeCacheSurface(cacheSurface, cacheCompletedSurface, cacheSurfaceThreadIndex, completedSurfaceThreadIndex);
765 }
766 
767 #ifndef USE_ROSEN_DRAWING
ClearNodeCacheSurface(sk_sp<SkSurface> & cacheSurface,sk_sp<SkSurface> & cacheCompletedSurface,uint32_t cacheSurfaceThreadIndex,uint32_t completedSurfaceThreadIndex)768 void RSUniRenderUtil::ClearNodeCacheSurface(sk_sp<SkSurface>& cacheSurface, sk_sp<SkSurface>& cacheCompletedSurface,
769     uint32_t cacheSurfaceThreadIndex, uint32_t completedSurfaceThreadIndex)
770 #else
771 void RSUniRenderUtil::ClearNodeCacheSurface(std::shared_ptr<Drawing::Surface>& cacheSurface,
772     std::shared_ptr<Drawing::Surface>& cacheCompletedSurface,
773     uint32_t cacheSurfaceThreadIndex, uint32_t completedSurfaceThreadIndex)
774 #endif
775 {
776     PostReleaseSurfaceTask(cacheSurface, cacheSurfaceThreadIndex);
777     PostReleaseSurfaceTask(cacheCompletedSurface, completedSurfaceThreadIndex);
778 }
779 
780 #ifndef USE_ROSEN_DRAWING
PostReleaseSurfaceTask(sk_sp<SkSurface> & surface,uint32_t threadIndex)781 void RSUniRenderUtil::PostReleaseSurfaceTask(sk_sp<SkSurface>& surface, uint32_t threadIndex)
782 #else
783 void RSUniRenderUtil::PostReleaseSurfaceTask(std::shared_ptr<Drawing::Surface>& surface, uint32_t threadId)
784 #endif
785 {
786     if (surface == nullptr) {
787         return;
788     }
789 
790     auto task = [tmpSurface = surface]() mutable {
791         RS_LOGD("clear node cache surface in main thread");
792         tmpSurface = nullptr;
793     };
794     surface = nullptr;
795     if (threadIndex == UNI_MAIN_THREAD_INDEX) {
796         RSMainThread::Instance()->PostTask(task);
797     } else {
798 #ifdef RS_ENABLE_GL
799         RSSubThreadManager::Instance()->PostTask(task, threadIndex);
800 #endif
801     }
802 }
803 
FloorTransXYInCanvasMatrix(RSPaintFilterCanvas & canvas)804 void RSUniRenderUtil::FloorTransXYInCanvasMatrix(RSPaintFilterCanvas& canvas)
805 {
806 #ifndef USE_ROSEN_DRAWING
807     auto matrix = canvas.getTotalMatrix();
808     matrix.setTranslateX(std::floor(matrix.getTranslateX()));
809     matrix.setTranslateY(std::floor(matrix.getTranslateY()));
810     canvas.setMatrix(matrix);
811 #else
812     auto matrix = canvas.GetTotalMatrix();
813     matrix.Set(Drawing::Matrix::TRANS_X, std::floor(matrix.Get(Drawing::Matrix::TRANS_X)));
814     matrix.Set(Drawing::Matrix::TRANS_Y, std::floor(matrix.Get(Drawing::Matrix::TRANS_Y)));
815     canvas.SetMatrix(matrix);
816 #endif
817 }
818 } // namespace Rosen
819 } // namespace OHOS
820