OSDN Git Service

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