1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "GraphicBufferMapper"
18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19 //#define LOG_NDEBUG 0
20 
21 #include <ui/GraphicBufferMapper.h>
22 
23 #include <grallocusage/GrallocUsageConversion.h>
24 
25 // We would eliminate the non-conforming zero-length array, but we can't since
26 // this is effectively included from the Linux kernel
27 #pragma clang diagnostic push
28 #pragma clang diagnostic ignored "-Wzero-length-array"
29 #include <sync/sync.h>
30 #pragma clang diagnostic pop
31 
32 #include <utils/Log.h>
33 #include <utils/Trace.h>
34 
35 #include <ui/Gralloc.h>
36 #include <ui/Gralloc2.h>
37 #include <ui/Gralloc3.h>
38 #include <ui/Gralloc4.h>
39 #include <ui/Gralloc5.h>
40 #include <ui/GraphicBuffer.h>
41 
42 #include <system/graphics.h>
43 
44 using unique_fd = ::android::base::unique_fd;
45 
46 namespace android {
47 // ---------------------------------------------------------------------------
48 
49 using LockResult = GraphicBufferMapper::LockResult;
50 
ANDROID_SINGLETON_STATIC_INSTANCE(GraphicBufferMapper)51 ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
52 
53 void GraphicBufferMapper::preloadHal() {
54     Gralloc2Mapper::preload();
55     Gralloc3Mapper::preload();
56     Gralloc4Mapper::preload();
57     Gralloc5Mapper::preload();
58 }
59 
GraphicBufferMapper()60 GraphicBufferMapper::GraphicBufferMapper() {
61     mMapper = std::make_unique<const Gralloc5Mapper>();
62     if (mMapper->isLoaded()) {
63         mMapperVersion = Version::GRALLOC_5;
64         return;
65     }
66     mMapper = std::make_unique<const Gralloc4Mapper>();
67     if (mMapper->isLoaded()) {
68         mMapperVersion = Version::GRALLOC_4;
69         return;
70     }
71     mMapper = std::make_unique<const Gralloc3Mapper>();
72     if (mMapper->isLoaded()) {
73         mMapperVersion = Version::GRALLOC_3;
74         return;
75     }
76     mMapper = std::make_unique<const Gralloc2Mapper>();
77     if (mMapper->isLoaded()) {
78         mMapperVersion = Version::GRALLOC_2;
79         return;
80     }
81 
82     LOG_ALWAYS_FATAL("gralloc-mapper is missing");
83 }
84 
dumpBuffer(buffer_handle_t bufferHandle,std::string & result,bool less) const85 void GraphicBufferMapper::dumpBuffer(buffer_handle_t bufferHandle, std::string& result,
86                                      bool less) const {
87     result.append(mMapper->dumpBuffer(bufferHandle, less));
88 }
89 
dumpBufferToSystemLog(buffer_handle_t bufferHandle,bool less)90 void GraphicBufferMapper::dumpBufferToSystemLog(buffer_handle_t bufferHandle, bool less) {
91     std::string s;
92     GraphicBufferMapper::getInstance().dumpBuffer(bufferHandle, s, less);
93     ALOGD("%s", s.c_str());
94 }
95 
importBuffer(const native_handle_t * rawHandle,uint32_t width,uint32_t height,uint32_t layerCount,PixelFormat format,uint64_t usage,uint32_t stride,buffer_handle_t * outHandle)96 status_t GraphicBufferMapper::importBuffer(const native_handle_t* rawHandle, uint32_t width,
97                                            uint32_t height, uint32_t layerCount, PixelFormat format,
98                                            uint64_t usage, uint32_t stride,
99                                            buffer_handle_t* outHandle) {
100     ATRACE_CALL();
101 
102     buffer_handle_t bufferHandle;
103     status_t error = mMapper->importBuffer(rawHandle, &bufferHandle);
104     if (error != NO_ERROR) {
105         ALOGW("importBuffer(%p) failed: %d", rawHandle, error);
106         return error;
107     }
108 
109     error = mMapper->validateBufferSize(bufferHandle, width, height, format, layerCount, usage,
110                                         stride);
111     if (error != NO_ERROR) {
112         ALOGE("validateBufferSize(%p) failed: %d", rawHandle, error);
113         freeBuffer(bufferHandle);
114         return static_cast<status_t>(error);
115     }
116 
117     *outHandle = bufferHandle;
118 
119     return NO_ERROR;
120 }
121 
importBufferNoValidate(const native_handle_t * rawHandle,buffer_handle_t * outHandle)122 status_t GraphicBufferMapper::importBufferNoValidate(const native_handle_t* rawHandle,
123                                                      buffer_handle_t* outHandle) {
124     return mMapper->importBuffer(rawHandle, outHandle);
125 }
126 
getTransportSize(buffer_handle_t handle,uint32_t * outTransportNumFds,uint32_t * outTransportNumInts)127 void GraphicBufferMapper::getTransportSize(buffer_handle_t handle,
128             uint32_t* outTransportNumFds, uint32_t* outTransportNumInts)
129 {
130     mMapper->getTransportSize(handle, outTransportNumFds, outTransportNumInts);
131 }
132 
freeBuffer(buffer_handle_t handle)133 status_t GraphicBufferMapper::freeBuffer(buffer_handle_t handle)
134 {
135     ATRACE_CALL();
136 
137     mMapper->freeBuffer(handle);
138 
139     return NO_ERROR;
140 }
141 
lock(buffer_handle_t handle,int64_t usage,const Rect & bounds,unique_fd && acquireFence)142 ui::Result<LockResult> GraphicBufferMapper::lock(buffer_handle_t handle, int64_t usage,
143                                                  const Rect& bounds, unique_fd&& acquireFence) {
144     ATRACE_CALL();
145 
146     LockResult result;
147     status_t status = mMapper->lock(handle, usage, bounds, acquireFence.release(), &result.address,
148                                     &result.bytesPerPixel, &result.bytesPerStride);
149     if (status != OK) {
150         return base::unexpected(ui::Error::statusToCode(status));
151     } else {
152         return result;
153     }
154 }
155 
lockYCbCr(buffer_handle_t handle,int64_t usage,const Rect & bounds,base::unique_fd && acquireFence)156 ui::Result<android_ycbcr> GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, int64_t usage,
157                                                          const Rect& bounds,
158                                                          base::unique_fd&& acquireFence) {
159     ATRACE_CALL();
160 
161     android_ycbcr result = {};
162     status_t status = mMapper->lock(handle, usage, bounds, acquireFence.release(), &result);
163     if (status != OK) {
164         return base::unexpected(ui::Error::statusToCode(status));
165     } else {
166         return result;
167     }
168 }
169 
unlock(buffer_handle_t handle,base::unique_fd * outFence)170 status_t GraphicBufferMapper::unlock(buffer_handle_t handle, base::unique_fd* outFence) {
171     ATRACE_CALL();
172     int fence = mMapper->unlock(handle);
173     if (outFence) {
174         *outFence = unique_fd{fence};
175     } else {
176         sync_wait(fence, -1);
177         close(fence);
178     }
179     return OK;
180 }
181 
lock(buffer_handle_t handle,uint32_t usage,const Rect & bounds,void ** vaddr)182 status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage, const Rect& bounds,
183                                    void** vaddr) {
184     auto result = lock(handle, static_cast<int64_t>(usage), bounds);
185     if (!result.has_value()) return result.asStatus();
186     auto val = result.value();
187     *vaddr = val.address;
188     return OK;
189 }
190 
lockYCbCr(buffer_handle_t handle,uint32_t usage,const Rect & bounds,android_ycbcr * ycbcr)191 status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage, const Rect& bounds,
192                                         android_ycbcr* ycbcr) {
193     auto result = lockYCbCr(handle, static_cast<int64_t>(usage), bounds);
194     if (!result.has_value()) return result.asStatus();
195     *ycbcr = result.value();
196     return OK;
197 }
198 
lockAsync(buffer_handle_t handle,uint32_t usage,const Rect & bounds,void ** vaddr,int fenceFd)199 status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint32_t usage, const Rect& bounds,
200                                         void** vaddr, int fenceFd) {
201     auto result = lock(handle, static_cast<int64_t>(usage), bounds, unique_fd{fenceFd});
202     if (!result.has_value()) return result.asStatus();
203     auto val = result.value();
204     *vaddr = val.address;
205     return OK;
206 }
207 
lockAsync(buffer_handle_t handle,uint64_t producerUsage,uint64_t consumerUsage,const Rect & bounds,void ** vaddr,int fenceFd)208 status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint64_t producerUsage,
209                                         uint64_t consumerUsage, const Rect& bounds, void** vaddr,
210                                         int fenceFd) {
211     return lockAsync(handle, android_convertGralloc1To0Usage(producerUsage, consumerUsage), bounds,
212                      vaddr, fenceFd);
213 }
214 
lockAsyncYCbCr(buffer_handle_t handle,uint32_t usage,const Rect & bounds,android_ycbcr * ycbcr,int fenceFd)215 status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle, uint32_t usage,
216                                              const Rect& bounds, android_ycbcr* ycbcr,
217                                              int fenceFd) {
218     auto result = lockYCbCr(handle, static_cast<int64_t>(usage), bounds, unique_fd{fenceFd});
219     if (!result.has_value()) return result.asStatus();
220     *ycbcr = result.value();
221     return OK;
222 }
223 
isSupported(uint32_t width,uint32_t height,android::PixelFormat format,uint32_t layerCount,uint64_t usage,bool * outSupported)224 status_t GraphicBufferMapper::isSupported(uint32_t width, uint32_t height,
225                                           android::PixelFormat format, uint32_t layerCount,
226                                           uint64_t usage, bool* outSupported) {
227     return mMapper->isSupported(width, height, format, layerCount, usage, outSupported);
228 }
229 
getBufferId(buffer_handle_t bufferHandle,uint64_t * outBufferId)230 status_t GraphicBufferMapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) {
231     return mMapper->getBufferId(bufferHandle, outBufferId);
232 }
233 
getName(buffer_handle_t bufferHandle,std::string * outName)234 status_t GraphicBufferMapper::getName(buffer_handle_t bufferHandle, std::string* outName) {
235     return mMapper->getName(bufferHandle, outName);
236 }
237 
getWidth(buffer_handle_t bufferHandle,uint64_t * outWidth)238 status_t GraphicBufferMapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) {
239     return mMapper->getWidth(bufferHandle, outWidth);
240 }
241 
getHeight(buffer_handle_t bufferHandle,uint64_t * outHeight)242 status_t GraphicBufferMapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) {
243     return mMapper->getHeight(bufferHandle, outHeight);
244 }
245 
getLayerCount(buffer_handle_t bufferHandle,uint64_t * outLayerCount)246 status_t GraphicBufferMapper::getLayerCount(buffer_handle_t bufferHandle, uint64_t* outLayerCount) {
247     return mMapper->getLayerCount(bufferHandle, outLayerCount);
248 }
249 
getPixelFormatRequested(buffer_handle_t bufferHandle,ui::PixelFormat * outPixelFormatRequested)250 status_t GraphicBufferMapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
251                                                       ui::PixelFormat* outPixelFormatRequested) {
252     return mMapper->getPixelFormatRequested(bufferHandle, outPixelFormatRequested);
253 }
254 
getPixelFormatFourCC(buffer_handle_t bufferHandle,uint32_t * outPixelFormatFourCC)255 status_t GraphicBufferMapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
256                                                    uint32_t* outPixelFormatFourCC) {
257     return mMapper->getPixelFormatFourCC(bufferHandle, outPixelFormatFourCC);
258 }
259 
getPixelFormatModifier(buffer_handle_t bufferHandle,uint64_t * outPixelFormatModifier)260 status_t GraphicBufferMapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
261                                                      uint64_t* outPixelFormatModifier) {
262     return mMapper->getPixelFormatModifier(bufferHandle, outPixelFormatModifier);
263 }
264 
getUsage(buffer_handle_t bufferHandle,uint64_t * outUsage)265 status_t GraphicBufferMapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) {
266     return mMapper->getUsage(bufferHandle, outUsage);
267 }
268 
getAllocationSize(buffer_handle_t bufferHandle,uint64_t * outAllocationSize)269 status_t GraphicBufferMapper::getAllocationSize(buffer_handle_t bufferHandle,
270                                                 uint64_t* outAllocationSize) {
271     return mMapper->getAllocationSize(bufferHandle, outAllocationSize);
272 }
273 
getProtectedContent(buffer_handle_t bufferHandle,uint64_t * outProtectedContent)274 status_t GraphicBufferMapper::getProtectedContent(buffer_handle_t bufferHandle,
275                                                   uint64_t* outProtectedContent) {
276     return mMapper->getProtectedContent(bufferHandle, outProtectedContent);
277 }
278 
getCompression(buffer_handle_t bufferHandle,aidl::android::hardware::graphics::common::ExtendableType * outCompression)279 status_t GraphicBufferMapper::getCompression(
280         buffer_handle_t bufferHandle,
281         aidl::android::hardware::graphics::common::ExtendableType* outCompression) {
282     return mMapper->getCompression(bufferHandle, outCompression);
283 }
284 
getCompression(buffer_handle_t bufferHandle,ui::Compression * outCompression)285 status_t GraphicBufferMapper::getCompression(buffer_handle_t bufferHandle,
286                                              ui::Compression* outCompression) {
287     return mMapper->getCompression(bufferHandle, outCompression);
288 }
289 
getInterlaced(buffer_handle_t bufferHandle,aidl::android::hardware::graphics::common::ExtendableType * outInterlaced)290 status_t GraphicBufferMapper::getInterlaced(
291         buffer_handle_t bufferHandle,
292         aidl::android::hardware::graphics::common::ExtendableType* outInterlaced) {
293     return mMapper->getInterlaced(bufferHandle, outInterlaced);
294 }
295 
getInterlaced(buffer_handle_t bufferHandle,ui::Interlaced * outInterlaced)296 status_t GraphicBufferMapper::getInterlaced(buffer_handle_t bufferHandle,
297                                             ui::Interlaced* outInterlaced) {
298     return mMapper->getInterlaced(bufferHandle, outInterlaced);
299 }
300 
getChromaSiting(buffer_handle_t bufferHandle,aidl::android::hardware::graphics::common::ExtendableType * outChromaSiting)301 status_t GraphicBufferMapper::getChromaSiting(
302         buffer_handle_t bufferHandle,
303         aidl::android::hardware::graphics::common::ExtendableType* outChromaSiting) {
304     return mMapper->getChromaSiting(bufferHandle, outChromaSiting);
305 }
306 
getChromaSiting(buffer_handle_t bufferHandle,ui::ChromaSiting * outChromaSiting)307 status_t GraphicBufferMapper::getChromaSiting(buffer_handle_t bufferHandle,
308                                               ui::ChromaSiting* outChromaSiting) {
309     return mMapper->getChromaSiting(bufferHandle, outChromaSiting);
310 }
311 
getPlaneLayouts(buffer_handle_t bufferHandle,std::vector<ui::PlaneLayout> * outPlaneLayouts)312 status_t GraphicBufferMapper::getPlaneLayouts(buffer_handle_t bufferHandle,
313                                               std::vector<ui::PlaneLayout>* outPlaneLayouts) {
314     return mMapper->getPlaneLayouts(bufferHandle, outPlaneLayouts);
315 }
316 
getPlaneLayouts(buffer_handle_t bufferHandle)317 ui::Result<std::vector<ui::PlaneLayout>> GraphicBufferMapper::getPlaneLayouts(
318         buffer_handle_t bufferHandle) {
319     std::vector<ui::PlaneLayout> temp;
320     status_t status = mMapper->getPlaneLayouts(bufferHandle, &temp);
321     if (status == OK) {
322         return std::move(temp);
323     } else {
324         return base::unexpected(ui::Error::statusToCode(status));
325     }
326 }
327 
getDataspace(buffer_handle_t bufferHandle,ui::Dataspace * outDataspace)328 status_t GraphicBufferMapper::getDataspace(buffer_handle_t bufferHandle,
329                                            ui::Dataspace* outDataspace) {
330     return mMapper->getDataspace(bufferHandle, outDataspace);
331 }
332 
setDataspace(buffer_handle_t bufferHandle,ui::Dataspace dataspace)333 status_t GraphicBufferMapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) {
334     return mMapper->setDataspace(bufferHandle, dataspace);
335 }
336 
getBlendMode(buffer_handle_t bufferHandle,ui::BlendMode * outBlendMode)337 status_t GraphicBufferMapper::getBlendMode(buffer_handle_t bufferHandle,
338                                            ui::BlendMode* outBlendMode) {
339     return mMapper->getBlendMode(bufferHandle, outBlendMode);
340 }
341 
getSmpte2086(buffer_handle_t bufferHandle,std::optional<ui::Smpte2086> * outSmpte2086)342 status_t GraphicBufferMapper::getSmpte2086(buffer_handle_t bufferHandle,
343                                            std::optional<ui::Smpte2086>* outSmpte2086) {
344     return mMapper->getSmpte2086(bufferHandle, outSmpte2086);
345 }
346 
setSmpte2086(buffer_handle_t bufferHandle,std::optional<ui::Smpte2086> smpte2086)347 status_t GraphicBufferMapper::setSmpte2086(buffer_handle_t bufferHandle,
348                                            std::optional<ui::Smpte2086> smpte2086) {
349     return mMapper->setSmpte2086(bufferHandle, smpte2086);
350 }
351 
getCta861_3(buffer_handle_t bufferHandle,std::optional<ui::Cta861_3> * outCta861_3)352 status_t GraphicBufferMapper::getCta861_3(buffer_handle_t bufferHandle,
353                                           std::optional<ui::Cta861_3>* outCta861_3) {
354     return mMapper->getCta861_3(bufferHandle, outCta861_3);
355 }
356 
setCta861_3(buffer_handle_t bufferHandle,std::optional<ui::Cta861_3> cta861_3)357 status_t GraphicBufferMapper::setCta861_3(buffer_handle_t bufferHandle,
358                                           std::optional<ui::Cta861_3> cta861_3) {
359     return mMapper->setCta861_3(bufferHandle, cta861_3);
360 }
361 
getSmpte2094_40(buffer_handle_t bufferHandle,std::optional<std::vector<uint8_t>> * outSmpte2094_40)362 status_t GraphicBufferMapper::getSmpte2094_40(
363         buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_40) {
364     return mMapper->getSmpte2094_40(bufferHandle, outSmpte2094_40);
365 }
366 
setSmpte2094_40(buffer_handle_t bufferHandle,std::optional<std::vector<uint8_t>> smpte2094_40)367 status_t GraphicBufferMapper::setSmpte2094_40(buffer_handle_t bufferHandle,
368                                               std::optional<std::vector<uint8_t>> smpte2094_40) {
369     return mMapper->setSmpte2094_40(bufferHandle, smpte2094_40);
370 }
371 
getSmpte2094_10(buffer_handle_t bufferHandle,std::optional<std::vector<uint8_t>> * outSmpte2094_10)372 status_t GraphicBufferMapper::getSmpte2094_10(
373         buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_10) {
374     return mMapper->getSmpte2094_10(bufferHandle, outSmpte2094_10);
375 }
376 
setSmpte2094_10(buffer_handle_t bufferHandle,std::optional<std::vector<uint8_t>> smpte2094_10)377 status_t GraphicBufferMapper::setSmpte2094_10(buffer_handle_t bufferHandle,
378                                               std::optional<std::vector<uint8_t>> smpte2094_10) {
379     return mMapper->setSmpte2094_10(bufferHandle, smpte2094_10);
380 }
381 
382 // ---------------------------------------------------------------------------
383 }; // namespace android
384