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