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