• 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 
16 #include "purgeable_pixelmap_builder.h"
17 
18 #include "hitrace_meter.h"
19 #include "hilog/log.h"
20 #include "media_errors.h"
21 #include "parameters.h"
22 #include "purgeable_ashmem.h"
23 #include "purgeable_mem_base.h"
24 #include "purgeable_mem_builder.h"
25 #include "purgeable_resource_manager.h"
26 
27 #ifndef _WIN32
28 #include "securec.h"
29 #else
30 #include "memory.h"
31 #endif
32 
33 namespace OHOS {
34 namespace PurgeableBuilder {
35 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001799, "PurgeablePixelMapBuilder" };
36 constexpr int THRESHOLD_HEIGHT = 256;
37 constexpr int THRESHOLD_WIDGHT = 256;
38 const std::string SYSTEM_PARAM_PURGEABLE_ENABLE = "persist.resourceschedule.memmgr.purgeable.enable";
39 const std::string SYSTEM_PARAM_PIXELMAP_THRESHOLD_HEIGHT = "persist.memmgr.purgeable.pixelmap.threshold.height";
40 const std::string SYSTEM_PARAM_PIXELMAP_THRESHOLD_WIDGHT = "persist.memmgr.purgeable.pixelmap.threshold.widght";
41 
PurgeablePixelMapBuilder(uint32_t index,std::unique_ptr<ImageSource> & imageSource,DecodeOptions opts)42 PurgeablePixelMapBuilder::PurgeablePixelMapBuilder(uint32_t index, std::unique_ptr<ImageSource> &imageSource,
43     DecodeOptions opts)
44     : index_(index), opts_(opts), imageSource_(move(imageSource)) {}
45 
Build(void * data,size_t size)46 bool PurgeablePixelMapBuilder::Build(void *data, size_t size)
47 {
48     HiviewDFX::HiLog::Debug(LABEL, "purgeableMem build in.");
49     uint32_t errorCode;
50     if (imageSource_ == nullptr) {
51         return false;
52     }
53 
54     StartTrace(HITRACE_TAG_ZIMAGE, "OHOS::PurgeableBuilder::PixelMapPurgeableMemBuilder::Build");
55     std::unique_ptr<PixelMap> pixelMap = imageSource_->CreatePixelMap(index_, opts_, errorCode);
56     if (pixelMap == nullptr || data == nullptr) {
57         FinishTrace(HITRACE_TAG_ZIMAGE);
58         return false;
59     }
60 
61     StartTrace(HITRACE_TAG_ZIMAGE, ("OHOS::PurgeableBuilder::PixelMapPurgeableMemBuilder::CopyData " +
62                                     std::to_string(size)));
63     if (memcpy_s((char *)data, size, (char *)pixelMap->GetPixels(), size)) {
64         FinishTrace(HITRACE_TAG_ZIMAGE);
65         return false;
66     }
67 
68     DoRebuildSuccessCallback();
69 
70     FinishTrace(HITRACE_TAG_ZIMAGE); // memcpy_s trace
71     FinishTrace(HITRACE_TAG_ZIMAGE); // PixelMapPurgeableMemBuilder::Build trace
72 
73     return true;
74 }
75 
GetSysForPurgeable()76 bool GetSysForPurgeable()
77 {
78     return system::GetBoolParameter(SYSTEM_PARAM_PURGEABLE_ENABLE, false);
79 }
80 
SetBuilderToBePurgeable(PixelMap * pixelMap,std::unique_ptr<PurgeableMem::PurgeableMemBuilder> & builder)81 void SetBuilderToBePurgeable(PixelMap *pixelMap,
82                              std::unique_ptr<PurgeableMem::PurgeableMemBuilder> &builder)
83 {
84     HiviewDFX::HiLog::Debug(LABEL, "set builder for purgeable pixelmap. allocatorType = %{public}d.",
85                             pixelMap->GetAllocatorType());
86     StartTrace(HITRACE_TAG_ZIMAGE, "OHOS::PurgeableBuilder::SetBuilderToBePurgeable");
87     if (pixelMap == nullptr) {
88         FinishTrace(HITRACE_TAG_ZIMAGE);
89         return;
90     }
91 
92     if (builder == nullptr) {
93         FinishTrace(HITRACE_TAG_ZIMAGE);
94         return;
95     }
96 
97     if (pixelMap->GetAllocatorType() == AllocatorType::SHARE_MEM_ALLOC) {
98         std::shared_ptr<OHOS::PurgeableMem::PurgeableAshMem> tmpPtr =
99             std::make_shared<OHOS::PurgeableMem::PurgeableAshMem>(std::move(builder));
100         bool isChanged = tmpPtr->ChangeAshmemData(pixelMap->GetCapacity(),
101             *(static_cast<int *>(pixelMap->GetFd())), pixelMap->GetWritablePixels());
102         if (isChanged) {
103             pixelMap->SetPurgeableMemPtr(tmpPtr);
104             pixelMap->GetPurgeableMemPtr()->BeginReadWithDataLock();
105         } else {
106             HiviewDFX::HiLog::Error(LABEL, "ChangeAshmemData fail.");
107         }
108     }
109 
110     FinishTrace(HITRACE_TAG_ZIMAGE);
111 }
112 
RemoveFromPurgeableResourceMgr(PixelMap * pixelMap)113 void RemoveFromPurgeableResourceMgr(PixelMap *pixelMap)
114 {
115     StartTrace(HITRACE_TAG_ZIMAGE, "OHOS::PurgeableBuilder::RemoveFromPurgeableResourceMgr");
116     HiviewDFX::HiLog::Debug(LABEL, "remove pixelmap from PurgeableResourceMgr.");
117 
118     if (pixelMap == nullptr) {
119         FinishTrace(HITRACE_TAG_ZIMAGE);
120         return;
121     }
122 
123     if (pixelMap->IsPurgeable()) {
124         PurgeableMem::PurgeableResourceManager::GetInstance().RemoveResource(pixelMap->GetPurgeableMemPtr());
125     }
126 
127     FinishTrace(HITRACE_TAG_ZIMAGE);
128 }
129 
AddToPurgeableResourceMgr(PixelMap * pixelMap)130 void AddToPurgeableResourceMgr(PixelMap *pixelMap)
131 {
132     StartTrace(HITRACE_TAG_ZIMAGE, "OHOS::PurgeableBuilder::AddToPurgeableResourceMgr");
133     HiviewDFX::HiLog::Debug(LABEL, "add pixelmap purgeablemem ptr to PurgeableResourceMgr");
134 
135     if (pixelMap == nullptr) {
136         FinishTrace(HITRACE_TAG_ZIMAGE);
137         return;
138     }
139 
140     if (pixelMap->IsPurgeable()) {
141         PurgeableMem::PurgeableResourceManager::GetInstance().AddResource(pixelMap->GetPurgeableMemPtr());
142     }
143 
144     FinishTrace(HITRACE_TAG_ZIMAGE);
145 }
146 
IfCanBePurgeable(DecodeOptions & decodeOpts)147 bool IfCanBePurgeable(DecodeOptions &decodeOpts)
148 {
149     int thresholdHeight = system::GetIntParameter(SYSTEM_PARAM_PIXELMAP_THRESHOLD_HEIGHT, THRESHOLD_HEIGHT);
150     int thresholdWidght = system::GetIntParameter(SYSTEM_PARAM_PIXELMAP_THRESHOLD_WIDGHT, THRESHOLD_WIDGHT);
151     Size size = decodeOpts.desiredSize;
152 
153     if (size.height > thresholdHeight || size.width > thresholdWidght) {
154         return false;
155     }
156     return true;
157 }
158 
MakePixelMapToBePurgeable(std::unique_ptr<PixelMap> & pixelMap,std::unique_ptr<ImageSource> & backupImgSrc4Rebuild,DecodeOptions & decodeOpts)159 bool MakePixelMapToBePurgeable(std::unique_ptr<PixelMap> &pixelMap, std::unique_ptr<ImageSource> &backupImgSrc4Rebuild,
160     DecodeOptions &decodeOpts)
161 {
162     return MakePixelMapToBePurgeableBySrc(pixelMap.get(), backupImgSrc4Rebuild, decodeOpts);
163 }
164 
MakePixelMapToBePurgeable(std::unique_ptr<PixelMap> & pixelMap,const int fd,const SourceOptions & opts,DecodeOptions & decodeOpts)165 bool MakePixelMapToBePurgeable(std::unique_ptr<PixelMap> &pixelMap, const int fd,
166     const SourceOptions &opts, DecodeOptions &decodeOpts)
167 {
168     return MakePixelMapToBePurgeableByFd(pixelMap.get(), fd, opts, decodeOpts);
169 }
170 
MakePixelMapToBePurgeableByFd(PixelMap * pixelMap,const int fd,const SourceOptions & opts,DecodeOptions & decodeOpts)171 bool MakePixelMapToBePurgeableByFd(PixelMap *pixelMap, const int fd, const SourceOptions &opts,
172     DecodeOptions &decodeOpts)
173 {
174     uint32_t errorCode = 0;
175     std::unique_ptr<ImageSource> backupImgSrc = ImageSource::CreateImageSource(fd, opts, errorCode);
176     if (errorCode != Media::SUCCESS) {
177         return false;
178     }
179     return MakePixelMapToBePurgeableBySrc(pixelMap, backupImgSrc, decodeOpts);
180 }
181 
MakePixelMapToBePurgeableBySrc(PixelMap * pixelMap,std::unique_ptr<ImageSource> & backupImgSrc4Rebuild,DecodeOptions & decodeOpts)182 bool MakePixelMapToBePurgeableBySrc(PixelMap *pixelMap,
183     std::unique_ptr<ImageSource> &backupImgSrc4Rebuild, DecodeOptions &decodeOpts)
184 {
185     StartTrace(HITRACE_TAG_ZIMAGE, "OHOS::PurgeableBuilder::MakePixelMapToBePurgeable");
186     HiviewDFX::HiLog::Debug(LABEL, "MakePixelMapToBePurgeable in.");
187 
188     if (!GetSysForPurgeable()) {
189         FinishTrace(HITRACE_TAG_ZIMAGE);
190         return false;
191     }
192 
193     if (!IfCanBePurgeable(decodeOpts)) {
194         FinishTrace(HITRACE_TAG_ZIMAGE);
195         return false;
196     }
197 
198     if (pixelMap == nullptr || backupImgSrc4Rebuild == nullptr) {
199         HiviewDFX::HiLog::Error(LABEL, "PixelMap or backupImgSrc4Rebuild is null.");
200         FinishTrace(HITRACE_TAG_ZIMAGE);
201         return false;
202     }
203 
204     if (pixelMap->IsPurgeable()) {
205         HiviewDFX::HiLog::Error(LABEL, "PixelMap is already purgeable.");
206         FinishTrace(HITRACE_TAG_ZIMAGE);
207         return false;
208     }
209 
210     std::unique_ptr<PurgeableMem::PurgeableMemBuilder> purgeableMemBuilder =
211         std::make_unique<PurgeablePixelMapBuilder>(0, backupImgSrc4Rebuild, decodeOpts);
212     SetBuilderToBePurgeable(pixelMap, purgeableMemBuilder);
213 
214     if (pixelMap->IsPurgeable()) {
215         AddToPurgeableResourceMgr(pixelMap);
216     }
217 
218     FinishTrace(HITRACE_TAG_ZIMAGE);
219     return true;
220 }
221 } // namespace PurgeableBuilder
222 } // namespace OHOS