• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "buffer_manager.h"
17 
18 #include <cerrno>
19 #include <mutex>
20 #include <sys/mman.h>
21 
22 #include "buffer_log.h"
23 
24 #define CHECK_INIT() \
25     do { \
26         if (displayGralloc_ == nullptr) { \
27             GSError ret = Init(); \
28             if (ret != GSERROR_OK) { \
29                 return ret; \
30             } \
31         } \
32     } while (0)
33 
34 #define CHECK_BUFFER(buffer) \
35     do { \
36         if ((buffer) == nullptr) { \
37             return GSERROR_INVALID_ARGUMENTS; \
38         } \
39     } while (0)
40 
41 namespace OHOS {
42 namespace {
GenerateError(GSError err,DispErrCode code)43 GSError GenerateError(GSError err, DispErrCode code)
44 {
45     switch (code) {
46         case DISPLAY_SUCCESS: return static_cast<GSError>(err + 0);
47         case DISPLAY_FAILURE: return static_cast<GSError>(err + LOWERROR_FAILURE);
48         case DISPLAY_FD_ERR: return static_cast<GSError>(err + EBADF);
49         case DISPLAY_PARAM_ERR: return static_cast<GSError>(err + EINVAL);
50         case DISPLAY_NULL_PTR: return static_cast<GSError>(err + EINVAL);
51         case DISPLAY_NOT_SUPPORT: return static_cast<GSError>(err + EOPNOTSUPP);
52         case DISPLAY_NOMEM: return static_cast<GSError>(err + ENOMEM);
53         case DISPLAY_SYS_BUSY: return static_cast<GSError>(err + EBUSY);
54         case DISPLAY_NOT_PERM: return static_cast<GSError>(err + EPERM);
55         default: break;
56     }
57     return static_cast<GSError>(err + LOWERROR_INVALID);
58 }
59 
GenerateError(GSError err,int32_t code)60 inline GSError GenerateError(GSError err, int32_t code)
61 {
62     return GenerateError(err, static_cast<DispErrCode>(code));
63 }
64 } // namespace
65 
GetInstance()66 sptr<BufferManager> BufferManager::GetInstance()
67 {
68     static std::mutex mutex;
69     std::lock_guard<std::mutex> lock(mutex);
70     if (instance == nullptr) {
71         instance = new BufferManager();
72     }
73     return instance;
74 }
75 
Init()76 GSError BufferManager::Init()
77 {
78     if (displayGralloc_ != nullptr) {
79         BLOGD("BufferManager has been initialized successfully.");
80         return GSERROR_OK;
81     }
82 
83     displayGralloc_.reset(::OHOS::HDI::Display::V1_0::IDisplayGralloc::Get());
84     if (displayGralloc_ == nullptr) {
85         BLOGE("IDisplayGralloc::Get return nullptr.");
86         return GSERROR_INTERNAL;
87     }
88     return GSERROR_OK;
89 }
90 
Alloc(const BufferRequestConfig & config,sptr<SurfaceBuffer> & buffer)91 GSError BufferManager::Alloc(const BufferRequestConfig &config, sptr<SurfaceBuffer> &buffer)
92 {
93     CHECK_INIT();
94     CHECK_BUFFER(buffer);
95 
96     BufferHandle *handle = nullptr;
97     int32_t allocWidth = config.width;
98     int32_t allocHeight = config.height;
99     AllocInfo info = {allocWidth, allocHeight, config.usage, (PixelFormat)config.format};
100     auto dret = displayGralloc_->AllocMem(info, handle);
101     if (dret == DISPLAY_SUCCESS) {
102         buffer->SetBufferHandle(handle);
103         buffer->SetSurfaceBufferWidth(allocWidth);
104         buffer->SetSurfaceBufferHeight(allocHeight);
105         buffer->SetSurfaceBufferColorGamut(config.colorGamut);
106         buffer->SetSurfaceBufferTransform(config.transform);
107         BLOGI("buffer handle %{public}p w: %{public}d h: %{public}d t: %{public}d", handle,
108             allocWidth, allocHeight, config.transform);
109         return GSERROR_OK;
110     }
111     BLOGW("Failed with %{public}d", dret);
112 
113     return GenerateError(GSERROR_API_FAILED, dret);
114 }
115 
Map(sptr<SurfaceBuffer> & buffer)116 GSError BufferManager::Map(sptr<SurfaceBuffer> &buffer)
117 {
118     CHECK_INIT();
119     CHECK_BUFFER(buffer);
120 
121     BufferHandle *handle = buffer->GetBufferHandle();
122     if (handle == nullptr) {
123         return GSERROR_INVALID_ARGUMENTS;
124     }
125 
126     void *virAddr = displayGralloc_->Mmap(*handle);
127     if (virAddr == nullptr || virAddr == MAP_FAILED) {
128         return GSERROR_API_FAILED;
129     }
130     return GSERROR_OK;
131 }
132 
Unmap(sptr<SurfaceBuffer> & buffer)133 GSError BufferManager::Unmap(sptr<SurfaceBuffer> &buffer)
134 {
135     CHECK_INIT();
136     CHECK_BUFFER(buffer);
137 
138     if (buffer->GetVirAddr() == nullptr) {
139         return GSERROR_OK;
140     }
141 
142     BufferHandle *handle = buffer->GetBufferHandle();
143     if (handle == nullptr) {
144         return GSERROR_INVALID_ARGUMENTS;
145     }
146 
147     auto dret = displayGralloc_->Unmap(*handle);
148     if (dret == DISPLAY_SUCCESS) {
149         handle->virAddr = nullptr;
150         return GSERROR_OK;
151     }
152     BLOGW("Failed with %{public}d", dret);
153     return GenerateError(GSERROR_API_FAILED, dret);
154 }
155 
Unmap(BufferHandle * bufferHandle)156 GSError BufferManager::Unmap(BufferHandle *bufferHandle)
157 {
158     CHECK_INIT();
159     if (bufferHandle == nullptr) {
160         return GSERROR_OK;
161     }
162     if (bufferHandle->virAddr == nullptr) {
163         return GSERROR_OK;
164     }
165     auto dret = displayGralloc_->Unmap(*bufferHandle);
166     if (dret == DISPLAY_SUCCESS) {
167         bufferHandle->virAddr = nullptr;
168         return GSERROR_OK;
169     }
170     BLOGW("Failed with %{public}d", dret);
171     return GenerateError(GSERROR_API_FAILED, dret);
172 }
173 
FlushCache(sptr<SurfaceBuffer> & buffer)174 GSError BufferManager::FlushCache(sptr<SurfaceBuffer> &buffer)
175 {
176     CHECK_INIT();
177     CHECK_BUFFER(buffer);
178 
179     BufferHandle *handle = buffer->GetBufferHandle();
180     if (handle == nullptr) {
181         return GSERROR_INVALID_ARGUMENTS;
182     }
183 
184     auto dret = displayGralloc_->FlushCache(*handle);
185     if (dret == DISPLAY_SUCCESS) {
186         return GSERROR_OK;
187     }
188     BLOGW("Failed with %{public}d", dret);
189     return GenerateError(GSERROR_API_FAILED, dret);
190 }
191 
InvalidateCache(sptr<SurfaceBuffer> & buffer)192 GSError BufferManager::InvalidateCache(sptr<SurfaceBuffer> &buffer)
193 {
194     CHECK_INIT();
195     CHECK_BUFFER(buffer);
196 
197     BufferHandle *handle = buffer->GetBufferHandle();
198     if (handle == nullptr) {
199         return GSERROR_INVALID_ARGUMENTS;
200     }
201 
202     auto dret = displayGralloc_->InvalidateCache(*handle);
203     if (dret == DISPLAY_SUCCESS) {
204         return GSERROR_OK;
205     }
206     BLOGW("Failed with %{public}d", dret);
207     return GenerateError(GSERROR_API_FAILED, dret);
208 }
209 
Free(sptr<SurfaceBuffer> & buffer)210 GSError BufferManager::Free(sptr<SurfaceBuffer> &buffer)
211 {
212     CHECK_INIT();
213     CHECK_BUFFER(buffer);
214 
215     BufferHandle *handle = buffer->GetBufferHandle();
216     buffer->SetBufferHandle(nullptr);
217     if (handle == nullptr) {
218         return GSERROR_INVALID_ARGUMENTS;
219     }
220 
221     displayGralloc_->FreeMem(*handle);
222     return GSERROR_OK;
223 }
224 
IsSupportedAlloc(const std::vector<BufferVerifyAllocInfo> & infos,std::vector<bool> & supporteds)225 GSError BufferManager::IsSupportedAlloc(const std::vector<BufferVerifyAllocInfo> &infos,
226                                         std::vector<bool> &supporteds)
227 {
228     CHECK_INIT();
229     // mock data
230     supporteds.clear();
231     for (uint32_t index = 0; index < infos.size(); index++) {
232         if (infos[index].format == GRAPHIC_PIXEL_FMT_RGBA_8888 ||
233             infos[index].format == GRAPHIC_PIXEL_FMT_YCRCB_420_SP) {
234             supporteds.push_back(true);
235         } else {
236             supporteds.push_back(false);
237         }
238     }
239     return GSERROR_OK;
240 }
241 } // namespace OHOS
242