1 /*
2 * Copyright (c) 2022 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 "render/rs_image_cache.h"
17 #include "pixel_map.h"
18
19 namespace OHOS {
20 namespace Rosen {
21 // modify the RSImageCache instance as global to extend life cycle, fix destructor crash
22 static RSImageCache gRSImageCacheInstance;
23
Instance()24 RSImageCache& RSImageCache::Instance()
25 {
26 return gRSImageCacheInstance;
27 }
28
29 #ifndef USE_ROSEN_DRAWING
CacheSkiaImage(uint64_t uniqueId,sk_sp<SkImage> img)30 void RSImageCache::CacheSkiaImage(uint64_t uniqueId, sk_sp<SkImage> img)
31 {
32 if (img && uniqueId > 0) {
33 std::lock_guard<std::mutex> lock(mutex_);
34 skiaImageCache_.emplace(uniqueId, std::make_pair(img, 0));
35 }
36 }
37 #else
CacheDrawingImage(uint64_t uniqueId,std::shared_ptr<Drawing::Image> img)38 void RSImageCache::CacheDrawingImage(uint64_t uniqueId, std::shared_ptr<Drawing::Image> img)
39 {
40 if (img && uniqueId > 0) {
41 std::lock_guard<std::mutex> lock(mutex_);
42 drawingImageCache_.emplace(uniqueId, std::make_pair(img, 0));
43 }
44 }
45 #endif
46
47 #ifndef USE_ROSEN_DRAWING
GetSkiaImageCache(uint64_t uniqueId) const48 sk_sp<SkImage> RSImageCache::GetSkiaImageCache(uint64_t uniqueId) const
49 {
50 std::lock_guard<std::mutex> lock(mutex_);
51 auto it = skiaImageCache_.find(uniqueId);
52 if (it != skiaImageCache_.end()) {
53 return it->second.first;
54 }
55 return nullptr;
56 }
57 #else
GetDrawingImageCache(uint64_t uniqueId) const58 std::shared_ptr<Drawing::Image> RSImageCache::GetDrawingImageCache(uint64_t uniqueId) const
59 {
60 std::lock_guard<std::mutex> lock(mutex_);
61 auto it = drawingImageCache_.find(uniqueId);
62 if (it != drawingImageCache_.end()) {
63 return it->second.first;
64 }
65 return nullptr;
66 }
67 #endif
68
69 #ifndef USE_ROSEN_DRAWING
IncreaseSkiaImageCacheRefCount(uint64_t uniqueId)70 void RSImageCache::IncreaseSkiaImageCacheRefCount(uint64_t uniqueId)
71 {
72 std::lock_guard<std::mutex> lock(mutex_);
73 auto it = skiaImageCache_.find(uniqueId);
74 if (it != skiaImageCache_.end()) {
75 it->second.second++;
76 }
77 }
78 #else
IncreaseDrawingImageCacheRefCount(uint64_t uniqueId)79 void RSImageCache::IncreaseDrawingImageCacheRefCount(uint64_t uniqueId)
80 {
81 std::lock_guard<std::mutex> lock(mutex_);
82 auto it = drawingImageCache_.find(uniqueId);
83 if (it != drawingImageCache_.end()) {
84 it->second.second++;
85 }
86 }
87 #endif
88
89 #ifndef USE_ROSEN_DRAWING
ReleaseSkiaImageCache(uint64_t uniqueId)90 void RSImageCache::ReleaseSkiaImageCache(uint64_t uniqueId)
91 {
92 // release the skImage if no RSImage holds it
93 std::lock_guard<std::mutex> lock(mutex_);
94 auto it = skiaImageCache_.find(uniqueId);
95 if (it != skiaImageCache_.end()) {
96 it->second.second--;
97 if (it->second.first == nullptr || it->second.second == 0) {
98 skiaImageCache_.erase(it);
99 }
100 }
101 }
102 #else
ReleaseDrawingImageCache(uint64_t uniqueId)103 void RSImageCache::ReleaseDrawingImageCache(uint64_t uniqueId)
104 {
105 // release the Drawing::Image if no RSImage holds it
106 std::lock_guard<std::mutex> lock(mutex_);
107 auto it = drawingImageCache_.find(uniqueId);
108 if (it != drawingImageCache_.end()) {
109 it->second.second--;
110 if (it->second.first == nullptr || it->second.second == 0) {
111 drawingImageCache_.erase(it);
112 }
113 }
114 }
115 #endif
116
CachePixelMap(uint64_t uniqueId,std::shared_ptr<Media::PixelMap> pixelMap)117 void RSImageCache::CachePixelMap(uint64_t uniqueId, std::shared_ptr<Media::PixelMap> pixelMap)
118 {
119 if (pixelMap && uniqueId > 0) {
120 std::lock_guard<std::mutex> lock(mutex_);
121 pixelMapCache_.emplace(uniqueId, std::make_pair(pixelMap, 0));
122 }
123 }
124
GetPixelMapCache(uint64_t uniqueId) const125 std::shared_ptr<Media::PixelMap> RSImageCache::GetPixelMapCache(uint64_t uniqueId) const
126 {
127 std::lock_guard<std::mutex> lock(mutex_);
128 auto it = pixelMapCache_.find(uniqueId);
129 if (it != pixelMapCache_.end()) {
130 return it->second.first;
131 }
132 return nullptr;
133 }
134
IncreasePixelMapCacheRefCount(uint64_t uniqueId)135 void RSImageCache::IncreasePixelMapCacheRefCount(uint64_t uniqueId)
136 {
137 std::lock_guard<std::mutex> lock(mutex_);
138 auto it = pixelMapCache_.find(uniqueId);
139 if (it != pixelMapCache_.end()) {
140 it->second.second++;
141 }
142 }
143
ReleasePixelMapCache(uint64_t uniqueId)144 void RSImageCache::ReleasePixelMapCache(uint64_t uniqueId)
145 {
146 std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
147 {
148 // release the pixelMap if no RSImage holds it
149 std::lock_guard<std::mutex> lock(mutex_);
150 auto it = pixelMapCache_.find(uniqueId);
151 if (it != pixelMapCache_.end()) {
152 it->second.second--;
153 if (it->second.first == nullptr || it->second.second == 0) {
154 pixelMap = it->second.first;
155 pixelMapCache_.erase(it);
156 #ifndef USE_ROSEN_DRAWING
157 ReleaseSkiaImageCacheByPixelMapId(uniqueId);
158 #else
159 ReleaseDrawingImageCacheByPixelMapId(uniqueId);
160 #endif
161 }
162 }
163 #ifndef USE_ROSEN_DRAWING
164 ReleaseSkiaImageCacheByPixelMapId(uniqueId);
165 #else
166 ReleaseDrawingImageCacheByPixelMapId(uniqueId);
167 #endif
168 }
169 }
170
171 #ifndef USE_ROSEN_DRAWING
CacheRenderSkiaImageByPixelMapId(uint64_t uniqueId,sk_sp<SkImage> img,pid_t tid)172 void RSImageCache::CacheRenderSkiaImageByPixelMapId(uint64_t uniqueId, sk_sp<SkImage> img, pid_t tid)
173 {
174 if (uniqueId > 0 && img) {
175 std::lock_guard<std::mutex> lock(mapMutex_);
176 pixelMapIdRelatedSkiaImageCache_[uniqueId][tid] = img;
177 }
178 }
179 #else
CacheRenderDrawingImageByPixelMapId(uint64_t uniqueId,std::shared_ptr<Drawing::Image> img,pid_t tid)180 void RSImageCache::CacheRenderDrawingImageByPixelMapId(uint64_t uniqueId,
181 std::shared_ptr<Drawing::Image> img, pid_t tid)
182 {
183 if (uniqueId > 0 && img) {
184 std::lock_guard<std::mutex> lock(mapMutex_);
185 pixelMapIdRelatedDrawingImageCache_[uniqueId][tid] = img;
186 }
187 }
188 #endif
189
190 #ifndef USE_ROSEN_DRAWING
GetRenderSkiaImageCacheByPixelMapId(uint64_t uniqueId,pid_t tid) const191 sk_sp<SkImage> RSImageCache::GetRenderSkiaImageCacheByPixelMapId(uint64_t uniqueId, pid_t tid) const
192 {
193 std::lock_guard<std::mutex> lock(mapMutex_);
194 auto it = pixelMapIdRelatedSkiaImageCache_.find(uniqueId);
195 if (it != pixelMapIdRelatedSkiaImageCache_.end()) {
196 auto innerIt = it->second.find(tid);
197 if (innerIt != it->second.end()) {
198 return innerIt->second;
199 }
200 }
201 return nullptr;
202 }
203 #else
GetRenderDrawingImageCacheByPixelMapId(uint64_t uniqueId,pid_t tid) const204 std::shared_ptr<Drawing::Image> RSImageCache::GetRenderDrawingImageCacheByPixelMapId(uint64_t uniqueId, pid_t tid) const
205 {
206 std::lock_guard<std::mutex> lock(mapMutex_);
207 auto it = pixelMapIdRelatedDrawingImageCache_.find(uniqueId);
208 if (it != pixelMapIdRelatedDrawingImageCache_.end()) {
209 auto innerIt = it->second.find(tid);
210 if (innerIt != it->second.end()) {
211 return innerIt->second;
212 }
213 }
214 return nullptr;
215 }
216 #endif
217
218 #ifndef USE_ROSEN_DRAWING
ReleaseSkiaImageCacheByPixelMapId(uint64_t uniqueId)219 void RSImageCache::ReleaseSkiaImageCacheByPixelMapId(uint64_t uniqueId)
220 {
221 std::lock_guard<std::mutex> lock(mapMutex_);
222 auto it = pixelMapIdRelatedSkiaImageCache_.find(uniqueId);
223 if (it != pixelMapIdRelatedSkiaImageCache_.end()) {
224 pixelMapIdRelatedSkiaImageCache_.erase(it);
225 }
226 }
227 #else
ReleaseDrawingImageCacheByPixelMapId(uint64_t uniqueId)228 void RSImageCache::ReleaseDrawingImageCacheByPixelMapId(uint64_t uniqueId)
229 {
230 std::lock_guard<std::mutex> lock(mapMutex_);
231 auto it = pixelMapIdRelatedDrawingImageCache_.find(uniqueId);
232 if (it != pixelMapIdRelatedDrawingImageCache_.end()) {
233 pixelMapIdRelatedDrawingImageCache_.erase(it);
234 }
235 }
236 #endif
237 } // namespace Rosen
238 } // namespace OHOS
239