• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above
10  *       copyright notice, this list of conditions and the following
11  *       disclaimer in the documentation and/or other materials provided
12  *       with the distribution.
13  *     * Neither the name of The Linux Foundation nor the names of its
14  *       contributors may be used to endorse or promote products derived
15  *       from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
31 #define DEBUG 0
32 #include "QtiMapper.h"
33 #include <cutils/trace.h>
34 #include <qdMetaData.h>
35 #include <sync/sync.h>
36 #include "gr_utils.h"
37 
38 namespace vendor {
39 namespace qti {
40 namespace hardware {
41 namespace display {
42 namespace mapper {
43 namespace V3_0 {
44 namespace implementation {
45 
46 using gralloc::BufferInfo;
47 
QtiMapper()48 QtiMapper::QtiMapper() {
49   extensions_ = new QtiMapperExtensions();
50   buf_mgr_ = BufferManager::GetInstance();
51   ALOGD_IF(DEBUG, "Created QtiMapper instance");
52 }
53 
ValidDescriptor(const BufferDescriptorInfo_3_0 & bd)54 bool QtiMapper::ValidDescriptor(const BufferDescriptorInfo_3_0 &bd) {
55   if (bd.width == 0 || bd.height == 0 || (static_cast<int32_t>(bd.format) <= 0) ||
56       bd.layerCount <= 0) {
57     return false;
58   }
59 
60   return true;
61 }
62 
CreateDescriptor(const BufferDescriptorInfo_3_0 & descriptor_info,IMapperBufferDescriptor * descriptor)63 Error QtiMapper::CreateDescriptor(const BufferDescriptorInfo_3_0 &descriptor_info,
64                                   IMapperBufferDescriptor *descriptor) {
65   ALOGD_IF(DEBUG,
66            "BufferDescriptorInfo: wxh: %dx%d usage: 0x%" PRIu64 " format: %d layer_count: %d",
67            descriptor_info.width, descriptor_info.height, descriptor_info.usage,
68            static_cast<uint32_t>(descriptor_info.format), descriptor_info.layerCount);
69 
70   if (ValidDescriptor(descriptor_info)) {
71     auto vec = Encode(descriptor_info);
72     *descriptor = vec;
73     return Error::NONE;
74   } else {
75     return Error::BAD_VALUE;
76   }
77 }
78 
79 // Methods from ::android::hardware::graphics::mapper::V2_0::IMapper follow.
createDescriptor(const BufferDescriptorInfo_3_0 & descriptor_info,createDescriptor_cb hidl_cb)80 Return<void> QtiMapper::createDescriptor(const BufferDescriptorInfo_3_0 &descriptor_info,
81                                          createDescriptor_cb hidl_cb) {
82   IMapperBufferDescriptor descriptor;
83   auto info_3_0 = BufferDescriptorInfo_3_0{
84       descriptor_info.width,
85       descriptor_info.height,
86       descriptor_info.layerCount,
87       static_cast<PixelFormat>(descriptor_info.format),
88       descriptor_info.usage,
89   };
90   auto err = CreateDescriptor(info_3_0, &descriptor);
91   hidl_cb(err, descriptor);
92   return Void();
93 }
94 
importBuffer(const hidl_handle & raw_handle,importBuffer_cb hidl_cb)95 Return<void> QtiMapper::importBuffer(const hidl_handle &raw_handle, importBuffer_cb hidl_cb) {
96   if (!raw_handle.getNativeHandle()) {
97     ALOGE("%s: Unable to import handle", __FUNCTION__);
98     hidl_cb(Error::BAD_BUFFER, nullptr);
99     return Void();
100   }
101 
102   native_handle_t *buffer_handle = native_handle_clone(raw_handle.getNativeHandle());
103   if (!buffer_handle) {
104     ALOGE("%s: Unable to clone handle", __FUNCTION__);
105     hidl_cb(Error::NO_RESOURCES, nullptr);
106     return Void();
107   }
108 
109   auto error =
110       static_cast<IMapper_3_0_Error>(buf_mgr_->RetainBuffer(PRIV_HANDLE_CONST(buffer_handle)));
111   if (error != Error::NONE) {
112     ALOGE("%s: Unable to retain handle: %p", __FUNCTION__, buffer_handle);
113     native_handle_close(buffer_handle);
114     native_handle_delete(buffer_handle);
115 
116     hidl_cb(error, nullptr);
117     return Void();
118   }
119   ALOGD_IF(DEBUG, "Imported handle: %p id: %" PRIu64, buffer_handle,
120            PRIV_HANDLE_CONST(buffer_handle)->id);
121   hidl_cb(Error::NONE, buffer_handle);
122   return Void();
123 }
124 
freeBuffer(void * buffer)125 Return<Error> QtiMapper::freeBuffer(void *buffer) {
126   if (!buffer) {
127     return Error::BAD_BUFFER;
128   }
129   return static_cast<IMapper_3_0_Error>(buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(buffer)));
130 }
131 
GetFenceFd(const hidl_handle & fence_handle,int * outFenceFd)132 bool QtiMapper::GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd) {
133   auto handle = fence_handle.getNativeHandle();
134   if (handle && handle->numFds > 1) {
135     ALOGE("invalid fence handle with %d fds", handle->numFds);
136     return false;
137   }
138 
139   *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
140   return true;
141 }
142 
WaitFenceFd(int fence_fd)143 void QtiMapper::WaitFenceFd(int fence_fd) {
144   if (fence_fd < 0) {
145     return;
146   }
147 
148   const int timeout = 3000;
149   ATRACE_BEGIN("fence wait");
150   const int error = sync_wait(fence_fd, timeout);
151   ATRACE_END();
152   if (error < 0) {
153     ALOGE("QtiMapper: lock fence %d didn't signal in %u ms -  error: %s", fence_fd, timeout,
154           strerror(errno));
155   }
156 }
157 
LockBuffer(void * buffer,uint64_t usage,const hidl_handle & acquire_fence)158 Error QtiMapper::LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence) {
159   if (!buffer) {
160     return Error::BAD_BUFFER;
161   }
162 
163   int fence_fd;
164   if (!GetFenceFd(acquire_fence, &fence_fd)) {
165     return Error::BAD_VALUE;
166   }
167 
168   if (fence_fd > 0) {
169     WaitFenceFd(fence_fd);
170   }
171 
172   auto hnd = PRIV_HANDLE_CONST(buffer);
173 
174   return static_cast<IMapper_3_0_Error>(buf_mgr_->LockBuffer(hnd, usage));
175 }
176 
lock(void * buffer,uint64_t cpu_usage,const IMapper::Rect &,const hidl_handle & acquire_fence,lock_cb hidl_cb)177 Return<void> QtiMapper::lock(void *buffer, uint64_t cpu_usage,
178                              const IMapper::Rect & /*access_region*/,
179                              const hidl_handle &acquire_fence, lock_cb hidl_cb) {
180   auto err = LockBuffer(buffer, cpu_usage, acquire_fence);
181   if (err != Error::NONE) {
182     hidl_cb(err, nullptr, -1, -1);
183     return Void();
184   }
185 
186   auto hnd = PRIV_HANDLE_CONST(buffer);
187   auto *out_data = reinterpret_cast<void *>(hnd->base);
188   hidl_cb(err, out_data, gralloc::GetBpp(hnd->format),
189           (hnd->width) * (gralloc::GetBpp(hnd->format)));
190   return Void();
191 }
192 
lockYCbCr(void * buffer,uint64_t cpu_usage,const IMapper::Rect &,const hidl_handle & acquire_fence,lockYCbCr_cb hidl_cb)193 Return<void> QtiMapper::lockYCbCr(void *buffer, uint64_t cpu_usage,
194                                   const IMapper::Rect & /*access_region*/,
195                                   const hidl_handle &acquire_fence, lockYCbCr_cb hidl_cb) {
196   YCbCrLayout layout = {};
197   auto err = LockBuffer(buffer, cpu_usage, acquire_fence);
198   if (err != Error::NONE) {
199     hidl_cb(err, layout);
200     return Void();
201   }
202 
203   auto hnd = PRIV_HANDLE_CONST(buffer);
204   android_ycbcr yuv_plane_info[2];
205   if (gralloc::GetYUVPlaneInfo(hnd, yuv_plane_info) != 0) {
206     hidl_cb(Error::BAD_VALUE, layout);
207   }
208   layout.y = yuv_plane_info[0].y;
209   layout.cr = yuv_plane_info[0].cr;
210   layout.cb = yuv_plane_info[0].cb;
211   layout.yStride = static_cast<uint32_t>(yuv_plane_info[0].ystride);
212   layout.cStride = static_cast<uint32_t>(yuv_plane_info[0].cstride);
213   layout.chromaStep = static_cast<uint32_t>(yuv_plane_info[0].chroma_step);
214   hidl_cb(Error::NONE, layout);
215   return Void();
216 }
217 
unlock(void * buffer,unlock_cb hidl_cb)218 Return<void> QtiMapper::unlock(void *buffer, unlock_cb hidl_cb) {
219   auto err = Error::BAD_BUFFER;
220   if (buffer != nullptr) {
221     err = static_cast<IMapper_3_0_Error>(buf_mgr_->UnlockBuffer(PRIV_HANDLE_CONST(buffer)));
222   }
223   // We don't have a release fence
224   hidl_cb(err, hidl_handle(nullptr));
225   return Void();
226 }
227 
validateBufferSize(void * buffer,const BufferDescriptorInfo_3_0 & descriptor_info,uint32_t)228 Return<Error> QtiMapper::validateBufferSize(void *buffer,
229                                             const BufferDescriptorInfo_3_0 &descriptor_info,
230                                             uint32_t /*stride*/) {
231   auto err = Error::BAD_BUFFER;
232   auto hnd = static_cast<private_handle_t *>(buffer);
233   if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
234     if (static_cast<IMapper_3_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) {
235       return Error::BAD_BUFFER;
236     }
237     auto info = gralloc::BufferInfo(descriptor_info.width, descriptor_info.height,
238                                     static_cast<uint32_t>(descriptor_info.format),
239                                     static_cast<uint64_t>(descriptor_info.usage));
240     info.layer_count = descriptor_info.layerCount;
241     err = static_cast<IMapper_3_0_Error>(buf_mgr_->ValidateBufferSize(hnd, info));
242   }
243   return err;
244 }
245 
getTransportSize(void * buffer,IMapper_3_0::getTransportSize_cb hidl_cb)246 Return<void> QtiMapper::getTransportSize(void *buffer, IMapper_3_0::getTransportSize_cb hidl_cb) {
247   auto err = Error::BAD_BUFFER;
248   auto hnd = static_cast<private_handle_t *>(buffer);
249   uint32_t num_fds = 0, num_ints = 0;
250   if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
251     if (static_cast<IMapper_3_0_Error>(buf_mgr_->IsBufferImported(hnd)) != Error::NONE) {
252       hidl_cb(err, num_fds, num_ints);
253       return Void();
254     }
255     num_fds = 2;
256     // TODO(user): reduce to transported values;
257     num_ints = static_cast<uint32_t >(hnd->numInts);
258     err = Error::NONE;
259   }
260   ALOGD_IF(DEBUG, "GetTransportSize: num fds: %d num ints: %d err:%d", num_fds, num_ints, err);
261   hidl_cb(err, num_fds, num_ints);
262   return Void();
263 }
264 
isSupported(const BufferDescriptorInfo_3_0 & descriptor_info,IMapper_3_0::isSupported_cb hidl_cb)265 Return<void> QtiMapper::isSupported(const BufferDescriptorInfo_3_0 &descriptor_info,
266                                     IMapper_3_0::isSupported_cb hidl_cb) {
267   IMapperBufferDescriptor descriptor;
268   auto err = CreateDescriptor(descriptor_info, &descriptor);
269   if (err != Error::NONE) {
270     hidl_cb(err, false);
271     return Void();
272   }
273 
274   gralloc::BufferDescriptor desc;
275   err = static_cast<IMapper_3_0_Error>(Decode(descriptor, &desc));
276   if (err != Error::NONE) {
277     hidl_cb(err, false);
278     return Void();
279   }
280 
281   buffer_handle_t buffer;
282   err = static_cast<IMapper_3_0_Error>(buf_mgr_->AllocateBuffer(desc, &buffer, 0, true));
283   if (err != Error::NONE) {
284     hidl_cb(err, false);
285   } else {
286     hidl_cb(err, true);
287   }
288 
289   return Void();
290 }
291 
getMapperExtensions(QtiMapper::getMapperExtensions_cb hidl_cb)292 Return<void> QtiMapper::getMapperExtensions(QtiMapper::getMapperExtensions_cb hidl_cb) {
293   if (extensions_ != nullptr) {
294     hidl_cb(Error::NONE, extensions_);
295   } else {
296     hidl_cb(Error::UNSUPPORTED, extensions_);
297   }
298   return Void();
299 }
300 
301 // Methods from ::android::hidl::base::V1_0::IBase follow.
302 
303 // When we are in passthrough mode, this method is used
304 // by hidl to obtain the SP HAL object
HIDL_FETCH_IMapper(const char *)305 extern "C" IMapper_3_0 *HIDL_FETCH_IMapper(const char * /* name */) {
306   ALOGD_IF(DEBUG, "Fetching IMapper from QtiMapper");
307   auto mapper = new QtiMapper();
308   return static_cast<IMapper_3_0 *>(mapper);
309 }
310 
HIDL_FETCH_IQtiMapper(const char *)311 extern "C" IQtiMapper *HIDL_FETCH_IQtiMapper(const char * /* name */) {
312   ALOGD_IF(DEBUG, "Fetching QtiMapper");
313   return new QtiMapper();
314 }
315 
316 }  // namespace implementation
317 }  // namespace V3_0
318 }  // namespace mapper
319 }  // namespace display
320 }  // namespace hardware
321 }  // namespace qti
322 }  // namespace vendor
323