OSDN Git Service

Remove the reject checking for HAL_PIXEL_FORMAT_YCbCr_420_888
[android-x86/external-minigbm.git] / cros_gralloc / gralloc1 / cros_gralloc1_module.cc
1 /*
2  * Copyright 2016 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 #undef LOG_TAG
18 #define LOG_TAG "CrosGralloc1 "
19 //#define LOG_NDEBUG 0
20
21 #include "cros_gralloc1_module.h"
22 #include "drv.h"
23
24 #include <hardware/gralloc.h>
25
26 #include <inttypes.h>
27 #include "../i915_private_android.h"
28 #include "../i915_private_android_types.h"
29
30 template <typename PFN, typename T> static gralloc1_function_pointer_t asFP(T function)
31 {
32         static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
33         return reinterpret_cast<gralloc1_function_pointer_t>(function);
34 }
35
36 uint64_t cros_gralloc1_convert_usage(uint64_t producer_flags, uint64_t consumer_flags)
37 {
38         uint64_t usage = BO_USE_NONE;
39
40         if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CURSOR)
41                 usage |= BO_USE_CURSOR;
42         if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CPU_READ)
43                 usage |= BO_USE_SW_READ_RARELY;
44         if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN)
45                 usage |= BO_USE_SW_READ_OFTEN;
46         if ((consumer_flags & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) ||
47             (consumer_flags & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) {
48                 /* HWC wants to use display hardware, but can defer to OpenGL. */
49                 usage |= BO_USE_SCANOUT | BO_USE_TEXTURE;
50         } else if (consumer_flags & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
51                 usage |= BO_USE_TEXTURE;
52         }
53         if (consumer_flags & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER)
54                 /*HACK: See b/30054495 */
55                 usage |= BO_USE_SW_READ_OFTEN;
56         if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CAMERA)
57                 usage |= BO_USE_CAMERA_READ;
58         if (consumer_flags & GRALLOC1_CONSUMER_USAGE_RENDERSCRIPT)
59                 usage |= BO_USE_RENDERSCRIPT;
60
61         if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ)
62                 usage |= BO_USE_SW_READ_RARELY;
63         if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)
64                 usage |= BO_USE_SW_READ_OFTEN;
65         if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_WRITE)
66                 usage |= BO_USE_SW_WRITE_RARELY;
67         if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)
68                 usage |= BO_USE_SW_WRITE_OFTEN;
69         if (producer_flags & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)
70                 usage |= BO_USE_RENDERING;
71         if (producer_flags & GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER)
72                 /* Video wants to use display hardware, but can defer to OpenGL. */
73                 usage |= BO_USE_SCANOUT | BO_USE_RENDERING;
74         if (producer_flags & GRALLOC1_PRODUCER_USAGE_PROTECTED)
75                 usage |= BO_USE_PROTECTED;
76         if (producer_flags & GRALLOC1_PRODUCER_USAGE_CAMERA)
77                 usage |= BO_USE_CAMERA_WRITE;
78
79         return usage;
80 }
81
82 uint64_t cros_gralloc1_convert_map_usage(uint64_t producer_flags, uint64_t consumer_flags)
83 {
84         uint64_t usage = BO_USE_NONE;
85
86         if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CPU_READ)
87                 usage |= BO_MAP_READ;
88         if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN)
89                 usage |= BO_MAP_READ;
90         if (consumer_flags & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER)
91                 /*HACK: See b/30054495 */
92                 usage |= BO_MAP_READ;
93
94         if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ)
95                 usage |= BO_MAP_READ;
96         if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)
97                 usage |= BO_MAP_READ;
98         if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_WRITE)
99                 usage |= BO_MAP_WRITE;
100         if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)
101                 usage |= BO_MAP_WRITE;
102
103         return usage;
104 }
105
106 bool IsSupportedYUVFormat(uint32_t droid_format)
107 {
108         switch (droid_format) {
109         case HAL_PIXEL_FORMAT_YCbCr_420_888:
110         case HAL_PIXEL_FORMAT_YV12:
111         case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
112                 return true;
113         default:
114                 return i915_private_supported_yuv_format(droid_format);
115         }
116
117         return false;
118 }
119
120 namespace android
121 {
122
123 /* CrosGralloc1 is a Singleton and pCrosGralloc1 holds pointer to its instance*/
124 static CrosGralloc1 *pCrosGralloc1 = NULL;
125 static uint32_t ref_count = 0;
126 static SpinLock global_lock_;
127
128 CrosGralloc1::CrosGralloc1()
129 {
130         getCapabilities = getCapabilitiesHook;
131         getFunction = getFunctionHook;
132         common.tag = HARDWARE_DEVICE_TAG;
133         common.version = HARDWARE_MODULE_API_VERSION(1, 0);
134         common.close = HookDevClose;
135 }
136
137 CrosGralloc1::~CrosGralloc1()
138 {
139 }
140
141 bool CrosGralloc1::Init()
142 {
143         if (driver)
144                 return true;
145
146         driver = std::make_unique<cros_gralloc_driver>();
147         if (driver->init()) {
148                 cros_gralloc_error("Failed to initialize driver.");
149                 return false;
150         }
151
152         return true;
153 }
154
155 void CrosGralloc1::doGetCapabilities(uint32_t *outCount, int32_t *outCapabilities)
156 {
157         if (outCapabilities == nullptr) {
158                 *outCount = 0;
159         }
160 }
161
162 gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor)
163 {
164         constexpr auto lastDescriptor = static_cast<int32_t>(GRALLOC1_LAST_FUNCTION);
165         if (intDescriptor < 0 || ((intDescriptor > lastDescriptor) && ((intDescriptor < 100) || (intDescriptor > GRALLOC1_LAST_CUSTOM)))) {
166                 ALOGE("Invalid function descriptor %d", intDescriptor);
167                 return nullptr;
168         }
169
170         auto descriptor = static_cast<gralloc1_function_descriptor_t>(intDescriptor);
171         switch (descriptor) {
172         case GRALLOC1_FUNCTION_DUMP:
173                 return asFP<GRALLOC1_PFN_DUMP>(dumpHook);
174         case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
175                 return asFP<GRALLOC1_PFN_CREATE_DESCRIPTOR>(createDescriptorHook);
176         case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
177                 return asFP<GRALLOC1_PFN_DESTROY_DESCRIPTOR>(destroyDescriptorHook);
178         case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
179                 return asFP<GRALLOC1_PFN_SET_CONSUMER_USAGE>(setConsumerUsageHook);
180         case GRALLOC1_FUNCTION_SET_DIMENSIONS:
181                 return asFP<GRALLOC1_PFN_SET_DIMENSIONS>(setDimensionsHook);
182         case GRALLOC1_FUNCTION_SET_FORMAT:
183                 return asFP<GRALLOC1_PFN_SET_FORMAT>(setFormatHook);
184         case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
185                 return asFP<GRALLOC1_PFN_SET_PRODUCER_USAGE>(setProducerUsageHook);
186         case GRALLOC1_FUNCTION_GET_BACKING_STORE:
187                 return asFP<GRALLOC1_PFN_GET_BACKING_STORE>(getBackingStoreHook);
188         case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
189                 return asFP<GRALLOC1_PFN_GET_CONSUMER_USAGE>(getConsumerUsageHook);
190         case GRALLOC1_FUNCTION_GET_DIMENSIONS:
191                 return asFP<GRALLOC1_PFN_GET_DIMENSIONS>(getDimensionsHook);
192         case GRALLOC1_FUNCTION_GET_FORMAT:
193                 return asFP<GRALLOC1_PFN_GET_FORMAT>(getFormatHook);
194         case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
195                 return asFP<GRALLOC1_PFN_GET_PRODUCER_USAGE>(getProducerUsageHook);
196         case GRALLOC1_FUNCTION_GET_STRIDE:
197                 return asFP<GRALLOC1_PFN_GET_STRIDE>(getStrideHook);
198         case GRALLOC1_FUNCTION_ALLOCATE:
199                 if (driver) {
200                         return asFP<GRALLOC1_PFN_ALLOCATE>(allocateBuffers);
201                 } else {
202                         return nullptr;
203                 }
204         case GRALLOC1_FUNCTION_RETAIN:
205                 return asFP<GRALLOC1_PFN_RETAIN>(managementHook<&CrosGralloc1::retain>);
206         case GRALLOC1_FUNCTION_RELEASE:
207                 return asFP<GRALLOC1_PFN_RELEASE>(managementHook<&CrosGralloc1::release>);
208         case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
209                 return asFP<GRALLOC1_PFN_GET_NUM_FLEX_PLANES>(getNumFlexPlanesHook);
210         case GRALLOC1_FUNCTION_LOCK:
211                 return asFP<GRALLOC1_PFN_LOCK>(lockHook<void *, &CrosGralloc1::lock>);
212         case GRALLOC1_FUNCTION_LOCK_FLEX:
213                 return asFP<GRALLOC1_PFN_LOCK_FLEX>(
214                     lockHook<struct android_flex_layout, &CrosGralloc1::lockFlex>);
215         case GRALLOC1_FUNCTION_UNLOCK:
216                 return asFP<GRALLOC1_PFN_UNLOCK>(unlockHook);
217         case GRALLOC1_FUNCTION_SET_MODIFIER:
218                 return asFP<GRALLOC1_PFN_SET_MODIFIER>(setModifierHook);
219         case GRALLOC1_FUNCTION_INVALID:
220                 ALOGE("Invalid function descriptor");
221                 return nullptr;
222         }
223
224         ALOGE("Unknown function descriptor: %d", intDescriptor);
225         return nullptr;
226 }
227
228 void CrosGralloc1::dump(uint32_t *outSize, char *outBuffer)
229 {
230         ALOGV("dump(%u (%p), %p", outSize ? *outSize : 0, outSize, outBuffer);
231 }
232
233 int32_t CrosGralloc1::createDescriptor(gralloc1_buffer_descriptor_t *outDescriptor)
234 {
235         if (!outDescriptor)
236                 return CROS_GRALLOC_ERROR_BAD_DESCRIPTOR;
237
238         struct cros_gralloc_buffer_descriptor *hnd = new cros_gralloc_buffer_descriptor();
239         *outDescriptor = (gralloc1_buffer_descriptor_t)hnd;
240         return CROS_GRALLOC_ERROR_NONE;
241 }
242
243 int32_t CrosGralloc1::destroyDescriptor(gralloc1_buffer_descriptor_t descriptor)
244 {
245         auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptor;
246         delete hnd;
247         return CROS_GRALLOC_ERROR_NONE;
248 }
249
250 int32_t CrosGralloc1::setConsumerUsage(gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage)
251 {
252         auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId;
253         hnd->consumer_usage = intUsage;
254         return CROS_GRALLOC_ERROR_NONE;
255 }
256
257 int32_t CrosGralloc1::setProducerUsage(gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage)
258 {
259         auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId;
260         hnd->producer_usage = intUsage;
261         return CROS_GRALLOC_ERROR_NONE;
262 }
263
264 int32_t CrosGralloc1::setDimensions(gralloc1_buffer_descriptor_t descriptorId, uint32_t width,
265                                     uint32_t height)
266 {
267         auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId;
268         hnd->width = width;
269         hnd->height = height;
270         return CROS_GRALLOC_ERROR_NONE;
271 }
272
273 int32_t CrosGralloc1::setFormat(gralloc1_buffer_descriptor_t descriptorId, int32_t format)
274 {
275         auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId;
276         hnd->droid_format = format;
277         hnd->drm_format = cros_gralloc_convert_format(format);
278         return CROS_GRALLOC_ERROR_NONE;
279 }
280
281 int32_t CrosGralloc1::setModifier(gralloc1_buffer_descriptor_t descriptorId, uint64_t modifier)
282 {
283         auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId;
284         hnd->modifier = modifier;
285         return CROS_GRALLOC_ERROR_NONE;
286 }
287
288 int32_t CrosGralloc1::allocate(struct cros_gralloc_buffer_descriptor *descriptor,
289                                buffer_handle_t *outBufferHandle)
290 {
291         // If this function is being called, it's because we handed out its function
292         // pointer, which only occurs when mDevice has been loaded successfully and
293         // we are permitted to allocate
294         uint64_t usage =
295             cros_gralloc1_convert_usage(descriptor->producer_usage, descriptor->consumer_usage);
296         descriptor->use_flags = usage;
297         bool supported = driver->is_supported(descriptor);
298         if (!supported && (descriptor->consumer_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER)) {
299                 descriptor->use_flags &= ~BO_USE_SCANOUT;
300                 supported = driver->is_supported(descriptor);
301         }
302
303         if (!supported) {
304                 cros_gralloc_error("Unsupported combination -- HAL format: %u, HAL flags: %u, "
305                                    "drv_format: %u, drv_flags: %llu",
306                                    descriptor->droid_format, usage, descriptor->drm_format,
307                                    static_cast<unsigned long long>(descriptor->use_flags));
308                 return CROS_GRALLOC_ERROR_UNSUPPORTED;
309         }
310         if (driver->allocate(descriptor, outBufferHandle))
311                 return CROS_GRALLOC_ERROR_NO_RESOURCES;
312
313         return CROS_GRALLOC_ERROR_NONE;
314 }
315
316 int32_t CrosGralloc1::allocateBuffers(gralloc1_device_t *device, uint32_t numDescriptors,
317                                       const gralloc1_buffer_descriptor_t *descriptors,
318                                       buffer_handle_t *outBuffers)
319 {
320         auto adapter = getAdapter(device);
321         for (uint32_t i = 0; i < numDescriptors; i++) {
322                 auto descriptor = (struct cros_gralloc_buffer_descriptor *)descriptors[i];
323                 if (!descriptor) {
324                         return CROS_GRALLOC_ERROR_BAD_DESCRIPTOR;
325                 }
326
327                 buffer_handle_t bufferHandle = nullptr;
328                 int32_t error = adapter->allocate(descriptor, &bufferHandle);
329                 if (error != CROS_GRALLOC_ERROR_NONE) {
330                         return error;
331                 }
332
333                 outBuffers[i] = bufferHandle;
334         }
335
336         return CROS_GRALLOC_ERROR_NONE;
337 }
338
339 int32_t CrosGralloc1::retain(buffer_handle_t bufferHandle)
340 {
341         if (driver->retain(bufferHandle))
342                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
343
344         return CROS_GRALLOC_ERROR_NONE;
345 }
346
347 int32_t CrosGralloc1::release(buffer_handle_t bufferHandle)
348 {
349         if (driver->release(bufferHandle))
350                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
351
352         return CROS_GRALLOC_ERROR_NONE;
353 }
354
355 int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage_t producerUsage,
356                            gralloc1_consumer_usage_t consumerUsage,
357                            const gralloc1_rect_t &accessRegion, void **outData,
358                            int32_t acquireFence)
359 {
360         uint64_t map_flags;
361         uint8_t *addr[DRV_MAX_PLANES];
362
363         auto hnd = cros_gralloc_convert_handle(bufferHandle);
364         if (!hnd) {
365                 cros_gralloc_error("Invalid handle.");
366                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
367         }
368
369         map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage);
370
371         if (driver->lock(bufferHandle, acquireFence, map_flags, addr))
372                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
373
374         *outData = addr[0];
375
376         return CROS_GRALLOC_ERROR_NONE;
377 }
378
379 android_flex_plane_t ycbcrplanes[3];
380
381 int32_t update_flex_layout(struct android_ycbcr *ycbcr, struct android_flex_layout *outFlexLayout)
382 {
383         outFlexLayout->format = FLEX_FORMAT_YCbCr;
384         outFlexLayout->num_planes = 3;
385         for (uint32_t i = 0; i < outFlexLayout->num_planes; i++) {
386                 ycbcrplanes[i].bits_per_component = 8;
387                 ycbcrplanes[i].bits_used = 8;
388         }
389
390         ycbcrplanes[0].top_left = static_cast<uint8_t *>(ycbcr->y);
391         ycbcrplanes[0].component = FLEX_COMPONENT_Y;
392         ycbcrplanes[0].h_increment = 1;
393         ycbcrplanes[0].v_increment = static_cast<int32_t>(ycbcr->ystride);
394
395         ycbcrplanes[1].top_left = static_cast<uint8_t *>(ycbcr->cb);
396         ycbcrplanes[1].component = FLEX_COMPONENT_Cb;
397         ycbcrplanes[1].h_increment = static_cast<int32_t>(ycbcr->chroma_step);
398         ycbcrplanes[1].v_increment = static_cast<int32_t>(ycbcr->cstride);
399
400         ycbcrplanes[2].top_left = static_cast<uint8_t *>(ycbcr->cr);
401         ycbcrplanes[2].component = FLEX_COMPONENT_Cr;
402         ycbcrplanes[2].h_increment = static_cast<int32_t>(ycbcr->chroma_step);
403         ycbcrplanes[2].v_increment = static_cast<int32_t>(ycbcr->cstride);
404
405         outFlexLayout->planes = ycbcrplanes;
406         return 0;
407 }
408
409 int32_t CrosGralloc1::lockFlex(buffer_handle_t bufferHandle,
410                                gralloc1_producer_usage_t producerUsage,
411                                gralloc1_consumer_usage_t consumerUsage,
412                                const gralloc1_rect_t &accessRegion,
413                                struct android_flex_layout *outData, int32_t acquireFence)
414 {
415         int32_t ret = -EINVAL;
416         int32_t outReleaseFence = 0;
417         struct android_ycbcr ycbcrData;
418
419         /*Check the format and support only for YUV format */
420         auto hnd = cros_gralloc_convert_handle(bufferHandle);
421         if (!hnd) {
422                 cros_gralloc_error("lockFlex: Invalid handle.");
423                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
424         }
425
426         if (!IsSupportedYUVFormat(hnd->droid_format)) {
427                 cros_gralloc_error("lockFlex: Non-YUV format not compatible.");
428                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
429         }
430
431         ret = lockYCbCr(bufferHandle, producerUsage, consumerUsage, accessRegion, &ycbcrData,
432                         acquireFence);
433
434         /* convert the data in flex format*/
435         update_flex_layout(&ycbcrData, outData);
436
437         return ret;
438 }
439
440 int32_t CrosGralloc1::lockYCbCr(buffer_handle_t bufferHandle,
441                                 gralloc1_producer_usage_t producerUsage,
442                                 gralloc1_consumer_usage_t consumerUsage,
443                                 const gralloc1_rect_t &accessRegion, struct android_ycbcr *ycbcr,
444                                 int32_t acquireFence)
445 {
446         uint64_t map_flags;
447         uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr };
448
449         auto hnd = cros_gralloc_convert_handle(bufferHandle);
450         if (!hnd) {
451                 cros_gralloc_error("Invalid handle.");
452                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
453         }
454
455         if (!IsSupportedYUVFormat(hnd->droid_format)) {
456                 cros_gralloc_error("Non-YUV format not compatible.");
457                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
458         }
459
460         map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage);
461         if (driver->lock(bufferHandle, acquireFence, map_flags, addr))
462                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
463
464         switch (hnd->format) {
465         case DRM_FORMAT_NV12:
466         case DRM_FORMAT_NV12_Y_TILED_INTEL:
467                 ycbcr->y = addr[0];
468                 ycbcr->cb = addr[1];
469                 ycbcr->cr = addr[1] + 1;
470                 ycbcr->ystride = hnd->strides[0];
471                 ycbcr->cstride = hnd->strides[1];
472                 ycbcr->chroma_step = 2;
473                 break;
474         case DRM_FORMAT_YVU420:
475         case DRM_FORMAT_YVU420_ANDROID:
476                 ycbcr->y = addr[0];
477                 ycbcr->cb = addr[2];
478                 ycbcr->cr = addr[1];
479                 ycbcr->ystride = hnd->strides[0];
480                 ycbcr->cstride = hnd->strides[1];
481                 ycbcr->chroma_step = 1;
482                 break;
483         case DRM_FORMAT_P010:
484                 ycbcr->y = addr[0];
485                 ycbcr->cb = addr[1];
486                 ycbcr->cr = addr[1] + 2;
487                 ycbcr->ystride = hnd->strides[0];
488                 ycbcr->cstride = hnd->strides[1];
489                 ycbcr->chroma_step = 4;
490                 break;
491         default:
492                 return CROS_GRALLOC_ERROR_UNSUPPORTED;
493         }
494
495         return CROS_GRALLOC_ERROR_NONE;
496 }
497
498 int32_t CrosGralloc1::unlock(buffer_handle_t bufferHandle, int32_t *outReleaseFence)
499 {
500         if (driver->unlock(bufferHandle, outReleaseFence))
501                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
502
503         return CROS_GRALLOC_ERROR_NONE;
504 }
505
506 int32_t CrosGralloc1::getNumFlexPlanes(buffer_handle_t buffer, uint32_t *outNumPlanes)
507 {
508         auto hnd = cros_gralloc_convert_handle(buffer);
509         if (!hnd) {
510                 cros_gralloc_error("Invalid handle.");
511                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
512         }
513
514         *outNumPlanes = drv_num_planes_from_format(hnd->format);
515         return CROS_GRALLOC_ERROR_NONE;
516 }
517
518 int32_t CrosGralloc1::getBackingStore(buffer_handle_t buffer, gralloc1_backing_store_t *outStore)
519 {
520         auto hnd = cros_gralloc_convert_handle(buffer);
521         if (!hnd) {
522                 cros_gralloc_error("Invalid handle.");
523                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
524         }
525
526         if (driver->get_backing_store(buffer, outStore))
527                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
528
529         return CROS_GRALLOC_ERROR_NONE;
530 }
531
532 int32_t CrosGralloc1::getConsumerUsage(buffer_handle_t buffer,
533                                        uint64_t * /*gralloc1_consumer_usage_t*/ outUsage)
534 {
535         auto hnd = cros_gralloc_convert_handle(buffer);
536         if (!hnd) {
537                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
538         }
539
540         *outUsage = hnd->consumer_usage;
541         return CROS_GRALLOC_ERROR_NONE;
542 }
543
544 int32_t CrosGralloc1::getDimensions(buffer_handle_t buffer, uint32_t *outWidth, uint32_t *outHeight)
545 {
546         auto hnd = cros_gralloc_convert_handle(buffer);
547         if (!hnd) {
548                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
549         }
550
551         *outWidth = hnd->width;
552         *outHeight = hnd->height;
553         return CROS_GRALLOC_ERROR_NONE;
554 }
555
556 int32_t CrosGralloc1::getFormat(buffer_handle_t buffer, int32_t *outFormat)
557 {
558         auto hnd = cros_gralloc_convert_handle(buffer);
559         if (!hnd) {
560                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
561         }
562
563         *outFormat = hnd->droid_format;
564         return CROS_GRALLOC_ERROR_NONE;
565 }
566
567 int32_t CrosGralloc1::getProducerUsage(buffer_handle_t buffer,
568                                        uint64_t * /*gralloc1_producer_usage_t*/ outUsage)
569 {
570         auto hnd = cros_gralloc_convert_handle(buffer);
571         if (!hnd) {
572                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
573         }
574
575         *outUsage = hnd->producer_usage;
576         return CROS_GRALLOC_ERROR_NONE;
577 }
578
579 int32_t CrosGralloc1::getStride(buffer_handle_t buffer, uint32_t *outStride)
580 {
581         auto hnd = cros_gralloc_convert_handle(buffer);
582         if (!hnd) {
583                 return CROS_GRALLOC_ERROR_BAD_HANDLE;
584         }
585
586         *outStride = hnd->pixel_stride;
587         return CROS_GRALLOC_ERROR_NONE;
588 }
589
590 // static
591 int CrosGralloc1::HookDevOpen(const struct hw_module_t *mod, const char *name,
592                               struct hw_device_t **device)
593 {
594         if (strcmp(name, GRALLOC_HARDWARE_MODULE_ID)) {
595                 ALOGE("Invalid module name- %s", name);
596                 return -EINVAL;
597         }
598
599         ScopedSpinLock lock(global_lock_);
600         ref_count++;
601
602         if (pCrosGralloc1 != NULL) {
603                 *device = &pCrosGralloc1->common;
604                 return 0;
605         } else
606                 pCrosGralloc1 = new CrosGralloc1();
607
608         std::unique_ptr<CrosGralloc1> ctx(pCrosGralloc1);
609         if (!ctx) {
610                 ALOGE("Failed to allocate CrosGralloc1");
611                 return -ENOMEM;
612         }
613
614         if (!ctx->Init()) {
615                 ALOGE("Failed to initialize CrosGralloc1. \n");
616                 return -EINVAL;
617         }
618
619         ctx->common.module = const_cast<hw_module_t *>(mod);
620         *device = &ctx->common;
621         ctx.release();
622         return 0;
623 }
624
625 // static
626 int CrosGralloc1::HookDevClose(hw_device_t * /*dev*/)
627 {
628         ScopedSpinLock lock(global_lock_);
629         if (ref_count > 0) {
630                 ref_count--;
631         }
632
633         if (ref_count > 0) {
634                 return 0;
635         }
636
637         if (pCrosGralloc1) {
638                 delete pCrosGralloc1;
639                 pCrosGralloc1 = NULL;
640         }
641
642         return 0;
643 }
644
645 } // namespace android
646
647 static struct hw_module_methods_t cros_gralloc_module_methods = {
648         .open = android::CrosGralloc1::HookDevOpen,
649 };
650
651 hw_module_t HAL_MODULE_INFO_SYM = {
652         .tag = HARDWARE_MODULE_TAG,
653         .module_api_version = HARDWARE_MODULE_API_VERSION(1, 0),
654         .id = GRALLOC_HARDWARE_MODULE_ID,
655         .name = "Gralloc module",
656         .author = "Chrome OS",
657         .methods = &cros_gralloc_module_methods,
658 };