• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "pipeline/sk_resource_manager.h"
16 
17 #include "rs_trace.h"
18 #include "platform/common/rs_log.h"
19 #include "pipeline/rs_task_dispatcher.h"
20 
21 namespace OHOS::Rosen {
22 #ifdef ROSEN_OHOS
23 constexpr uint32_t MAX_CHECK_SIZE = 20; // empirical value
24 #endif
Instance()25 SKResourceManager& SKResourceManager::Instance()
26 {
27     static SKResourceManager instance;
28     return instance;
29 }
30 
HoldResource(const std::shared_ptr<Drawing::Image> & img)31 void SKResourceManager::HoldResource(const std::shared_ptr<Drawing::Image> &img)
32 {
33 #ifdef ROSEN_OHOS
34     auto tid = gettid();
35     if (!RSTaskDispatcher::GetInstance().HasRegisteredTask(tid)) {
36         return;
37     }
38     std::scoped_lock<std::recursive_mutex> lock(mutex_);
39     if (images_.find(tid) != images_.end()) {
40         images_[tid]->HoldResource(img);
41     } else {
42         std::shared_ptr<Drawing::ResourceHolder> holder = std::make_shared<Drawing::ResourceHolder>();
43         holder->HoldResource(img);
44         images_.emplace(tid, holder);
45     }
46 #endif
47 }
48 
HoldResource(std::shared_ptr<Drawing::Surface> surface)49 void SKResourceManager::HoldResource(std::shared_ptr<Drawing::Surface> surface)
50 {
51 #ifdef ROSEN_OHOS
52     auto tid = gettid();
53     if (!RSTaskDispatcher::GetInstance().HasRegisteredTask(tid)) {
54         return;
55     }
56     std::scoped_lock<std::recursive_mutex> lock(mutex_);
57     if (std::any_of(skSurfaces_[tid].cbegin(), skSurfaces_[tid].cend(),
58         [&surface](const std::shared_ptr<Drawing::Surface>& skSurface) {return skSurface.get() == surface.get(); })) {
59         return;
60     }
61     skSurfaces_[tid].push_back(surface);
62 #endif
63 }
64 
65 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
DeleteSharedTextureContext(void * context)66 void SKResourceManager::DeleteSharedTextureContext(void* context)
67 {
68     SharedTextureContext* cleanupHelper = static_cast<SharedTextureContext*>(context);
69     if (cleanupHelper != nullptr) {
70         delete cleanupHelper;
71         cleanupHelper = nullptr;
72     }
73 }
74 #endif
75 
HaveReleaseableResourceCheck(const std::list<std::shared_ptr<Drawing::Surface>> & list)76 bool SKResourceManager::HaveReleaseableResourceCheck(const std::list<std::shared_ptr<Drawing::Surface>> &list)
77 {
78 #ifdef ROSEN_OHOS
79     if (list.empty()) {
80         return false;
81     }
82     if (list.size() > MAX_CHECK_SIZE) {
83         /* to avoid this function taking too long, return true directly,
84          * which means resources may need to be released
85          */
86         return true;
87     }
88     for (auto& surface : list) {
89         if (surface.unique()) {
90             return true;
91         }
92     }
93     return false;
94 #else
95     return false;
96 #endif
97 }
98 
99 
ReleaseResource()100 void SKResourceManager::ReleaseResource()
101 {
102 #ifdef ROSEN_OHOS
103     RS_TRACE_FUNC();
104     std::scoped_lock<std::recursive_mutex> lock(mutex_);
105     for (auto& images : images_) {
106         if (images.second->HaveReleaseableResourceCheck()) {
107             RSTaskDispatcher::GetInstance().PostTask(images.first, [this]() {
108                 auto tid = gettid();
109                 std::scoped_lock<std::recursive_mutex> lock(mutex_);
110                 images_[tid]->ReleaseResource();
111             });
112         }
113     }
114 
115     for (auto& skSurface : skSurfaces_) {
116         if (HaveReleaseableResourceCheck(skSurface.second)) {
117             RSTaskDispatcher::GetInstance().PostTask(skSurface.first, [this]() {
118                 auto tid = gettid();
119                 std::scoped_lock<std::recursive_mutex> lock(mutex_);
120                 size_t size = skSurfaces_[tid].size();
121                 while (size-- > 0) {
122 #ifdef RS_ENABLE_PREFETCH
123                     size_t prefetchStep = 2;
124                     if (size > prefetchStep) {
125                         __builtin_prefetch(&*(++(++skSurfaces_[tid].begin())), 0, 1);
126                     }
127 #endif
128                     auto surface = skSurfaces_[tid].front();
129                     skSurfaces_[tid].pop_front();
130                     if (surface == nullptr) {
131                         continue;
132                     }
133                     if (surface.unique()) {
134                         surface = nullptr;
135                     } else {
136                         skSurfaces_[tid].push_back(surface);
137                     }
138                 }
139             });
140         }
141     }
142 #endif
143 }
144 } // OHOS::Rosen