blob: dee2973386378a539104eef184fc87c4fd02a4e7 [file] [log] [blame]
Yin-Chia Yeh248ed702017-01-23 17:27:26 -08001/*
2 * Copyright (C) 2017 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#define LOG_TAG "HandleImporter"
18#include <utils/Log.h>
19#include "HandleImporter.h"
20
21namespace android {
22namespace hardware {
23namespace camera {
24namespace common {
25namespace V1_0 {
26namespace helper {
27
28HandleImporter HandleImporter::sHandleImporter;
29
30HandleImporter& HandleImporter::getInstance() {
31 sHandleImporter.initialize();
32 return sHandleImporter;
33}
34
35bool HandleImporter::initialize() {
36 // allow only one client
37 if (mInitialized) {
38 return false;
39 }
40
41 if (!openGralloc()) {
42 return false;
43 }
44
45 mInitialized = true;
46 return true;
47}
48
49void HandleImporter::cleanup() {
50 if (!mInitialized) {
51 return;
52 }
53
54 closeGralloc();
55 mInitialized = false;
56}
57
58// In IComposer, any buffer_handle_t is owned by the caller and we need to
59// make a clone for hwcomposer2. We also need to translate empty handle
60// to nullptr. This function does that, in-place.
61bool HandleImporter::importBuffer(buffer_handle_t& handle) {
62 if (!handle->numFds && !handle->numInts) {
63 handle = nullptr;
64 return true;
65 }
66
67 buffer_handle_t clone = cloneBuffer(handle);
68 if (!clone) {
69 return false;
70 }
71
72 handle = clone;
73 return true;
74}
75
76void HandleImporter::freeBuffer(buffer_handle_t handle) {
77 if (!handle) {
78 return;
79 }
80
81 releaseBuffer(handle);
82}
83
84bool HandleImporter::importFence(const native_handle_t* handle, int& fd) {
85 if (handle == nullptr || handle->numFds == 0) {
86 fd = -1;
87 } else if (handle->numFds == 1) {
88 fd = dup(handle->data[0]);
89 if (fd < 0) {
90 ALOGE("failed to dup fence fd %d", handle->data[0]);
91 return false;
92 }
93 } else {
94 ALOGE("invalid fence handle with %d file descriptors",
95 handle->numFds);
96 return false;
97 }
98
99 return true;
100}
101
102void HandleImporter::closeFence(int fd) {
103 if (fd >= 0) {
104 close(fd);
105 }
106}
107
108bool HandleImporter::openGralloc() {
109 const hw_module_t* module;
110 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
111 if (err) {
112 ALOGE("failed to get gralloc module");
113 return false;
114 }
115
116 uint8_t major = (module->module_api_version >> 8) & 0xff;
117 if (major > 1) {
118 ALOGE("unknown gralloc module major version %d", major);
119 return false;
120 }
121
122 if (major == 1) {
123 err = gralloc1_open(module, &mDevice);
124 if (err) {
125 ALOGE("failed to open gralloc1 device");
126 return false;
127 }
128
129 mRetain = reinterpret_cast<GRALLOC1_PFN_RETAIN>(
130 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RETAIN));
131 mRelease = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
132 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RELEASE));
133 if (!mRetain || !mRelease) {
134 ALOGE("invalid gralloc1 device");
135 gralloc1_close(mDevice);
136 return false;
137 }
138 } else {
139 mModule = reinterpret_cast<const gralloc_module_t*>(module);
140 }
141
142 return true;
143}
144
145void HandleImporter::closeGralloc() {
146 if (mDevice) {
147 gralloc1_close(mDevice);
148 }
149}
150
151buffer_handle_t HandleImporter::cloneBuffer(buffer_handle_t handle) {
152 native_handle_t* clone = native_handle_clone(handle);
153 if (!clone) {
154 ALOGE("failed to clone buffer %p", handle);
155 return nullptr;
156 }
157
158 bool err;
159 if (mDevice) {
160 err = (mRetain(mDevice, clone) != GRALLOC1_ERROR_NONE);
161 } else {
162 err = (mModule->registerBuffer(mModule, clone) != 0);
163 }
164
165 if (err) {
166 ALOGE("failed to retain/register buffer %p", clone);
167 native_handle_close(clone);
168 native_handle_delete(clone);
169 return nullptr;
170 }
171
172 return clone;
173}
174
175void HandleImporter::releaseBuffer(buffer_handle_t handle) {
176 if (mDevice) {
177 mRelease(mDevice, handle);
178 } else {
179 mModule->unregisterBuffer(mModule, handle);
180 }
181 native_handle_close(handle);
182 native_handle_delete(const_cast<native_handle_t*>(handle));
183}
184
185} // namespace helper
186} // namespace V1_0
187} // namespace common
188} // namespace camera
189} // namespace hardware
190} // namespace android