blob: 526aca23b6e2e09cb9d6a2fb858747f95d7f3597 [file] [log] [blame]
Chia-I Wu0f215c52016-10-11 11:48:21 +08001/*
2 * Copyright 2016 The Android Open Source Project
3 * * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#define LOG_TAG "GrallocMapperPassthrough"
17
Chia-I Wu158d5302016-10-04 06:00:12 +080018#include "GrallocMapper.h"
19
Chia-I Wu939e4012016-12-12 21:51:33 +080020#include <mutex>
Chia-I Wu158d5302016-10-04 06:00:12 +080021#include <vector>
Chia-I Wu939e4012016-12-12 21:51:33 +080022#include <unordered_map>
Chia-I Wu158d5302016-10-04 06:00:12 +080023
24#include <string.h>
25
Chia-I Wu0f215c52016-10-11 11:48:21 +080026#include <hardware/gralloc1.h>
27#include <log/log.h>
28
29namespace android {
30namespace hardware {
31namespace graphics {
32namespace mapper {
33namespace V2_0 {
34namespace implementation {
35
Chia-I Wu158d5302016-10-04 06:00:12 +080036namespace {
Craig Donner0b00adf2016-10-20 17:12:58 -070037
Chia-I Wu158d5302016-10-04 06:00:12 +080038using android::hardware::graphics::allocator::V2_0::Error;
39using android::hardware::graphics::common::V1_0::PixelFormat;
40
41class GrallocMapperHal : public IMapper {
Chia-I Wu0f215c52016-10-11 11:48:21 +080042public:
Chia-I Wu158d5302016-10-04 06:00:12 +080043 GrallocMapperHal(const hw_module_t* module);
44 ~GrallocMapperHal();
Chia-I Wu0f215c52016-10-11 11:48:21 +080045
46 // IMapper interface
Chia-I Wu158d5302016-10-04 06:00:12 +080047 Return<Error> retain(const hidl_handle& bufferHandle) override;
48 Return<Error> release(const hidl_handle& bufferHandle) override;
49 Return<void> getDimensions(const hidl_handle& bufferHandle,
50 getDimensions_cb hidl_cb) override;
51 Return<void> getFormat(const hidl_handle& bufferHandle,
52 getFormat_cb hidl_cb) override;
53 Return<void> getLayerCount(const hidl_handle& bufferHandle,
54 getLayerCount_cb hidl_cb) override;
55 Return<void> getProducerUsageMask(const hidl_handle& bufferHandle,
56 getProducerUsageMask_cb hidl_cb) override;
57 Return<void> getConsumerUsageMask(const hidl_handle& bufferHandle,
58 getConsumerUsageMask_cb hidl_cb) override;
59 Return<void> getBackingStore(const hidl_handle& bufferHandle,
60 getBackingStore_cb hidl_cb) override;
61 Return<void> getStride(const hidl_handle& bufferHandle,
62 getStride_cb hidl_cb) override;
63 Return<void> lock(const hidl_handle& bufferHandle,
Chia-I Wu0f215c52016-10-11 11:48:21 +080064 uint64_t producerUsageMask, uint64_t consumerUsageMask,
Chia-I Wu158d5302016-10-04 06:00:12 +080065 const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
66 lock_cb hidl_cb) override;
67 Return<void> lockFlex(const hidl_handle& bufferHandle,
Chia-I Wu0f215c52016-10-11 11:48:21 +080068 uint64_t producerUsageMask, uint64_t consumerUsageMask,
Chia-I Wu158d5302016-10-04 06:00:12 +080069 const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
70 lockFlex_cb hidl_cb) override;
71 Return<void> unlock(const hidl_handle& bufferHandle,
72 unlock_cb hidl_cb) override;
Chia-I Wu0f215c52016-10-11 11:48:21 +080073
74private:
Craig Donner0b00adf2016-10-20 17:12:58 -070075 void initCapabilities();
76
Chia-I Wu158d5302016-10-04 06:00:12 +080077 template<typename T>
78 void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
Chia-I Wu0f215c52016-10-11 11:48:21 +080079 void initDispatch();
Chia-I Wu158d5302016-10-04 06:00:12 +080080
81 static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect);
82 static bool dupFence(const hidl_handle& fenceHandle, int* outFd);
Chia-I Wu0f215c52016-10-11 11:48:21 +080083
84 gralloc1_device_t* mDevice;
85
Chia-I Wu158d5302016-10-04 06:00:12 +080086 struct {
87 bool layeredBuffers;
88 } mCapabilities;
Craig Donner0b00adf2016-10-20 17:12:58 -070089
Chia-I Wu0f215c52016-10-11 11:48:21 +080090 struct {
91 GRALLOC1_PFN_RETAIN retain;
92 GRALLOC1_PFN_RELEASE release;
93 GRALLOC1_PFN_GET_DIMENSIONS getDimensions;
94 GRALLOC1_PFN_GET_FORMAT getFormat;
Craig Donner0b00adf2016-10-20 17:12:58 -070095 GRALLOC1_PFN_GET_LAYER_COUNT getLayerCount;
Chia-I Wu0f215c52016-10-11 11:48:21 +080096 GRALLOC1_PFN_GET_PRODUCER_USAGE getProducerUsage;
97 GRALLOC1_PFN_GET_CONSUMER_USAGE getConsumerUsage;
98 GRALLOC1_PFN_GET_BACKING_STORE getBackingStore;
99 GRALLOC1_PFN_GET_STRIDE getStride;
100 GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes;
101 GRALLOC1_PFN_LOCK lock;
102 GRALLOC1_PFN_LOCK_FLEX lockFlex;
103 GRALLOC1_PFN_UNLOCK unlock;
104 } mDispatch;
Chia-I Wu939e4012016-12-12 21:51:33 +0800105
106 std::mutex mMutex;
107 std::unordered_map<buffer_handle_t, size_t> mBufferReferenceCounts;
Chia-I Wu0f215c52016-10-11 11:48:21 +0800108};
109
Chia-I Wu158d5302016-10-04 06:00:12 +0800110GrallocMapperHal::GrallocMapperHal(const hw_module_t* module)
111 : mDevice(nullptr), mCapabilities(), mDispatch()
Chia-I Wu0f215c52016-10-11 11:48:21 +0800112{
Chia-I Wu158d5302016-10-04 06:00:12 +0800113 int status = gralloc1_open(module, &mDevice);
Chia-I Wu0f215c52016-10-11 11:48:21 +0800114 if (status) {
Chia-I Wu158d5302016-10-04 06:00:12 +0800115 LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
116 strerror(-status));
Chia-I Wu0f215c52016-10-11 11:48:21 +0800117 }
118
Craig Donner0b00adf2016-10-20 17:12:58 -0700119 initCapabilities();
Chia-I Wu0f215c52016-10-11 11:48:21 +0800120 initDispatch();
121}
122
Chia-I Wu158d5302016-10-04 06:00:12 +0800123GrallocMapperHal::~GrallocMapperHal()
Chia-I Wu0f215c52016-10-11 11:48:21 +0800124{
125 gralloc1_close(mDevice);
126}
127
Chia-I Wu158d5302016-10-04 06:00:12 +0800128void GrallocMapperHal::initCapabilities()
Craig Donner0b00adf2016-10-20 17:12:58 -0700129{
Chia-I Wud412d7b2017-03-07 14:44:04 -0800130 uint32_t count = 0;
Craig Donner0b00adf2016-10-20 17:12:58 -0700131 mDevice->getCapabilities(mDevice, &count, nullptr);
132
Chia-I Wu158d5302016-10-04 06:00:12 +0800133 std::vector<int32_t> caps(count);
134 mDevice->getCapabilities(mDevice, &count, caps.data());
Craig Donner0b00adf2016-10-20 17:12:58 -0700135 caps.resize(count);
136
Chia-I Wu158d5302016-10-04 06:00:12 +0800137 for (auto cap : caps) {
138 switch (cap) {
139 case GRALLOC1_CAPABILITY_LAYERED_BUFFERS:
140 mCapabilities.layeredBuffers = true;
141 break;
142 default:
143 break;
144 }
Craig Donner0b00adf2016-10-20 17:12:58 -0700145 }
Chia-I Wu0f215c52016-10-11 11:48:21 +0800146}
147
Chia-I Wu158d5302016-10-04 06:00:12 +0800148template<typename T>
149void GrallocMapperHal::initDispatch(gralloc1_function_descriptor_t desc,
150 T* outPfn)
Craig Donner0b00adf2016-10-20 17:12:58 -0700151{
Chia-I Wu158d5302016-10-04 06:00:12 +0800152 auto pfn = mDevice->getFunction(mDevice, desc);
153 if (!pfn) {
154 LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
155 }
156
157 *outPfn = reinterpret_cast<T>(pfn);
Craig Donner0b00adf2016-10-20 17:12:58 -0700158}
159
Chia-I Wu158d5302016-10-04 06:00:12 +0800160void GrallocMapperHal::initDispatch()
Chia-I Wu0f215c52016-10-11 11:48:21 +0800161{
Chia-I Wu158d5302016-10-04 06:00:12 +0800162 initDispatch(GRALLOC1_FUNCTION_RETAIN, &mDispatch.retain);
163 initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
164 initDispatch(GRALLOC1_FUNCTION_GET_DIMENSIONS, &mDispatch.getDimensions);
165 initDispatch(GRALLOC1_FUNCTION_GET_FORMAT, &mDispatch.getFormat);
166 if (mCapabilities.layeredBuffers) {
167 initDispatch(GRALLOC1_FUNCTION_GET_LAYER_COUNT,
168 &mDispatch.getLayerCount);
169 }
170 initDispatch(GRALLOC1_FUNCTION_GET_PRODUCER_USAGE,
171 &mDispatch.getProducerUsage);
172 initDispatch(GRALLOC1_FUNCTION_GET_CONSUMER_USAGE,
173 &mDispatch.getConsumerUsage);
174 initDispatch(GRALLOC1_FUNCTION_GET_BACKING_STORE,
175 &mDispatch.getBackingStore);
176 initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride);
177 initDispatch(GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES,
178 &mDispatch.getNumFlexPlanes);
179 initDispatch(GRALLOC1_FUNCTION_LOCK, &mDispatch.lock);
180 initDispatch(GRALLOC1_FUNCTION_LOCK_FLEX, &mDispatch.lockFlex);
181 initDispatch(GRALLOC1_FUNCTION_UNLOCK, &mDispatch.unlock);
Chia-I Wu0f215c52016-10-11 11:48:21 +0800182}
183
Chia-I Wu158d5302016-10-04 06:00:12 +0800184gralloc1_rect_t GrallocMapperHal::asGralloc1Rect(const IMapper::Rect& rect)
Chia-I Wu0f215c52016-10-11 11:48:21 +0800185{
Chia-I Wu158d5302016-10-04 06:00:12 +0800186 return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height};
Chia-I Wu0f215c52016-10-11 11:48:21 +0800187}
188
Chia-I Wu158d5302016-10-04 06:00:12 +0800189bool GrallocMapperHal::dupFence(const hidl_handle& fenceHandle, int* outFd)
Chia-I Wu0f215c52016-10-11 11:48:21 +0800190{
Chia-I Wu158d5302016-10-04 06:00:12 +0800191 auto handle = fenceHandle.getNativeHandle();
192 if (!handle || handle->numFds == 0) {
193 *outFd = -1;
194 return true;
195 }
196
197 if (handle->numFds > 1) {
198 ALOGE("invalid fence handle with %d fds", handle->numFds);
199 return false;
200 }
201
202 *outFd = dup(handle->data[0]);
203 return (*outFd >= 0);
Chia-I Wu0f215c52016-10-11 11:48:21 +0800204}
205
Chia-I Wu158d5302016-10-04 06:00:12 +0800206Return<Error> GrallocMapperHal::retain(const hidl_handle& bufferHandle)
Chia-I Wu0f215c52016-10-11 11:48:21 +0800207{
Chia-I Wu158d5302016-10-04 06:00:12 +0800208 int32_t err = mDispatch.retain(mDevice, bufferHandle);
Chia-I Wu939e4012016-12-12 21:51:33 +0800209 if (err == GRALLOC1_ERROR_NONE) {
210 auto nativeHandle = bufferHandle.getNativeHandle();
211 std::lock_guard<std::mutex> lock(mMutex);
212
213 ++mBufferReferenceCounts[nativeHandle];
214 }
Chia-I Wu158d5302016-10-04 06:00:12 +0800215 return static_cast<Error>(err);
Chia-I Wu0f215c52016-10-11 11:48:21 +0800216}
217
Chia-I Wu158d5302016-10-04 06:00:12 +0800218Return<Error> GrallocMapperHal::release(const hidl_handle& bufferHandle)
Craig Donner0b00adf2016-10-20 17:12:58 -0700219{
Chia-I Wu158d5302016-10-04 06:00:12 +0800220 int32_t err = mDispatch.release(mDevice, bufferHandle);
Chia-I Wu939e4012016-12-12 21:51:33 +0800221 if (err == GRALLOC1_ERROR_NONE) {
222 auto nativeHandle = bufferHandle.getNativeHandle();
223 std::lock_guard<std::mutex> lock(mMutex);
224
225 auto iter = mBufferReferenceCounts.find(bufferHandle);
226 if (iter == mBufferReferenceCounts.end()) {
227 // this should never happen
228 err = GRALLOC1_ERROR_BAD_HANDLE;
229 } else if (--iter->second == 0) {
230 native_handle_close(nativeHandle);
231 native_handle_delete(const_cast<native_handle_t*>(nativeHandle));
232
233 mBufferReferenceCounts.erase(iter);
234 }
235 }
236
Chia-I Wu158d5302016-10-04 06:00:12 +0800237 return static_cast<Error>(err);
238}
239
240Return<void> GrallocMapperHal::getDimensions(const hidl_handle& bufferHandle,
241 getDimensions_cb hidl_cb)
242{
243 uint32_t width = 0;
244 uint32_t height = 0;
245 int32_t err = mDispatch.getDimensions(mDevice, bufferHandle,
246 &width, &height);
247
248 hidl_cb(static_cast<Error>(err), width, height);
249 return Void();
250}
251
252Return<void> GrallocMapperHal::getFormat(const hidl_handle& bufferHandle,
253 getFormat_cb hidl_cb)
254{
255 int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
256 int32_t err = mDispatch.getFormat(mDevice, bufferHandle, &format);
257
258 hidl_cb(static_cast<Error>(err), static_cast<PixelFormat>(format));
259 return Void();
260}
261
262Return<void> GrallocMapperHal::getLayerCount(const hidl_handle& bufferHandle,
263 getLayerCount_cb hidl_cb)
264{
265 int32_t err = GRALLOC1_ERROR_NONE;
266 uint32_t count = 1;
267 if (mCapabilities.layeredBuffers) {
268 err = mDispatch.getLayerCount(mDevice, bufferHandle, &count);
269 }
270
271 hidl_cb(static_cast<Error>(err), count);
272 return Void();
273}
274
275Return<void> GrallocMapperHal::getProducerUsageMask(
276 const hidl_handle& bufferHandle, getProducerUsageMask_cb hidl_cb)
277{
278 uint64_t mask = 0x0;
279 int32_t err = mDispatch.getProducerUsage(mDevice, bufferHandle, &mask);
280
281 hidl_cb(static_cast<Error>(err), mask);
282 return Void();
283}
284
285Return<void> GrallocMapperHal::getConsumerUsageMask(
286 const hidl_handle& bufferHandle, getConsumerUsageMask_cb hidl_cb)
287{
288 uint64_t mask = 0x0;
289 int32_t err = mDispatch.getConsumerUsage(mDevice, bufferHandle, &mask);
290
291 hidl_cb(static_cast<Error>(err), mask);
292 return Void();
293}
294
295Return<void> GrallocMapperHal::getBackingStore(
296 const hidl_handle& bufferHandle, getBackingStore_cb hidl_cb)
297{
298 uint64_t store = 0;
299 int32_t err = mDispatch.getBackingStore(mDevice, bufferHandle, &store);
300
301 hidl_cb(static_cast<Error>(err), store);
302 return Void();
303}
304
305Return<void> GrallocMapperHal::getStride(const hidl_handle& bufferHandle,
306 getStride_cb hidl_cb)
307{
308 uint32_t stride = 0;
309 int32_t err = mDispatch.getStride(mDevice, bufferHandle, &stride);
310
311 hidl_cb(static_cast<Error>(err), stride);
312 return Void();
313}
314
315Return<void> GrallocMapperHal::lock(const hidl_handle& bufferHandle,
316 uint64_t producerUsageMask, uint64_t consumerUsageMask,
317 const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
318 lock_cb hidl_cb)
319{
320 gralloc1_rect_t rect = asGralloc1Rect(accessRegion);
321
322 int fence = -1;
323 if (!dupFence(acquireFence, &fence)) {
324 hidl_cb(Error::NO_RESOURCES, nullptr);
325 return Void();
326 }
327
328 void* data = nullptr;
329 int32_t err = mDispatch.lock(mDevice, bufferHandle, producerUsageMask,
330 consumerUsageMask, &rect, &data, fence);
331 if (err != GRALLOC1_ERROR_NONE) {
332 close(fence);
333 }
334
335 hidl_cb(static_cast<Error>(err), data);
336 return Void();
337}
338
339Return<void> GrallocMapperHal::lockFlex(const hidl_handle& bufferHandle,
340 uint64_t producerUsageMask, uint64_t consumerUsageMask,
341 const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
342 lockFlex_cb hidl_cb)
343{
344 FlexLayout layout_reply{};
345
346 uint32_t planeCount = 0;
347 int32_t err = mDispatch.getNumFlexPlanes(mDevice, bufferHandle,
348 &planeCount);
349 if (err != GRALLOC1_ERROR_NONE) {
350 hidl_cb(static_cast<Error>(err), layout_reply);
351 return Void();
352 }
353
354 gralloc1_rect_t rect = asGralloc1Rect(accessRegion);
355
356 int fence = -1;
357 if (!dupFence(acquireFence, &fence)) {
358 hidl_cb(Error::NO_RESOURCES, layout_reply);
359 return Void();
360 }
361
362 std::vector<android_flex_plane_t> planes(planeCount);
363 android_flex_layout_t layout{};
364 layout.num_planes = planes.size();
365 layout.planes = planes.data();
366
367 err = mDispatch.lockFlex(mDevice, bufferHandle, producerUsageMask,
368 consumerUsageMask, &rect, &layout, fence);
369 if (err == GRALLOC1_ERROR_NONE) {
370 layout_reply.format = static_cast<FlexFormat>(layout.format);
371
372 planes.resize(layout.num_planes);
373 layout_reply.planes.setToExternal(
374 reinterpret_cast<FlexPlane*>(planes.data()), planes.size());
Craig Donner0b00adf2016-10-20 17:12:58 -0700375 } else {
Chia-I Wu158d5302016-10-04 06:00:12 +0800376 close(fence);
Craig Donner0b00adf2016-10-20 17:12:58 -0700377 }
Chia-I Wu158d5302016-10-04 06:00:12 +0800378
379 hidl_cb(static_cast<Error>(err), layout_reply);
380 return Void();
Craig Donner0b00adf2016-10-20 17:12:58 -0700381}
382
Chia-I Wu158d5302016-10-04 06:00:12 +0800383Return<void> GrallocMapperHal::unlock(const hidl_handle& bufferHandle,
384 unlock_cb hidl_cb)
Chia-I Wu0f215c52016-10-11 11:48:21 +0800385{
Chia-I Wu158d5302016-10-04 06:00:12 +0800386 int32_t fence = -1;
387 int32_t err = mDispatch.unlock(mDevice, bufferHandle, &fence);
388
389 NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
390 hidl_handle fenceHandle;
391 if (err == GRALLOC1_ERROR_NONE && fence >= 0) {
392 auto nativeHandle = native_handle_init(fenceStorage, 1, 0);
393 nativeHandle->data[0] = fence;
394
395 fenceHandle = nativeHandle;
396 }
397
398 hidl_cb(static_cast<Error>(err), fenceHandle);
399 return Void();
Chia-I Wu0f215c52016-10-11 11:48:21 +0800400}
401
Chia-I Wu158d5302016-10-04 06:00:12 +0800402} // anonymous namespace
Chia-I Wu0f215c52016-10-11 11:48:21 +0800403
Chia-I Wu158d5302016-10-04 06:00:12 +0800404IMapper* HIDL_FETCH_IMapper(const char* /* name */) {
405 const hw_module_t* module = nullptr;
406 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
407 if (err) {
408 ALOGE("failed to get gralloc module");
409 return nullptr;
Chia-I Wu0f215c52016-10-11 11:48:21 +0800410 }
411
Chia-I Wu158d5302016-10-04 06:00:12 +0800412 uint8_t major = (module->module_api_version >> 8) & 0xff;
413 if (major != 1) {
414 ALOGE("unknown gralloc module major version %d", major);
415 return nullptr;
Chia-I Wu0f215c52016-10-11 11:48:21 +0800416 }
417
Chia-I Wu158d5302016-10-04 06:00:12 +0800418 return new GrallocMapperHal(module);
Chia-I Wu0f215c52016-10-11 11:48:21 +0800419}
420
421} // namespace implementation
422} // namespace V2_0
423} // namespace mapper
424} // namespace graphics
425} // namespace hardware
426} // namespace android