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