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