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
ReleaseResource()99 void SKResourceManager::ReleaseResource()
100 {
101 #ifdef ROSEN_OHOS
102 RS_TRACE_FUNC();
103 std::scoped_lock<std::recursive_mutex> lock(mutex_);
104 for (auto& images : images_) {
105 if (images.second->HaveReleaseableResourceCheck()) {
106 RSTaskDispatcher::GetInstance().PostTask(images.first, [this]() {
107 auto tid = gettid();
108 std::scoped_lock<std::recursive_mutex> lock(mutex_);
109 images_[tid]->ReleaseResource();
110 });
111 }
112 }
113
114 for (auto& skSurface : skSurfaces_) {
115 if (HaveReleaseableResourceCheck(skSurface.second)) {
116 RSTaskDispatcher::GetInstance().PostTask(skSurface.first, [this]() {
117 auto tid = gettid();
118 std::scoped_lock<std::recursive_mutex> lock(mutex_);
119 size_t size = skSurfaces_[tid].size();
120 while (size-- > 0) {
121 auto surface = skSurfaces_[tid].front();
122 skSurfaces_[tid].pop_front();
123 if (surface == nullptr) {
124 continue;
125 }
126 if (surface.unique()) {
127 surface = nullptr;
128 } else {
129 skSurfaces_[tid].push_back(surface);
130 }
131 }
132 });
133 }
134 }
135 #endif
136 }
137 } // OHOS::Rosen