OSDN Git Service

526aca23b6e2e09cb9d6a2fb858747f95d7f3597
[android-x86/hardware-interfaces.git] / graphics / mapper / 2.0 / default / GrallocMapper.cpp
1 /*
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
18 #include "GrallocMapper.h"
19
20 #include <mutex>
21 #include <vector>
22 #include <unordered_map>
23
24 #include <string.h>
25
26 #include <hardware/gralloc1.h>
27 #include <log/log.h>
28
29 namespace android {
30 namespace hardware {
31 namespace graphics {
32 namespace mapper {
33 namespace V2_0 {
34 namespace implementation {
35
36 namespace {
37
38 using android::hardware::graphics::allocator::V2_0::Error;
39 using android::hardware::graphics::common::V1_0::PixelFormat;
40
41 class GrallocMapperHal : public IMapper {
42 public:
43     GrallocMapperHal(const hw_module_t* module);
44     ~GrallocMapperHal();
45
46     // IMapper interface
47     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,
64             uint64_t producerUsageMask, uint64_t consumerUsageMask,
65             const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
66             lock_cb hidl_cb) override;
67     Return<void> lockFlex(const hidl_handle& bufferHandle,
68             uint64_t producerUsageMask, uint64_t consumerUsageMask,
69             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;
73
74 private:
75     void initCapabilities();
76
77     template<typename T>
78     void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
79     void initDispatch();
80
81     static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect);
82     static bool dupFence(const hidl_handle& fenceHandle, int* outFd);
83
84     gralloc1_device_t* mDevice;
85
86     struct {
87         bool layeredBuffers;
88     } mCapabilities;
89
90     struct {
91         GRALLOC1_PFN_RETAIN retain;
92         GRALLOC1_PFN_RELEASE release;
93         GRALLOC1_PFN_GET_DIMENSIONS getDimensions;
94         GRALLOC1_PFN_GET_FORMAT getFormat;
95         GRALLOC1_PFN_GET_LAYER_COUNT getLayerCount;
96         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;
105
106     std::mutex mMutex;
107     std::unordered_map<buffer_handle_t, size_t> mBufferReferenceCounts;
108 };
109
110 GrallocMapperHal::GrallocMapperHal(const hw_module_t* module)
111     : mDevice(nullptr), mCapabilities(), mDispatch()
112 {
113     int status = gralloc1_open(module, &mDevice);
114     if (status) {
115         LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
116                 strerror(-status));
117     }
118
119     initCapabilities();
120     initDispatch();
121 }
122
123 GrallocMapperHal::~GrallocMapperHal()
124 {
125     gralloc1_close(mDevice);
126 }
127
128 void GrallocMapperHal::initCapabilities()
129 {
130     uint32_t count = 0;
131     mDevice->getCapabilities(mDevice, &count, nullptr);
132
133     std::vector<int32_t> caps(count);
134     mDevice->getCapabilities(mDevice, &count, caps.data());
135     caps.resize(count);
136
137     for (auto cap : caps) {
138         switch (cap) {
139         case GRALLOC1_CAPABILITY_LAYERED_BUFFERS:
140             mCapabilities.layeredBuffers = true;
141             break;
142         default:
143             break;
144         }
145     }
146 }
147
148 template<typename T>
149 void GrallocMapperHal::initDispatch(gralloc1_function_descriptor_t desc,
150         T* outPfn)
151 {
152     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);
158 }
159
160 void GrallocMapperHal::initDispatch()
161 {
162     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);
182 }
183
184 gralloc1_rect_t GrallocMapperHal::asGralloc1Rect(const IMapper::Rect& rect)
185 {
186     return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height};
187 }
188
189 bool GrallocMapperHal::dupFence(const hidl_handle& fenceHandle, int* outFd)
190 {
191     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);
204 }
205
206 Return<Error> GrallocMapperHal::retain(const hidl_handle& bufferHandle)
207 {
208     int32_t err = mDispatch.retain(mDevice, bufferHandle);
209     if (err == GRALLOC1_ERROR_NONE) {
210         auto nativeHandle = bufferHandle.getNativeHandle();
211         std::lock_guard<std::mutex> lock(mMutex);
212
213         ++mBufferReferenceCounts[nativeHandle];
214     }
215     return static_cast<Error>(err);
216 }
217
218 Return<Error> GrallocMapperHal::release(const hidl_handle& bufferHandle)
219 {
220     int32_t err = mDispatch.release(mDevice, bufferHandle);
221     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
237     return static_cast<Error>(err);
238 }
239
240 Return<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
252 Return<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
262 Return<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
275 Return<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
285 Return<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
295 Return<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
305 Return<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
315 Return<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
339 Return<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());
375     } else {
376         close(fence);
377     }
378
379     hidl_cb(static_cast<Error>(err), layout_reply);
380     return Void();
381 }
382
383 Return<void> GrallocMapperHal::unlock(const hidl_handle& bufferHandle,
384         unlock_cb hidl_cb)
385 {
386     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();
400 }
401
402 } // anonymous namespace
403
404 IMapper* 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;
410     }
411
412     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;
416     }
417
418     return new GrallocMapperHal(module);
419 }
420
421 } // namespace implementation
422 } // namespace V2_0
423 } // namespace mapper
424 } // namespace graphics
425 } // namespace hardware
426 } // namespace android