1 /*
2  * Copyright (C) 2020 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 #include "GrallocModule.h"
18 
19 #define LOG_NDEBUG 0
20 #define LOG_TAG "EmulatedCamera_GrallocModule"
21 #include <log/log.h>
22 
23 using android::hardware::hidl_handle;
24 
25 using V3Error = android::hardware::graphics::mapper::V3_0::Error;
26 using V3Mapper = android::hardware::graphics::mapper::V3_0::IMapper;
27 using V3YCbCrLayout = android::hardware::graphics::mapper::V3_0::YCbCrLayout;
28 
GrallocModule()29 GrallocModule::GrallocModule() {
30   mGralloc3 = V3Mapper::getService();
31   if (mGralloc3 != nullptr) {
32     ALOGV("%s: Using gralloc 3.", __FUNCTION__);
33     return;
34   }
35 
36   const hw_module_t* module = NULL;
37   int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
38   if (ret) {
39     ALOGE("%s: Failed to get gralloc module: %d", __FUNCTION__, ret);
40   } else {
41     ALOGV("%s: Using gralloc 0.", __FUNCTION__);
42     mGralloc0 = reinterpret_cast<const gralloc_module_t *>(module);
43     return;
44   }
45 
46   ALOGE("%s: No gralloc available.", __FUNCTION__);
47 }
48 
import(buffer_handle_t handle,buffer_handle_t * imported_handle)49 int GrallocModule::import(buffer_handle_t handle,
50                           buffer_handle_t* imported_handle) {
51   if (mGralloc3 != nullptr) {
52     V3Error error = V3Error::NONE;
53     auto ret = mGralloc3->importBuffer(
54       handle,
55       [&](const auto& tmp_err, const auto& tmp_buf) {
56         error = tmp_err;
57         if (error == V3Error::NONE) {
58           *imported_handle = static_cast<buffer_handle_t>(tmp_buf);
59         }
60       });
61     if (!ret.isOk() || error != V3Error::NONE) {
62       ALOGE("%s: Failed to import gralloc3 buffer.", __FUNCTION__);
63       return -1;
64     }
65     return 0;
66   }
67 
68   if (mGralloc0 != nullptr) {
69     int ret = mGralloc0->registerBuffer(mGralloc0, handle);
70     if (ret) {
71       ALOGE("%s: Failed to import gralloc0 buffer: %d.", __FUNCTION__, ret);
72     }
73 
74     *imported_handle = handle;
75     return ret;
76   }
77 
78   ALOGE("%s: No gralloc available for import.", __FUNCTION__);
79   return -1;
80 }
81 
release(buffer_handle_t handle)82 int GrallocModule::release(buffer_handle_t handle) {
83   if (mGralloc3 != nullptr) {
84     native_handle_t* native_handle = const_cast<native_handle_t*>(handle);
85 
86     auto ret = mGralloc3->freeBuffer(native_handle);
87     if (!ret.isOk()) {
88       ALOGE("%s: Failed to release gralloc3 buffer.", __FUNCTION__);
89       return -1;
90     }
91     return 0;
92   }
93 
94   if (mGralloc0 != nullptr) {
95     int ret = mGralloc0->unregisterBuffer(mGralloc0, handle);
96     if (ret) {
97       ALOGE("%s: Failed to release gralloc0 buffer: %d.", __FUNCTION__, ret);
98     }
99     return ret;
100   }
101 
102   ALOGE("%s: No gralloc available for release.", __FUNCTION__);
103   return -1;
104 }
105 
lock(buffer_handle_t handle,int usage,int l,int t,int w,int h,void ** vaddr)106 int GrallocModule::lock(buffer_handle_t handle, int usage, int l, int t, int w,
107                         int h, void **vaddr) {
108   if (mGralloc3 != nullptr) {
109     native_handle_t* native_handle = const_cast<native_handle_t*>(handle);
110 
111     V3Mapper::Rect rect;
112     rect.left = l;
113     rect.top = t;
114     rect.width = w;
115     rect.height = h;
116 
117     hidl_handle empty_fence_handle;
118 
119     V3Error error = V3Error::NONE;
120     auto ret = mGralloc3->lock(native_handle, usage, rect, empty_fence_handle,
121                                [&](const auto& tmp_err,
122                                    const auto& tmp_vaddr,
123                                    const auto& /*bytes_per_pixel*/,
124                                    const auto& /*bytes_per_stride*/) {
125                                  error = tmp_err;
126                                  if (tmp_err == V3Error::NONE) {
127                                    *vaddr = tmp_vaddr;
128                                  }
129                                });
130     if (!ret.isOk() || error != V3Error::NONE) {
131       ALOGE("%s Failed to lock gralloc3 buffer.", __FUNCTION__);
132       return -1;
133     }
134     return 0;
135   }
136 
137   if (mGralloc0 != nullptr) {
138     int ret = mGralloc0->lock(mGralloc0, handle, usage, l, t, w, h, vaddr);
139     if (ret) {
140       ALOGE("%s: Failed to lock gralloc0 buffer: %d", __FUNCTION__, ret);
141     }
142     return ret;
143   }
144 
145   ALOGE("%s: No gralloc available for lock.", __FUNCTION__);
146   return -1;
147 }
148 
lock_ycbcr(buffer_handle_t handle,int usage,int l,int t,int w,int h,struct android_ycbcr * ycbcr)149 int GrallocModule::lock_ycbcr(buffer_handle_t handle, int usage, int l, int t,
150                               int w, int h, struct android_ycbcr *ycbcr) {
151   if (mGralloc3 != nullptr) {
152     native_handle_t* native_handle = const_cast<native_handle_t*>(handle);
153 
154     V3Mapper::Rect rect;
155     rect.left = l;
156     rect.top = t;
157     rect.width = w;
158     rect.height = h;
159 
160     hidl_handle empty_fence_handle;
161 
162     V3YCbCrLayout ycbcr_layout = {};
163 
164     V3Error error;
165     auto ret = mGralloc3->lockYCbCr(native_handle, usage, rect,
166                                     empty_fence_handle,
167                                     [&](const auto& tmp_err,
168                                         const auto& tmp_ycbcr_layout) {
169                                       error = tmp_err;
170                                       if (tmp_err == V3Error::NONE) {
171                                         ycbcr_layout = tmp_ycbcr_layout;
172                                       }
173                                     });
174 
175     if (!ret.isOk() || error != V3Error::NONE) {
176       ALOGE("%s: Failed to lock_ycbcr gralloc3 buffer.", __FUNCTION__);
177       return -1;
178     }
179 
180     ycbcr->y = ycbcr_layout.y;
181     ycbcr->cb = ycbcr_layout.cb;
182     ycbcr->cr = ycbcr_layout.cr;
183     ycbcr->ystride = ycbcr_layout.yStride;
184     ycbcr->cstride = ycbcr_layout.cStride;
185     ycbcr->chroma_step = ycbcr_layout.chromaStep;
186     return 0;
187   }
188 
189   if (mGralloc0 != nullptr) {
190     int ret = mGralloc0->lock_ycbcr(mGralloc0, handle, usage, l, t, w, h,
191                                     ycbcr);
192     if (ret) {
193       ALOGE("%s: Failed to lock_ycbcr gralloc0 buffer: %d", __FUNCTION__, ret);
194     }
195     return ret;
196   }
197 
198   ALOGE("%s: No gralloc available for lock_ycbcr.", __FUNCTION__);
199   return -1;
200 }
201 
unlock(buffer_handle_t handle)202 int GrallocModule::unlock(buffer_handle_t handle) {
203   if (mGralloc3 != nullptr) {
204     native_handle_t* native_handle = const_cast<native_handle_t*>(handle);
205 
206     V3Error error;
207     auto ret = mGralloc3->unlock(native_handle,
208                                  [&](const auto& tmp_err, const auto&) {
209                                    error = tmp_err;
210                                  });
211     if (!ret.isOk() || error != V3Error::NONE) {
212       ALOGE("%s: Failed to unlock gralloc3 buffer.", __FUNCTION__);
213       return -1;
214     }
215     return 0;
216   }
217 
218   if (mGralloc0 != nullptr) {
219     int ret = mGralloc0->unlock(mGralloc0, handle);
220     if (ret) {
221       ALOGE("%s: Failed to unlock gralloc0 buffer: %d", __FUNCTION__, ret);
222     }
223     return ret;
224   }
225 
226   ALOGE("%s: No gralloc available for unlock.", __FUNCTION__);
227   return -1;
228 }