blob: 2af1d2cf9330ba764eb3640c363c61ca9d9dc8df [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
Craig Donner0b00adf2016-10-20 17:12:58 -070018#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
Chia-I Wu0f215c52016-10-11 11:48:21 +080019#include <android/hardware/graphics/mapper/2.0/IMapper.h>
20#include <hardware/gralloc1.h>
21#include <log/log.h>
22
Craig Donner0b00adf2016-10-20 17:12:58 -070023#include <unordered_set>
24
Chia-I Wu0f215c52016-10-11 11:48:21 +080025namespace android {
26namespace hardware {
27namespace graphics {
28namespace mapper {
29namespace V2_0 {
30namespace implementation {
31
Craig Donner0b00adf2016-10-20 17:12:58 -070032using Capability = allocator::V2_0::IAllocator::Capability;
33
Chia-I Wu0f215c52016-10-11 11:48:21 +080034class GrallocDevice : public Device {
35public:
36 GrallocDevice();
37 ~GrallocDevice();
38
39 // IMapper interface
40 Error retain(const native_handle_t* bufferHandle);
41 Error release(const native_handle_t* bufferHandle);
42 Error getDimensions(const native_handle_t* bufferHandle,
43 uint32_t* outWidth, uint32_t* outHeight);
44 Error getFormat(const native_handle_t* bufferHandle,
45 PixelFormat* outFormat);
Craig Donner0b00adf2016-10-20 17:12:58 -070046 Error getLayerCount(const native_handle_t* bufferHandle,
47 uint32_t* outLayerCount);
Chia-I Wu0f215c52016-10-11 11:48:21 +080048 Error getProducerUsageMask(const native_handle_t* bufferHandle,
49 uint64_t* outUsageMask);
50 Error getConsumerUsageMask(const native_handle_t* bufferHandle,
51 uint64_t* outUsageMask);
52 Error getBackingStore(const native_handle_t* bufferHandle,
53 BackingStore* outStore);
54 Error getStride(const native_handle_t* bufferHandle, uint32_t* outStride);
55 Error getNumFlexPlanes(const native_handle_t* bufferHandle,
56 uint32_t* outNumPlanes);
57 Error lock(const native_handle_t* bufferHandle,
58 uint64_t producerUsageMask, uint64_t consumerUsageMask,
59 const Rect* accessRegion, int32_t acquireFence, void** outData);
60 Error lockFlex(const native_handle_t* bufferHandle,
61 uint64_t producerUsageMask, uint64_t consumerUsageMask,
62 const Rect* accessRegion, int32_t acquireFence,
63 FlexLayout* outFlexLayout);
64 Error unlock(const native_handle_t* bufferHandle,
65 int32_t* outReleaseFence);
66
67private:
Craig Donner0b00adf2016-10-20 17:12:58 -070068 void initCapabilities();
69
Chia-I Wu0f215c52016-10-11 11:48:21 +080070 void initDispatch();
Craig Donner0b00adf2016-10-20 17:12:58 -070071 bool hasCapability(Capability capability) const;
Chia-I Wu0f215c52016-10-11 11:48:21 +080072
73 gralloc1_device_t* mDevice;
74
Craig Donner0b00adf2016-10-20 17:12:58 -070075 std::unordered_set<Capability> mCapabilities;
76
Chia-I Wu0f215c52016-10-11 11:48:21 +080077 struct {
78 GRALLOC1_PFN_RETAIN retain;
79 GRALLOC1_PFN_RELEASE release;
80 GRALLOC1_PFN_GET_DIMENSIONS getDimensions;
81 GRALLOC1_PFN_GET_FORMAT getFormat;
Craig Donner0b00adf2016-10-20 17:12:58 -070082 GRALLOC1_PFN_GET_LAYER_COUNT getLayerCount;
Chia-I Wu0f215c52016-10-11 11:48:21 +080083 GRALLOC1_PFN_GET_PRODUCER_USAGE getProducerUsage;
84 GRALLOC1_PFN_GET_CONSUMER_USAGE getConsumerUsage;
85 GRALLOC1_PFN_GET_BACKING_STORE getBackingStore;
86 GRALLOC1_PFN_GET_STRIDE getStride;
87 GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes;
88 GRALLOC1_PFN_LOCK lock;
89 GRALLOC1_PFN_LOCK_FLEX lockFlex;
90 GRALLOC1_PFN_UNLOCK unlock;
91 } mDispatch;
92};
93
94GrallocDevice::GrallocDevice()
95{
96 const hw_module_t* module;
97 int status = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
98 if (status) {
99 LOG_ALWAYS_FATAL("failed to get gralloc module");
100 }
101
102 uint8_t major = (module->module_api_version >> 8) & 0xff;
103 if (major != 1) {
104 LOG_ALWAYS_FATAL("unknown gralloc module major version %d", major);
105 }
106
107 status = gralloc1_open(module, &mDevice);
108 if (status) {
109 LOG_ALWAYS_FATAL("failed to open gralloc1 device");
110 }
111
Craig Donner0b00adf2016-10-20 17:12:58 -0700112 initCapabilities();
Chia-I Wu0f215c52016-10-11 11:48:21 +0800113 initDispatch();
114}
115
116GrallocDevice::~GrallocDevice()
117{
118 gralloc1_close(mDevice);
119}
120
Craig Donner0b00adf2016-10-20 17:12:58 -0700121void GrallocDevice::initCapabilities()
122{
123 uint32_t count;
124 mDevice->getCapabilities(mDevice, &count, nullptr);
125
126 std::vector<Capability> caps(count);
127 mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
128 std::underlying_type<Capability>::type*>(caps.data()));
129 caps.resize(count);
130
131 mCapabilities.insert(caps.cbegin(), caps.cend());
132}
133
Chia-I Wu0f215c52016-10-11 11:48:21 +0800134void GrallocDevice::initDispatch()
135{
136#define CHECK_FUNC(func, desc) do { \
137 mDispatch.func = reinterpret_cast<decltype(mDispatch.func)>( \
138 mDevice->getFunction(mDevice, desc)); \
139 if (!mDispatch.func) { \
140 LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc); \
141 } \
142} while (0)
143
144 CHECK_FUNC(retain, GRALLOC1_FUNCTION_RETAIN);
145 CHECK_FUNC(release, GRALLOC1_FUNCTION_RELEASE);
146 CHECK_FUNC(getDimensions, GRALLOC1_FUNCTION_GET_DIMENSIONS);
147 CHECK_FUNC(getFormat, GRALLOC1_FUNCTION_GET_FORMAT);
Craig Donner0b00adf2016-10-20 17:12:58 -0700148 if (hasCapability(Capability::LAYERED_BUFFERS)) {
149 CHECK_FUNC(getLayerCount, GRALLOC1_FUNCTION_GET_LAYER_COUNT);
150 }
Chia-I Wu0f215c52016-10-11 11:48:21 +0800151 CHECK_FUNC(getProducerUsage, GRALLOC1_FUNCTION_GET_PRODUCER_USAGE);
152 CHECK_FUNC(getConsumerUsage, GRALLOC1_FUNCTION_GET_CONSUMER_USAGE);
153 CHECK_FUNC(getBackingStore, GRALLOC1_FUNCTION_GET_BACKING_STORE);
154 CHECK_FUNC(getStride, GRALLOC1_FUNCTION_GET_STRIDE);
155 CHECK_FUNC(getNumFlexPlanes, GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES);
156 CHECK_FUNC(lock, GRALLOC1_FUNCTION_LOCK);
157 CHECK_FUNC(lockFlex, GRALLOC1_FUNCTION_LOCK_FLEX);
158 CHECK_FUNC(unlock, GRALLOC1_FUNCTION_UNLOCK);
159
160#undef CHECK_FUNC
161}
162
Craig Donner0b00adf2016-10-20 17:12:58 -0700163bool GrallocDevice::hasCapability(Capability capability) const
164{
165 return (mCapabilities.count(capability) > 0);
166}
167
Chia-I Wu0f215c52016-10-11 11:48:21 +0800168Error GrallocDevice::retain(const native_handle_t* bufferHandle)
169{
170 int32_t error = mDispatch.retain(mDevice, bufferHandle);
171 return static_cast<Error>(error);
172}
173
174Error GrallocDevice::release(const native_handle_t* bufferHandle)
175{
176 int32_t error = mDispatch.release(mDevice, bufferHandle);
177 return static_cast<Error>(error);
178}
179
180Error GrallocDevice::getDimensions(const native_handle_t* bufferHandle,
181 uint32_t* outWidth, uint32_t* outHeight)
182{
183 int32_t error = mDispatch.getDimensions(mDevice, bufferHandle,
184 outWidth, outHeight);
185 return static_cast<Error>(error);
186}
187
188Error GrallocDevice::getFormat(const native_handle_t* bufferHandle,
189 PixelFormat* outFormat)
190{
191 int32_t error = mDispatch.getFormat(mDevice, bufferHandle,
192 reinterpret_cast<int32_t*>(outFormat));
193 return static_cast<Error>(error);
194}
195
Craig Donner0b00adf2016-10-20 17:12:58 -0700196Error GrallocDevice::getLayerCount(const native_handle_t* bufferHandle,
197 uint32_t* outLayerCount)
198{
199 if (hasCapability(Capability::LAYERED_BUFFERS)) {
200 int32_t error = mDispatch.getLayerCount(mDevice, bufferHandle,
201 outLayerCount);
202 return static_cast<Error>(error);
203 } else {
204 *outLayerCount = 1;
205 return Error::NONE;
206 }
207}
208
Chia-I Wu0f215c52016-10-11 11:48:21 +0800209Error GrallocDevice::getProducerUsageMask(const native_handle_t* bufferHandle,
210 uint64_t* outUsageMask)
211{
212 int32_t error = mDispatch.getProducerUsage(mDevice, bufferHandle,
213 outUsageMask);
214 return static_cast<Error>(error);
215}
216
217Error GrallocDevice::getConsumerUsageMask(const native_handle_t* bufferHandle,
218 uint64_t* outUsageMask)
219{
220 int32_t error = mDispatch.getConsumerUsage(mDevice, bufferHandle,
221 outUsageMask);
222 return static_cast<Error>(error);
223}
224
225Error GrallocDevice::getBackingStore(const native_handle_t* bufferHandle,
226 BackingStore* outStore)
227{
228 int32_t error = mDispatch.getBackingStore(mDevice, bufferHandle,
229 outStore);
230 return static_cast<Error>(error);
231}
232
233Error GrallocDevice::getStride(const native_handle_t* bufferHandle,
234 uint32_t* outStride)
235{
236 int32_t error = mDispatch.getStride(mDevice, bufferHandle, outStride);
237 return static_cast<Error>(error);
238}
239
240Error GrallocDevice::getNumFlexPlanes(const native_handle_t* bufferHandle,
241 uint32_t* outNumPlanes)
242{
243 int32_t error = mDispatch.getNumFlexPlanes(mDevice, bufferHandle,
244 outNumPlanes);
245 return static_cast<Error>(error);
246}
247
248Error GrallocDevice::lock(const native_handle_t* bufferHandle,
249 uint64_t producerUsageMask, uint64_t consumerUsageMask,
250 const Rect* accessRegion, int32_t acquireFence,
251 void** outData)
252{
253 int32_t error = mDispatch.lock(mDevice, bufferHandle,
254 producerUsageMask, consumerUsageMask,
255 reinterpret_cast<const gralloc1_rect_t*>(accessRegion),
256 outData, acquireFence);
257 return static_cast<Error>(error);
258}
259
260Error GrallocDevice::lockFlex(const native_handle_t* bufferHandle,
261 uint64_t producerUsageMask, uint64_t consumerUsageMask,
262 const Rect* accessRegion, int32_t acquireFence,
263 FlexLayout* outFlexLayout)
264{
265 int32_t error = mDispatch.lockFlex(mDevice, bufferHandle,
266 producerUsageMask, consumerUsageMask,
267 reinterpret_cast<const gralloc1_rect_t*>(accessRegion),
268 reinterpret_cast<android_flex_layout_t*>(outFlexLayout),
269 acquireFence);
270 return static_cast<Error>(error);
271}
272
273Error GrallocDevice::unlock(const native_handle_t* bufferHandle,
274 int32_t* outReleaseFence)
275{
276 int32_t error = mDispatch.unlock(mDevice, bufferHandle, outReleaseFence);
277 return static_cast<Error>(error);
278}
279
280class GrallocMapper : public IMapper {
281public:
282 GrallocMapper() : IMapper{
283 .createDevice = createDevice,
284 .destroyDevice = destroyDevice,
285 .retain = retain,
286 .release = release,
287 .getDimensions = getDimensions,
288 .getFormat = getFormat,
Craig Donner0b00adf2016-10-20 17:12:58 -0700289 .getLayerCount = getLayerCount,
Chia-I Wu0f215c52016-10-11 11:48:21 +0800290 .getProducerUsageMask = getProducerUsageMask,
291 .getConsumerUsageMask = getConsumerUsageMask,
292 .getBackingStore = getBackingStore,
293 .getStride = getStride,
294 .getNumFlexPlanes = getNumFlexPlanes,
295 .lock = lock,
296 .lockFlex = lockFlex,
297 .unlock = unlock,
298 } {}
299
300 const IMapper* getInterface() const
301 {
302 return static_cast<const IMapper*>(this);
303 }
304
305private:
306 static GrallocDevice* cast(Device* device)
307 {
308 return reinterpret_cast<GrallocDevice*>(device);
309 }
310
311 static Error createDevice(Device** outDevice)
312 {
313 *outDevice = new GrallocDevice;
314 return Error::NONE;
315 }
316
317 static Error destroyDevice(Device* device)
318 {
319 delete cast(device);
320 return Error::NONE;
321 }
322
323 static Error retain(Device* device,
324 const native_handle_t* bufferHandle)
325 {
326 return cast(device)->retain(bufferHandle);
327 }
328
329 static Error release(Device* device,
330 const native_handle_t* bufferHandle)
331 {
332 return cast(device)->release(bufferHandle);
333 }
334
335 static Error getDimensions(Device* device,
336 const native_handle_t* bufferHandle,
337 uint32_t* outWidth, uint32_t* outHeight)
338 {
339 return cast(device)->getDimensions(bufferHandle, outWidth, outHeight);
340 }
341
342 static Error getFormat(Device* device,
343 const native_handle_t* bufferHandle, PixelFormat* outFormat)
344 {
345 return cast(device)->getFormat(bufferHandle, outFormat);
346 }
347
Craig Donner0b00adf2016-10-20 17:12:58 -0700348 static Error getLayerCount(Device* device,
349 const native_handle_t* bufferHandle, uint32_t* outLayerCount)
350 {
351 return cast(device)->getLayerCount(bufferHandle, outLayerCount);
352 }
353
Chia-I Wu0f215c52016-10-11 11:48:21 +0800354 static Error getProducerUsageMask(Device* device,
355 const native_handle_t* bufferHandle, uint64_t* outUsageMask)
356 {
357 return cast(device)->getProducerUsageMask(bufferHandle, outUsageMask);
358 }
359
360 static Error getConsumerUsageMask(Device* device,
361 const native_handle_t* bufferHandle, uint64_t* outUsageMask)
362 {
363 return cast(device)->getConsumerUsageMask(bufferHandle, outUsageMask);
364 }
365
366 static Error getBackingStore(Device* device,
367 const native_handle_t* bufferHandle, BackingStore* outStore)
368 {
369 return cast(device)->getBackingStore(bufferHandle, outStore);
370 }
371
372 static Error getStride(Device* device,
373 const native_handle_t* bufferHandle, uint32_t* outStride)
374 {
375 return cast(device)->getStride(bufferHandle, outStride);
376 }
377
378 static Error getNumFlexPlanes(Device* device,
379 const native_handle_t* bufferHandle, uint32_t* outNumPlanes)
380 {
381 return cast(device)->getNumFlexPlanes(bufferHandle, outNumPlanes);
382 }
383
384 static Error lock(Device* device,
385 const native_handle_t* bufferHandle,
386 uint64_t producerUsageMask, uint64_t consumerUsageMask,
387 const Device::Rect* accessRegion, int32_t acquireFence,
388 void** outData)
389 {
390 return cast(device)->lock(bufferHandle,
391 producerUsageMask, consumerUsageMask,
392 accessRegion, acquireFence, outData);
393 }
394
395 static Error lockFlex(Device* device,
396 const native_handle_t* bufferHandle,
397 uint64_t producerUsageMask, uint64_t consumerUsageMask,
398 const Device::Rect* accessRegion, int32_t acquireFence,
399 FlexLayout* outFlexLayout)
400 {
401 return cast(device)->lockFlex(bufferHandle,
402 producerUsageMask, consumerUsageMask,
403 accessRegion, acquireFence, outFlexLayout);
404 }
405
406 static Error unlock(Device* device,
407 const native_handle_t* bufferHandle, int32_t* outReleaseFence)
408 {
409 return cast(device)->unlock(bufferHandle, outReleaseFence);
410 }
411};
412
413extern "C" const void* HALLIB_FETCH_Interface(const char* name)
414{
415 if (strcmp(name, "android.hardware.graphics.mapper@2.0::IMapper") == 0) {
416 static GrallocMapper sGrallocMapper;
417 return sGrallocMapper.getInterface();
418 }
419
420 return nullptr;
421}
422
423} // namespace implementation
424} // namespace V2_0
425} // namespace mapper
426} // namespace graphics
427} // namespace hardware
428} // namespace android