blob: 6441af63962f0133e208f2b03f61609578bcb181 [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 Wu78b63dc2017-04-19 11:03:00 -070039namespace {
40
41class RegisteredHandlePool {
42 public:
43 bool add(buffer_handle_t bufferHandle) {
44 std::lock_guard<std::mutex> lock(mMutex);
45 return mHandles.insert(bufferHandle).second;
46 }
47
48 native_handle_t* pop(void* buffer) {
49 auto bufferHandle = static_cast<native_handle_t*>(buffer);
50
51 std::lock_guard<std::mutex> lock(mMutex);
52 return mHandles.erase(bufferHandle) == 1 ? bufferHandle : nullptr;
53 }
54
55 buffer_handle_t get(const void* buffer) {
56 auto bufferHandle = static_cast<buffer_handle_t>(buffer);
57
58 std::lock_guard<std::mutex> lock(mMutex);
59 return mHandles.count(bufferHandle) == 1 ? bufferHandle : nullptr;
60 }
61
62 private:
63 std::mutex mMutex;
64 std::unordered_set<buffer_handle_t> mHandles;
65};
66
67// GraphicBufferMapper is expected to be valid (and leaked) during process
68// termination. We need to make sure IMapper, and in turn, gRegisteredHandles
69// are valid as well. Create the registered handle pool on the heap, and let
70// it leak for simplicity.
71//
72// However, there is no way to make sure gralloc0/gralloc1 are valid. Any use
73// of static/global object in gralloc0/gralloc1 that may have been destructed
74// is potentially broken.
75RegisteredHandlePool* gRegisteredHandles = new RegisteredHandlePool;
76
77} // anonymous namespace
Chia-I Wu0f215c52016-10-11 11:48:21 +080078
Chia-I Wu79d13ff2017-03-31 12:48:11 -070079bool GrallocMapper::validateDescriptorInfo(
80 const BufferDescriptorInfo& descriptorInfo) const {
81 const uint64_t validUsageBits =
82 BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
83 BufferUsage::GPU_TEXTURE | BufferUsage::GPU_RENDER_TARGET |
84 BufferUsage::COMPOSER_OVERLAY | BufferUsage::COMPOSER_CLIENT_TARGET |
85 BufferUsage::PROTECTED | BufferUsage::COMPOSER_CURSOR |
86 BufferUsage::VIDEO_ENCODER | BufferUsage::CAMERA_OUTPUT |
87 BufferUsage::CAMERA_INPUT | BufferUsage::RENDERSCRIPT |
88 BufferUsage::VIDEO_DECODER | BufferUsage::SENSOR_DIRECT_DATA |
89 BufferUsage::GPU_DATA_BUFFER | BufferUsage::VENDOR_MASK |
90 (mCapabilities.highUsageBits ? BufferUsage::VENDOR_MASK_HI
91 : static_cast<BufferUsage>(0));
Chia-I Wu0f215c52016-10-11 11:48:21 +080092
Chia-I Wu79d13ff2017-03-31 12:48:11 -070093 if (!descriptorInfo.width || !descriptorInfo.height ||
94 !descriptorInfo.layerCount) {
Chia-I Wu158d5302016-10-04 06:00:12 +080095 return false;
96 }
97
Chia-I Wu79d13ff2017-03-31 12:48:11 -070098 if (!mCapabilities.layeredBuffers && descriptorInfo.layerCount > 1) {
99 return false;
Chia-I Wu939e4012016-12-12 21:51:33 +0800100 }
101
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700102 if (descriptorInfo.format == static_cast<PixelFormat>(0)) {
103 return false;
Chia-I Wu158d5302016-10-04 06:00:12 +0800104 }
105
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700106 if (descriptorInfo.usage & ~validUsageBits) {
107 // could not fail as gralloc may use the reserved bits...
108 ALOGW("buffer descriptor with invalid usage bits 0x%" PRIx64,
109 descriptorInfo.usage & ~validUsageBits);
110 }
111
112 return true;
113}
114
115Return<void> GrallocMapper::createDescriptor(
116 const BufferDescriptorInfo& descriptorInfo, createDescriptor_cb hidl_cb) {
117 if (validateDescriptorInfo(descriptorInfo)) {
118 hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo));
119 } else {
120 hidl_cb(Error::BAD_VALUE, BufferDescriptor());
121 }
122
Chia-I Wu158d5302016-10-04 06:00:12 +0800123 return Void();
124}
125
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700126Return<void> GrallocMapper::importBuffer(const hidl_handle& rawHandle,
127 importBuffer_cb hidl_cb) {
128 // importing an already imported handle rather than a raw handle
Chia-I Wu78b63dc2017-04-19 11:03:00 -0700129 if (gRegisteredHandles->get(rawHandle.getNativeHandle())) {
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700130 hidl_cb(Error::BAD_BUFFER, nullptr);
131 return Void();
132 }
Chia-I Wu158d5302016-10-04 06:00:12 +0800133
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700134 if (!rawHandle.getNativeHandle()) {
135 hidl_cb(Error::BAD_BUFFER, nullptr);
136 return Void();
137 }
Chia-I Wu158d5302016-10-04 06:00:12 +0800138
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700139 native_handle_t* bufferHandle =
140 native_handle_clone(rawHandle.getNativeHandle());
141 if (!bufferHandle) {
Chia-I Wu158d5302016-10-04 06:00:12 +0800142 hidl_cb(Error::NO_RESOURCES, nullptr);
143 return Void();
144 }
145
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700146 Error error = registerBuffer(bufferHandle);
147 if (error != Error::NONE) {
148 native_handle_close(bufferHandle);
149 native_handle_delete(bufferHandle);
150
151 hidl_cb(error, nullptr);
152 return Void();
153 }
154
155 // The newly cloned handle is already registered? This can only happen
156 // when a handle previously registered was native_handle_delete'd instead
157 // of freeBuffer'd.
Chia-I Wu78b63dc2017-04-19 11:03:00 -0700158 if (!gRegisteredHandles->add(bufferHandle)) {
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700159 ALOGE("handle %p has already been imported; potential fd leaking",
160 bufferHandle);
161 unregisterBuffer(bufferHandle);
162 if (!mCapabilities.unregisterImplyDelete) {
163 native_handle_close(bufferHandle);
164 native_handle_delete(bufferHandle);
165 }
166
167 hidl_cb(Error::NO_RESOURCES, nullptr);
168 return Void();
169 }
170
171 hidl_cb(Error::NONE, bufferHandle);
172 return Void();
173}
174
175Return<Error> GrallocMapper::freeBuffer(void* buffer) {
Chia-I Wu78b63dc2017-04-19 11:03:00 -0700176 native_handle_t* bufferHandle = gRegisteredHandles->pop(buffer);
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700177 if (!bufferHandle) {
178 return Error::BAD_BUFFER;
179 }
180
181 unregisterBuffer(bufferHandle);
182 if (!mCapabilities.unregisterImplyDelete) {
183 native_handle_close(bufferHandle);
184 native_handle_delete(bufferHandle);
185 }
186
187 return Error::NONE;
188}
189
190void GrallocMapper::waitFenceFd(int fenceFd, const char* logname) {
191 if (fenceFd < 0) {
192 return;
193 }
194
195 const int warningTimeout = 3500;
196 const int error = sync_wait(fenceFd, warningTimeout);
197 if (error < 0 && errno == ETIME) {
198 ALOGE("%s: fence %d didn't signal in %u ms", logname, fenceFd,
199 warningTimeout);
200 sync_wait(fenceFd, -1);
201 }
202}
203
204bool GrallocMapper::getFenceFd(const hidl_handle& fenceHandle,
205 int* outFenceFd) {
206 auto handle = fenceHandle.getNativeHandle();
207 if (handle && handle->numFds > 1) {
208 ALOGE("invalid fence handle with %d fds", handle->numFds);
209 return false;
210 }
211
212 *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
213 return true;
214}
215
216hidl_handle GrallocMapper::getFenceHandle(int fenceFd, char* handleStorage) {
217 native_handle_t* handle = nullptr;
218 if (fenceFd >= 0) {
219 handle = native_handle_init(handleStorage, 1, 0);
220 handle->data[0] = fenceFd;
221 }
222
223 return hidl_handle(handle);
224}
225
226Return<void> GrallocMapper::lock(void* buffer, uint64_t cpuUsage,
227 const IMapper::Rect& accessRegion,
228 const hidl_handle& acquireFence,
229 lock_cb hidl_cb) {
Chia-I Wu78b63dc2017-04-19 11:03:00 -0700230 buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700231 if (!bufferHandle) {
232 hidl_cb(Error::BAD_BUFFER, nullptr);
233 return Void();
234 }
235
236 int fenceFd;
237 if (!getFenceFd(acquireFence, &fenceFd)) {
238 hidl_cb(Error::BAD_VALUE, nullptr);
239 return Void();
240 }
241
Chia-I Wu158d5302016-10-04 06:00:12 +0800242 void* data = nullptr;
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700243 Error error =
244 lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data);
Chia-I Wu158d5302016-10-04 06:00:12 +0800245
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700246 hidl_cb(error, data);
Chia-I Wu158d5302016-10-04 06:00:12 +0800247 return Void();
248}
249
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700250Return<void> GrallocMapper::lockYCbCr(void* buffer, uint64_t cpuUsage,
251 const IMapper::Rect& accessRegion,
252 const hidl_handle& acquireFence,
253 lockYCbCr_cb hidl_cb) {
254 YCbCrLayout layout = {};
Chia-I Wu158d5302016-10-04 06:00:12 +0800255
Chia-I Wu78b63dc2017-04-19 11:03:00 -0700256 buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700257 if (!bufferHandle) {
258 hidl_cb(Error::BAD_BUFFER, layout);
Chia-I Wu158d5302016-10-04 06:00:12 +0800259 return Void();
260 }
261
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700262 int fenceFd;
263 if (!getFenceFd(acquireFence, &fenceFd)) {
264 hidl_cb(Error::BAD_VALUE, layout);
Chia-I Wu158d5302016-10-04 06:00:12 +0800265 return Void();
266 }
267
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700268 Error error =
269 lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &layout);
Chia-I Wu158d5302016-10-04 06:00:12 +0800270
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700271 hidl_cb(error, layout);
272 return Void();
273}
Chia-I Wu158d5302016-10-04 06:00:12 +0800274
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700275Return<void> GrallocMapper::unlock(void* buffer, unlock_cb hidl_cb) {
Chia-I Wu78b63dc2017-04-19 11:03:00 -0700276 buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700277 if (!bufferHandle) {
278 hidl_cb(Error::BAD_BUFFER, nullptr);
279 return Void();
280 }
281
282 int fenceFd;
283 Error error = unlockBuffer(bufferHandle, &fenceFd);
284 if (error == Error::NONE) {
285 NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
286
287 hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
288
289 if (fenceFd >= 0) {
290 close(fenceFd);
291 }
Craig Donner0b00adf2016-10-20 17:12:58 -0700292 } else {
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700293 hidl_cb(error, nullptr);
Craig Donner0b00adf2016-10-20 17:12:58 -0700294 }
Chia-I Wu158d5302016-10-04 06:00:12 +0800295
Chia-I Wu158d5302016-10-04 06:00:12 +0800296 return Void();
Craig Donner0b00adf2016-10-20 17:12:58 -0700297}
298
Chia-I Wu158d5302016-10-04 06:00:12 +0800299IMapper* HIDL_FETCH_IMapper(const char* /* name */) {
300 const hw_module_t* module = nullptr;
301 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
302 if (err) {
303 ALOGE("failed to get gralloc module");
304 return nullptr;
Chia-I Wu0f215c52016-10-11 11:48:21 +0800305 }
306
Chia-I Wu158d5302016-10-04 06:00:12 +0800307 uint8_t major = (module->module_api_version >> 8) & 0xff;
Chia-I Wu79d13ff2017-03-31 12:48:11 -0700308 switch (major) {
309 case 1:
310 return new Gralloc1Mapper(module);
311 case 0:
312 return new Gralloc0Mapper(module);
313 default:
314 ALOGE("unknown gralloc module major version %d", major);
315 return nullptr;
Chia-I Wu0f215c52016-10-11 11:48:21 +0800316 }
Chia-I Wu0f215c52016-10-11 11:48:21 +0800317}
318
319} // namespace implementation
320} // namespace V2_0
321} // namespace mapper
322} // namespace graphics
323} // namespace hardware
324} // namespace android