1 /*
2  * Copyright 2016 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 "Gralloc3"
18 
19 #include <hidl/ServiceManagement.h>
20 #include <hwbinder/IPCThreadState.h>
21 #include <ui/Gralloc3.h>
22 
23 #include <inttypes.h>
24 #include <log/log.h>
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wzero-length-array"
27 #include <sync/sync.h>
28 #pragma clang diagnostic pop
29 
30 using android::hardware::graphics::allocator::V3_0::IAllocator;
31 using android::hardware::graphics::common::V1_2::BufferUsage;
32 using android::hardware::graphics::mapper::V3_0::BufferDescriptor;
33 using android::hardware::graphics::mapper::V3_0::Error;
34 using android::hardware::graphics::mapper::V3_0::IMapper;
35 using android::hardware::graphics::mapper::V3_0::YCbCrLayout;
36 
37 namespace android {
38 
39 namespace {
40 
41 static constexpr Error kTransactionError = Error::NO_RESOURCES;
42 
getValidUsageBits()43 uint64_t getValidUsageBits() {
44     static const uint64_t validUsageBits = []() -> uint64_t {
45         uint64_t bits = 0;
46         for (const auto bit :
47              hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
48             bits = bits | bit;
49         }
50         return bits;
51     }();
52     return validUsageBits;
53 }
54 
sGralloc3Rect(const Rect & rect)55 static inline IMapper::Rect sGralloc3Rect(const Rect& rect) {
56     IMapper::Rect outRect{};
57     outRect.left = rect.left;
58     outRect.top = rect.top;
59     outRect.width = rect.width();
60     outRect.height = rect.height();
61     return outRect;
62 }
sBufferDescriptorInfo(uint32_t width,uint32_t height,android::PixelFormat format,uint32_t layerCount,uint64_t usage,IMapper::BufferDescriptorInfo * outDescriptorInfo)63 static inline void sBufferDescriptorInfo(uint32_t width, uint32_t height,
64                                          android::PixelFormat format, uint32_t layerCount,
65                                          uint64_t usage,
66                                          IMapper::BufferDescriptorInfo* outDescriptorInfo) {
67     outDescriptorInfo->width = width;
68     outDescriptorInfo->height = height;
69     outDescriptorInfo->layerCount = layerCount;
70     outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
71     outDescriptorInfo->usage = usage;
72 }
73 
74 } // anonymous namespace
75 
preload()76 void Gralloc3Mapper::preload() {
77     android::hardware::preloadPassthroughService<IMapper>();
78 }
79 
Gralloc3Mapper()80 Gralloc3Mapper::Gralloc3Mapper() {
81     mMapper = IMapper::getService();
82     if (mMapper == nullptr) {
83         ALOGW("mapper 3.x is not supported");
84         return;
85     }
86     if (mMapper->isRemote()) {
87         LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
88     }
89 }
90 
isLoaded() const91 bool Gralloc3Mapper::isLoaded() const {
92     return mMapper != nullptr;
93 }
94 
validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo * descriptorInfo) const95 status_t Gralloc3Mapper::validateBufferDescriptorInfo(
96         IMapper::BufferDescriptorInfo* descriptorInfo) const {
97     uint64_t validUsageBits = getValidUsageBits();
98 
99     if (descriptorInfo->usage & ~validUsageBits) {
100         ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
101               descriptorInfo->usage & ~validUsageBits);
102         return BAD_VALUE;
103     }
104     return NO_ERROR;
105 }
106 
createDescriptor(void * bufferDescriptorInfo,void * outBufferDescriptor) const107 status_t Gralloc3Mapper::createDescriptor(void* bufferDescriptorInfo,
108                                           void* outBufferDescriptor) const {
109     IMapper::BufferDescriptorInfo* descriptorInfo =
110             static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
111     BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
112 
113     status_t status = validateBufferDescriptorInfo(descriptorInfo);
114     if (status != NO_ERROR) {
115         return status;
116     }
117 
118     Error error;
119     auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
120         error = tmpError;
121         if (error != Error::NONE) {
122             return;
123         }
124         *outDescriptor = tmpDescriptor;
125     };
126 
127     hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
128 
129     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
130 }
131 
importBuffer(const hardware::hidl_handle & rawHandle,buffer_handle_t * outBufferHandle) const132 status_t Gralloc3Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
133                                       buffer_handle_t* outBufferHandle) const {
134     Error error;
135     auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
136         error = tmpError;
137         if (error != Error::NONE) {
138             return;
139         }
140         *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
141     });
142 
143     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
144 }
145 
freeBuffer(buffer_handle_t bufferHandle) const146 void Gralloc3Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
147     auto buffer = const_cast<native_handle_t*>(bufferHandle);
148     auto ret = mMapper->freeBuffer(buffer);
149 
150     auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
151     ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
152 }
153 
validateBufferSize(buffer_handle_t bufferHandle,uint32_t width,uint32_t height,android::PixelFormat format,uint32_t layerCount,uint64_t usage,uint32_t stride) const154 status_t Gralloc3Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
155                                             uint32_t height, android::PixelFormat format,
156                                             uint32_t layerCount, uint64_t usage,
157                                             uint32_t stride) const {
158     IMapper::BufferDescriptorInfo descriptorInfo;
159     sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
160 
161     auto buffer = const_cast<native_handle_t*>(bufferHandle);
162     auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
163 
164     return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
165 }
166 
getTransportSize(buffer_handle_t bufferHandle,uint32_t * outNumFds,uint32_t * outNumInts) const167 void Gralloc3Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
168                                       uint32_t* outNumInts) const {
169     *outNumFds = uint32_t(bufferHandle->numFds);
170     *outNumInts = uint32_t(bufferHandle->numInts);
171 
172     Error error;
173     auto buffer = const_cast<native_handle_t*>(bufferHandle);
174     auto ret = mMapper->getTransportSize(buffer,
175                                          [&](const auto& tmpError, const auto& tmpNumFds,
176                                              const auto& tmpNumInts) {
177                                              error = tmpError;
178                                              if (error != Error::NONE) {
179                                                  return;
180                                              }
181                                              *outNumFds = tmpNumFds;
182                                              *outNumInts = tmpNumInts;
183                                          });
184 
185     error = (ret.isOk()) ? error : kTransactionError;
186 
187     ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
188 }
189 
lock(buffer_handle_t bufferHandle,uint64_t usage,const Rect & bounds,int acquireFence,void ** outData,int32_t * outBytesPerPixel,int32_t * outBytesPerStride) const190 status_t Gralloc3Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
191                               int acquireFence, void** outData, int32_t* outBytesPerPixel,
192                               int32_t* outBytesPerStride) const {
193     auto buffer = const_cast<native_handle_t*>(bufferHandle);
194 
195     IMapper::Rect accessRegion = sGralloc3Rect(bounds);
196 
197     // put acquireFence in a hidl_handle
198     hardware::hidl_handle acquireFenceHandle;
199     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
200     if (acquireFence >= 0) {
201         auto h = native_handle_init(acquireFenceStorage, 1, 0);
202         h->data[0] = acquireFence;
203         acquireFenceHandle = h;
204     }
205 
206     Error error;
207     auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
208                              [&](const auto& tmpError, const auto& tmpData,
209                                  const auto& tmpBytesPerPixel, const auto& tmpBytesPerStride) {
210                                  error = tmpError;
211                                  if (error != Error::NONE) {
212                                      return;
213                                  }
214                                  *outData = tmpData;
215                                  if (outBytesPerPixel) {
216                                      *outBytesPerPixel = tmpBytesPerPixel;
217                                  }
218                                  if (outBytesPerStride) {
219                                      *outBytesPerStride = tmpBytesPerStride;
220                                  }
221                              });
222 
223     // we own acquireFence even on errors
224     if (acquireFence >= 0) {
225         close(acquireFence);
226     }
227 
228     error = (ret.isOk()) ? error : kTransactionError;
229 
230     ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
231 
232     return static_cast<status_t>(error);
233 }
234 
lock(buffer_handle_t bufferHandle,uint64_t usage,const Rect & bounds,int acquireFence,android_ycbcr * ycbcr) const235 status_t Gralloc3Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
236                               int acquireFence, android_ycbcr* ycbcr) const {
237     auto buffer = const_cast<native_handle_t*>(bufferHandle);
238 
239     IMapper::Rect accessRegion = sGralloc3Rect(bounds);
240 
241     // put acquireFence in a hidl_handle
242     hardware::hidl_handle acquireFenceHandle;
243     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
244     if (acquireFence >= 0) {
245         auto h = native_handle_init(acquireFenceStorage, 1, 0);
246         h->data[0] = acquireFence;
247         acquireFenceHandle = h;
248     }
249 
250     YCbCrLayout layout;
251     Error error;
252     auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion, acquireFenceHandle,
253                                   [&](const auto& tmpError, const auto& tmpLayout) {
254                                       error = tmpError;
255                                       if (error != Error::NONE) {
256                                           return;
257                                       }
258 
259                                       layout = tmpLayout;
260                                   });
261 
262     if (error == Error::NONE) {
263         ycbcr->y = layout.y;
264         ycbcr->cb = layout.cb;
265         ycbcr->cr = layout.cr;
266         ycbcr->ystride = static_cast<size_t>(layout.yStride);
267         ycbcr->cstride = static_cast<size_t>(layout.cStride);
268         ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
269     }
270 
271     // we own acquireFence even on errors
272     if (acquireFence >= 0) {
273         close(acquireFence);
274     }
275 
276     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
277 }
278 
unlock(buffer_handle_t bufferHandle) const279 int Gralloc3Mapper::unlock(buffer_handle_t bufferHandle) const {
280     auto buffer = const_cast<native_handle_t*>(bufferHandle);
281 
282     int releaseFence = -1;
283     Error error;
284     auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
285         error = tmpError;
286         if (error != Error::NONE) {
287             return;
288         }
289 
290         auto fenceHandle = tmpReleaseFence.getNativeHandle();
291         if (fenceHandle && fenceHandle->numFds == 1) {
292             int fd = dup(fenceHandle->data[0]);
293             if (fd >= 0) {
294                 releaseFence = fd;
295             } else {
296                 ALOGD("failed to dup unlock release fence");
297                 sync_wait(fenceHandle->data[0], -1);
298             }
299         }
300     });
301 
302     if (!ret.isOk()) {
303         error = kTransactionError;
304     }
305 
306     if (error != Error::NONE) {
307         ALOGE("unlock(%p) failed with %d", buffer, error);
308     }
309 
310     return releaseFence;
311 }
312 
isSupported(uint32_t width,uint32_t height,android::PixelFormat format,uint32_t layerCount,uint64_t usage,bool * outSupported) const313 status_t Gralloc3Mapper::isSupported(uint32_t width, uint32_t height, android::PixelFormat format,
314                                      uint32_t layerCount, uint64_t usage,
315                                      bool* outSupported) const {
316     IMapper::BufferDescriptorInfo descriptorInfo;
317     sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
318 
319     Error error;
320     auto ret = mMapper->isSupported(descriptorInfo,
321                                     [&](const auto& tmpError, const auto& tmpSupported) {
322                                         error = tmpError;
323                                         if (error != Error::NONE) {
324                                             return;
325                                         }
326                                         if (outSupported) {
327                                             *outSupported = tmpSupported;
328                                         }
329                                     });
330 
331     if (!ret.isOk()) {
332         error = kTransactionError;
333     }
334 
335     if (error != Error::NONE) {
336         ALOGE("isSupported(%u, %u, %d, %u, ...) failed with %d", width, height, format, layerCount,
337               error);
338     }
339 
340     return static_cast<status_t>(error);
341 }
342 
Gralloc3Allocator(const Gralloc3Mapper & mapper)343 Gralloc3Allocator::Gralloc3Allocator(const Gralloc3Mapper& mapper) : mMapper(mapper) {
344     mAllocator = IAllocator::getService();
345     if (mAllocator == nullptr) {
346         ALOGW("allocator 3.x is not supported");
347         return;
348     }
349 }
350 
isLoaded() const351 bool Gralloc3Allocator::isLoaded() const {
352     return mAllocator != nullptr;
353 }
354 
dumpDebugInfo() const355 std::string Gralloc3Allocator::dumpDebugInfo() const {
356     std::string debugInfo;
357 
358     mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
359 
360     return debugInfo;
361 }
362 
allocate(uint32_t width,uint32_t height,android::PixelFormat format,uint32_t layerCount,uint64_t usage,uint32_t bufferCount,uint32_t * outStride,buffer_handle_t * outBufferHandles) const363 status_t Gralloc3Allocator::allocate(uint32_t width, uint32_t height, android::PixelFormat format,
364                                      uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
365                                      uint32_t* outStride, buffer_handle_t* outBufferHandles) const {
366     IMapper::BufferDescriptorInfo descriptorInfo;
367     sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
368 
369     BufferDescriptor descriptor;
370     status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
371                                               static_cast<void*>(&descriptor));
372     if (error != NO_ERROR) {
373         return error;
374     }
375 
376     auto ret = mAllocator->allocate(descriptor, bufferCount,
377                                     [&](const auto& tmpError, const auto& tmpStride,
378                                         const auto& tmpBuffers) {
379                                         error = static_cast<status_t>(tmpError);
380                                         if (tmpError != Error::NONE) {
381                                             return;
382                                         }
383 
384                                         // import buffers
385                                         for (uint32_t i = 0; i < bufferCount; i++) {
386                                             error = mMapper.importBuffer(tmpBuffers[i],
387                                                                          &outBufferHandles[i]);
388                                             if (error != NO_ERROR) {
389                                                 for (uint32_t j = 0; j < i; j++) {
390                                                     mMapper.freeBuffer(outBufferHandles[j]);
391                                                     outBufferHandles[j] = nullptr;
392                                                 }
393                                                 return;
394                                             }
395                                         }
396                                         *outStride = tmpStride;
397                                     });
398 
399     // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
400     hardware::IPCThreadState::self()->flushCommands();
401 
402     return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
403 }
404 
405 } // namespace android
406