1 /*
2  * Copyright (c) 2024 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 "drawable/rs_render_node_drawable_adapter.h"
17 #include <mutex>
18 #include <sstream>
19 
20 #include "skia_adapter/skia_canvas.h"
21 #include "src/core/SkCanvasPriv.h"
22 
23 #include "common/rs_background_thread.h"
24 #include "common/rs_optional_trace.h"
25 #include "drawable/rs_misc_drawable.h"
26 #include "drawable/rs_render_node_shadow_drawable.h"
27 #include "params/rs_canvas_drawing_render_params.h"
28 #include "params/rs_display_render_params.h"
29 #include "params/rs_effect_render_params.h"
30 #include "params/rs_surface_render_params.h"
31 #include "pipeline/rs_context.h"
32 #include "pipeline/rs_render_node.h"
33 #include "pipeline/rs_render_node_gc.h"
34 #include "platform/common/rs_log.h"
35 
36 #ifdef ROSEN_OHOS
37 #include "hisysevent.h"
38 #endif
39 
40 namespace OHOS::Rosen::DrawableV2 {
41 std::map<RSRenderNodeType, RSRenderNodeDrawableAdapter::Generator> RSRenderNodeDrawableAdapter::GeneratorMap;
42 std::map<NodeId, RSRenderNodeDrawableAdapter::WeakPtr> RSRenderNodeDrawableAdapter::RenderNodeDrawableCache_;
43 RSRenderNodeDrawableAdapter::DrawableVec RSRenderNodeDrawableAdapter::toClearDrawableVec_;
44 RSRenderNodeDrawableAdapter::CmdListVec RSRenderNodeDrawableAdapter::toClearCmdListVec_;
45 #ifdef ROSEN_OHOS
46 thread_local RSRenderNodeDrawableAdapter* RSRenderNodeDrawableAdapter::curDrawingCacheRoot_ = nullptr;
47 #else
48 RSRenderNodeDrawableAdapter* RSRenderNodeDrawableAdapter::curDrawingCacheRoot_ = nullptr;
49 #endif
50 
RSRenderNodeDrawableAdapter(std::shared_ptr<const RSRenderNode> && node)51 RSRenderNodeDrawableAdapter::RSRenderNodeDrawableAdapter(std::shared_ptr<const RSRenderNode>&& node)
52     : nodeType_(node ? node->GetType() : RSRenderNodeType::UNKNOW), renderNode_(std::move(node)) {}
53 
54 RSRenderNodeDrawableAdapter::~RSRenderNodeDrawableAdapter() = default;
55 
GetDrawableById(NodeId id)56 RSRenderNodeDrawableAdapter::SharedPtr RSRenderNodeDrawableAdapter::GetDrawableById(NodeId id)
57 {
58     std::lock_guard<std::mutex> lock(cacheMapMutex_);
59     if (const auto cacheIt = RenderNodeDrawableCache_.find(id); cacheIt != RenderNodeDrawableCache_.end()) {
60         if (const auto ptr = cacheIt->second.lock()) {
61             return ptr;
62         }
63     }
64     return nullptr;
65 }
66 
GetDrawableVectorById(const std::unordered_set<NodeId> & ids)67 std::vector<RSRenderNodeDrawableAdapter::SharedPtr> RSRenderNodeDrawableAdapter::GetDrawableVectorById(
68     const std::unordered_set<NodeId>& ids)
69 {
70     std::vector<RSRenderNodeDrawableAdapter::SharedPtr> vec;
71     std::lock_guard<std::mutex> lock(cacheMapMutex_);
72     for (const auto& id : ids) {
73         if (const auto cacheIt = RenderNodeDrawableCache_.find(id); cacheIt != RenderNodeDrawableCache_.end()) {
74             if (const auto ptr = cacheIt->second.lock()) {
75                 vec.push_back(ptr);
76             }
77         }
78     }
79     return vec;
80 }
81 
OnGenerate(const std::shared_ptr<const RSRenderNode> & node)82 RSRenderNodeDrawableAdapter::SharedPtr RSRenderNodeDrawableAdapter::OnGenerate(
83     const std::shared_ptr<const RSRenderNode>& node)
84 {
85     if (node == nullptr) {
86         ROSEN_LOGE("RSRenderNodeDrawableAdapter::OnGenerate, node null");
87         return nullptr;
88     }
89     if (node->renderDrawable_ != nullptr) {
90         return node->renderDrawable_;
91     }
92     static const auto Destructor = [](RSRenderNodeDrawableAdapter* ptr) {
93         RemoveDrawableFromCache(ptr->nodeId_); // Remove from cache before deleting
94         RSRenderNodeGC::DrawableDestructor(ptr);
95     };
96     auto id = node->GetId();
97     // Try to get a cached drawable if it exists.
98     {
99         std::lock_guard<std::mutex> lock(cacheMapMutex_);
100         if (const auto cacheIt = RenderNodeDrawableCache_.find(id); cacheIt != RenderNodeDrawableCache_.end()) {
101             if (const auto ptr = cacheIt->second.lock()) {
102                 ROSEN_LOGE("RSRenderNodeDrawableAdapter::OnGenerate, node id in Cache is %{public}" PRIu64, id);
103                 return ptr;
104             } else {
105                 RenderNodeDrawableCache_.erase(cacheIt);
106             }
107         }
108     }
109     // If we don't have a cached drawable, try to generate a new one and cache it.
110     const auto it = GeneratorMap.find(node->GetType());
111     if (it == GeneratorMap.end()) {
112         ROSEN_LOGE("RSRenderNodeDrawableAdapter::OnGenerate, node type %{public}d is not supported", node->GetType());
113         return nullptr;
114     }
115     auto ptr = it->second(node);
116     auto sharedPtr = std::shared_ptr<RSRenderNodeDrawableAdapter>(ptr, Destructor);
117     node->renderDrawable_ = sharedPtr;
118     sharedPtr->nodeId_ = id;
119     InitRenderParams(node, sharedPtr);
120 
121     {
122         std::lock_guard<std::mutex> lock(cacheMapMutex_);
123         RenderNodeDrawableCache_.emplace(id, sharedPtr);
124     }
125     return sharedPtr;
126 }
127 
InitRenderParams(const std::shared_ptr<const RSRenderNode> & node,std::shared_ptr<RSRenderNodeDrawableAdapter> & sharedPtr)128 void RSRenderNodeDrawableAdapter::InitRenderParams(const std::shared_ptr<const RSRenderNode>& node,
129                                                    std::shared_ptr<RSRenderNodeDrawableAdapter>& sharedPtr)
130 {
131     auto id = node->GetId();
132     switch (node->GetType()) {
133         case RSRenderNodeType::SURFACE_NODE:
134             sharedPtr->renderParams_ = std::make_unique<RSSurfaceRenderParams>(id);
135             sharedPtr->uifirstRenderParams_ = std::make_unique<RSSurfaceRenderParams>(id);
136             break;
137         case RSRenderNodeType::DISPLAY_NODE:
138             sharedPtr->renderParams_ = std::make_unique<RSDisplayRenderParams>(id);
139             sharedPtr->uifirstRenderParams_ = std::make_unique<RSDisplayRenderParams>(id);
140             break;
141         case RSRenderNodeType::EFFECT_NODE:
142             sharedPtr->renderParams_ = std::make_unique<RSEffectRenderParams>(sharedPtr->nodeId_);
143             sharedPtr->uifirstRenderParams_ = std::make_unique<RSEffectRenderParams>(sharedPtr->nodeId_);
144             break;
145         case RSRenderNodeType::CANVAS_DRAWING_NODE:
146             sharedPtr->renderParams_ = std::make_unique<RSCanvasDrawingRenderParams>(id);
147             sharedPtr->uifirstRenderParams_ = std::make_unique<RSCanvasDrawingRenderParams>(id);
148             break;
149         default:
150             sharedPtr->renderParams_ = std::make_unique<RSRenderParams>(id);
151             sharedPtr->uifirstRenderParams_ = std::make_unique<RSRenderParams>(id);
152             break;
153     }
154     sharedPtr->renderParams_->SetParamsType(RSRenderParamsType::RS_PARAM_OWNED_BY_DRAWABLE);
155     sharedPtr->uifirstRenderParams_->SetParamsType(RSRenderParamsType::RS_PARAM_OWNED_BY_DRAWABLE_UIFIRST);
156 }
157 
OnGenerateShadowDrawable(const std::shared_ptr<const RSRenderNode> & node,const std::shared_ptr<RSRenderNodeDrawableAdapter> & drawable)158 RSRenderNodeDrawableAdapter::SharedPtr RSRenderNodeDrawableAdapter::OnGenerateShadowDrawable(
159     const std::shared_ptr<const RSRenderNode>& node, const std::shared_ptr<RSRenderNodeDrawableAdapter>& drawable)
160 {
161     static std::map<NodeId, RSRenderNodeDrawableAdapter::WeakPtr> shadowDrawableCache;
162     static std::mutex shadowCacheMapMutex;
163     static const auto Destructor = [](RSRenderNodeDrawableAdapter* ptr) {
164         {
165             std::lock_guard<std::mutex> lock(shadowCacheMapMutex);
166             shadowDrawableCache.erase(ptr->nodeId_); // Remove from cache before deleting
167         }
168         RSRenderNodeGC::DrawableDestructor(ptr);
169     };
170 
171     if (node == nullptr) {
172         ROSEN_LOGE("RSRenderNodeDrawableAdapter::OnGenerateShadowDrawable, node null");
173         return nullptr;
174     }
175     auto id = node->GetId();
176     // Try to get a cached drawable if it exists.
177     {
178         std::lock_guard<std::mutex> lock(shadowCacheMapMutex);
179         if (const auto cacheIt = shadowDrawableCache.find(id); cacheIt != shadowDrawableCache.end()) {
180             if (const auto ptr = cacheIt->second.lock()) {
181                 return ptr;
182             } else {
183                 shadowDrawableCache.erase(cacheIt);
184             }
185         }
186     }
187 
188     auto ptr = new RSRenderNodeShadowDrawable(node, drawable);
189     auto sharedPtr = std::shared_ptr<RSRenderNodeDrawableAdapter>(ptr, Destructor);
190     {
191         std::lock_guard<std::mutex> lock(shadowCacheMapMutex);
192         shadowDrawableCache.emplace(id, sharedPtr);
193     }
194     return sharedPtr;
195 }
196 
DrawRangeImpl(Drawing::Canvas & canvas,const Drawing::Rect & rect,int8_t start,int8_t end) const197 void RSRenderNodeDrawableAdapter::DrawRangeImpl(
198     Drawing::Canvas& canvas, const Drawing::Rect& rect, int8_t start, int8_t end) const
199 {
200     if (drawCmdList_.empty() || start < 0 || end < 0 || start > end) {
201         return;
202     }
203 
204     if (static_cast<uint32_t>(end) > drawCmdList_.size()) {
205         ROSEN_LOGE("RSRenderNodeDrawableAdapter::DrawRangeImpl, end is invalid");
206         return;
207     }
208 
209     if (UNLIKELY(skipType_ != SkipType::NONE)) {
210         auto skipIndex_ = GetSkipIndex();
211         if (start <= skipIndex_ && end > skipIndex_) {
212             // skip index is in the range
213             for (auto i = start; i < skipIndex_; i++) {
214                 drawCmdList_[i](&canvas, &rect);
215             }
216             for (auto i = skipIndex_ + 1; i < end; i++) {
217                 drawCmdList_[i](&canvas, &rect);
218             }
219             return;
220         }
221         // skip index is not in the range, fall back to normal drawing
222     }
223 
224     for (auto i = start; i < end; i++) {
225         drawCmdList_[i](&canvas, &rect);
226     }
227 }
228 
DrawImpl(Drawing::Canvas & canvas,const Drawing::Rect & rect,int8_t index) const229 void RSRenderNodeDrawableAdapter::DrawImpl(Drawing::Canvas& canvas, const Drawing::Rect& rect, int8_t index) const
230 {
231     if (drawCmdList_.empty() || index < 0 || static_cast<uint32_t>(index) >= drawCmdList_.size()) {
232         return;
233     }
234 
235     if (UNLIKELY(skipType_ != SkipType::NONE)) {
236         auto skipIndex_ = GetSkipIndex();
237         if (index == skipIndex_) {
238             return;
239         }
240     }
241 
242     drawCmdList_[index](&canvas, &rect);
243 }
244 
DrawBackground(Drawing::Canvas & canvas,const Drawing::Rect & rect) const245 void RSRenderNodeDrawableAdapter::DrawBackground(Drawing::Canvas& canvas, const Drawing::Rect& rect) const
246 {
247     DrawRangeImpl(canvas, rect, 0, drawCmdIndex_.backgroundEndIndex_);
248 }
249 
DrawContent(Drawing::Canvas & canvas,const Drawing::Rect & rect) const250 void RSRenderNodeDrawableAdapter::DrawContent(Drawing::Canvas& canvas, const Drawing::Rect& rect) const
251 {
252     if (drawCmdList_.empty()) {
253         return;
254     }
255 
256     auto index = drawCmdIndex_.contentIndex_;
257     if (index == -1) {
258         return;
259     }
260     drawCmdList_[index](&canvas, &rect);
261 }
262 
DrawChildren(Drawing::Canvas & canvas,const Drawing::Rect & rect) const263 void RSRenderNodeDrawableAdapter::DrawChildren(Drawing::Canvas& canvas, const Drawing::Rect& rect) const
264 {
265     if (drawCmdList_.empty()) {
266         return;
267     }
268 
269     auto index = drawCmdIndex_.childrenIndex_;
270     if (index == -1) {
271         return;
272     }
273     drawCmdList_[index](&canvas, &rect);
274 }
275 
DrawUifirstContentChildren(Drawing::Canvas & canvas,const Drawing::Rect & rect)276 void RSRenderNodeDrawableAdapter::DrawUifirstContentChildren(Drawing::Canvas& canvas, const Drawing::Rect& rect)
277 {
278     RSRenderNodeSingleDrawableLocker singleLocker(this);
279     if (UNLIKELY(!singleLocker.IsLocked())) {
280         singleLocker.DrawableOnDrawMultiAccessEventReport(__func__);
281         RS_LOGE("RSRenderNodeDrawableAdapter::DrawUifirstContentChildren %{public}" PRIu64 " onDraw!!!", GetId());
282         return;
283     }
284 
285     if (uifirstDrawCmdList_.empty()) {
286         return;
287     }
288 
289     const auto& drawCmdList = uifirstDrawCmdList_;
290     auto contentIdx = uifirstDrawCmdIndex_.contentIndex_;
291     auto childrenIdx = uifirstDrawCmdIndex_.childrenIndex_;
292     if (contentIdx != -1) {
293         drawCmdList[contentIdx](&canvas, &rect);
294     }
295     if (childrenIdx != -1) {
296         drawCmdList[childrenIdx](&canvas, &rect);
297     }
298 }
299 
DrawForeground(Drawing::Canvas & canvas,const Drawing::Rect & rect) const300 void RSRenderNodeDrawableAdapter::DrawForeground(Drawing::Canvas& canvas, const Drawing::Rect& rect) const
301 {
302     DrawRangeImpl(canvas, rect, drawCmdIndex_.foregroundBeginIndex_, drawCmdIndex_.endIndex_);
303 }
304 
DrawAll(Drawing::Canvas & canvas,const Drawing::Rect & rect) const305 void RSRenderNodeDrawableAdapter::DrawAll(Drawing::Canvas& canvas, const Drawing::Rect& rect) const
306 {
307     DrawRangeImpl(canvas, rect, 0, drawCmdIndex_.endIndex_);
308 }
309 
310 // can only run in sync mode
DumpDrawableTree(int32_t depth,std::string & out,const RSContext & context) const311 void RSRenderNodeDrawableAdapter::DumpDrawableTree(int32_t depth, std::string& out, const RSContext& context) const
312 {
313     for (int32_t i = 0; i < depth; ++i) {
314         out += "  ";
315     }
316     auto renderNode = (depth == 0 && nodeId_ == INVALID_NODEID) ? context.GetGlobalRootRenderNode()
317                                                 : context.GetNodeMap().GetRenderNode<RSRenderNode>(nodeId_);
318     if (renderNode == nullptr) {
319         out += "[" + std::to_string(nodeId_) + ": nullptr]\n";
320         return;
321     }
322     RSRenderNode::DumpNodeType(nodeType_, out);
323     out += "[" + std::to_string(nodeId_) + "]";
324     renderNode->DumpSubClassNode(out);
325     out += ", DrawableVec:[" + DumpDrawableVec(renderNode) + "]";
326     if (renderParams_ == nullptr) {
327         out += ", StagingParams null";
328     } else {
329         out += ", " + renderParams_->ToString();
330     }
331 
332     if (skipType_ != SkipType::NONE) {
333         out += ", SkipType:" + std::to_string(static_cast<int>(skipType_));
334         out += ", SkipIndex:" + std::to_string(GetSkipIndex());
335     }
336     if (drawSkipType_ != DrawSkipType::NONE) {
337         out += ", DrawSkipType:" + std::to_string(static_cast<int>(drawSkipType_));
338     }
339     out += ", ChildrenIndex:" + std::to_string(drawCmdIndex_.childrenIndex_);
340     out += "\n";
341 
342     auto childrenDrawable = std::static_pointer_cast<RSChildrenDrawable>(
343         renderNode->drawableVec_[static_cast<int32_t>(RSDrawableSlot::CHILDREN)]);
344     if (childrenDrawable) {
345         for (const auto& renderNodeDrawable : childrenDrawable->childrenDrawableVec_) {
346             renderNodeDrawable->DumpDrawableTree(depth + 1, out, context);
347         }
348     }
349 }
350 
351 // can only run in sync mode
DumpDrawableVec(const std::shared_ptr<RSRenderNode> & renderNode) const352 std::string RSRenderNodeDrawableAdapter::DumpDrawableVec(const std::shared_ptr<RSRenderNode>& renderNode) const
353 {
354     if (renderNode == nullptr) {
355         return "";
356     }
357     const auto& drawableVec = renderNode->drawableVec_;
358     std::string str;
359     for (uint8_t i = 0; i < drawableVec.size(); ++i) {
360         if (drawableVec[i]) {
361             str += std::to_string(i) + ", ";
362         }
363     }
364     // str has more than 2 chars
365     if (str.length() > 2) {
366         str.pop_back();
367         str.pop_back();
368     }
369 
370     return str;
371 }
372 
QuickReject(Drawing::Canvas & canvas,const RectF & localDrawRect)373 bool RSRenderNodeDrawableAdapter::QuickReject(Drawing::Canvas& canvas, const RectF& localDrawRect)
374 {
375     auto paintFilterCanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
376     if (paintFilterCanvas->GetIsParallelCanvas() || paintFilterCanvas->IsDirtyRegionStackEmpty()) {
377         return false;
378     }
379 
380     Drawing::Rect dst;
381     canvas.GetTotalMatrix().MapRect(
382         dst, { localDrawRect.GetLeft(), localDrawRect.GetTop(), localDrawRect.GetRight(), localDrawRect.GetBottom() });
383     auto originalCanvas = paintFilterCanvas->GetOriginalCanvas();
384     if (originalCanvas && !paintFilterCanvas->GetOffscreenDataList().empty()) {
385         originalCanvas->GetTotalMatrix().MapRect(dst, dst);
386     }
387     Drawing::Region dstRegion;
388     if (!dstRegion.SetRect(dst.RoundOut()) && !dst.IsEmpty()) {
389         RS_LOGW("invalid dstDrawRect: %{public}s, RoundOut: %{public}s",
390             dst.ToString().c_str(), dst.RoundOut().ToString().c_str());
391         RS_OPTIONAL_TRACE_NAME_FMT("invalid dstDrawRect: %s, RoundOut: %s",
392             dst.ToString().c_str(), dst.RoundOut().ToString().c_str());
393         return false;
394     }
395     return !(paintFilterCanvas->GetCurDirtyRegion().IsIntersects(dstRegion));
396 }
397 
CollectInfoForNodeWithoutFilter(Drawing::Canvas & canvas)398 void RSRenderNodeDrawableAdapter::CollectInfoForNodeWithoutFilter(Drawing::Canvas& canvas)
399 {
400     if (drawCmdList_.empty() || curDrawingCacheRoot_ == nullptr) {
401         return;
402     }
403     curDrawingCacheRoot_->withoutFilterMatrixMap_[GetId()] = canvas.GetTotalMatrix();
404 }
405 
DrawBackgroundWithoutFilterAndEffect(Drawing::Canvas & canvas,const RSRenderParams & params)406 void RSRenderNodeDrawableAdapter::DrawBackgroundWithoutFilterAndEffect(
407     Drawing::Canvas& canvas, const RSRenderParams& params)
408 {
409     if (drawCmdList_.empty()) {
410         return;
411     }
412 
413     auto backgroundIndex = drawCmdIndex_.backgroundEndIndex_;
414     auto bounds = params.GetBounds();
415     auto curCanvas = static_cast<RSPaintFilterCanvas*>(&canvas);
416     for (auto index = 0; index < backgroundIndex; ++index) {
417         if (index == drawCmdIndex_.shadowIndex_) {
418             if (!params.GetShadowRect().IsEmpty()) {
419                 auto shadowRect = params.GetShadowRect();
420                 RS_OPTIONAL_TRACE_NAME_FMT("ClipHoleForBlur shadowRect:[%.2f, %.2f, %.2f, %.2f]", shadowRect.GetLeft(),
421                     shadowRect.GetTop(), shadowRect.GetWidth(), shadowRect.GetHeight());
422                 Drawing::AutoCanvasRestore arc(*curCanvas, true);
423                 auto coreCanvas = curCanvas->GetCanvasData();
424                 auto skiaCanvas = static_cast<Drawing::SkiaCanvas*>(coreCanvas.get());
425                 SkCanvasPriv::ResetClip(skiaCanvas->ExportSkCanvas());
426                 curCanvas->ClipRect(shadowRect);
427                 curCanvas->Clear(Drawing::Color::COLOR_TRANSPARENT);
428                 UpdateFilterInfoForNodeGroup(curCanvas);
429             } else {
430                 drawCmdList_[index](&canvas, &bounds);
431             }
432             continue;
433         }
434         if (index == drawCmdIndex_.useEffectIndex_ || index == drawCmdIndex_.backgroundFilterIndex_) {
435             RS_OPTIONAL_TRACE_NAME_FMT(
436                 "ClipHoleForBlur filterRect:[%.2f, %.2f]", bounds.GetWidth(), bounds.GetHeight());
437             Drawing::AutoCanvasRestore arc(*curCanvas, true);
438             curCanvas->ClipRect(bounds, Drawing::ClipOp::INTERSECT, false);
439             curCanvas->Clear(Drawing::Color::COLOR_TRANSPARENT);
440             UpdateFilterInfoForNodeGroup(curCanvas);
441         } else {
442             drawCmdList_[index](&canvas, &bounds);
443         }
444     }
445 }
446 
UpdateFilterInfoForNodeGroup(RSPaintFilterCanvas * curCanvas)447 void RSRenderNodeDrawableAdapter::UpdateFilterInfoForNodeGroup(RSPaintFilterCanvas* curCanvas)
448 {
449     if (curDrawingCacheRoot_ != nullptr && curCanvas != nullptr) {
450         auto iter = std::find_if(curDrawingCacheRoot_->filterInfoVec_.begin(),
451             curDrawingCacheRoot_->filterInfoVec_.end(),
452             [nodeId = GetId()](const auto& item) -> bool { return item.nodeId_ == nodeId; });
453         if (iter != curDrawingCacheRoot_->filterInfoVec_.end()) {
454             iter->rectVec_.emplace_back(curCanvas->GetDeviceClipBounds());
455         } else {
456             curDrawingCacheRoot_->filterInfoVec_.emplace_back(
457                 FilterNodeInfo(GetId(), curCanvas->GetTotalMatrix(), { curCanvas->GetDeviceClipBounds() }));
458         }
459     }
460 }
461 
CheckShadowRectAndDrawBackground(Drawing::Canvas & canvas,const RSRenderParams & params)462 void RSRenderNodeDrawableAdapter::CheckShadowRectAndDrawBackground(
463     Drawing::Canvas& canvas, const RSRenderParams& params)
464 {
465     // The shadow without shadowRect has drawn in Nodegroup's cache, so we can't draw it again
466     if (!params.GetShadowRect().IsEmpty()) {
467         DrawBackground(canvas, params.GetBounds());
468     } else {
469         DrawRangeImpl(
470             canvas, params.GetBounds(), drawCmdIndex_.foregroundFilterBeginIndex_, drawCmdIndex_.backgroundEndIndex_);
471     }
472 }
473 
DrawBeforeCacheWithForegroundFilter(Drawing::Canvas & canvas,const Drawing::Rect & rect) const474 void RSRenderNodeDrawableAdapter::DrawBeforeCacheWithForegroundFilter(Drawing::Canvas& canvas,
475     const Drawing::Rect& rect) const
476 {
477     DrawRangeImpl(canvas, rect, 0, static_cast<int8_t>(drawCmdIndex_.foregroundFilterBeginIndex_));
478 }
479 
DrawCacheWithForegroundFilter(Drawing::Canvas & canvas,const Drawing::Rect & rect) const480 void RSRenderNodeDrawableAdapter::DrawCacheWithForegroundFilter(Drawing::Canvas& canvas,
481     const Drawing::Rect& rect) const
482 {
483     DrawRangeImpl(canvas, rect, drawCmdIndex_.foregroundFilterBeginIndex_,
484         drawCmdIndex_.foregroundFilterEndIndex_);
485 }
486 
DrawAfterCacheWithForegroundFilter(Drawing::Canvas & canvas,const Drawing::Rect & rect) const487 void RSRenderNodeDrawableAdapter::DrawAfterCacheWithForegroundFilter(Drawing::Canvas& canvas,
488     const Drawing::Rect& rect) const
489 {
490     DrawRangeImpl(canvas, rect, drawCmdIndex_.foregroundFilterEndIndex_,
491         drawCmdIndex_.endIndex_);
492 }
493 
DrawCacheWithProperty(Drawing::Canvas & canvas,const Drawing::Rect & rect) const494 void RSRenderNodeDrawableAdapter::DrawCacheWithProperty(Drawing::Canvas& canvas, const Drawing::Rect& rect) const
495 {
496     DrawRangeImpl(canvas, rect, drawCmdIndex_.renderGroupBeginIndex_,
497         drawCmdIndex_.renderGroupEndIndex_);
498 }
499 
DrawBeforeCacheWithProperty(Drawing::Canvas & canvas,const Drawing::Rect & rect) const500 void RSRenderNodeDrawableAdapter::DrawBeforeCacheWithProperty(Drawing::Canvas& canvas, const Drawing::Rect& rect) const
501 {
502     DrawRangeImpl(canvas, rect, 0, static_cast<int8_t>(drawCmdIndex_.renderGroupBeginIndex_));
503 }
504 
DrawAfterCacheWithProperty(Drawing::Canvas & canvas,const Drawing::Rect & rect) const505 void RSRenderNodeDrawableAdapter::DrawAfterCacheWithProperty(Drawing::Canvas& canvas, const Drawing::Rect& rect) const
506 {
507     DrawRangeImpl(canvas, rect, drawCmdIndex_.renderGroupEndIndex_,
508         drawCmdIndex_.endIndex_);
509 }
510 
HasFilterOrEffect() const511 bool RSRenderNodeDrawableAdapter::HasFilterOrEffect() const
512 {
513     return drawCmdIndex_.shadowIndex_ != -1 || drawCmdIndex_.backgroundFilterIndex_ != -1 ||
514            drawCmdIndex_.useEffectIndex_ != -1;
515 }
516 
ClearResource()517 void RSRenderNodeDrawableAdapter::ClearResource()
518 {
519     RS_TRACE_NAME_FMT("ClearResource count drawable %d, cmdList %d",
520         toClearDrawableVec_.size(), toClearCmdListVec_.size());
521     toClearDrawableVec_.clear();
522     toClearCmdListVec_.clear();
523 }
524 
AddToClearDrawables(DrawableVec & vec)525 void RSRenderNodeDrawableAdapter::AddToClearDrawables(DrawableVec &vec)
526 {
527     for (auto &drawable: vec) {
528         toClearDrawableVec_.push_back(drawable);
529     }
530     vec.clear();
531 }
532 
AddToClearCmdList(CmdListVec & vec)533 void RSRenderNodeDrawableAdapter::AddToClearCmdList(CmdListVec &vec)
534 {
535     for (auto &cmdList: vec) {
536         toClearCmdListVec_.push_back(cmdList);
537     }
538     vec.clear();
539 }
540 
GetCountOfClipHoleForCache(const RSRenderParams & params) const541 int RSRenderNodeDrawableAdapter::GetCountOfClipHoleForCache(const RSRenderParams& params) const
542 {
543     int count = (drawCmdIndex_.shadowIndex_ != -1 && !params.GetShadowRect().IsEmpty()) ? 1 : 0;
544     count += drawCmdIndex_.backgroundFilterIndex_ != -1 ? 1 : 0;
545     count += drawCmdIndex_.useEffectIndex_ != -1 ? 1 : 0;
546     return count;
547 }
548 
GetSkipIndex() const549 int8_t RSRenderNodeDrawableAdapter::GetSkipIndex() const
550 {
551     switch (skipType_) {
552         case SkipType::SKIP_BACKGROUND_COLOR:
553             return drawCmdIndex_.backgroundColorIndex_;
554         case SkipType::SKIP_SHADOW:
555             return drawCmdIndex_.shadowIndex_;
556         case SkipType::NONE:
557         default:
558             return -1;
559     }
560 }
561 
RemoveDrawableFromCache(const NodeId nodeId)562 void RSRenderNodeDrawableAdapter::RemoveDrawableFromCache(const NodeId nodeId)
563 {
564     std::lock_guard<std::mutex> lock(cacheMapMutex_);
565     RenderNodeDrawableCache_.erase(nodeId);
566 }
567 
RegisterClearSurfaceFunc(ClearSurfaceTask task)568 void RSRenderNodeDrawableAdapter::RegisterClearSurfaceFunc(ClearSurfaceTask task)
569 {
570     clearSurfaceTask_ = task;
571 }
572 
ResetClearSurfaceFunc()573 void RSRenderNodeDrawableAdapter::ResetClearSurfaceFunc()
574 {
575     clearSurfaceTask_ = nullptr;
576 }
577 
TryClearSurfaceOnSync()578 void RSRenderNodeDrawableAdapter::TryClearSurfaceOnSync()
579 {
580     if (!clearSurfaceTask_) {
581         return;
582     }
583     clearSurfaceTask_();
584 }
585 
SetSkipCacheLayer(bool hasSkipCacheLayer)586 void RSRenderNodeDrawableAdapter::SetSkipCacheLayer(bool hasSkipCacheLayer)
587 {
588     hasSkipCacheLayer_ = hasSkipCacheLayer;
589 }
590 
IsFilterCacheValidForOcclusion() const591 bool RSRenderNodeDrawableAdapter::IsFilterCacheValidForOcclusion() const
592 {
593     if (!RSSystemProperties::GetBlurEnabled() || !RSSystemProperties::GetFilterCacheEnabled() ||
594         !RSUniRenderJudgement::IsUniRender()) {
595         ROSEN_LOGD("blur is disabled or filter cache is disabled.");
596         return false;
597     }
598 
599     bool val = false;
600     if (backgroundFilterDrawable_) {
601         val = val || backgroundFilterDrawable_->IsFilterCacheValidForOcclusion();
602     }
603     if (compositingFilterDrawable_) {
604         val = val || compositingFilterDrawable_->IsFilterCacheValidForOcclusion();
605     }
606     return val;
607 }
608 
GetFilterCachedRegion() const609 const RectI RSRenderNodeDrawableAdapter::GetFilterCachedRegion() const
610 {
611     RectI rect{0, 0, 0, 0};
612     if (!RSSystemProperties::GetBlurEnabled()) {
613         ROSEN_LOGD("blur is disabled");
614         return rect;
615     }
616 
617     if (compositingFilterDrawable_) {
618         return compositingFilterDrawable_->GetFilterCachedRegion();
619     } else if (backgroundFilterDrawable_) {
620         return backgroundFilterDrawable_->GetFilterCachedRegion();
621     } else {
622         return rect;
623     }
624 }
625 
ApplyForegroundColorIfNeed(Drawing::Canvas & canvas,const Drawing::Rect & rect) const626 void RSRenderNodeDrawableAdapter::ApplyForegroundColorIfNeed(Drawing::Canvas& canvas, const Drawing::Rect& rect) const
627 {
628     if (drawCmdIndex_.envForeGroundColorIndex_ != -1) {
629         drawCmdList_[drawCmdIndex_.envForeGroundColorIndex_](&canvas, &rect);
630     }
631 }
632 
633 // will only called by OnDraw or OnSync
DrawableOnDrawMultiAccessEventReport(const std::string & func) const634 void RSRenderNodeSingleDrawableLocker::DrawableOnDrawMultiAccessEventReport(const std::string& func) const
635 {
636 #ifdef ROSEN_OHOS
637     auto tid = gettid();
638     MultiAccessReportInfo reportInfo;
639     if (drawable_) {
640         reportInfo.drawableNotNull = true;
641         reportInfo.nodeId = drawable_->GetId();
642         reportInfo.nodeType = drawable_->GetNodeType();
643         const auto& params = drawable_->GetRenderParams();
644         if (params) {
645             reportInfo.paramNotNull = true;
646             reportInfo.uifirstRootNodeId = params->GetUifirstRootNodeId();
647             reportInfo.firstLevelNodeId = params->GetFirstLevelNodeId();
648         }
649     }
650 
651     auto task = [tid, func, reportInfo]() {
652         RS_TRACE_NAME_FMT("DrawableOnDrawMultiAccessEventReport HiSysEventWrite nodeId:%" PRIu64, reportInfo.nodeId);
653         std::ostringstream oss;
654         oss << "func:" << func << ",";
655         oss << "drawable:" << reportInfo.drawableNotNull << ",";
656         oss << "param:" << reportInfo.paramNotNull << ",";
657         if (reportInfo.drawableNotNull) {
658             oss << "id:" << reportInfo.nodeId << ",";
659             oss << "type:" << int(reportInfo.nodeType) << ",";
660         }
661         if (reportInfo.paramNotNull) {
662             oss << "URN:" << reportInfo.uifirstRootNodeId << ",";
663             oss << "FLN:" << reportInfo.firstLevelNodeId << ",";
664         }
665         oss << "tid:" << tid;
666         HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::GRAPHIC, "RENDER_DRAWABLE_MULTI_ACCESS",
667             OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "MULTI_ACCESS_MSG", oss.str());
668     };
669     RSBackgroundThread::Instance().PostTask(task);
670 #endif
671 }
672 } // namespace OHOS::Rosen::DrawableV2
673