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