blob: 339317aff87ce16e00b3111faa5ae04908670ffa [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
Chia-I Wu158d5302016-10-04 06:00:12 +080018#include "GrallocMapper.h"
19
Chia-I Wu79d13ff2017-03-31 12:48:11 -070020#include "Gralloc0Mapper.h"
21#include "Gralloc1Mapper.h"
22#include "GrallocBufferDescriptor.h"
Chia-I Wu158d5302016-10-04 06:00:12 +080023
Chia-I Wu79d13ff2017-03-31 12:48:11 -070024#include <inttypes.h>
Chia-I Wu158d5302016-10-04 06:00:12 +080025
Chia-I Wu0f215c52016-10-11 11:48:21 +080026#include <log/log.h>
Chia-I Wu79d13ff2017-03-31 12:48:11 -070027#include <sync/sync.h>
Chia-I Wu0f215c52016-10-11 11:48:21 +080028
29namespace android {
30namespace hardware {
31namespace graphics {
32namespace mapper {
33namespace V2_0 {
34namespace implementation {
35
Chia-I Wu79d13ff2017-03-31 12:48:11 -070036using android::hardware::graphics::common::V1_0::BufferUsage;
Chia-I Wu158d5302016-10-04 06:00:12 +080037using android::hardware::graphics::common::V1_0::PixelFormat;
38
Chia-I Wu79d13ff2017-03-31 12:48:11 -070039std::mutex GrallocMapper::mMutex;
40std::unordered_set<buffer_handle_t> GrallocMapper::mRegisteredHandles;
Chia-I Wu0f215c52016-10-11 11:48:21 +080041
Chia-I Wu79d13ff2017-03-31 12:48:11 -070042bool GrallocMapper::validateDescriptorInfo(
43 const BufferDescriptorInfo& descriptorInfo) const {
44 const uint64_t validUsageBits =
45 BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
46 BufferUsage::GPU_TEXTURE | BufferUsage::GPU_RENDER_TARGET |
47 BufferUsage::COMPOSER_OVERLAY | BufferUsage::COMPOSER_CLIENT_TARGET |
48 BufferUsage::PROTECTED | BufferUsage::COMPOSER_CURSOR |
49 BufferUsage::VIDEO_ENCODER | BufferUsage::CAMERA_OUTPUT |
50 BufferUsage::CAMERA_INPUT | BufferUsage::RENDERSCRIPT |
51 BufferUsage::VIDEO_DECODER | BufferUsage::SENSOR_DIRECT_DATA |
52 BufferUsage::GPU_DATA_BUFFER | BufferUsage::VENDOR_MASK |
53 (mCapabilities.highUsageBits ? BufferUsage::VENDOR_MASK_HI
54 : static_cast<BufferUsage>(0));
Chia-I Wu0f215c52016-10-11 11:48:21 +080055
Chia-I Wu79d13ff2017-03-31 12:48:11 -070056 if (!descriptorInfo.width || !descriptorInfo.height ||
57 !descriptorInfo.layerCount) {
Chia-I Wu158d5302016-10-04 06:00:12 +080058 return false;
59 }
60
Chia-I Wu79d13ff2017-03-31 12:48:11 -070061 if (!mCapabilities.layeredBuffers && descriptorInfo.layerCount > 1) {
62 return false;
Chia-I Wu939e4012016-12-12 21:51:33 +080063 }
64
Chia-I Wu79d13ff2017-03-31 12:48:11 -070065 if (descriptorInfo.format == static_cast<PixelFormat>(0)) {
66 return false;
Chia-I Wu158d5302016-10-04 06:00:12 +080067 }
68
Chia-I Wu79d13ff2017-03-31 12:48:11 -070069 if (descriptorInfo.usage & ~validUsageBits) {
70 // could not fail as gralloc may use the reserved bits...
71 ALOGW("buffer descriptor with invalid usage bits 0x%" PRIx64,
72 descriptorInfo.usage & ~validUsageBits);
73 }
74
75 return true;
76}
77
78Return<void> GrallocMapper::createDescriptor(
79 const BufferDescriptorInfo& descriptorInfo, createDescriptor_cb hidl_cb) {
80 if (validateDescriptorInfo(descriptorInfo)) {
81 hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo));
82 } else {
83 hidl_cb(Error::BAD_VALUE, BufferDescriptor());
84 }
85
Chia-I Wu158d5302016-10-04 06:00:12 +080086 return Void();
87}
88
Chia-I Wu79d13ff2017-03-31 12:48:11 -070089bool GrallocMapper::addRegisteredHandle(buffer_handle_t bufferHandle) {
90 std::lock_guard<std::mutex> lock(mMutex);
91 return mRegisteredHandles.insert(bufferHandle).second;
Chia-I Wu158d5302016-10-04 06:00:12 +080092}
93
Chia-I Wu79d13ff2017-03-31 12:48:11 -070094native_handle_t* GrallocMapper::popRegisteredHandle(void* buffer) {
95 auto bufferHandle = static_cast<native_handle_t*>(buffer);
Chia-I Wu158d5302016-10-04 06:00:12 +080096
Chia-I Wu79d13ff2017-03-31 12:48:11 -070097 std::lock_guard<std::mutex> lock(mMutex);
98 return mRegisteredHandles.erase(bufferHandle) == 1 ? bufferHandle : nullptr;
Chia-I Wu158d5302016-10-04 06:00:12 +080099}
100
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700101buffer_handle_t GrallocMapper::getRegisteredHandle(const void* buffer) {
102 auto bufferHandle = static_cast<buffer_handle_t>(buffer);
Chia-I Wu158d5302016-10-04 06:00:12 +0800103
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700104 std::lock_guard<std::mutex> lock(mMutex);
105 return mRegisteredHandles.count(bufferHandle) == 1 ? bufferHandle : nullptr;
Chia-I Wu158d5302016-10-04 06:00:12 +0800106}
107
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700108Return<void> GrallocMapper::importBuffer(const hidl_handle& rawHandle,
109 importBuffer_cb hidl_cb) {
110 // importing an already imported handle rather than a raw handle
111 if (getRegisteredHandle(rawHandle.getNativeHandle())) {
112 hidl_cb(Error::BAD_BUFFER, nullptr);
113 return Void();
114 }
Chia-I Wu158d5302016-10-04 06:00:12 +0800115
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700116 if (!rawHandle.getNativeHandle()) {
117 hidl_cb(Error::BAD_BUFFER, nullptr);
118 return Void();
119 }
Chia-I Wu158d5302016-10-04 06:00:12 +0800120
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700121 native_handle_t* bufferHandle =
122 native_handle_clone(rawHandle.getNativeHandle());
123 if (!bufferHandle) {
Chia-I Wu158d5302016-10-04 06:00:12 +0800124 hidl_cb(Error::NO_RESOURCES, nullptr);
125 return Void();
126 }
127
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700128 Error error = registerBuffer(bufferHandle);
129 if (error != Error::NONE) {
130 native_handle_close(bufferHandle);
131 native_handle_delete(bufferHandle);
132
133 hidl_cb(error, nullptr);
134 return Void();
135 }
136
137 // The newly cloned handle is already registered? This can only happen
138 // when a handle previously registered was native_handle_delete'd instead
139 // of freeBuffer'd.
140 if (!addRegisteredHandle(bufferHandle)) {
141 ALOGE("handle %p has already been imported; potential fd leaking",
142 bufferHandle);
143 unregisterBuffer(bufferHandle);
144 if (!mCapabilities.unregisterImplyDelete) {
145 native_handle_close(bufferHandle);
146 native_handle_delete(bufferHandle);
147 }
148
149 hidl_cb(Error::NO_RESOURCES, nullptr);
150 return Void();
151 }
152
153 hidl_cb(Error::NONE, bufferHandle);
154 return Void();
155}
156
157Return<Error> GrallocMapper::freeBuffer(void* buffer) {
158 native_handle_t* bufferHandle = popRegisteredHandle(buffer);
159 if (!bufferHandle) {
160 return Error::BAD_BUFFER;
161 }
162
163 unregisterBuffer(bufferHandle);
164 if (!mCapabilities.unregisterImplyDelete) {
165 native_handle_close(bufferHandle);
166 native_handle_delete(bufferHandle);
167 }
168
169 return Error::NONE;
170}
171
172void GrallocMapper::waitFenceFd(int fenceFd, const char* logname) {
173 if (fenceFd < 0) {
174 return;
175 }
176
177 const int warningTimeout = 3500;
178 const int error = sync_wait(fenceFd, warningTimeout);
179 if (error < 0 && errno == ETIME) {
180 ALOGE("%s: fence %d didn't signal in %u ms", logname, fenceFd,
181 warningTimeout);
182 sync_wait(fenceFd, -1);
183 }
184}
185
186bool GrallocMapper::getFenceFd(const hidl_handle& fenceHandle,
187 int* outFenceFd) {
188 auto handle = fenceHandle.getNativeHandle();
189 if (handle && handle->numFds > 1) {
190 ALOGE("invalid fence handle with %d fds", handle->numFds);
191 return false;
192 }
193
194 *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
195 return true;
196}
197
198hidl_handle GrallocMapper::getFenceHandle(int fenceFd, char* handleStorage) {
199 native_handle_t* handle = nullptr;
200 if (fenceFd >= 0) {
201 handle = native_handle_init(handleStorage, 1, 0);
202 handle->data[0] = fenceFd;
203 }
204
205 return hidl_handle(handle);
206}
207
208Return<void> GrallocMapper::lock(void* buffer, uint64_t cpuUsage,
209 const IMapper::Rect& accessRegion,
210 const hidl_handle& acquireFence,
211 lock_cb hidl_cb) {
212 buffer_handle_t bufferHandle = getRegisteredHandle(buffer);
213 if (!bufferHandle) {
214 hidl_cb(Error::BAD_BUFFER, nullptr);
215 return Void();
216 }
217
218 int fenceFd;
219 if (!getFenceFd(acquireFence, &fenceFd)) {
220 hidl_cb(Error::BAD_VALUE, nullptr);
221 return Void();
222 }
223
Chia-I Wu158d5302016-10-04 06:00:12 +0800224 void* data = nullptr;
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700225 Error error =
226 lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data);
Chia-I Wu158d5302016-10-04 06:00:12 +0800227
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700228 hidl_cb(error, data);
Chia-I Wu158d5302016-10-04 06:00:12 +0800229 return Void();
230}
231
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700232Return<void> GrallocMapper::lockYCbCr(void* buffer, uint64_t cpuUsage,
233 const IMapper::Rect& accessRegion,
234 const hidl_handle& acquireFence,
235 lockYCbCr_cb hidl_cb) {
236 YCbCrLayout layout = {};
Chia-I Wu158d5302016-10-04 06:00:12 +0800237
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700238 buffer_handle_t bufferHandle = getRegisteredHandle(buffer);
239 if (!bufferHandle) {
240 hidl_cb(Error::BAD_BUFFER, layout);
Chia-I Wu158d5302016-10-04 06:00:12 +0800241 return Void();
242 }
243
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700244 int fenceFd;
245 if (!getFenceFd(acquireFence, &fenceFd)) {
246 hidl_cb(Error::BAD_VALUE, layout);
Chia-I Wu158d5302016-10-04 06:00:12 +0800247 return Void();
248 }
249
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700250 Error error =
251 lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &layout);
Chia-I Wu158d5302016-10-04 06:00:12 +0800252
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700253 hidl_cb(error, layout);
254 return Void();
255}
Chia-I Wu158d5302016-10-04 06:00:12 +0800256
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700257Return<void> GrallocMapper::unlock(void* buffer, unlock_cb hidl_cb) {
258 buffer_handle_t bufferHandle = getRegisteredHandle(buffer);
259 if (!bufferHandle) {
260 hidl_cb(Error::BAD_BUFFER, nullptr);
261 return Void();
262 }
263
264 int fenceFd;
265 Error error = unlockBuffer(bufferHandle, &fenceFd);
266 if (error == Error::NONE) {
267 NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
268
269 hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
270
271 if (fenceFd >= 0) {
272 close(fenceFd);
273 }
Craig Donner0b00adf2016-10-20 17:12:58 -0700274 } else {
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700275 hidl_cb(error, nullptr);
Craig Donner0b00adf2016-10-20 17:12:58 -0700276 }
Chia-I Wu158d5302016-10-04 06:00:12 +0800277
Chia-I Wu158d5302016-10-04 06:00:12 +0800278 return Void();
Craig Donner0b00adf2016-10-20 17:12:58 -0700279}
280
Chia-I Wu158d5302016-10-04 06:00:12 +0800281IMapper* HIDL_FETCH_IMapper(const char* /* name */) {
282 const hw_module_t* module = nullptr;
283 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
284 if (err) {
285 ALOGE("failed to get gralloc module");
286 return nullptr;
Chia-I Wu0f215c52016-10-11 11:48:21 +0800287 }
288
Chia-I Wu158d5302016-10-04 06:00:12 +0800289 uint8_t major = (module->module_api_version >> 8) & 0xff;
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700290 switch (major) {
291 case 1:
292 return new Gralloc1Mapper(module);
293 case 0:
294 return new Gralloc0Mapper(module);
295 default:
296 ALOGE("unknown gralloc module major version %d", major);
297 return nullptr;
Chia-I Wu0f215c52016-10-11 11:48:21 +0800298 }
Chia-I Wu0f215c52016-10-11 11:48:21 +0800299}
300
301} // namespace implementation
302} // namespace V2_0
303} // namespace mapper
304} // namespace graphics
305} // namespace hardware
306} // namespace android