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