blob: b09fdc61a611613564d385b0238c4bed69e56ed8 [file] [log] [blame]
Dan Stozaeb03fd32016-01-11 15:21:07 -08001/*
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#ifndef ANDROID_UI_GRALLOC_1_ON_0_ADAPTER_H
18#define ANDROID_UI_GRALLOC_1_ON_0_ADAPTER_H
19
Mathias Agopiana9347642017-02-13 16:42:28 -080020#include <log/log.h>
Dan Stozaeb03fd32016-01-11 15:21:07 -080021
Mathias Agopiana9347642017-02-13 16:42:28 -080022#include <ui/Fence.h>
23
24#include <hardware/gralloc.h>
Dan Stozaeb03fd32016-01-11 15:21:07 -080025#include <hardware/gralloc1.h>
26
27#include <mutex>
28#include <string>
29#include <unordered_map>
30#include <vector>
31
Mathias Agopiana9347642017-02-13 16:42:28 -080032namespace android {
33class GraphicBuffer;
34} // namespace android
35
Dan Stozaeb03fd32016-01-11 15:21:07 -080036struct gralloc_module_t;
37
38// This is not an "official" capability (i.e., it is not found in gralloc1.h),
39// but we will use it to detect that we are running through the adapter, which
40// is capable of collaborating with GraphicBuffer such that queries on a
41// buffer_handle_t succeed
42static const auto GRALLOC1_CAPABILITY_ON_ADAPTER =
43 static_cast<gralloc1_capability_t>(GRALLOC1_LAST_CAPABILITY + 1);
44
45static const auto GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER =
46 static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 1);
47static const auto GRALLOC1_FUNCTION_ALLOCATE_WITH_ID =
48 static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 2);
49static const auto GRALLOC1_FUNCTION_LOCK_YCBCR =
50 static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 3);
51static const auto GRALLOC1_LAST_ADAPTER_FUNCTION = GRALLOC1_FUNCTION_LOCK_YCBCR;
52
53typedef gralloc1_error_t (*GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER)(
54 gralloc1_device_t* device, const android::GraphicBuffer* buffer);
55typedef gralloc1_error_t (*GRALLOC1_PFN_ALLOCATE_WITH_ID)(
56 gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
57 gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
58typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_LOCK_YCBCR)(
59 gralloc1_device_t* device, buffer_handle_t buffer,
60 uint64_t /*gralloc1_producer_usage_t*/ producerUsage,
61 uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage,
62 const gralloc1_rect_t* accessRegion, struct android_ycbcr* outYCbCr,
63 int32_t acquireFence);
64
65namespace android {
66
67class Gralloc1On0Adapter : public gralloc1_device_t
68{
69public:
70 Gralloc1On0Adapter(const hw_module_t* module);
71 ~Gralloc1On0Adapter();
72
73 gralloc1_device_t* getDevice() {
74 return static_cast<gralloc1_device_t*>(this);
75 }
76
77private:
78 static inline Gralloc1On0Adapter* getAdapter(gralloc1_device_t* device) {
79 return static_cast<Gralloc1On0Adapter*>(device);
80 }
81
82 // getCapabilities
83
84 void doGetCapabilities(uint32_t* outCount,
85 int32_t* /*gralloc1_capability_t*/ outCapabilities);
86 static void getCapabilitiesHook(gralloc1_device_t* device,
87 uint32_t* outCount,
88 int32_t* /*gralloc1_capability_t*/ outCapabilities) {
89 getAdapter(device)->doGetCapabilities(outCount, outCapabilities);
Colin Cross17576de2016-09-26 13:07:06 -070090 }
Dan Stozaeb03fd32016-01-11 15:21:07 -080091
92 // getFunction
93
94 gralloc1_function_pointer_t doGetFunction(
95 int32_t /*gralloc1_function_descriptor_t*/ descriptor);
96 static gralloc1_function_pointer_t getFunctionHook(
97 gralloc1_device_t* device,
98 int32_t /*gralloc1_function_descriptor_t*/ descriptor) {
99 return getAdapter(device)->doGetFunction(descriptor);
100 }
101
102 // dump
103
104 void dump(uint32_t* outSize, char* outBuffer);
105 static void dumpHook(gralloc1_device_t* device, uint32_t* outSize,
106 char* outBuffer) {
107 return getAdapter(device)->dump(outSize, outBuffer);
108 }
109 std::string mCachedDump;
110
111 // Buffer descriptor lifecycle functions
112
Colin Crossa2362b42016-09-26 13:48:25 -0700113 struct Descriptor;
Dan Stozaeb03fd32016-01-11 15:21:07 -0800114
115 gralloc1_error_t createDescriptor(
116 gralloc1_buffer_descriptor_t* outDescriptor);
117 static int32_t createDescriptorHook(gralloc1_device_t* device,
118 gralloc1_buffer_descriptor_t* outDescriptor) {
119 auto error = getAdapter(device)->createDescriptor(outDescriptor);
120 return static_cast<int32_t>(error);
121 }
122
123 gralloc1_error_t destroyDescriptor(gralloc1_buffer_descriptor_t descriptor);
124 static int32_t destroyDescriptorHook(gralloc1_device_t* device,
125 gralloc1_buffer_descriptor_t descriptor) {
126 auto error = getAdapter(device)->destroyDescriptor(descriptor);
127 return static_cast<int32_t>(error);
128 }
129
130 // Buffer descriptor modification functions
131
132 struct Descriptor : public std::enable_shared_from_this<Descriptor> {
Colin Cross382ecd32016-09-26 13:33:59 -0700133 Descriptor(Gralloc1On0Adapter* _adapter,
134 gralloc1_buffer_descriptor_t _id)
135 : adapter(_adapter),
136 id(_id),
Dan Stozaeb03fd32016-01-11 15:21:07 -0800137 width(0),
138 height(0),
139 format(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
Craig Donner6ebc46a2016-10-21 15:23:44 -0700140 layerCount(1),
Dan Stozaeb03fd32016-01-11 15:21:07 -0800141 producerUsage(GRALLOC1_PRODUCER_USAGE_NONE),
142 consumerUsage(GRALLOC1_CONSUMER_USAGE_NONE) {}
143
144 gralloc1_error_t setDimensions(uint32_t w, uint32_t h) {
145 width = w;
146 height = h;
147 return GRALLOC1_ERROR_NONE;
148 }
149
150 gralloc1_error_t setFormat(int32_t f) {
151 format = f;
152 return GRALLOC1_ERROR_NONE;
153 }
154
Craig Donner6ebc46a2016-10-21 15:23:44 -0700155 gralloc1_error_t setLayerCount(uint32_t lc) {
156 layerCount = lc;
157 return GRALLOC1_ERROR_NONE;
158 }
159
Dan Stozaeb03fd32016-01-11 15:21:07 -0800160 gralloc1_error_t setProducerUsage(gralloc1_producer_usage_t usage) {
161 producerUsage = usage;
162 return GRALLOC1_ERROR_NONE;
163 }
164
165 gralloc1_error_t setConsumerUsage(gralloc1_consumer_usage_t usage) {
166 consumerUsage = usage;
167 return GRALLOC1_ERROR_NONE;
168 }
169
170 Gralloc1On0Adapter* const adapter;
171 const gralloc1_buffer_descriptor_t id;
172
173 uint32_t width;
174 uint32_t height;
175 int32_t format;
Craig Donner6ebc46a2016-10-21 15:23:44 -0700176 uint32_t layerCount;
Dan Stozaeb03fd32016-01-11 15:21:07 -0800177 gralloc1_producer_usage_t producerUsage;
178 gralloc1_consumer_usage_t consumerUsage;
179 };
180
181 template <typename ...Args>
182 static int32_t callDescriptorFunction(gralloc1_device_t* device,
183 gralloc1_buffer_descriptor_t descriptorId,
184 gralloc1_error_t (Descriptor::*member)(Args...), Args... args) {
185 auto descriptor = getAdapter(device)->getDescriptor(descriptorId);
186 if (!descriptor) {
187 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
188 }
189 auto error = ((*descriptor).*member)(std::forward<Args>(args)...);
190 return static_cast<int32_t>(error);
191 }
192
193 static int32_t setConsumerUsageHook(gralloc1_device_t* device,
194 gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) {
195 auto usage = static_cast<gralloc1_consumer_usage_t>(intUsage);
196 return callDescriptorFunction(device, descriptorId,
197 &Descriptor::setConsumerUsage, usage);
198 }
199
200 static int32_t setDimensionsHook(gralloc1_device_t* device,
201 gralloc1_buffer_descriptor_t descriptorId, uint32_t width,
202 uint32_t height) {
203 return callDescriptorFunction(device, descriptorId,
204 &Descriptor::setDimensions, width, height);
205 }
206
207 static int32_t setFormatHook(gralloc1_device_t* device,
208 gralloc1_buffer_descriptor_t descriptorId, int32_t format) {
209 return callDescriptorFunction(device, descriptorId,
210 &Descriptor::setFormat, format);
211 }
212
Craig Donner6ebc46a2016-10-21 15:23:44 -0700213 static int32_t setLayerCountHook(gralloc1_device_t* device,
214 gralloc1_buffer_descriptor_t descriptorId, uint32_t layerCount) {
215 return callDescriptorFunction(device, descriptorId,
216 &Descriptor::setLayerCount, layerCount);
217 }
218
Dan Stozaeb03fd32016-01-11 15:21:07 -0800219 static int32_t setProducerUsageHook(gralloc1_device_t* device,
220 gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) {
221 auto usage = static_cast<gralloc1_producer_usage_t>(intUsage);
222 return callDescriptorFunction(device, descriptorId,
223 &Descriptor::setProducerUsage, usage);
224 }
225
226 // Buffer handle query functions
227
228 class Buffer {
229 public:
230 Buffer(buffer_handle_t handle, gralloc1_backing_store_t store,
231 const Descriptor& descriptor, uint32_t stride,
232 bool wasAllocated);
233
234 buffer_handle_t getHandle() const { return mHandle; }
235
236 void retain() { ++mReferenceCount; }
237
238 // Returns true if the reference count has dropped to 0, indicating that
239 // the buffer needs to be released
240 bool release() { return --mReferenceCount == 0; }
241
242 bool wasAllocated() const { return mWasAllocated; }
243
244 gralloc1_error_t getBackingStore(
245 gralloc1_backing_store_t* outStore) const {
246 *outStore = mStore;
247 return GRALLOC1_ERROR_NONE;
248 }
249
250 gralloc1_error_t getConsumerUsage(
251 gralloc1_consumer_usage_t* outUsage) const {
252 *outUsage = mDescriptor.consumerUsage;
253 return GRALLOC1_ERROR_NONE;
254 }
255
256 gralloc1_error_t getDimensions(uint32_t* outWidth,
257 uint32_t* outHeight) const {
258 *outWidth = mDescriptor.width;
259 *outHeight = mDescriptor.height;
260 return GRALLOC1_ERROR_NONE;
261 }
262
263 gralloc1_error_t getFormat(int32_t* outFormat) const {
264 *outFormat = mDescriptor.format;
265 return GRALLOC1_ERROR_NONE;
266 }
267
Craig Donner6ebc46a2016-10-21 15:23:44 -0700268 gralloc1_error_t getLayerCount(uint32_t* outLayerCount) const {
269 *outLayerCount = mDescriptor.layerCount;
270 return GRALLOC1_ERROR_NONE;
271 }
272
Dan Stozaeb03fd32016-01-11 15:21:07 -0800273 gralloc1_error_t getNumFlexPlanes(uint32_t* outNumPlanes) const {
274 // TODO: This is conservative, and we could do better by examining
275 // the format, but it won't hurt anything for now
276 *outNumPlanes = 4;
277 return GRALLOC1_ERROR_NONE;
278 }
279
280 gralloc1_error_t getProducerUsage(
281 gralloc1_producer_usage_t* outUsage) const {
282 *outUsage = mDescriptor.producerUsage;
283 return GRALLOC1_ERROR_NONE;
284 }
285
286 gralloc1_error_t getStride(uint32_t* outStride) const {
287 *outStride = mStride;
288 return GRALLOC1_ERROR_NONE;
289 }
290
291 private:
292
293 const buffer_handle_t mHandle;
294 size_t mReferenceCount;
295
296 // Since we're adapting to gralloc0, there will always be a 1:1
297 // correspondence between buffer handles and backing stores, and the
298 // backing store ID will be the same as the GraphicBuffer unique ID
299 const gralloc1_backing_store_t mStore;
300
301 const Descriptor mDescriptor;
302 const uint32_t mStride;
303
304 // Whether this buffer allocated in this process (as opposed to just
305 // being retained here), which determines whether to free or unregister
306 // the buffer when this Buffer is released
307 const bool mWasAllocated;
308 };
309
310 template <typename ...Args>
311 static int32_t callBufferFunction(gralloc1_device_t* device,
312 buffer_handle_t bufferHandle,
313 gralloc1_error_t (Buffer::*member)(Args...) const, Args... args) {
314 auto buffer = getAdapter(device)->getBuffer(bufferHandle);
315 if (!buffer) {
316 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
317 }
318 auto error = ((*buffer).*member)(std::forward<Args>(args)...);
319 return static_cast<int32_t>(error);
320 }
321
322 template <typename MF, MF memFunc, typename ...Args>
323 static int32_t bufferHook(gralloc1_device_t* device,
324 buffer_handle_t bufferHandle, Args... args) {
325 return Gralloc1On0Adapter::callBufferFunction(device, bufferHandle,
326 memFunc, std::forward<Args>(args)...);
327 }
328
329 static int32_t getConsumerUsageHook(gralloc1_device_t* device,
330 buffer_handle_t bufferHandle, uint64_t* outUsage) {
331 auto usage = GRALLOC1_CONSUMER_USAGE_NONE;
332 auto error = callBufferFunction(device, bufferHandle,
333 &Buffer::getConsumerUsage, &usage);
Craig Donner58a1ef22017-02-02 12:40:05 -0800334 if (error == GRALLOC1_ERROR_NONE) {
Dan Stozaeb03fd32016-01-11 15:21:07 -0800335 *outUsage = static_cast<uint64_t>(usage);
336 }
337 return error;
338 }
339
340 static int32_t getProducerUsageHook(gralloc1_device_t* device,
341 buffer_handle_t bufferHandle, uint64_t* outUsage) {
342 auto usage = GRALLOC1_PRODUCER_USAGE_NONE;
343 auto error = callBufferFunction(device, bufferHandle,
344 &Buffer::getProducerUsage, &usage);
Craig Donner58a1ef22017-02-02 12:40:05 -0800345 if (error == GRALLOC1_ERROR_NONE) {
Dan Stozaeb03fd32016-01-11 15:21:07 -0800346 *outUsage = static_cast<uint64_t>(usage);
347 }
348 return error;
349 }
350
351 // Buffer management functions
352
353 // We don't provide GRALLOC1_FUNCTION_ALLOCATE, since this should always be
354 // called through GRALLOC1_FUNCTION_ALLOCATE_WITH_ID
355 gralloc1_error_t allocate(
356 const std::shared_ptr<Descriptor>& descriptor,
357 gralloc1_backing_store_t id,
358 buffer_handle_t* outBufferHandle);
359 static gralloc1_error_t allocateWithIdHook(gralloc1_device_t* device,
360 gralloc1_buffer_descriptor_t descriptors,
361 gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
362
363 gralloc1_error_t retain(const std::shared_ptr<Buffer>& buffer);
364 gralloc1_error_t release(const std::shared_ptr<Buffer>& buffer);
365
366 // Member function pointer 'member' will either be retain or release
367 template <gralloc1_error_t (Gralloc1On0Adapter::*member)(
368 const std::shared_ptr<Buffer>& buffer)>
369 static int32_t managementHook(gralloc1_device_t* device,
370 buffer_handle_t bufferHandle) {
371 auto adapter = getAdapter(device);
372
373 auto buffer = adapter->getBuffer(bufferHandle);
374 if (!buffer) {
375 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
376 }
377
378 auto error = ((*adapter).*member)(buffer);
379 return static_cast<int32_t>(error);
380 }
381
382 gralloc1_error_t retain(const GraphicBuffer* buffer);
383 static gralloc1_error_t retainGraphicBufferHook(gralloc1_device_t* device,
384 const GraphicBuffer* buffer) {
385 auto adapter = getAdapter(device);
386 return adapter->retain(buffer);
387 }
388
389 // Buffer access functions
390
391 gralloc1_error_t lock(const std::shared_ptr<Buffer>& buffer,
392 gralloc1_producer_usage_t producerUsage,
393 gralloc1_consumer_usage_t consumerUsage,
394 const gralloc1_rect_t& accessRegion, void** outData,
395 const sp<Fence>& acquireFence);
396 gralloc1_error_t lockFlex(const std::shared_ptr<Buffer>& buffer,
397 gralloc1_producer_usage_t producerUsage,
398 gralloc1_consumer_usage_t consumerUsage,
399 const gralloc1_rect_t& accessRegion,
400 struct android_flex_layout* outFlex,
401 const sp<Fence>& acquireFence);
402 gralloc1_error_t lockYCbCr(const std::shared_ptr<Buffer>& buffer,
403 gralloc1_producer_usage_t producerUsage,
404 gralloc1_consumer_usage_t consumerUsage,
405 const gralloc1_rect_t& accessRegion,
406 struct android_ycbcr* outFlex,
407 const sp<Fence>& acquireFence);
408
409 template <typename OUT, gralloc1_error_t (Gralloc1On0Adapter::*member)(
410 const std::shared_ptr<Buffer>&, gralloc1_producer_usage_t,
411 gralloc1_consumer_usage_t, const gralloc1_rect_t&, OUT*,
412 const sp<Fence>&)>
413 static int32_t lockHook(gralloc1_device_t* device,
414 buffer_handle_t bufferHandle,
415 uint64_t /*gralloc1_producer_usage_t*/ uintProducerUsage,
416 uint64_t /*gralloc1_consumer_usage_t*/ uintConsumerUsage,
417 const gralloc1_rect_t* accessRegion, OUT* outData,
418 int32_t acquireFenceFd) {
419 auto adapter = getAdapter(device);
420
421 // Exactly one of producer and consumer usage must be *_USAGE_NONE,
422 // but we can't check this until the upper levels of the framework
423 // correctly distinguish between producer and consumer usage
424 /*
425 bool hasProducerUsage =
426 uintProducerUsage != GRALLOC1_PRODUCER_USAGE_NONE;
427 bool hasConsumerUsage =
428 uintConsumerUsage != GRALLOC1_CONSUMER_USAGE_NONE;
429 if (hasProducerUsage && hasConsumerUsage ||
430 !hasProducerUsage && !hasConsumerUsage) {
431 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
432 }
433 */
434
435 auto producerUsage =
436 static_cast<gralloc1_producer_usage_t>(uintProducerUsage);
437 auto consumerUsage =
438 static_cast<gralloc1_consumer_usage_t>(uintConsumerUsage);
439
440 if (!outData) {
441 const auto producerCpuUsage = GRALLOC1_PRODUCER_USAGE_CPU_READ |
442 GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
Colin Cross27224162016-09-27 14:09:07 -0700443 if ((producerUsage & producerCpuUsage) != 0) {
Dan Stozaeb03fd32016-01-11 15:21:07 -0800444 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
445 }
Colin Cross27224162016-09-27 14:09:07 -0700446 if ((consumerUsage & GRALLOC1_CONSUMER_USAGE_CPU_READ) != 0) {
Dan Stozaeb03fd32016-01-11 15:21:07 -0800447 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
448 }
449 }
450
451 auto buffer = adapter->getBuffer(bufferHandle);
452 if (!buffer) {
453 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
454 }
455
456 if (!accessRegion) {
457 ALOGE("accessRegion is null");
458 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
459 }
460
461 sp<Fence> acquireFence{new Fence(acquireFenceFd)};
462 auto error = ((*adapter).*member)(buffer, producerUsage, consumerUsage,
463 *accessRegion, outData, acquireFence);
464 return static_cast<int32_t>(error);
465 }
466
467 gralloc1_error_t unlock(const std::shared_ptr<Buffer>& buffer,
468 sp<Fence>* outReleaseFence);
469 static int32_t unlockHook(gralloc1_device_t* device,
470 buffer_handle_t bufferHandle, int32_t* outReleaseFenceFd) {
471 auto adapter = getAdapter(device);
472
473 auto buffer = adapter->getBuffer(bufferHandle);
474 if (!buffer) {
475 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
476 }
477
478 sp<Fence> releaseFence = Fence::NO_FENCE;
479 auto error = adapter->unlock(buffer, &releaseFence);
480 if (error == GRALLOC1_ERROR_NONE) {
481 *outReleaseFenceFd = releaseFence->dup();
482 }
483 return static_cast<int32_t>(error);
484 }
485
486 // Adapter internals
487 const gralloc_module_t* mModule;
488 uint8_t mMinorVersion;
489 alloc_device_t* mDevice;
490
491 std::shared_ptr<Descriptor> getDescriptor(
492 gralloc1_buffer_descriptor_t descriptorId);
493 std::shared_ptr<Buffer> getBuffer(buffer_handle_t bufferHandle);
494
495 static std::atomic<gralloc1_buffer_descriptor_t> sNextBufferDescriptorId;
496 std::mutex mDescriptorMutex;
497 std::unordered_map<gralloc1_buffer_descriptor_t,
498 std::shared_ptr<Descriptor>> mDescriptors;
499 std::mutex mBufferMutex;
500 std::unordered_map<buffer_handle_t, std::shared_ptr<Buffer>> mBuffers;
501};
502
503} // namespace android
504
505#endif